diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 89b7ffa10..885612f13 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,3 +1,4 @@ # These are supported funding model platforms +github: odin-lang patreon: gingerbill diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6742b56f3..d72775636 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,9 +7,9 @@ jobs: steps: - uses: actions/checkout@v1 - name: Download LLVM, botan - run: sudo apt-get install llvm-11 clang-11 llvm libbotan-2-dev botan + run: sudo apt-get install llvm-11 clang-11 libbotan-2-dev botan - name: build odin - run: make release + run: ./build_odin.sh release - name: Odin version run: ./odin version timeout-minutes: 1 @@ -17,13 +17,16 @@ jobs: run: ./odin report timeout-minutes: 1 - name: Odin check - run: ./odin check examples/demo/demo.odin -vet + run: ./odin check examples/demo -vet timeout-minutes: 10 - name: Odin run - run: ./odin run examples/demo/demo.odin + run: ./odin run examples/demo timeout-minutes: 10 - name: Odin run -debug - run: ./odin run examples/demo/demo.odin -debug + run: ./odin run examples/demo -debug + timeout-minutes: 10 + - name: Odin check examples/all + run: ./odin check examples/all -strict-style timeout-minutes: 10 - name: Core library tests run: | @@ -35,6 +38,20 @@ jobs: cd tests/vendor make timeout-minutes: 10 + - name: Odin issues tests + run: | + cd tests/issues + ./run.sh + timeout-minutes: 10 + - name: Odin check examples/all for Linux i386 + run: ./odin check examples/all -vet -strict-style -target:linux_i386 + timeout-minutes: 10 + - name: Odin check examples/all for FreeBSD amd64 + run: ./odin check examples/all -vet -strict-style -target:freebsd_amd64 + timeout-minutes: 10 + - name: Odin check examples/all for OpenBSD amd64 + run: ./odin check examples/all -vet -strict-style -target:openbsd_amd64 + timeout-minutes: 10 build_macOS: runs-on: macos-latest steps: @@ -46,7 +63,7 @@ jobs: TMP_PATH=$(xcrun --show-sdk-path)/user/include echo "CPATH=$TMP_PATH" >> $GITHUB_ENV - name: build odin - run: make release + run: ./build_odin.sh release - name: Odin version run: ./odin version timeout-minutes: 1 @@ -54,13 +71,16 @@ jobs: run: ./odin report timeout-minutes: 1 - name: Odin check - run: ./odin check examples/demo/demo.odin -vet + run: ./odin check examples/demo -vet timeout-minutes: 10 - name: Odin run - run: ./odin run examples/demo/demo.odin + run: ./odin run examples/demo timeout-minutes: 10 - name: Odin run -debug - run: ./odin run examples/demo/demo.odin -debug + run: ./odin run examples/demo -debug + timeout-minutes: 10 + - name: Odin check examples/all + run: ./odin check examples/all -strict-style timeout-minutes: 10 - name: Core library tests run: | @@ -72,8 +92,19 @@ jobs: cd tests/vendor make timeout-minutes: 10 + - name: Odin issues tests + run: | + cd tests/issues + ./run.sh + timeout-minutes: 10 + - name: Odin check examples/all for Darwin arm64 + run: ./odin check examples/all -vet -strict-style -target:darwin_arm64 + timeout-minutes: 10 + - name: Odin check examples/all for Linux arm64 + run: ./odin check examples/all -vet -strict-style -target:linux_arm64 + timeout-minutes: 10 build_windows: - runs-on: windows-latest + runs-on: windows-2019 steps: - uses: actions/checkout@v1 - name: build Odin @@ -91,19 +122,25 @@ jobs: shell: cmd run: | call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat - odin check examples/demo/demo.odin -vet + odin check examples/demo -vet timeout-minutes: 10 - name: Odin run shell: cmd run: | call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat - odin run examples/demo/demo.odin + odin run examples/demo timeout-minutes: 10 - name: Odin run -debug shell: cmd run: | call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat - odin run examples/demo/demo.odin -debug + odin run examples/demo -debug + timeout-minutes: 10 + - name: Odin check examples/all + shell: cmd + run: | + call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat + odin check examples/all -strict-style timeout-minutes: 10 - name: Core library tests shell: cmd @@ -126,3 +163,16 @@ jobs: cd tests\core\math\big call build.bat timeout-minutes: 10 + - name: Odin issues tests + shell: cmd + run: | + call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat + cd tests\issues + call run.bat + timeout-minutes: 10 + - name: Odin check examples/all for Windows 32bits + shell: cmd + run: | + call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat + odin check examples/all -strict-style -target:windows_i386 + timeout-minutes: 10 diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 2b33c45a8..3c4185830 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -7,7 +7,7 @@ on: jobs: build_windows: - runs-on: windows-latest + runs-on: windows-2019 steps: - uses: actions/checkout@v1 - name: build Odin @@ -19,7 +19,7 @@ jobs: shell: cmd run: | call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat - odin run examples/demo/demo.odin + odin run examples/demo - name: Copy artifacts run: | rm bin/llvm/windows/LLVM-C.lib @@ -41,11 +41,11 @@ jobs: steps: - uses: actions/checkout@v1 - name: (Linux) Download LLVM - run: sudo apt-get install llvm-11 clang-11 llvm + run: sudo apt-get install llvm-11 clang-11 - name: build odin run: make nightly - name: Odin run - run: ./odin run examples/demo/demo.odin + run: ./odin run examples/demo - name: Copy artifacts run: | mkdir dist @@ -72,7 +72,7 @@ jobs: - name: build odin run: make nightly - name: Odin run - run: ./odin run examples/demo/demo.odin + run: ./odin run examples/demo - name: Copy artifacts run: | mkdir dist @@ -129,7 +129,7 @@ jobs: run: | echo Authorizing B2 account b2 authorize-account "$APPID" "$APPKEY" - + echo Uploading artifcates to B2 chmod +x ./ci/upload_create_nightly.sh ./ci/upload_create_nightly.sh "$BUCKET" windows-amd64 windows_artifacts/ @@ -141,7 +141,7 @@ jobs: echo Creating nightly.json python3 ci/create_nightly_json.py "$BUCKET" > nightly.json - + echo Uploading nightly.json b2 upload-file "$BUCKET" nightly.json nightly.json diff --git a/.gitignore b/.gitignore index 0d606498e..e8b3d3050 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,9 @@ # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs +# For macOS +.DS_Store + # Build results [Dd]ebug/ [Dd]ebugPublic/ @@ -276,3 +279,5 @@ shared/ *.ll *.sublime-workspace +examples/bug/ +build.sh diff --git a/LICENSE b/LICENSE index 9ca94bcdf..9a87ab8da 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2016-2021 Ginger Bill. All rights reserved. +Copyright (c) 2016-2022 Ginger Bill. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/Makefile b/Makefile index 23fb7be66..91010a620 100644 --- a/Makefile +++ b/Makefile @@ -1,58 +1,19 @@ -GIT_SHA=$(shell git rev-parse --short HEAD) -DISABLED_WARNINGS=-Wno-switch -Wno-macro-redefined -Wno-unused-value -LDFLAGS=-pthread -ldl -lm -lstdc++ -CFLAGS=-std=c++14 -DGIT_SHA=\"$(GIT_SHA)\" -CFLAGS:=$(CFLAGS) -DODIN_VERSION_RAW=\"dev-$(shell date +"%Y-%m")\" -CC=clang - -OS=$(shell uname) - -ifeq ($(OS), Darwin) - LLVM_CONFIG=llvm-config - ifneq ($(shell llvm-config --version | grep '^11\.'),) - LLVM_CONFIG=llvm-config - else - $(error "Requirement: llvm-config must be version 11") - endif - - LDFLAGS:=$(LDFLAGS) -liconv - CFLAGS:=$(CFLAGS) $(shell $(LLVM_CONFIG) --cxxflags --ldflags) - LDFLAGS:=$(LDFLAGS) -lLLVM-C -endif -ifeq ($(OS), Linux) - LLVM_CONFIG=llvm-config-11 - ifneq ($(shell which llvm-config-11 2>/dev/null),) - LLVM_CONFIG=llvm-config-11 - else ifneq ($(shell which llvm-config-11-64 2>/dev/null),) - LLVM_CONFIG=llvm-config-11-64 - else - ifneq ($(shell llvm-config --version | grep '^11\.'),) - LLVM_CONFIG=llvm-config - else - $(error "Requirement: llvm-config must be version 11") - endif - endif - - CFLAGS:=$(CFLAGS) $(shell $(LLVM_CONFIG) --cxxflags --ldflags) - LDFLAGS:=$(LDFLAGS) $(shell $(LLVM_CONFIG) --libs core native --system-libs) -endif - -all: debug demo +all: debug demo: - ./odin run examples/demo/demo.odin + ./odin run examples/demo/demo.odin -file report: ./odin report debug: - $(CC) src/main.cpp src/libtommath.cpp $(DISABLED_WARNINGS) $(CFLAGS) -g $(LDFLAGS) -o odin + ./build_odin.sh debug release: - $(CC) src/main.cpp src/libtommath.cpp $(DISABLED_WARNINGS) $(CFLAGS) -O3 $(LDFLAGS) -o odin + ./build_odin.sh release release_native: - $(CC) src/main.cpp src/libtommath.cpp $(DISABLED_WARNINGS) $(CFLAGS) -O3 -march=native $(LDFLAGS) -o odin + ./build_odin.sh release-native nightly: - $(CC) src/main.cpp src/libtommath.cpp $(DISABLED_WARNINGS) $(CFLAGS) -DNIGHTLY -O3 $(LDFLAGS) -o odin + ./build_odin.sh nightly diff --git a/README.md b/README.md index b1d0a39a1..9e46f80d0 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@
- + @@ -58,6 +58,10 @@ main :: proc() { Instructions for downloading and installing the Odin compiler and libraries. +#### [Nightly Builds](https://odin-lang.org/docs/nightly/) + +Get the latest nightly builds of Odin. + ### Learning Odin #### [Overview of Odin](https://odin-lang.org/docs/overview) @@ -68,6 +72,10 @@ An overview of the Odin programming language. Answers to common questions about Odin. +#### [Packages](https://pkg.odin-lang.org/) + +Documentation for all the official packages part of the [core](https://pkg.odin-lang.org/core/) and [vendor](https://pkg.odin-lang.org/vendor/) library collections. + #### [The Odin Wiki](https://github.com/odin-lang/Odin/wiki) A wiki maintained by the Odin community. @@ -76,15 +84,9 @@ A wiki maintained by the Odin community. Get live support and talk with other odiners on the Odin Discord. -### References - -#### [Language Specification](https://odin-lang.org/docs/spec/) - -The official Odin Language specification. - ### Articles -#### [The Odin Blog](https://odin-lang.org/blog) +#### [The Odin Blog](https://odin-lang.org/news/) The official blog of the Odin programming language, featuring announcements, news, and in-depth articles by the Odin team and guests. diff --git a/build_odin.sh b/build_odin.sh new file mode 100755 index 000000000..aef3f2836 --- /dev/null +++ b/build_odin.sh @@ -0,0 +1,150 @@ +#!/bin/bash +set -eu + +GIT_SHA=$(git rev-parse --short HEAD) +DISABLED_WARNINGS="-Wno-switch -Wno-macro-redefined -Wno-unused-value" +LDFLAGS="-pthread -lm -lstdc++" +CFLAGS="-std=c++14 -DGIT_SHA=\"$GIT_SHA\"" +CFLAGS="$CFLAGS -DODIN_VERSION_RAW=\"dev-$(date +"%Y-%m")\"" +CC=clang +OS=$(uname) + +panic() { + printf "%s\n" "$1" + exit 1 +} + +version() { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; } + +config_darwin() { + ARCH=$(uname -m) + LLVM_CONFIG=llvm-config + + # allow for arm only llvm's with version 13 + if [ ARCH == arm64 ]; then + MIN_LLVM_VERSION=("13.0.0") + else + # allow for x86 / amd64 all llvm versions begining from 11 + MIN_LLVM_VERSION=("11.1.0") + fi + + if [ $(version $($LLVM_CONFIG --version)) -lt $(version $MIN_LLVM_VERSION) ]; then + if [ ARCH == arm64 ]; then + panic "Requirement: llvm-config must be base version 13 for arm64" + else + panic "Requirement: llvm-config must be base version greater than 11 for amd64/x86" + fi + fi + + LDFLAGS="$LDFLAGS -liconv -ldl" + CFLAGS="$CFLAGS $($LLVM_CONFIG --cxxflags --ldflags)" + LDFLAGS="$LDFLAGS -lLLVM-C" +} + +config_freebsd() { + LLVM_CONFIG=/usr/local/bin/llvm-config11 + + CFLAGS="$CFLAGS $($LLVM_CONFIG --cxxflags --ldflags)" + LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs)" +} + +config_openbsd() { + LLVM_CONFIG=/usr/local/bin/llvm-config + + LDFLAGS="$LDFLAGS -liconv" + CFLAGS="$CFLAGS $($LLVM_CONFIG --cxxflags --ldflags)" + LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs)" +} + +config_linux() { + if which llvm-config > /dev/null 2>&1; then + LLVM_CONFIG=llvm-config + elif which llvm-config-11 > /dev/null 2>&1; then + LLVM_CONFIG=llvm-config-11 + elif which llvm-config-11-64 > /dev/null 2>&1; then + LLVM_CONFIG=llvm-config-11-64 + else + panic "Unable to find LLVM-config" + fi + + MIN_LLVM_VERSION=("11.0.0") + if [ $(version $($LLVM_CONFIG --version)) -lt $(version $MIN_LLVM_VERSION) ]; then + echo "Tried to use " $(which $LLVM_CONFIG) "version" $($LLVM_CONFIG --version) + panic "Requirement: llvm-config must be base version greater than 11" + fi + + LDFLAGS="$LDFLAGS -ldl" + CFLAGS="$CFLAGS $($LLVM_CONFIG --cxxflags --ldflags)" + LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs)" +} + +build_odin() { + case $1 in + debug) + EXTRAFLAGS="-g" + ;; + release) + EXTRAFLAGS="-O3" + ;; + release-native) + EXTRAFLAGS="-O3 -march=native" + ;; + nightly) + EXTRAFLAGS="-DNIGHTLY -O3" + ;; + *) + panic "Build mode unsupported!" + esac + + set -x + $CC src/main.cpp src/libtommath.cpp $DISABLED_WARNINGS $CFLAGS $EXTRAFLAGS $LDFLAGS -o odin + set +x +} + +run_demo() { + ./odin run examples/demo/demo.odin -file +} + +case $OS in +Linux) + config_linux + ;; +Darwin) + config_darwin + ;; +OpenBSD) + config_openbsd + ;; +FreeBSD) + config_freebsd + ;; +*) + panic "Platform unsupported!" +esac + +if [[ $# -eq 0 ]]; then + build_odin debug + run_demo + exit 0 +fi + +if [[ $# -eq 1 ]]; then + case $1 in + report) + if [[ ! -f "./odin" ]]; then + build_odin debug + fi + + ./odin report + exit 0 + ;; + *) + build_odin $1 + ;; + esac + + run_demo + exit 0 +else + panic "Too many arguments!" +fi diff --git a/core/bufio/scanner.odin b/core/bufio/scanner.odin index cc3b4533a..86e6d8eb0 100644 --- a/core/bufio/scanner.odin +++ b/core/bufio/scanner.odin @@ -8,6 +8,7 @@ import "core:intrinsics" // Extra errors returns by scanning procedures Scanner_Extra_Error :: enum i32 { + None, Negative_Advance, Advanced_Too_Far, Bad_Read_Count, @@ -15,7 +16,7 @@ Scanner_Extra_Error :: enum i32 { Too_Short, } -Scanner_Error :: union { +Scanner_Error :: union #shared_nil { io.Error, Scanner_Extra_Error, } @@ -68,7 +69,7 @@ scanner_destroy :: proc(s: ^Scanner) { // Returns the first non-EOF error that was encounted by the scanner scanner_error :: proc(s: ^Scanner) -> Scanner_Error { switch s._err { - case .EOF, .None: + case .EOF, nil: return nil } return s._err @@ -93,10 +94,6 @@ scanner_text :: proc(s: ^Scanner) -> string { // scanner_scan advances the scanner scanner_scan :: proc(s: ^Scanner) -> bool { set_err :: proc(s: ^Scanner, err: Scanner_Error) { - err := err - if err == .None { - err = nil - } switch s._err { case nil, .EOF: s._err = err diff --git a/core/builtin/builtin.odin b/core/builtin/builtin.odin index 74283720f..259fdef37 100644 --- a/core/builtin/builtin.odin +++ b/core/builtin/builtin.odin @@ -2,7 +2,7 @@ package builtin nil :: nil; -false :: 0!==0; +false :: 0!=0; true :: 0==0; ODIN_OS :: ODIN_OS; diff --git a/core/bytes/bytes.odin b/core/bytes/bytes.odin index cbc1e2506..09a3ed259 100644 --- a/core/bytes/bytes.odin +++ b/core/bytes/bytes.odin @@ -5,9 +5,8 @@ import "core:unicode" import "core:unicode/utf8" clone :: proc(s: []byte, allocator := context.allocator, loc := #caller_location) -> []byte { - c := make([]byte, len(s)+1, allocator, loc) + c := make([]byte, len(s), allocator, loc) copy(c, s) - c[len(s)] = 0 return c[:len(s)] } @@ -219,61 +218,37 @@ split_after_n :: proc(s, sep: []byte, n: int, allocator := context.allocator) -> @private -_split_iterator :: proc(s: ^[]byte, sep: []byte, sep_save, n: int) -> (res: []byte, ok: bool) { - s, n := s, n - - if n == 0 { - return - } - - if sep == nil { +_split_iterator :: proc(s: ^[]byte, sep: []byte, sep_save: int) -> (res: []byte, ok: bool) { + if len(sep) == 0 { res = s[:] ok = true s^ = s[len(s):] return } - if n < 0 { - n = count(s^, sep) + 1 - } - - n -= 1 - - i := 0 - for ; i < n; i += 1 { - m := index(s^, sep) - if m < 0 { - break - } + m := index(s^, sep) + if m < 0 { + // not found + res = s[:] + ok = len(res) != 0 + s^ = s[len(s):] + } else { res = s[:m+sep_save] ok = true s^ = s[m+len(sep):] - return } - res = s[:] - ok = res != nil - s^ = s[len(s):] return } split_iterator :: proc(s: ^[]byte, sep: []byte) -> ([]byte, bool) { - return _split_iterator(s, sep, 0, -1) -} - -split_n_iterator :: proc(s: ^[]byte, sep: []byte, n: int) -> ([]byte, bool) { - return _split_iterator(s, sep, 0, n) + return _split_iterator(s, sep, 0) } split_after_iterator :: proc(s: ^[]byte, sep: []byte) -> ([]byte, bool) { - return _split_iterator(s, sep, len(sep), -1) + return _split_iterator(s, sep, len(sep)) } -split_after_n_iterator :: proc(s: ^[]byte, sep: []byte, n: int) -> ([]byte, bool) { - return _split_iterator(s, sep, len(sep), n) -} - - index_byte :: proc(s: []byte, c: byte) -> int { for i := 0; i < len(s); i += 1 { @@ -1143,7 +1118,7 @@ fields_proc :: proc(s: []byte, f: proc(rune) -> bool, allocator := context.alloc } if start >= 0 { - append(&subslices, s[start : end]) + append(&subslices, s[start : len(s)]) } return subslices[:] diff --git a/core/c/c.odin b/core/c/c.odin index d135fa93c..05732476f 100644 --- a/core/c/c.odin +++ b/core/c/c.odin @@ -3,22 +3,24 @@ package c import builtin "core:builtin" char :: builtin.u8 // assuming -funsigned-char + +schar :: builtin.i8 short :: builtin.i16 int :: builtin.i32 -long :: builtin.i32 when (ODIN_OS == "windows" || size_of(builtin.rawptr) == 4) else builtin.i64 +long :: builtin.i32 when (ODIN_OS == .Windows || size_of(builtin.rawptr) == 4) else builtin.i64 longlong :: builtin.i64 uchar :: builtin.u8 ushort :: builtin.u16 uint :: builtin.u32 -ulong :: builtin.u32 when (ODIN_OS == "windows" || size_of(builtin.rawptr) == 4) else builtin.u64 +ulong :: builtin.u32 when (ODIN_OS == .Windows || size_of(builtin.rawptr) == 4) else builtin.u64 ulonglong :: builtin.u64 bool :: builtin.bool size_t :: builtin.uint ssize_t :: builtin.int -wchar_t :: builtin.u16 when (ODIN_OS == "windows") else builtin.u32 +wchar_t :: builtin.u16 when (ODIN_OS == .Windows) else builtin.u32 float :: builtin.f32 double :: builtin.f64 @@ -46,7 +48,7 @@ int_least64_t :: builtin.i64 uint_least64_t :: builtin.u64 // Same on Windows, Linux, and FreeBSD -when ODIN_ARCH == "386" || ODIN_ARCH == "amd64" { +when ODIN_ARCH == .i386 || ODIN_ARCH == .amd64 { int_fast8_t :: builtin.i8 uint_fast8_t :: builtin.u8 int_fast16_t :: builtin.i32 diff --git a/core/c/frontend/preprocessor/preprocess.odin b/core/c/frontend/preprocessor/preprocess.odin index 62b4183bc..9651cc81c 100644 --- a/core/c/frontend/preprocessor/preprocess.odin +++ b/core/c/frontend/preprocessor/preprocess.odin @@ -956,7 +956,7 @@ substitute_token :: proc(cpp: ^Preprocessor, tok: ^Token, args: ^Macro_Arg) -> ^ continue } - if tok.lit == "__VA__OPT__" && tok.next.lit == "(" { + if tok.lit == "__VA_OPT__" && tok.next.lit == "(" { opt_arg := read_macro_arg_one(cpp, &tok, tok.next.next, true) if has_varargs(args) { for t := opt_arg.tok; t.kind != .EOF; t = t.next { diff --git a/core/c/libc/complex.odin b/core/c/libc/complex.odin index 62b28f0cd..22c422cce 100644 --- a/core/c/libc/complex.odin +++ b/core/c/libc/complex.odin @@ -2,9 +2,9 @@ package libc // 7.3 Complex arithmetic -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" diff --git a/core/c/libc/ctype.odin b/core/c/libc/ctype.odin index 05d9dcd37..185385a5e 100644 --- a/core/c/libc/ctype.odin +++ b/core/c/libc/ctype.odin @@ -1,8 +1,8 @@ package libc -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" diff --git a/core/c/libc/errno.odin b/core/c/libc/errno.odin index 8ebe2f734..53437f42f 100644 --- a/core/c/libc/errno.odin +++ b/core/c/libc/errno.odin @@ -2,9 +2,9 @@ package libc // 7.5 Errors -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" @@ -14,7 +14,7 @@ when ODIN_OS == "windows" { // EDOM, // EILSEQ // ERANGE -when ODIN_OS == "linux" || ODIN_OS == "freebsd" { +when ODIN_OS == .Linux || ODIN_OS == .FreeBSD { @(private="file") @(default_calling_convention="c") foreign libc { @@ -27,7 +27,20 @@ when ODIN_OS == "linux" || ODIN_OS == "freebsd" { ERANGE :: 34 } -when ODIN_OS == "windows" { +when ODIN_OS == .OpenBSD { + @(private="file") + @(default_calling_convention="c") + foreign libc { + @(link_name="__errno") + _get_errno :: proc() -> ^int --- + } + + EDOM :: 33 + EILSEQ :: 84 + ERANGE :: 34 +} + +when ODIN_OS == .Windows { @(private="file") @(default_calling_convention="c") foreign libc { @@ -40,7 +53,7 @@ when ODIN_OS == "windows" { ERANGE :: 34 } -when ODIN_OS == "darwin" { +when ODIN_OS == .Darwin { @(private="file") @(default_calling_convention="c") foreign libc { diff --git a/core/c/libc/math.odin b/core/c/libc/math.odin index ee702b82e..97f77236f 100644 --- a/core/c/libc/math.odin +++ b/core/c/libc/math.odin @@ -4,9 +4,9 @@ package libc import "core:intrinsics" -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" diff --git a/core/c/libc/setjmp.odin b/core/c/libc/setjmp.odin index dcd4a9c64..c2cd1d047 100644 --- a/core/c/libc/setjmp.odin +++ b/core/c/libc/setjmp.odin @@ -2,14 +2,14 @@ package libc // 7.13 Nonlocal jumps -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" } -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { @(default_calling_convention="c") foreign libc { // 7.13.1 Save calling environment diff --git a/core/c/libc/signal.odin b/core/c/libc/signal.odin index e1044dc02..186b74d8c 100644 --- a/core/c/libc/signal.odin +++ b/core/c/libc/signal.odin @@ -2,9 +2,9 @@ package libc // 7.14 Signal handling -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" @@ -21,7 +21,7 @@ foreign libc { raise :: proc(sig: int) -> int --- } -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { SIG_ERR :: rawptr(~uintptr(0)) SIG_DFL :: rawptr(uintptr(0)) SIG_IGN :: rawptr(uintptr(1)) @@ -34,7 +34,7 @@ when ODIN_OS == "windows" { SIGTERM :: 15 } -when ODIN_OS == "linux" || ODIN_OS == "freebsd" { +when ODIN_OS == .Linux || ODIN_OS == .FreeBSD { SIG_ERR :: rawptr(~uintptr(0)) SIG_DFL :: rawptr(uintptr(0)) SIG_IGN :: rawptr(uintptr(1)) @@ -47,7 +47,7 @@ when ODIN_OS == "linux" || ODIN_OS == "freebsd" { SIGTERM :: 15 } -when ODIN_OS == "darwin" { +when ODIN_OS == .Darwin { SIG_ERR :: rawptr(~uintptr(0)) SIG_DFL :: rawptr(uintptr(0)) SIG_IGN :: rawptr(uintptr(1)) diff --git a/core/c/libc/stdatomic.odin b/core/c/libc/stdatomic.odin index fbe1ef7ea..6e1581c58 100644 --- a/core/c/libc/stdatomic.odin +++ b/core/c/libc/stdatomic.odin @@ -47,29 +47,30 @@ kill_dependency :: #force_inline proc(value: $T) -> T { // 7.17.4 Fences atomic_thread_fence :: #force_inline proc(order: memory_order) { - switch (order) { - case .relaxed: - return - case .consume: - intrinsics.atomic_fence_acq() - case .acquire: - intrinsics.atomic_fence_acq() - case .release: - intrinsics.atomic_fence_rel() - case .acq_rel: - intrinsics.atomic_fence_acqrel() - case .seq_cst: - intrinsics.atomic_fence_acqrel() + assert(order != .relaxed) + assert(order != .consume) + #partial switch order { + case .acquire: intrinsics.atomic_thread_fence(.Acquire) + case .release: intrinsics.atomic_thread_fence(.Release) + case .acq_rel: intrinsics.atomic_thread_fence(.Acq_Rel) + case .seq_cst: intrinsics.atomic_thread_fence(.Seq_Cst) } } atomic_signal_fence :: #force_inline proc(order: memory_order) { - atomic_thread_fence(order) + assert(order != .relaxed) + assert(order != .consume) + #partial switch order { + case .acquire: intrinsics.atomic_signal_fence(.Acquire) + case .release: intrinsics.atomic_signal_fence(.Release) + case .acq_rel: intrinsics.atomic_signal_fence(.Acq_Rel) + case .seq_cst: intrinsics.atomic_signal_fence(.Seq_Cst) + } } // 7.17.5 Lock-free property atomic_is_lock_free :: #force_inline proc(obj: ^$T) -> bool { - return size_of(T) <= 8 && (intrinsics.type_is_integer(T) || intrinsics.type_is_pointer(T)) + return intrinsics.atomic_type_is_lock_free(T) } // 7.17.6 Atomic integer types @@ -121,13 +122,10 @@ atomic_store_explicit :: #force_inline proc(object: ^$T, desired: T, order: memo assert(order != .acquire) assert(order != .acq_rel) - #partial switch (order) { - case .relaxed: - intrinsics.atomic_store_relaxed(object, desired) - case .release: - intrinsics.atomic_store_rel(object, desired) - case .seq_cst: - intrinsics.atomic_store(object, desired) + #partial switch order { + case .relaxed: intrinsics.atomic_store_explicit(object, desired, .Relaxed) + case .release: intrinsics.atomic_store_explicit(object, desired, .Release) + case .seq_cst: intrinsics.atomic_store_explicit(object, desired, .Seq_Cst) } } @@ -139,36 +137,26 @@ atomic_load_explicit :: #force_inline proc(object: ^$T, order: memory_order) { assert(order != .release) assert(order != .acq_rel) - #partial switch (order) { - case .relaxed: - return intrinsics.atomic_load_relaxed(object) - case .consume: - return intrinsics.atomic_load_acq(object) - case .acquire: - return intrinsics.atomic_load_acq(object) - case .seq_cst: - return intrinsics.atomic_load(object) + #partial switch order { + case .relaxed: return intrinsics.atomic_load_explicit(object, .Relaxed) + case .consume: return intrinsics.atomic_load_explicit(object, .Consume) + case .acquire: return intrinsics.atomic_load_explicit(object, .Acquire) + case .seq_cst: return intrinsics.atomic_load_explicit(object, .Seq_Cst) } } atomic_exchange :: #force_inline proc(object: ^$T, desired: T) -> T { - return intrinsics.atomic_xchg(object, desired) + return intrinsics.atomic_exchange(object, desired) } atomic_exchange_explicit :: #force_inline proc(object: ^$T, desired: T, order: memory_order) -> T { - switch (order) { - case .relaxed: - return intrinsics.atomic_xchg_relaxed(object, desired) - case .consume: - return intrinsics.atomic_xchg_acq(object, desired) - case .acquire: - return intrinsics.atomic_xchg_acq(object, desired) - case .release: - return intrinsics.atomic_xchg_rel(object, desired) - case .acq_rel: - return intrinsics.atomic_xchg_acqrel(object, desired) - case .seq_cst: - return intrinsics.atomic_xchg(object, desired) + switch order { + case .relaxed: return intrinsics.atomic_exchange_explicit(object, desired, .Relaxed) + case .consume: return intrinsics.atomic_exchange_explicit(object, desired, .Consume) + case .acquire: return intrinsics.atomic_exchange_explicit(object, desired, .Acquire) + case .release: return intrinsics.atomic_exchange_explicit(object, desired, .Release) + case .acq_rel: return intrinsics.atomic_exchange_explicit(object, desired, .Acq_Rel) + case .seq_cst: return intrinsics.atomic_exchange_explicit(object, desired, .Seq_Cst) } return false } @@ -189,102 +177,104 @@ atomic_exchange_explicit :: #force_inline proc(object: ^$T, desired: T, order: m // [success = seq_cst, failure = acquire] => failacq // [success = acquire, failure = relaxed] => acq_failrelaxed // [success = acq_rel, failure = relaxed] => acqrel_failrelaxed -atomic_compare_exchange_strong :: #force_inline proc(object, expected: ^$T, desired: T) { - value, ok := intrinsics.atomic_cxchg(object, expected^, desired) +atomic_compare_exchange_strong :: #force_inline proc(object, expected: ^$T, desired: T) -> bool { + value, ok := intrinsics.atomic_compare_exchange_strong(object, expected^, desired) if !ok { expected^ = value } return ok } -atomic_compare_exchange_strong_explicit :: #force_inline proc(object, expected: ^$T, desired: T, success, failure: memory_order) { +atomic_compare_exchange_strong_explicit :: #force_inline proc(object, expected: ^$T, desired: T, success, failure: memory_order) -> bool { assert(failure != .release) assert(failure != .acq_rel) value: T; ok: bool - #partial switch (failure) { + #partial switch failure { case .seq_cst: assert(success != .relaxed) - #partial switch (success) { + #partial switch success { case .seq_cst: - value, ok := intrinsics.atomic_cxchg(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Seq_Cst, .Seq_Cst) case .acquire: - value, ok := intrinsics.atomic_cxchg_acq(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Acquire, .Seq_Cst) case .consume: - value, ok := intrinsics.atomic_cxchg_acq(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Consume, .Seq_Cst) case .release: - value, ok := intrinsics.atomic_cxchg_rel(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Release, .Seq_Cst) case .acq_rel: - value, ok := intrinsics.atomic_cxchg_acqrel(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Acq_Rel, .Seq_Cst) } case .relaxed: assert(success != .release) - #partial switch (success) { + #partial switch success { case .relaxed: - value, ok := intrinsics.atomic_cxchg_relaxed(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Relaxed, .Relaxed) case .seq_cst: - value, ok := intrinsics.atomic_cxchg_failrelaxed(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Seq_Cst, .Relaxed) case .acquire: - value, ok := intrinsics.atomic_cxchg_acq_failrelaxed(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Acquire, .Relaxed) case .consume: - value, ok := intrinsics.atomic_cxchg_acq_failrelaxed(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Consume, .Relaxed) case .acq_rel: - value, ok := intrinsics.atomic_cxchg_acqrel_failrelaxed(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Acq_Rel, .Relaxed) } case .consume: - fallthrough + assert(success == .seq_cst) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Seq_Cst, .Consume) case .acquire: assert(success == .seq_cst) - value, ok := intrinsics.atomic_cxchg_failacq(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_strong_explicit(object, expected^, desired, .Seq_Cst, .Acquire) } if !ok { expected^ = value } return ok } -atomic_compare_exchange_weak :: #force_inline proc(object, expected: ^$T, desired: T) { - value, ok := intrinsics.atomic_cxchgweak(object, expected^, desired) +atomic_compare_exchange_weak :: #force_inline proc(object, expected: ^$T, desired: T) -> bool { + value, ok := intrinsics.atomic_compare_exchange_weak(object, expected^, desired) if !ok { expected^ = value } return ok } -atomic_compare_exchange_weak_explicit :: #force_inline proc(object, expected: ^$T, desited: T, success, failure: memory_order) { +atomic_compare_exchange_weak_explicit :: #force_inline proc(object, expected: ^$T, desited: T, success, failure: memory_order) -> bool { assert(failure != .release) assert(failure != .acq_rel) value: T; ok: bool - #partial switch (failure) { + #partial switch failure { case .seq_cst: assert(success != .relaxed) - #partial switch (success) { + #partial switch success { case .seq_cst: - value, ok := intrinsics.atomic_cxchgweak(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Seq_Cst, .Seq_Cst) case .acquire: - value, ok := intrinsics.atomic_cxchgweak_acq(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Acquire, .Seq_Cst) case .consume: - value, ok := intrinsics.atomic_cxchgweak_acq(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Consume, .Seq_Cst) case .release: - value, ok := intrinsics.atomic_cxchgweak_rel(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Release, .Seq_Cst) case .acq_rel: - value, ok := intrinsics.atomic_cxchgweak_acqrel(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Acq_Rel, .Seq_Cst) } case .relaxed: assert(success != .release) - #partial switch (success) { + #partial switch success { case .relaxed: - value, ok := intrinsics.atomic_cxchgweak_relaxed(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Relaxed, .Relaxed) case .seq_cst: - value, ok := intrinsics.atomic_cxchgweak_failrelaxed(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Seq_Cst, .Relaxed) case .acquire: - value, ok := intrinsics.atomic_cxchgweak_acq_failrelaxed(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Acquire, .Relaxed) case .consume: - value, ok := intrinsics.atomic_cxchgweak_acq_failrelaxed(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Consume, .Relaxed) case .acq_rel: - value, ok := intrinsics.atomic_cxchgweak_acqrel_failrelaxed(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Acq_Rel, .Relaxed) } case .consume: - fallthrough + assert(success == .seq_cst) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Seq_Cst, .Consume) case .acquire: assert(success == .seq_cst) - value, ok := intrinsics.atomic_cxchgweak_failacq(object, expected^, desired) + value, ok = intrinsics.atomic_compare_exchange_weak_explicit(object, expected^, desired, .Seq_Cst, .Acquire) } if !ok { expected^ = value } @@ -297,19 +287,14 @@ atomic_fetch_add :: #force_inline proc(object: ^$T, operand: T) -> T { } atomic_fetch_add_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T { - switch (order) { - case .relaxed: - return intrinsics.atomic_add_relaxed(object, operand) - case .consume: - return intrinsics.atomic_add_acq(object, operand) - case .acquire: - return intrinsics.atomic_add_acq(object, operand) - case .release: - return intrinsics.atomic_add_rel(object, operand) - case .acq_rel: - return intrinsics.atomic_add_acqrel(object, operand) - case .seq_cst: - return intrinsics.atomic_add(object, operand) + switch order { + case .relaxed: return intrinsics.atomic_add_explicit(object, operand, .Relaxed) + case .consume: return intrinsics.atomic_add_explicit(object, operand, .Consume) + case .acquire: return intrinsics.atomic_add_explicit(object, operand, .Acquire) + case .release: return intrinsics.atomic_add_explicit(object, operand, .Release) + case .acq_rel: return intrinsics.atomic_add_explicit(object, operand, .Acq_Rel) + case: fallthrough + case .seq_cst: return intrinsics.atomic_add_explicit(object, operand, .Seq_Cst) } } @@ -318,19 +303,14 @@ atomic_fetch_sub :: #force_inline proc(object: ^$T, operand: T) -> T { } atomic_fetch_sub_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T { - switch (order) { - case .relaxed: - return intrinsics.atomic_sub_relaxed(object, operand) - case .consume: - return intrinsics.atomic_sub_acq(object, operand) - case .acquire: - return intrinsics.atomic_sub_acq(object, operand) - case .release: - return intrinsics.atomic_sub_rel(object, operand) - case .acq_rel: - return intrinsics.atomic_sub_acqrel(object, operand) - case .seq_cst: - return intrinsics.atomic_sub(object, operand) + switch order { + case .relaxed: return intrinsics.atomic_sub_explicit(object, operand, .Relaxed) + case .consume: return intrinsics.atomic_sub_explicit(object, operand, .Consume) + case .acquire: return intrinsics.atomic_sub_explicit(object, operand, .Acquire) + case .release: return intrinsics.atomic_sub_explicit(object, operand, .Release) + case .acq_rel: return intrinsics.atomic_sub_explicit(object, operand, .Acq_Rel) + case: fallthrough + case .seq_cst: return intrinsics.atomic_sub_explicit(object, operand, .Seq_Cst) } } @@ -339,19 +319,14 @@ atomic_fetch_or :: #force_inline proc(object: ^$T, operand: T) -> T { } atomic_fetch_or_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T { - switch (order) { - case .relaxed: - return intrinsics.atomic_or_relaxed(object, operand) - case .consume: - return intrinsics.atomic_or_acq(object, operand) - case .acquire: - return intrinsics.atomic_or_acq(object, operand) - case .release: - return intrinsics.atomic_or_rel(object, operand) - case .acq_rel: - return intrinsics.atomic_or_acqrel(object, operand) - case .seq_cst: - return intrinsics.atomic_or(object, operand) + switch order { + case .relaxed: return intrinsics.atomic_or_explicit(object, operand, .Relaxed) + case .consume: return intrinsics.atomic_or_explicit(object, operand, .Consume) + case .acquire: return intrinsics.atomic_or_explicit(object, operand, .Acquire) + case .release: return intrinsics.atomic_or_explicit(object, operand, .Release) + case .acq_rel: return intrinsics.atomic_or_explicit(object, operand, .Acq_Rel) + case: fallthrough + case .seq_cst: return intrinsics.atomic_or_explicit(object, operand, .Seq_Cst) } } @@ -360,19 +335,14 @@ atomic_fetch_xor :: #force_inline proc(object: ^$T, operand: T) -> T { } atomic_fetch_xor_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T { - switch (order) { - case .relaxed: - return intrinsics.atomic_xor_relaxed(object, operand) - case .consume: - return intrinsics.atomic_xor_acq(object, operand) - case .acquire: - return intrinsics.atomic_xor_acq(object, operand) - case .release: - return intrinsics.atomic_xor_rel(object, operand) - case .acq_rel: - return intrinsics.atomic_xor_acqrel(object, operand) - case .seq_cst: - return intrinsics.atomic_xor(object, operand) + switch order { + case .relaxed: return intrinsics.atomic_xor_explicit(object, operand, .Relaxed) + case .consume: return intrinsics.atomic_xor_explicit(object, operand, .Consume) + case .acquire: return intrinsics.atomic_xor_explicit(object, operand, .Acquire) + case .release: return intrinsics.atomic_xor_explicit(object, operand, .Release) + case .acq_rel: return intrinsics.atomic_xor_explicit(object, operand, .Acq_Rel) + case: fallthrough + case .seq_cst: return intrinsics.atomic_xor_explicit(object, operand, .Seq_Cst) } } @@ -380,19 +350,14 @@ atomic_fetch_and :: #force_inline proc(object: ^$T, operand: T) -> T { return intrinsics.atomic_and(object, operand) } atomic_fetch_and_explicit :: #force_inline proc(object: ^$T, operand: T, order: memory_order) -> T { - switch (order) { - case .relaxed: - return intrinsics.atomic_and_relaxed(object, operand) - case .consume: - return intrinsics.atomic_and_acq(object, operand) - case .acquire: - return intrinsics.atomic_and_acq(object, operand) - case .release: - return intrinsics.atomic_and_rel(object, operand) - case .acq_rel: - return intrinsics.atomic_and_acqrel(object, operand) - case .seq_cst: - return intrinsics.atomic_and(object, operand) + switch order { + case .relaxed: return intrinsics.atomic_and_explicit(object, operand, .Relaxed) + case .consume: return intrinsics.atomic_and_explicit(object, operand, .Consume) + case .acquire: return intrinsics.atomic_and_explicit(object, operand, .Acquire) + case .release: return intrinsics.atomic_and_explicit(object, operand, .Release) + case .acq_rel: return intrinsics.atomic_and_explicit(object, operand, .Acq_Rel) + case: fallthrough + case .seq_cst: return intrinsics.atomic_and_explicit(object, operand, .Seq_Cst) } } diff --git a/core/c/libc/stdio.odin b/core/c/libc/stdio.odin index 4a39c22e9..01d0cd427 100644 --- a/core/c/libc/stdio.odin +++ b/core/c/libc/stdio.odin @@ -1,8 +1,8 @@ package libc -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" @@ -13,7 +13,7 @@ when ODIN_OS == "windows" { FILE :: struct {} // MSVCRT compatible. -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { _IOFBF :: 0x0000 _IONBF :: 0x0004 _IOLBF :: 0x0040 @@ -48,7 +48,7 @@ when ODIN_OS == "windows" { } // GLIBC and MUSL compatible. -when ODIN_OS == "linux" { +when ODIN_OS == .Linux { fpos_t :: struct #raw_union { _: [16]char, _: longlong, _: double, } _IOFBF :: 0 @@ -78,7 +78,57 @@ when ODIN_OS == "linux" { } } -when ODIN_OS == "darwin" { +when ODIN_OS == .OpenBSD { + fpos_t :: distinct i64 + + _IOFBF :: 0 + _IOLBF :: 1 + _IONBF :: 1 + + BUFSIZ :: 1024 + + EOF :: int(-1) + + FOPEN_MAX :: 20 + FILENAME_MAX :: 1024 + + SEEK_SET :: 0 + SEEK_CUR :: 1 + SEEK_END :: 2 + + foreign libc { + stderr: ^FILE + stdin: ^FILE + stdout: ^FILE + } +} + +when ODIN_OS == .FreeBSD { + fpos_t :: distinct i64 + + _IOFBF :: 0 + _IOLBF :: 1 + _IONBF :: 1 + + BUFSIZ :: 1024 + + EOF :: int(-1) + + FOPEN_MAX :: 20 + FILENAME_MAX :: 1024 + + SEEK_SET :: 0 + SEEK_CUR :: 1 + SEEK_END :: 2 + + foreign libc { + stderr: ^FILE + stdin: ^FILE + stdout: ^FILE + } +} + +when ODIN_OS == .Darwin { fpos_t :: distinct i64 _IOFBF :: 0 @@ -149,7 +199,7 @@ foreign libc { putchar :: proc() -> int --- puts :: proc(s: cstring) -> int --- ungetc :: proc(c: int, stream: ^FILE) -> int --- - fread :: proc(ptr: rawptr, size: size_t, stream: ^FILE) -> size_t --- + fread :: proc(ptr: rawptr, size: size_t, nmemb: size_t, stream: ^FILE) -> size_t --- fwrite :: proc(ptr: rawptr, size: size_t, nmemb: size_t, stream: ^FILE) -> size_t --- // 7.21.9 File positioning functions diff --git a/core/c/libc/stdlib.odin b/core/c/libc/stdlib.odin index b368c0cee..a278db0ef 100644 --- a/core/c/libc/stdlib.odin +++ b/core/c/libc/stdlib.odin @@ -2,15 +2,15 @@ package libc // 7.22 General utilities -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" } -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { RAND_MAX :: 0x7fff @(private="file") @@ -24,7 +24,7 @@ when ODIN_OS == "windows" { } } -when ODIN_OS == "linux" { +when ODIN_OS == .Linux { RAND_MAX :: 0x7fffffff // GLIBC and MUSL only @@ -40,7 +40,7 @@ when ODIN_OS == "linux" { } -when ODIN_OS == "darwin" { +when ODIN_OS == .Darwin { RAND_MAX :: 0x7fffffff // GLIBC and MUSL only diff --git a/core/c/libc/string.odin b/core/c/libc/string.odin index c91124dcb..8f83ee1b9 100644 --- a/core/c/libc/string.odin +++ b/core/c/libc/string.odin @@ -4,9 +4,9 @@ import "core:runtime" // 7.24 String handling -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" diff --git a/core/c/libc/threads.odin b/core/c/libc/threads.odin index ad305b517..a7a45150d 100644 --- a/core/c/libc/threads.odin +++ b/core/c/libc/threads.odin @@ -5,7 +5,7 @@ package libc thrd_start_t :: proc "c" (rawptr) -> int tss_dtor_t :: proc "c" (rawptr) -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc { "system:libucrt.lib", "system:msvcprt.lib" @@ -74,7 +74,7 @@ when ODIN_OS == "windows" { } // GLIBC and MUSL compatible constants and types. -when ODIN_OS == "linux" { +when ODIN_OS == .Linux { foreign import libc { "system:c", "system:pthread" @@ -138,6 +138,6 @@ when ODIN_OS == "linux" { } -when ODIN_OS == "darwin" { +when ODIN_OS == .Darwin { // TODO: find out what this is meant to be! } diff --git a/core/c/libc/time.odin b/core/c/libc/time.odin index 96e80e216..b337e139a 100644 --- a/core/c/libc/time.odin +++ b/core/c/libc/time.odin @@ -2,9 +2,9 @@ package libc // 7.27 Date and time -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" @@ -12,7 +12,7 @@ when ODIN_OS == "windows" { // We enforce 64-bit time_t and timespec as there is no reason to use 32-bit as // we approach the 2038 problem. Windows has defaulted to this since VC8 (2005). -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign libc { // 7.27.2 Time manipulation functions clock :: proc() -> clock_t --- @@ -45,7 +45,7 @@ when ODIN_OS == "windows" { } } -when ODIN_OS == "linux" || ODIN_OS == "freebsd" || ODIN_OS == "darwin" { +when ODIN_OS == .Linux || ODIN_OS == .FreeBSD || ODIN_OS == .Darwin || ODIN_OS == .OpenBSD { @(default_calling_convention="c") foreign libc { // 7.27.2 Time manipulation functions @@ -63,7 +63,12 @@ when ODIN_OS == "linux" || ODIN_OS == "freebsd" || ODIN_OS == "darwin" { strftime :: proc(s: [^]char, maxsize: size_t, format: cstring, timeptr: ^tm) -> size_t --- } - CLOCKS_PER_SEC :: 1000000 + when ODIN_OS == .OpenBSD { + CLOCKS_PER_SEC :: 100 + } else { + CLOCKS_PER_SEC :: 1000000 + } + TIME_UTC :: 1 time_t :: distinct i64 diff --git a/core/c/libc/types.odin b/core/c/libc/types.odin index 7199cf57b..a49e52fb6 100644 --- a/core/c/libc/types.odin +++ b/core/c/libc/types.odin @@ -3,6 +3,8 @@ package libc import "core:c" char :: c.char // assuming -funsigned-char + +schar :: c.schar short :: c.short int :: c.int long :: c.long diff --git a/core/c/libc/uchar.odin b/core/c/libc/uchar.odin index e49c29e51..a10969ceb 100644 --- a/core/c/libc/uchar.odin +++ b/core/c/libc/uchar.odin @@ -2,9 +2,9 @@ package libc // 7.28 Unicode utilities -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" diff --git a/core/c/libc/wchar.odin b/core/c/libc/wchar.odin index fc206e494..f2aa8410e 100644 --- a/core/c/libc/wchar.odin +++ b/core/c/libc/wchar.odin @@ -2,9 +2,9 @@ package libc // 7.29 Extended multibyte and wide character utilities -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" diff --git a/core/c/libc/wctype.odin b/core/c/libc/wctype.odin index 47f17e0b4..43aee9dc6 100644 --- a/core/c/libc/wctype.odin +++ b/core/c/libc/wctype.odin @@ -2,27 +2,34 @@ package libc // 7.30 Wide character classification and mapping utilities -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import libc "system:libucrt.lib" -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { foreign import libc "system:System.framework" } else { foreign import libc "system:c" } -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { wctrans_t :: distinct wchar_t wctype_t :: distinct ushort -} -when ODIN_OS == "linux" { +} else when ODIN_OS == .Linux { wctrans_t :: distinct intptr_t wctype_t :: distinct ulong -} -when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { wctrans_t :: distinct int wctype_t :: distinct u32 + +} else when ODIN_OS == .OpenBSD { + wctrans_t :: distinct rawptr + wctype_t :: distinct rawptr + +} else when ODIN_OS == .FreeBSD { + wctrans_t :: distinct int + wctype_t :: distinct ulong + } @(default_calling_convention="c") diff --git a/core/compress/common.odin b/core/compress/common.odin index 41f292b6f..f4e378269 100644 --- a/core/compress/common.odin +++ b/core/compress/common.odin @@ -5,6 +5,9 @@ List of contributors: Jeroen van Rijn: Initial implementation, optimization. */ + + +// package compress is a collection of utilities to aid with other compression packages package compress import "core:io" @@ -44,7 +47,7 @@ when size_of(uintptr) == 8 { } -Error :: union { +Error :: union #shared_nil { General_Error, Deflate_Error, ZLIB_Error, @@ -55,6 +58,7 @@ Error :: union { } General_Error :: enum { + None = 0, File_Not_Found, Cannot_Open_File, File_Too_Short, @@ -73,6 +77,7 @@ General_Error :: enum { } GZIP_Error :: enum { + None = 0, Invalid_GZIP_Signature, Reserved_Flag_Set, Invalid_Extra_Data, @@ -97,6 +102,7 @@ GZIP_Error :: enum { } ZIP_Error :: enum { + None = 0, Invalid_ZIP_File_Signature, Unexpected_Signature, Insert_Next_Disk, @@ -104,6 +110,7 @@ ZIP_Error :: enum { } ZLIB_Error :: enum { + None = 0, Unsupported_Window_Size, FDICT_Unsupported, Unsupported_Compression_Level, @@ -111,6 +118,7 @@ ZLIB_Error :: enum { } Deflate_Error :: enum { + None = 0, Huffman_Bad_Sizes, Huffman_Bad_Code_Lengths, Inflate_Error, @@ -120,7 +128,6 @@ Deflate_Error :: enum { BType_3, } - // General I/O context for ZLIB, LZW, etc. Context_Memory_Input :: struct #packed { input_data: []u8, @@ -136,7 +143,12 @@ Context_Memory_Input :: struct #packed { size_packed: i64, size_unpacked: i64, } -#assert(size_of(Context_Memory_Input) == 64) +when size_of(rawptr) == 8 { + #assert(size_of(Context_Memory_Input) == 64) +} else { + // e.g. `-target:windows_i386` + #assert(size_of(Context_Memory_Input) == 52) +} Context_Stream_Input :: struct #packed { input_data: []u8, @@ -171,8 +183,6 @@ Context_Stream_Input :: struct #packed { This simplifies end-of-stream handling where bits may be left in the bit buffer. */ -// TODO: Make these return compress.Error errors. - input_size_from_memory :: proc(z: ^Context_Memory_Input) -> (res: i64, err: Error) { return i64(len(z.input_data)), nil } @@ -470,4 +480,4 @@ discard_to_next_byte_lsb_from_stream :: proc(z: ^Context_Stream_Input) { consume_bits_lsb(z, discard) } -discard_to_next_byte_lsb :: proc{discard_to_next_byte_lsb_from_memory, discard_to_next_byte_lsb_from_stream}; \ No newline at end of file +discard_to_next_byte_lsb :: proc{discard_to_next_byte_lsb_from_memory, discard_to_next_byte_lsb_from_stream} diff --git a/core/compress/gzip/gzip.odin b/core/compress/gzip/gzip.odin index 1a72500bf..4482d4a7e 100644 --- a/core/compress/gzip/gzip.odin +++ b/core/compress/gzip/gzip.odin @@ -66,7 +66,8 @@ OS :: enum u8 { _Unknown = 14, Unknown = 255, } -OS_Name :: #partial [OS]string{ +OS_Name :: #sparse[OS]string{ + ._Unknown = "", .FAT = "FAT", .Amiga = "Amiga", .VMS = "VMS/OpenVMS", @@ -99,7 +100,7 @@ E_GZIP :: compress.GZIP_Error E_ZLIB :: compress.ZLIB_Error E_Deflate :: compress.Deflate_Error -GZIP_MAX_PAYLOAD_SIZE :: int(max(u32le)) +GZIP_MAX_PAYLOAD_SIZE :: i64(max(u32le)) load :: proc{load_from_slice, load_from_file, load_from_context} @@ -135,7 +136,7 @@ load_from_context :: proc(z: ^$C, buf: ^bytes.Buffer, known_gzip_size := -1, exp z.output = buf - if expected_output_size > GZIP_MAX_PAYLOAD_SIZE { + if i64(expected_output_size) > i64(GZIP_MAX_PAYLOAD_SIZE) { return E_GZIP.Payload_Size_Exceeds_Max_Payload } diff --git a/core/compress/shoco/model.odin b/core/compress/shoco/model.odin new file mode 100644 index 000000000..bbc38903d --- /dev/null +++ b/core/compress/shoco/model.odin @@ -0,0 +1,148 @@ +/* + This file was generated, so don't edit this by hand. + Transliterated from https://github.com/Ed-von-Schleck/shoco/blob/master/shoco_model.h, + which is an English word model. +*/ + +// package shoco is an implementation of the shoco short string compressor +package shoco + +DEFAULT_MODEL :: Shoco_Model { + min_char = 39, + max_char = 122, + characters_by_id = { + 'e', 'a', 'i', 'o', 't', 'h', 'n', 'r', 's', 'l', 'u', 'c', 'w', 'm', 'd', 'b', 'p', 'f', 'g', 'v', 'y', 'k', '-', 'H', 'M', 'T', '\'', 'B', 'x', 'I', 'W', 'L', + }, + ids_by_character = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 27, -1, -1, -1, -1, -1, 23, 29, -1, -1, 31, 24, -1, -1, -1, -1, -1, -1, 25, -1, -1, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 15, 11, 14, 0, 17, 18, 5, 2, -1, 21, 9, 13, 6, 3, 16, -1, 7, 8, 4, 10, 19, 12, 28, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }, + successors_by_bigram = { + 7, 4, 12, -1, 6, -1, 1, 0, 3, 5, -1, 9, -1, 8, 2, -1, 15, 14, -1, 10, 11, -1, -1, -1, -1, -1, -1, -1, 13, -1, -1, -1, + 1, -1, 6, -1, 1, -1, 0, 3, 2, 4, 15, 11, -1, 9, 5, 10, 13, -1, 12, 8, 7, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 9, 11, -1, 4, 2, -1, 0, 8, 1, 5, -1, 6, -1, 3, 7, 15, -1, 12, 10, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 14, 7, 5, -1, 1, 2, 8, 9, 0, 15, 6, 4, 11, -1, 12, 3, -1, 10, -1, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 2, 4, 3, 1, 5, 0, -1, 6, 10, 9, 7, 12, 11, -1, -1, -1, -1, 13, -1, -1, 8, -1, 15, -1, -1, -1, 14, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, -1, -1, 5, 9, 10, 6, -1, -1, 8, 15, 11, -1, 14, -1, -1, 7, -1, 13, -1, -1, -1, 12, -1, -1, -1, -1, -1, + 2, 8, 7, 4, 3, -1, 9, -1, 6, 11, -1, 5, -1, -1, 0, -1, -1, 14, 1, 15, 10, 12, -1, -1, -1, -1, 13, -1, -1, -1, -1, -1, + 0, 3, 1, 2, 6, -1, 9, 8, 4, 12, 13, 10, -1, 11, 7, -1, -1, 15, 14, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 6, 3, 4, 1, 2, -1, -1, 5, 10, 7, 9, 11, 12, -1, -1, 8, 14, -1, -1, 15, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 6, 2, 5, 9, -1, -1, -1, 10, 1, 8, -1, 12, 14, 4, -1, 15, 7, -1, 13, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 8, 10, 9, 15, 1, -1, 4, 0, 3, 2, -1, 6, -1, 12, 11, 13, 7, 14, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 3, 6, 0, 4, 2, -1, 7, 13, 8, 9, 11, -1, -1, 15, -1, -1, -1, -1, -1, 10, 5, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 3, 0, 1, 4, -1, 2, 5, 6, 7, 8, -1, 14, -1, -1, 9, 15, -1, 12, -1, -1, -1, 10, 11, -1, -1, -1, 13, -1, -1, -1, -1, -1, + 0, 1, 3, 2, 15, -1, 12, -1, 7, 14, 4, -1, -1, 9, -1, 8, 5, 10, -1, -1, 6, -1, 13, -1, -1, -1, 11, -1, -1, -1, -1, -1, + 0, 3, 1, 2, -1, -1, 12, 6, 4, 9, 7, -1, -1, 14, 8, -1, -1, 15, 11, 13, 5, -1, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 5, 7, 2, 10, 13, -1, 6, 8, 1, 3, -1, -1, 14, 15, 11, -1, -1, -1, 12, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 2, 6, 3, 7, 10, -1, 1, 9, 4, 8, -1, -1, 15, -1, 12, 5, -1, -1, -1, 11, -1, 13, -1, -1, -1, 14, -1, -1, -1, -1, -1, + 1, 3, 4, 0, 7, -1, 12, 2, 11, 8, 6, 13, -1, -1, -1, -1, -1, 5, -1, -1, 10, 15, 9, -1, -1, -1, 14, -1, -1, -1, -1, -1, + 1, 3, 5, 2, 13, 0, 9, 4, 7, 6, 8, -1, -1, 15, -1, 11, -1, -1, 10, -1, 14, -1, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 2, 1, 3, -1, -1, -1, 6, -1, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 11, 4, 0, 3, -1, 13, 12, 2, 7, -1, -1, 15, 10, 5, 8, 14, -1, -1, -1, -1, -1, 9, -1, -1, -1, 6, -1, -1, -1, -1, -1, + 0, 9, 2, 14, 15, 4, 1, 13, 3, 5, -1, -1, 10, -1, -1, -1, -1, 6, 12, -1, 7, -1, 8, -1, -1, -1, 11, -1, -1, -1, -1, -1, + -1, 2, 14, -1, 1, 5, 8, 7, 4, 12, -1, 6, 9, 11, 13, 3, 10, 15, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 3, 2, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 4, 3, 1, 5, -1, -1, -1, 0, -1, -1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 2, 8, 4, 1, -1, 0, -1, 6, -1, -1, 5, -1, 7, -1, -1, -1, -1, -1, -1, -1, 10, -1, -1, 9, -1, -1, -1, -1, -1, -1, -1, -1, + 12, 5, -1, -1, 1, -1, -1, 7, 0, 3, -1, 2, -1, 4, 6, -1, -1, -1, -1, 8, -1, -1, 15, -1, 13, 9, -1, -1, -1, -1, -1, 11, + 1, 3, 2, 4, -1, -1, -1, 5, -1, 7, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, -1, -1, -1, -1, -1, -1, -1, -1, 8, -1, -1, + 5, 3, 4, 12, 1, 6, -1, -1, -1, -1, 8, 2, -1, -1, -1, -1, 0, 9, -1, -1, 11, -1, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 0, -1, 1, 12, 3, -1, -1, -1, -1, 5, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, 6, -1, 10, + 2, 3, 1, 4, -1, 0, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, -1, -1, -1, -1, -1, -1, -1, -1, 6, -1, -1, + 5, 1, 3, 0, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, 9, -1, -1, 6, -1, 7, + }, + successors_reversed = { + 's', 't', 'c', 'l', 'm', 'a', 'd', 'r', 'v', 'T', 'A', 'L', 'e', 'M', 'Y', '-', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '-', 't', 'a', 'b', 's', 'h', 'c', 'r', 'n', 'w', 'p', 'm', 'l', 'd', 'i', 'f', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + 'u', 'e', 'i', 'a', 'o', 'r', 'y', 'l', 'I', 'E', 'R', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + 'e', 'a', 'o', 'i', 'u', 'A', 'y', 'E', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + 't', 'n', 'f', 's', '\'', 'm', 'I', 'N', 'A', 'E', 'L', 'Z', 'r', 'V', 'R', 'C', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + 'o', 'a', 'y', 'i', 'u', 'e', 'I', 'L', 'D', '\'', 'E', 'Y', '\x00', '\x00', '\x00', '\x00', + 'r', 'i', 'y', 'a', 'e', 'o', 'u', 'Y', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + 'h', 'o', 'e', 'E', 'i', 'u', 'r', 'w', 'a', 'H', 'y', 'R', 'Z', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + 'h', 'i', 'e', 'a', 'o', 'r', 'I', 'y', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + 'n', 't', 's', 'r', 'l', 'd', 'i', 'y', 'v', 'm', 'b', 'c', 'g', 'p', 'k', 'u', + 'e', 'l', 'o', 'u', 'y', 'a', 'r', 'i', 's', 'j', 't', 'b', 'v', 'h', 'm', 'd', + 'o', 'e', 'h', 'a', 't', 'k', 'i', 'r', 'l', 'u', 'y', 'c', 'q', 's', '-', 'd', + 'e', 'i', 'o', 'a', 's', 'y', 'r', 'u', 'd', 'l', '-', 'g', 'n', 'v', 'm', 'f', + 'r', 'n', 'd', 's', 'a', 'l', 't', 'e', 'm', 'c', 'v', 'y', 'i', 'x', 'f', 'p', + 'o', 'e', 'r', 'a', 'i', 'f', 'u', 't', 'l', '-', 'y', 's', 'n', 'c', '\'', 'k', + 'h', 'e', 'o', 'a', 'r', 'i', 'l', 's', 'u', 'n', 'g', 'b', '-', 't', 'y', 'm', + 'e', 'a', 'i', 'o', 't', 'r', 'u', 'y', 'm', 's', 'l', 'b', '\'', '-', 'f', 'd', + 'n', 's', 't', 'm', 'o', 'l', 'c', 'd', 'r', 'e', 'g', 'a', 'f', 'v', 'z', 'b', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + 'e', 'n', 'i', 's', 'h', 'l', 'f', 'y', '-', 'a', 'w', '\'', 'g', 'r', 'o', 't', + 'e', 'l', 'i', 'y', 'd', 'o', 'a', 'f', 'u', 't', 's', 'k', 'w', 'v', 'm', 'p', + 'e', 'a', 'o', 'i', 'u', 'p', 'y', 's', 'b', 'm', 'f', '\'', 'n', '-', 'l', 't', + 'd', 'g', 'e', 't', 'o', 'c', 's', 'i', 'a', 'n', 'y', 'l', 'k', '\'', 'f', 'v', + 'u', 'n', 'r', 'f', 'm', 't', 'w', 'o', 's', 'l', 'v', 'd', 'p', 'k', 'i', 'c', + 'e', 'r', 'a', 'o', 'l', 'p', 'i', 't', 'u', 's', 'h', 'y', 'b', '-', '\'', 'm', + '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + 'e', 'i', 'o', 'a', 's', 'y', 't', 'd', 'r', 'n', 'c', 'm', 'l', 'u', 'g', 'f', + 'e', 't', 'h', 'i', 'o', 's', 'a', 'u', 'p', 'c', 'l', 'w', 'm', 'k', 'f', 'y', + 'h', 'o', 'e', 'i', 'a', 't', 'r', 'u', 'y', 'l', 's', 'w', 'c', 'f', '\'', '-', + 'r', 't', 'l', 's', 'n', 'g', 'c', 'p', 'e', 'i', 'a', 'd', 'm', 'b', 'f', 'o', + 'e', 'i', 'a', 'o', 'y', 'u', 'r', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', + 'a', 'i', 'h', 'e', 'o', 'n', 'r', 's', 'l', 'd', 'k', '-', 'f', '\'', 'c', 'b', + 'p', 't', 'c', 'a', 'i', 'e', 'h', 'q', 'u', 'f', '-', 'y', 'o', '\x00', '\x00', '\x00', + 'o', 'e', 's', 't', 'i', 'd', '\'', 'l', 'b', '-', 'm', 'a', 'r', 'n', 'p', 'w', + }, + + character_count = 32, + successor_count = 16, + + max_successor_n = 7, + packs = { + { 0x80000000, 1, 2, { 26, 24, 24, 24, 24, 24, 24, 24 }, { 15, 3, 0, 0, 0, 0, 0, 0 }, 0xc0, 0x80 }, + { 0xc0000000, 2, 4, { 25, 22, 19, 16, 16, 16, 16, 16 }, { 15, 7, 7, 7, 0, 0, 0, 0 }, 0xe0, 0xc0 }, + { 0xe0000000, 4, 8, { 23, 19, 15, 11, 8, 5, 2, 0 }, { 31, 15, 15, 15, 7, 7, 7, 3 }, 0xf0, 0xe0 }, + }, +} \ No newline at end of file diff --git a/core/compress/shoco/shoco.odin b/core/compress/shoco/shoco.odin new file mode 100644 index 000000000..f94ce70b7 --- /dev/null +++ b/core/compress/shoco/shoco.odin @@ -0,0 +1,318 @@ +/* + Copyright 2022 Jeroen van Rijn . + Made available under Odin's BSD-3 license. + + List of contributors: + Jeroen van Rijn: Initial implementation. + + An implementation of [shoco](https://github.com/Ed-von-Schleck/shoco) by Christian Schramm. +*/ + +// package shoco is an implementation of the shoco short string compressor +package shoco + +import "core:intrinsics" +import "core:compress" + +Shoco_Pack :: struct { + word: u32, + bytes_packed: i8, + bytes_unpacked: i8, + offsets: [8]u16, + masks: [8]i16, + header_mask: u8, + header: u8, +} + +Shoco_Model :: struct { + min_char: u8, + max_char: u8, + characters_by_id: []u8, + ids_by_character: [256]i16, + successors_by_bigram: []i8, + successors_reversed: []u8, + + character_count: u8, + successor_count: u8, + max_successor_n: i8, + packs: []Shoco_Pack, +} + +compress_bound :: proc(uncompressed_size: int) -> (worst_case_compressed_size: int) { + // Worst case compression happens when input is non-ASCII (128-255) + // Encoded as 0x00 + the byte in question. + return uncompressed_size * 2 +} + +decompress_bound :: proc(compressed_size: int, model := DEFAULT_MODEL) -> (maximum_decompressed_size: int) { + // Best case compression is 2:1 + most: f64 + for pack in model.packs { + val := f64(compressed_size) / f64(pack.bytes_packed) * f64(pack.bytes_unpacked) + most = max(most, val) + } + return int(most) +} + +find_best_encoding :: proc(indices: []i16, n_consecutive: i8, model := DEFAULT_MODEL) -> (res: int) { + for p := len(model.packs); p > 0; p -= 1 { + pack := model.packs[p - 1] + if n_consecutive >= pack.bytes_unpacked { + have_index := true + for i := 0; i < int(pack.bytes_unpacked); i += 1 { + if indices[i] > pack.masks[i] { + have_index = false + break + } + } + if have_index { + return p - 1 + } + } + } + return -1 +} + +validate_model :: proc(model: Shoco_Model) -> (int, compress.Error) { + if len(model.characters_by_id) != int(model.character_count) { + return 0, .Unknown_Compression_Method + } + + if len(model.successors_by_bigram) != int(model.character_count) * int(model.character_count) { + return 0, .Unknown_Compression_Method + } + + if len(model.successors_reversed) != int(model.successor_count) * int(model.max_char - model.min_char) { + return 0, .Unknown_Compression_Method + } + + // Model seems legit. + return 0, nil +} + +// Decompresses into provided buffer. +decompress_slice_to_output_buffer :: proc(input: []u8, output: []u8, model := DEFAULT_MODEL) -> (size: int, err: compress.Error) { + inp, inp_end := 0, len(input) + out, out_end := 0, len(output) + + validate_model(model) or_return + + for inp < inp_end { + val := transmute(i8)input[inp] + mark := int(-1) + + for val < 0 { + val <<= 1 + mark += 1 + } + + if mark > len(model.packs) { + return out, .Unknown_Compression_Method + } + + if mark < 0 { + if out >= out_end { + return out, .Output_Too_Short + } + + // Ignore the sentinel value for non-ASCII chars + if input[inp] == 0x00 { + inp += 1 + if inp >= inp_end { + return out, .Stream_Too_Short + } + } + output[out] = input[inp] + inp, out = inp + 1, out + 1 + + } else { + pack := model.packs[mark] + + if out + int(pack.bytes_unpacked) > out_end { + return out, .Output_Too_Short + } else if inp + int(pack.bytes_packed) > inp_end { + return out, .Stream_Too_Short + } + + code := intrinsics.unaligned_load((^u32)(&input[inp])) + when ODIN_ENDIAN == .Little { + code = intrinsics.byte_swap(code) + } + + // Unpack the leading char + offset := pack.offsets[0] + mask := pack.masks[0] + + last_chr := model.characters_by_id[(code >> offset) & u32(mask)] + output[out] = last_chr + + // Unpack the successor chars + for i := 1; i < int(pack.bytes_unpacked); i += 1 { + offset = pack.offsets[i] + mask = pack.masks[i] + + index_major := u32(last_chr - model.min_char) * u32(model.successor_count) + index_minor := (code >> offset) & u32(mask) + + last_chr = model.successors_reversed[index_major + index_minor] + + output[out + i] = last_chr + } + + out += int(pack.bytes_unpacked) + inp += int(pack.bytes_packed) + } + } + + return out, nil +} + +decompress_slice_to_string :: proc(input: []u8, model := DEFAULT_MODEL, allocator := context.allocator) -> (res: string, err: compress.Error) { + context.allocator = allocator + + if len(input) == 0 { + return "", .Stream_Too_Short + } + + max_output_size := decompress_bound(len(input), model) + + buf: [dynamic]u8 + if !resize(&buf, max_output_size) { + return "", .Out_Of_Memory + } + + length, result := decompress_slice_to_output_buffer(input, buf[:]) + resize(&buf, length) + return string(buf[:]), result +} +decompress :: proc{decompress_slice_to_output_buffer, decompress_slice_to_string} + +compress_string_to_buffer :: proc(input: string, output: []u8, model := DEFAULT_MODEL, allocator := context.allocator) -> (size: int, err: compress.Error) { + inp, inp_end := 0, len(input) + out, out_end := 0, len(output) + output := output + + validate_model(model) or_return + + indices := make([]i16, model.max_successor_n + 1) + defer delete(indices) + + last_resort := false + + encode: for inp < inp_end { + if last_resort { + last_resort = false + + if input[inp] & 0x80 == 0x80 { + // Non-ASCII case + if out + 2 > out_end { + return out, .Output_Too_Short + } + + // Put in a sentinel byte + output[out] = 0x00 + out += 1 + } else { + // An ASCII byte + if out + 1 > out_end { + return out, .Output_Too_Short + } + } + output[out] = input[inp] + out, inp = out + 1, inp + 1 + } else { + // Find the longest string of known successors + indices[0] = model.ids_by_character[input[inp]] + last_chr_index := indices[0] + + if last_chr_index < 0 { + last_resort = true + continue encode + } + + rest := inp_end - inp + n_consecutive: i8 = 1 + for ; n_consecutive <= model.max_successor_n; n_consecutive += 1 { + if inp_end > 0 && int(n_consecutive) == rest { + break + } + + current_index := model.ids_by_character[input[inp + int(n_consecutive)]] + if current_index < 0 { // '\0' is always -1 + break + } + + successor_index := model.successors_by_bigram[last_chr_index * i16(model.character_count) + current_index] + if successor_index < 0 { + break + } + + indices[n_consecutive] = i16(successor_index) + last_chr_index = current_index + } + + if n_consecutive < 2 { + last_resort = true + continue encode + } + + pack_n := find_best_encoding(indices, n_consecutive) + if pack_n >= 0 { + if out + int(model.packs[pack_n].bytes_packed) > out_end { + return out, .Output_Too_Short + } + + pack := model.packs[pack_n] + code := pack.word + + for i := 0; i < int(pack.bytes_unpacked); i += 1 { + code |= u32(indices[i]) << pack.offsets[i] + } + + // In the little-endian world, we need to swap what's in the register to match the memory representation. + when ODIN_ENDIAN == .Little { + code = intrinsics.byte_swap(code) + } + out_ptr := raw_data(output[out:]) + + switch pack.bytes_packed { + case 4: + intrinsics.unaligned_store(transmute(^u32)out_ptr, code) + case 2: + intrinsics.unaligned_store(transmute(^u16)out_ptr, u16(code)) + case 1: + intrinsics.unaligned_store(transmute(^u8)out_ptr, u8(code)) + case: + return out, .Unknown_Compression_Method + } + + out += int(pack.bytes_packed) + inp += int(pack.bytes_unpacked) + } else { + last_resort = true + continue encode + } + } + } + return out, nil +} + +compress_string :: proc(input: string, model := DEFAULT_MODEL, allocator := context.allocator) -> (output: []u8, err: compress.Error) { + context.allocator = allocator + + if len(input) == 0 { + return {}, .Stream_Too_Short + } + + max_output_size := compress_bound(len(input)) + + buf: [dynamic]u8 + if !resize(&buf, max_output_size) { + return {}, .Out_Of_Memory + } + + length, result := compress_string_to_buffer(input, buf[:]) + resize(&buf, length) + return buf[:length], result +} +compress :: proc{compress_string_to_buffer, compress_string} \ No newline at end of file diff --git a/core/compress/zlib/zlib.odin b/core/compress/zlib/zlib.odin index 9ae980042..855eef7a8 100644 --- a/core/compress/zlib/zlib.odin +++ b/core/compress/zlib/zlib.odin @@ -47,10 +47,10 @@ Options :: struct { level: u8, } -Error :: compress.Error -E_General :: compress.General_Error -E_ZLIB :: compress.ZLIB_Error -E_Deflate :: compress.Deflate_Error +Error :: compress.Error +General_Error :: compress.General_Error +ZLIB_Error :: compress.ZLIB_Error +Deflate_Error :: compress.Deflate_Error DEFLATE_MAX_CHUNK_SIZE :: 65535 DEFLATE_MAX_LITERAL_SIZE :: 65535 @@ -111,9 +111,9 @@ ZFAST_MASK :: ((1 << ZFAST_BITS) - 1) */ Huffman_Table :: struct { fast: [1 << ZFAST_BITS]u16, - firstcode: [16]u16, + firstcode: [17]u16, maxcode: [17]int, - firstsymbol: [16]u16, + firstsymbol: [17]u16, size: [288]u8, value: [288]u16, } @@ -244,7 +244,7 @@ allocate_huffman_table :: proc(allocator := context.allocator) -> (z: ^Huffman_T @(optimization_mode="speed") build_huffman :: proc(z: ^Huffman_Table, code_lengths: []u8) -> (err: Error) { sizes: [HUFFMAN_MAX_BITS+1]int - next_code: [HUFFMAN_MAX_BITS]int + next_code: [HUFFMAN_MAX_BITS+1]int k := int(0) @@ -256,21 +256,21 @@ build_huffman :: proc(z: ^Huffman_Table, code_lengths: []u8) -> (err: Error) { } sizes[0] = 0 - for i in 1..<(HUFFMAN_MAX_BITS+1) { + for i in 1 ..< HUFFMAN_MAX_BITS { if sizes[i] > (1 << uint(i)) { - return E_Deflate.Huffman_Bad_Sizes + return .Huffman_Bad_Sizes } } code := int(0) - for i in 1..= (1 << u16(i)) { - return E_Deflate.Huffman_Bad_Code_Lengths + return .Huffman_Bad_Code_Lengths } } z.maxcode[i] = code << (HUFFMAN_MAX_BITS - uint(i)) @@ -314,15 +314,15 @@ decode_huffman_slowpath :: proc(z: ^$C, t: ^Huffman_Table) -> (r: u16, err: Erro s += 1 } if s >= 16 { - return 0, E_Deflate.Bad_Huffman_Code + return 0, .Bad_Huffman_Code } // code size is s, so: b := (k >> (16-s)) - int(t.firstcode[s]) + int(t.firstsymbol[s]) if b >= size_of(t.size) { - return 0, E_Deflate.Bad_Huffman_Code + return 0, .Bad_Huffman_Code } if t.size[b] != s { - return 0, E_Deflate.Bad_Huffman_Code + return 0, .Bad_Huffman_Code } compress.consume_bits_lsb(z, s) @@ -335,11 +335,11 @@ decode_huffman_slowpath :: proc(z: ^$C, t: ^Huffman_Table) -> (r: u16, err: Erro decode_huffman :: proc(z: ^$C, t: ^Huffman_Table) -> (r: u16, err: Error) #no_bounds_check { if z.num_bits < 16 { if z.num_bits > 63 { - return 0, E_ZLIB.Code_Buffer_Malformed + return 0, .Code_Buffer_Malformed } compress.refill_lsb(z) if z.num_bits > 63 { - return 0, E_General.Stream_Too_Short + return 0, .Stream_Too_Short } } #no_bounds_check b := t.fast[z.code_buffer & ZFAST_MASK] @@ -361,7 +361,7 @@ parse_huffman_block :: proc(z: ^$C, z_repeat, z_offset: ^Huffman_Table) -> (err: if value < 256 { e := write_byte(z, u8(value)) if e != .None { - return E_General.Output_Too_Short + return .Output_Too_Short } } else { if value == 256 { @@ -377,7 +377,7 @@ parse_huffman_block :: proc(z: ^$C, z_repeat, z_offset: ^Huffman_Table) -> (err: value, e = decode_huffman(z, z_offset) if e != nil { - return E_Deflate.Bad_Huffman_Code + return .Bad_Huffman_Code } distance := Z_DIST_BASE[value] @@ -387,7 +387,7 @@ parse_huffman_block :: proc(z: ^$C, z_repeat, z_offset: ^Huffman_Table) -> (err: if z.bytes_written < i64(distance) { // Distance is longer than we've decoded so far. - return E_Deflate.Bad_Distance + return .Bad_Distance } /* @@ -405,14 +405,14 @@ parse_huffman_block :: proc(z: ^$C, z_repeat, z_offset: ^Huffman_Table) -> (err: c := z.output.buf[z.bytes_written - i64(distance)] e := repl_byte(z, length, c) if e != .None { - return E_General.Output_Too_Short + return .Output_Too_Short } } } else { if length > 0 { e := repl_bytes(z, length, distance) if e != .None { - return E_General.Output_Too_Short + return .Output_Too_Short } } } @@ -432,25 +432,25 @@ inflate_from_context :: proc(using ctx: ^compress.Context_Memory_Input, raw := f if !raw { size, size_err := compress.input_size(ctx) if size < 6 || size_err != nil { - return E_General.Stream_Too_Short + return .Stream_Too_Short } cmf, _ := compress.read_u8(ctx) method := Compression_Method(cmf & 0xf) if method != .DEFLATE { - return E_General.Unknown_Compression_Method + return .Unknown_Compression_Method } if cinfo := (cmf >> 4) & 0xf; cinfo > 7 { - return E_ZLIB.Unsupported_Window_Size + return .Unsupported_Window_Size } flg, _ := compress.read_u8(ctx) fcheck := flg & 0x1f fcheck_computed := (cmf << 8 | flg) & 0x1f if fcheck != fcheck_computed { - return E_General.Checksum_Failed + return .Checksum_Failed } /* @@ -458,7 +458,7 @@ inflate_from_context :: proc(using ctx: ^compress.Context_Memory_Input, raw := f They're application specific and PNG doesn't use them. */ if fdict := (flg >> 5) & 1; fdict != 0 { - return E_ZLIB.FDICT_Unsupported + return .FDICT_Unsupported } // flevel := Compression_Level((flg >> 6) & 3); @@ -485,7 +485,7 @@ inflate_from_context :: proc(using ctx: ^compress.Context_Memory_Input, raw := f output_hash := hash.adler32(ctx.output.buf[:]) if output_hash != u32(adler) { - return E_General.Checksum_Failed + return .Checksum_Failed } } return nil @@ -538,23 +538,24 @@ inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.all final = compress.read_bits_lsb(z, 1) type = compress.read_bits_lsb(z, 2) - // fmt.printf("Final: %v | Type: %v\n", final, type); + // fmt.printf("Final: %v | Type: %v\n", final, type) switch type { case 0: + // fmt.printf("Method 0: STORED\n") // Uncompressed block // Discard bits until next byte boundary compress.discard_to_next_byte_lsb(z) - uncompressed_len := i16(compress.read_bits_lsb(z, 16)) - length_check := i16(compress.read_bits_lsb(z, 16)) + uncompressed_len := u16(compress.read_bits_lsb(z, 16)) + length_check := u16(compress.read_bits_lsb(z, 16)) - // fmt.printf("LEN: %v, ~LEN: %v, NLEN: %v, ~NLEN: %v\n", uncompressed_len, ~uncompressed_len, length_check, ~length_check); + // fmt.printf("LEN: %v, ~LEN: %v, NLEN: %v, ~NLEN: %v\n", uncompressed_len, ~uncompressed_len, length_check, ~length_check) if ~uncompressed_len != length_check { - return E_Deflate.Len_Nlen_Mismatch + return .Len_Nlen_Mismatch } /* @@ -567,10 +568,12 @@ inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.all write_byte(z, u8(lit)) uncompressed_len -= 1 } + assert(uncompressed_len == 0) + case 3: - return E_Deflate.BType_3 + return .BType_3 case: - // log.debugf("Err: %v | Final: %v | Type: %v\n", err, final, type); + // fmt.printf("Err: %v | Final: %v | Type: %v\n", err, final, type) if type == 1 { // Use fixed code lengths. build_huffman(z_repeat, Z_FIXED_LENGTH[:]) or_return @@ -601,7 +604,7 @@ inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.all c = decode_huffman(z, codelength_ht) or_return if c < 0 || c >= 19 { - return E_Deflate.Huffman_Bad_Code_Lengths + return .Huffman_Bad_Code_Lengths } if c < 16 { lencodes[n] = u8(c) @@ -613,7 +616,7 @@ inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.all case 16: c = u16(compress.read_bits_no_refill_lsb(z, 2) + 3) if n == 0 { - return E_Deflate.Huffman_Bad_Code_Lengths + return .Huffman_Bad_Code_Lengths } fill = lencodes[n - 1] case 17: @@ -621,11 +624,11 @@ inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.all case 18: c = u16(compress.read_bits_no_refill_lsb(z, 7) + 11) case: - return E_Deflate.Huffman_Bad_Code_Lengths + return .Huffman_Bad_Code_Lengths } if ntot - n < u32(c) { - return E_Deflate.Huffman_Bad_Code_Lengths + return .Huffman_Bad_Code_Lengths } nc := n + u32(c) @@ -636,7 +639,7 @@ inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.all } if n != ntot { - return E_Deflate.Huffman_Bad_Code_Lengths + return .Huffman_Bad_Code_Lengths } build_huffman(z_repeat, lencodes[:hlit]) or_return @@ -674,4 +677,4 @@ inflate_from_byte_array_raw :: proc(input: []u8, buf: ^bytes.Buffer, raw := fals return inflate_raw(z=&ctx, expected_output_size=expected_output_size) } -inflate :: proc{inflate_from_context, inflate_from_byte_array}; \ No newline at end of file +inflate :: proc{inflate_from_context, inflate_from_byte_array} diff --git a/core/container/array.odin b/core/container/array.odin deleted file mode 100644 index 2d5a64ec3..000000000 --- a/core/container/array.odin +++ /dev/null @@ -1,216 +0,0 @@ -package container - -import "core:mem" -import "core:runtime" - -Array :: struct($T: typeid) { - data: ^T, - len: int, - cap: int, - allocator: mem.Allocator, -} - -ARRAY_DEFAULT_CAPACITY :: 16 - -/* -array_init :: proc { - array_init_none, - array_init_len, - array_init_len_cap, -} -array_init -array_delete -array_len -array_cap -array_space -array_slice -array_get -array_get_ptr -array_set -array_reserve -array_resize -array_push = array_append :: proc{ - array_push_back, - array_push_back_elems, -} -array_push_front -array_pop_back -array_pop_front -array_consume -array_trim -array_clear -array_clone -array_set_capacity -array_grow -*/ - - -array_init_none :: proc(a: ^$A/Array, allocator := context.allocator) { - array_init_len_cap(a, 0, ARRAY_DEFAULT_CAPACITY, allocator) -} -array_init_len :: proc(a: ^$A/Array, len: int, allocator := context.allocator) { - array_init_len_cap(a, len, len, allocator) -} -array_init_len_cap :: proc(a: ^$A/Array($T), len: int, cap: int, allocator := context.allocator) { - a.allocator = allocator - a.data = (^T)(mem.alloc(size_of(T)*cap, align_of(T), a.allocator)) - a.len = len - a.cap = cap -} - -array_init :: proc{array_init_none, array_init_len, array_init_len_cap} - -array_delete :: proc(a: $A/Array) { - mem.free(a.data, a.allocator) -} - -array_len :: proc(a: $A/Array) -> int { - return a.len -} - -array_cap :: proc(a: $A/Array) -> int { - return a.cap -} - -array_space :: proc(a: $A/Array) -> int { - return a.cap - a.len -} - -array_slice :: proc(a: $A/Array($T)) -> []T { - s := mem.Raw_Slice{a.data, a.len} - return transmute([]T)s -} - -array_cap_slice :: proc(a: $A/Array($T)) -> []T { - s := mem.Raw_Slice{a.data, a.cap} - return transmute([]T)s -} - -array_get :: proc(a: $A/Array($T), index: int, loc := #caller_location) -> T { - runtime.bounds_check_error_loc(loc, index, array_len(a)) - return (^T)(uintptr(a.data) + size_of(T)*uintptr(index))^ -} -array_get_ptr :: proc(a: $A/Array($T), index: int, loc := #caller_location) -> ^T { - runtime.bounds_check_error_loc(loc, index, array_len(a)) - return (^T)(uintptr(a.data) + size_of(T)*uintptr(index)) -} - -array_set :: proc(a: ^$A/Array($T), index: int, item: T, loc := #caller_location) { - runtime.bounds_check_error_loc(loc, index, array_len(a^)) - (^T)(uintptr(a.data) + size_of(T)*uintptr(index))^ = item -} - - -array_reserve :: proc(a: ^$A/Array, capacity: int) { - if capacity > a.len { - array_set_capacity(a, capacity) - } -} - -array_resize :: proc(a: ^$A/Array, length: int) { - if length > a.len { - array_set_capacity(a, length) - } - a.len = length -} - - - -array_push_back :: proc(a: ^$A/Array($T), item: T) { - if array_space(a^) == 0 { - array_grow(a) - } - - a.len += 1 - array_set(a, a.len-1, item) -} - -array_push_front :: proc(a: ^$A/Array($T), item: T) { - if array_space(a^) == 0 { - array_grow(a) - } - - a.len += 1 - data := array_slice(a^) - copy(data[1:], data[:]) - data[0] = item -} - -array_pop_back :: proc(a: ^$A/Array($T), loc := #caller_location) -> T { - assert(condition=a.len > 0, loc=loc) - item := array_get(a^, a.len-1) - a.len -= 1 - return item -} - -array_pop_front :: proc(a: ^$A/Array($T), loc := #caller_location) -> T { - assert(condition=a.len > 0, loc=loc) - item := array_get(a^, 0) - s := array_slice(a^) - copy(s[:], s[1:]) - a.len -= 1 - return item -} - - -array_consume :: proc(a: ^$A/Array($T), count: int, loc := #caller_location) { - assert(condition=a.len >= count, loc=loc) - a.len -= count -} - - -array_trim :: proc(a: ^$A/Array($T)) { - array_set_capacity(a, a.len) -} - -array_clear :: proc(a: ^$A/Array($T)) { - array_resize(a, 0) -} - -array_clone :: proc(a: $A/Array($T), allocator := context.allocator) -> A { - res: A - array_init(&res, array_len(a), array_len(a), allocator) - copy(array_slice(res), array_slice(a)) - return res -} - -array_push_back_elems :: proc(a: ^$A/Array($T), items: ..T) { - if array_space(a^) < len(items) { - array_grow(a, a.len + len(items)) - } - offset := a.len - data := array_cap_slice(a^) - n := copy(data[a.len:], items) - a.len += n -} - -array_push :: proc{array_push_back, array_push_back_elems} -array_append :: proc{array_push_back, array_push_back_elems} - -array_set_capacity :: proc(a: ^$A/Array($T), new_capacity: int) { - if new_capacity == a.cap { - return - } - - if new_capacity < a.len { - array_resize(a, new_capacity) - } - - new_data: ^T - if new_capacity > 0 { - if a.allocator.procedure == nil { - a.allocator = context.allocator - } - new_data = (^T)(mem.alloc(size_of(T)*new_capacity, align_of(T), a.allocator)) - if new_data != nil { - mem.copy(new_data, a.data, size_of(T)*a.len) - } - } - mem.free(a.data, a.allocator) - a.data = new_data - a.cap = new_capacity -} -array_grow :: proc(a: ^$A/Array, min_capacity: int = 0) { - new_capacity := max(array_len(a^)*2 + 8, min_capacity) - array_set_capacity(a, new_capacity) -} diff --git a/core/container/bit_array/bit_array.odin b/core/container/bit_array/bit_array.odin new file mode 100644 index 000000000..98ef4b542 --- /dev/null +++ b/core/container/bit_array/bit_array.odin @@ -0,0 +1,239 @@ +package dynamic_bit_array + +import "core:intrinsics" +import "core:mem" + +/* + Note that these constants are dependent on the backing being a u64. +*/ +@(private="file") +INDEX_SHIFT :: 6 + +@(private="file") +INDEX_MASK :: 63 + +@(private="file") +NUM_BITS :: 64 + +Bit_Array :: struct { + bits: [dynamic]u64, + bias: int, + max_index: int, + free_pointer: bool, +} + +Bit_Array_Iterator :: struct { + array: ^Bit_Array, + word_idx: int, + bit_idx: uint, +} + +/* + In: + - ba: ^Bit_Array - the array to iterate over + + Out: + - it: ^Bit_Array_Iterator - the iterator that holds iteration state +*/ +make_iterator :: proc (ba: ^Bit_Array) -> (it: Bit_Array_Iterator) { + return Bit_Array_Iterator { array = ba } +} + +/* + In: + - it: ^Bit_Array_Iterator - the iterator struct that holds the state. + + Out: + - set: bool - the state of the bit at `index` + - index: int - the next bit of the Bit_Array referenced by `it`. + - ok: bool - `true` if the iterator returned a valid index, + `false` if there were no more bits +*/ +iterate_by_all :: proc (it: ^Bit_Array_Iterator) -> (set: bool, index: int, ok: bool) { + index = it.word_idx * NUM_BITS + int(it.bit_idx) + it.array.bias + if index > it.array.max_index { return false, 0, false } + + word := it.array.bits[it.word_idx] if len(it.array.bits) > it.word_idx else 0 + set = (word >> it.bit_idx & 1) == 1 + + it.bit_idx += 1 + if it.bit_idx >= NUM_BITS { + it.bit_idx = 0 + it.word_idx += 1 + } + + return set, index, true +} + +/* + In: + - it: ^Bit_Array_Iterator - the iterator struct that holds the state. + + Out: + - index: int - the next set bit of the Bit_Array referenced by `it`. + - ok: bool - `true` if the iterator returned a valid index, + `false` if there were no more bits set +*/ +iterate_by_set :: proc (it: ^Bit_Array_Iterator) -> (index: int, ok: bool) { + return iterate_internal_(it, true) +} + +/* + In: + - it: ^Bit_Array_Iterator - the iterator struct that holds the state. + + Out: + - index: int - the next unset bit of the Bit_Array referenced by `it`. + - ok: bool - `true` if the iterator returned a valid index, + `false` if there were no more unset bits +*/ +iterate_by_unset:: proc (it: ^Bit_Array_Iterator) -> (index: int, ok: bool) { + return iterate_internal_(it, false) +} + +@(private="file") +iterate_internal_ :: proc (it: ^Bit_Array_Iterator, $ITERATE_SET_BITS: bool) -> (index: int, ok: bool) { + word := it.array.bits[it.word_idx] if len(it.array.bits) > it.word_idx else 0 + when ! ITERATE_SET_BITS { word = ~word } + + // if the word is empty or we have already gone over all the bits in it, + // b.bit_idx is greater than the index of any set bit in the word, + // meaning that word >> b.bit_idx == 0. + for it.word_idx < len(it.array.bits) && word >> it.bit_idx == 0 { + it.word_idx += 1 + it.bit_idx = 0 + word = it.array.bits[it.word_idx] if len(it.array.bits) > it.word_idx else 0 + when ! ITERATE_SET_BITS { word = ~word } + } + + // if we are iterating the set bits, reaching the end of the array means we have no more bits to check + when ITERATE_SET_BITS { + if it.word_idx >= len(it.array.bits) { + return 0, false + } + } + + // reaching here means that the word has some set bits + it.bit_idx += uint(intrinsics.count_trailing_zeros(word >> it.bit_idx)) + index = it.word_idx * NUM_BITS + int(it.bit_idx) + it.array.bias + + it.bit_idx += 1 + if it.bit_idx >= NUM_BITS { + it.bit_idx = 0 + it.word_idx += 1 + } + return index, index <= it.array.max_index +} + + +/* + In: + - ba: ^Bit_Array - a pointer to the Bit Array + - index: The bit index. Can be an enum member. + + Out: + - res: The bit you're interested in. + - ok: Whether the index was valid. Returns `false` if the index is smaller than the bias. + + The `ok` return value may be ignored. +*/ +get :: proc(ba: ^Bit_Array, #any_int index: uint, allocator := context.allocator) -> (res: bool, ok: bool) { + idx := int(index) - ba.bias + + if ba == nil || int(index) < ba.bias { return false, false } + context.allocator = allocator + + leg_index := idx >> INDEX_SHIFT + bit_index := idx & INDEX_MASK + + /* + If we `get` a bit that doesn't fit in the Bit Array, it's naturally `false`. + This early-out prevents unnecessary resizing. + */ + if leg_index + 1 > len(ba.bits) { return false, true } + + val := u64(1 << uint(bit_index)) + res = ba.bits[leg_index] & val == val + + return res, true +} + +/* + In: + - ba: ^Bit_Array - a pointer to the Bit Array + - index: The bit index. Can be an enum member. + + Out: + - ok: Whether or not we managed to set requested bit. + + `set` automatically resizes the Bit Array to accommodate the requested index if needed. +*/ +set :: proc(ba: ^Bit_Array, #any_int index: uint, allocator := context.allocator) -> (ok: bool) { + + idx := int(index) - ba.bias + + if ba == nil || int(index) < ba.bias { return false } + context.allocator = allocator + + leg_index := idx >> INDEX_SHIFT + bit_index := idx & INDEX_MASK + + resize_if_needed(ba, leg_index) or_return + + ba.max_index = max(idx, ba.max_index) + ba.bits[leg_index] |= 1 << uint(bit_index) + return true +} + +/* + A helper function to create a Bit Array with optional bias, in case your smallest index is non-zero (including negative). +*/ +create :: proc(max_index: int, min_index := 0, allocator := context.allocator) -> (res: ^Bit_Array, ok: bool) #optional_ok { + context.allocator = allocator + size_in_bits := max_index - min_index + + if size_in_bits < 1 { return {}, false } + + legs := size_in_bits >> INDEX_SHIFT + + res = new(Bit_Array) + res.bias = min_index + res.max_index = max_index + res.free_pointer = true + return res, resize_if_needed(res, legs) +} + +/* + Sets all bits to `false`. +*/ +clear :: proc(ba: ^Bit_Array) { + if ba == nil { return } + mem.zero_slice(ba.bits[:]) +} + +/* + Releases the memory used by the Bit Array. +*/ +destroy :: proc(ba: ^Bit_Array) { + if ba == nil { return } + delete(ba.bits) + if ba.free_pointer { // Only free if this Bit_Array was created using `create`, not when on the stack. + free(ba) + } +} + +/* + Resizes the Bit Array. For internal use. + If you want to reserve the memory for a given-sized Bit Array up front, you can use `create`. +*/ +@(private="file") +resize_if_needed :: proc(ba: ^Bit_Array, legs: int, allocator := context.allocator) -> (ok: bool) { + if ba == nil { return false } + + context.allocator = allocator + + if legs + 1 > len(ba.bits) { + resize(&ba.bits, legs + 1) + } + return len(ba.bits) > legs +} diff --git a/core/container/bit_array/doc.odin b/core/container/bit_array/doc.odin new file mode 100644 index 000000000..52e252d8a --- /dev/null +++ b/core/container/bit_array/doc.odin @@ -0,0 +1,53 @@ +package dynamic_bit_array + +/* + The Bit Array can be used in several ways: + + -- By default you don't need to instantiate a Bit Array: + + package test + + import "core:fmt" + import "core:container/bit_array" + + main :: proc() { + using bit_array + + bits: Bit_Array + + // returns `true` + fmt.println(set(&bits, 42)) + + // returns `false`, `false`, because this Bit Array wasn't created to allow negative indices. + was_set, was_retrieved := get(&bits, -1) + fmt.println(was_set, was_retrieved) + destroy(&bits) + } + + -- A Bit Array can optionally allow for negative indices, if the mininum value was given during creation: + + package test + + import "core:fmt" + import "core:container/bit_array" + + main :: proc() { + Foo :: enum int { + Negative_Test = -42, + Bar = 420, + Leaves = 69105, + } + + using bit_array + + bits := create(int(max(Foo)), int(min(Foo))) + defer destroy(bits) + + fmt.printf("Set(Bar): %v\n", set(bits, Foo.Bar)) + fmt.printf("Get(Bar): %v, %v\n", get(bits, Foo.Bar)) + fmt.printf("Set(Negative_Test): %v\n", set(bits, Foo.Negative_Test)) + fmt.printf("Get(Leaves): %v, %v\n", get(bits, Foo.Leaves)) + fmt.printf("Get(Negative_Test): %v, %v\n", get(bits, Foo.Negative_Test)) + fmt.printf("Freed.\n") + } +*/ \ No newline at end of file diff --git a/core/container/bloom_filter.odin b/core/container/bloom_filter.odin deleted file mode 100644 index 8af7aeb85..000000000 --- a/core/container/bloom_filter.odin +++ /dev/null @@ -1,80 +0,0 @@ -package container - -import "core:mem" - -Bloom_Hash_Proc :: #type proc(data: []byte) -> u32 - -Bloom_Hash :: struct { - hash_proc: Bloom_Hash_Proc, - next: ^Bloom_Hash, -} - -Bloom_Filter :: struct { - allocator: mem.Allocator, - hash: ^Bloom_Hash, - bits: []byte, -} - -bloom_filter_init :: proc(b: ^Bloom_Filter, size: int, allocator := context.allocator) { - b.allocator = allocator - b.bits = make([]byte, size, allocator) -} - -bloom_filter_destroy :: proc(b: ^Bloom_Filter) { - context.allocator = b.allocator - delete(b.bits) - for b.hash != nil { - hash := b.hash - b.hash = b.hash.next - free(hash) - } -} - -bloom_filter_add_hash_proc :: proc(b: ^Bloom_Filter, hash_proc: Bloom_Hash_Proc) { - context.allocator = b.allocator - h := new(Bloom_Hash) - h.hash_proc = hash_proc - - head := &b.hash - for head^ != nil { - head = &(head^.next) - } - head^ = h -} - -bloom_filter_add :: proc(b: ^Bloom_Filter, item: []byte) { - #no_bounds_check for h := b.hash; h != nil; h = h.next { - hash := h.hash_proc(item) - hash %= u32(len(b.bits) * 8) - b.bits[hash >> 3] |= 1 << (hash & 3) - } -} - -bloom_filter_add_string :: proc(b: ^Bloom_Filter, item: string) { - bloom_filter_add(b, transmute([]byte)item) -} - -bloom_filter_add_raw :: proc(b: ^Bloom_Filter, data: rawptr, size: int) { - item := mem.slice_ptr((^byte)(data), size) - bloom_filter_add(b, item) -} - -bloom_filter_test :: proc(b: ^Bloom_Filter, item: []byte) -> bool { - #no_bounds_check for h := b.hash; h != nil; h = h.next { - hash := h.hash_proc(item) - hash %= u32(len(b.bits) * 8) - if (b.bits[hash >> 3] & (1 << (hash & 3)) == 0) { - return false - } - } - return true -} - -bloom_filter_test_string :: proc(b: ^Bloom_Filter, item: string) -> bool { - return bloom_filter_test(b, transmute([]byte)item) -} - -bloom_filter_test_raw :: proc(b: ^Bloom_Filter, data: rawptr, size: int) -> bool { - item := mem.slice_ptr((^byte)(data), size) - return bloom_filter_test(b, item) -} diff --git a/core/container/lru/lru_cache.odin b/core/container/lru/lru_cache.odin new file mode 100644 index 000000000..b59f29f0c --- /dev/null +++ b/core/container/lru/lru_cache.odin @@ -0,0 +1,201 @@ +package container_lru + +import "core:runtime" +import "core:intrinsics" +_ :: runtime +_ :: intrinsics + +Node :: struct($Key, $Value: typeid) where intrinsics.type_is_valid_map_key(Key) { + prev, next: ^Node(Key, Value), + key: Key, + value: Value, +} + +// Cache is an LRU cache. It automatically removes entries as new entries are +// added if the capacity is reached. Entries are removed based on how recently +// they were used where the oldest entries are removed first. +Cache :: struct($Key, $Value: typeid) where intrinsics.type_is_valid_map_key(Key) { + head: ^Node(Key, Value), + tail: ^Node(Key, Value), + + entries: map[Key]^Node(Key, Value), + + count: int, + capacity: int, + + node_allocator: runtime.Allocator, + + on_remove: proc(key: Key, value: Value, user_data: rawptr), + on_remove_user_data: rawptr, +} + +// init initializes a Cache +init :: proc(c: ^$C/Cache($Key, $Value), capacity: int, entries_allocator := context.allocator, node_allocator := context.allocator) { + c.entries.allocator = entries_allocator + c.node_allocator = node_allocator + c.capacity = capacity +} + +// destroy deinitializes a Cachem +destroy :: proc(c: ^$C/Cache($Key, $Value), call_on_remove: bool) { + clear(c, call_on_remove) + delete(c.entries) +} + +// clear the contents of a Cache +clear :: proc(c: ^$C/Cache($Key, $Value), call_on_remove: bool) { + for _, node in c.entries { + if call_on_remove { + _call_on_remove(c, node) + } + free(node, c.node_allocator) + } + runtime.clear(&c.entries) + c.head = nil + c.tail = nil + c.count = 0 +} + +// set the given key value pair. This operation updates the recent usage of the item. +set :: proc(c: ^$C/Cache($Key, $Value), key: Key, value: Value) -> runtime.Allocator_Error { + if e, ok := c.entries[key]; ok { + e.value = value + _pop_node(c, e) + _push_front_node(c, e) + return nil + } + + e : ^Node(Key, Value) = nil + assert(c.count <= c.capacity) + if c.count == c.capacity { + e = c.tail + _remove_node(c, e) + } + else { + c.count += 1 + e = new(Node(Key, Value), c.node_allocator) or_return + } + + e.key = key + e.value = value + _push_front_node(c, e) + c.entries[key] = e + + return nil +} + +// get a value from the cache from a given key. This operation updates the usage of the item. +get :: proc(c: ^$C/Cache($Key, $Value), key: Key) -> (value: Value, ok: bool) #optional_ok { + e: ^Node(Key, Value) + e, ok = c.entries[key] + if !ok { + return + } + _pop_node(c, e) + _push_front_node(c, e) + return e.value, true +} + +// get_ptr gets the pointer to a value the cache from a given key. This operation updates the usage of the item. +get_ptr :: proc(c: ^$C/Cache($Key, $Value), key: Key) -> (value: ^Value, ok: bool) #optional_ok { + e: ^Node(Key, Value) + e, ok = c.entries[key] + if !ok { + return + } + _pop_node(c, e) + _push_front_node(c, e) + return &e.value, true +} + +// peek gets the value from the cache from a given key without updating the recent usage. +peek :: proc(c: ^$C/Cache($Key, $Value), key: Key) -> (value: Value, ok: bool) #optional_ok { + e: ^Node(Key, Value) + e, ok = c.entries[key] + if !ok { + return + } + return e.value, true +} + +// exists checks for the existence of a value from a given key without updating the recent usage. +exists :: proc(c: ^$C/Cache($Key, $Value), key: Key) -> bool { + return key in c.entries +} + +// remove removes an item from the cache. +remove :: proc(c: ^$C/Cache($Key, $Value), key: Key) -> bool { + e, ok := c.entries[key] + if !ok { + return false + } + _remove_node(c, e) + free(node, c.node_allocator) + c.count -= 1 + return true +} + + +@(private) +_remove_node :: proc(c: ^$C/Cache($Key, $Value), node: ^Node(Key, Value)) { + if c.head == node { + c.head = node.next + } + if c.tail == node { + c.tail = node.prev + } + if node.prev != nil { + node.prev.next = node.next + } + if node.next != nil { + node.next.prev = node.prev + } + node.prev = nil + node.next = nil + + delete_key(&c.entries, node.key) + + _call_on_remove(c, node) +} + +@(private) +_call_on_remove :: proc(c: ^$C/Cache($Key, $Value), node: ^Node(Key, Value)) { + if c.on_remove != nil { + c.on_remove(node.key, node.value, c.on_remove_user_data) + } +} + +@(private) +_push_front_node :: proc(c: ^$C/Cache($Key, $Value), e: ^Node(Key, Value)) { + if c.head != nil { + e.next = c.head + e.next.prev = e + } + c.head = e + if c.tail == nil { + c.tail = e + } + e.prev = nil +} + +@(private) +_pop_node :: proc(c: ^$C/Cache($Key, $Value), e: ^Node(Key, Value)) { + if e == nil { + return + } + if c.head == e { + c.head = e.next + } + if c.tail == e { + c.tail = e.prev + } + if e.prev != nil { + e.prev.next = e.next + } + + if e.next != nil { + e.next.prev = e.prev + } + e.prev = nil + e.next = nil +} \ No newline at end of file diff --git a/core/container/map.odin b/core/container/map.odin deleted file mode 100644 index 54cbc22fc..000000000 --- a/core/container/map.odin +++ /dev/null @@ -1,377 +0,0 @@ -package container - -import "core:intrinsics" -_ :: intrinsics - - -Map :: struct($Key, $Value: typeid) where intrinsics.type_is_valid_map_key(Key) { - hash: Array(int), - entries: Array(Map_Entry(Key, Value)), -} - -Map_Entry :: struct($Key, $Value: typeid) where intrinsics.type_is_valid_map_key(Key) { - hash: uintptr, - next: int, - key: Key, - value: Value, -} - - -/* -map_init :: proc{ - map_init_none, - map_init_cap, -} -map_delete - -map_has -map_get -map_get_default -map_get_ptr -map_set -map_remove -map_reserve -map_clear - -// Multi Map - -multi_map_find_first -multi_map_find_next -multi_map_count -multi_map_get :: proc{ - multi_map_get_array, - multi_map_get_slice, -}; -multi_map_get_as_slice -multi_map_insert -multi_map_remove -multi_map_remove_all - -*/ - -map_init :: proc{map_init_none, map_init_cap} - -map_init_none :: proc(m: ^$M/Map($Key, $Value), allocator := context.allocator) { - m.hash.allocator = allocator - m.entries.allocator = allocator -} - -map_init_cap :: proc(m: ^$M/Map($Key, $Value), cap: int, allocator := context.allocator) { - m.hash.allocator = allocator - m.entries.allocator = allocator - map_reserve(m, cap) -} - -map_delete :: proc(m: $M/Map($Key, $Value)) { - array_delete(m.hash) - array_delete(m.entries) -} - - -map_has :: proc(m: $M/Map($Key, $Value), key: Key) -> bool { - return _map_find_or_fail(m, key) >= 0 -} - -map_get :: proc(m: $M/Map($Key, $Value), key: Key) -> (res: Value, ok: bool) #optional_ok { - i := _map_find_or_fail(m, key) - if i < 0 { - return {}, false - } - return array_get(m.entries, i).value, true -} - -map_get_default :: proc(m: $M/Map($Key, $Value), key: Key, default: Value) -> (res: Value, ok: bool) #optional_ok { - i := _map_find_or_fail(m, key) - if i < 0 { - return default, false - } - return array_get(m.entries, i).value, true -} - -map_get_ptr :: proc(m: $M/Map($Key, $Value), key: Key) -> ^Value { - i := _map_find_or_fail(m, key) - if i < 0 { - return nil - } - return array_get_ptr(m.entries, i).value -} - -map_set :: proc(m: ^$M/Map($Key, $Value), key: Key, value: Value) { - if array_len(m.hash) == 0 { - _map_grow(m) - } - - i := _map_find_or_make(m, key) - array_get_ptr(m.entries, i).value = value - if _map_full(m^) { - _map_grow(m) - } -} - -map_remove :: proc(m: ^$M/Map($Key, $Value), key: Key) { - fr := _map_find_key(m^, key) - if fr.entry_index >= 0 { - _map_erase(m, fr) - } -} - - -map_reserve :: proc(m: ^$M/Map($Key, $Value), new_size: int) { - nm: M - map_init(&nm, m.hash.allocator) - array_resize(&nm.hash, new_size) - array_reserve(&nm.entries, array_len(m.entries)) - - for i in 0.. ^Map_Entry(Key, Value) { - i := _map_find_or_fail(m, key) - if i < 0 { - return nil - } - return array_get_ptr(m.entries, i) -} - -multi_map_find_next :: proc(m: $M/Map($Key, $Value), e: ^Map_Entry(Key, Value)) -> ^Map_Entry(Key, Value) { - i := e.next - for i >= 0 { - it := array_get_ptr(m.entries, i) - if it.hash == e.hash && it.key == e.key { - return it - } - i = it.next - } - return nil -} - -multi_map_count :: proc(m: $M/Map($Key, $Value), key: Key) -> int { - n := 0 - e := multi_map_find_first(m, key) - for e != nil { - n += 1 - e = multi_map_find_next(m, e) - } - return n -} - -multi_map_get :: proc{multi_map_get_array, multi_map_get_slice} - -multi_map_get_array :: proc(m: $M/Map($Key, $Value), key: Key, items: ^Array(Value)) { - if items == nil { - return - } - e := multi_map_find_first(m, key) - for e != nil { - array_append(items, e.value) - e = multi_map_find_next(m, e) - } -} - -multi_map_get_slice :: proc(m: $M/Map($Key, $Value), key: Key, items: []Value) { - e := multi_map_find_first(m, key) - i := 0 - for e != nil && i < len(items) { - items[i] = e.value - i += 1 - e = multi_map_find_next(m, e) - } -} - -multi_map_get_as_slice :: proc(m: $M/Map($Key, $Value), key: Key) -> []Value { - items: Array(Value) - array_init(&items, 0) - - e := multi_map_find_first(m, key) - for e != nil { - array_append(&items, e.value) - e = multi_map_find_next(m, e) - } - - return array_slice(items) -} - - -multi_map_insert :: proc(m: ^$M/Map($Key, $Value), key: Key, value: Value) { - if array_len(m.hash) == 0 { - _map_grow(m) - } - - i := _map_make(m, key) - array_get_ptr(m.entries, i).value = value - if _map_full(m^) { - _map_grow(m) - } -} - -multi_map_remove :: proc(m: ^$M/Map($Key, $Value), e: ^Map_Entry(Key, Value)) { - fr := _map_find_entry(m, e) - if fr.entry_index >= 0 { - _map_erase(m, fr) - } -} - -multi_map_remove_all :: proc(m: ^$M/Map($Key, $Value), key: Key) { - for map_exist(m^, key) { - map_remove(m, key) - } -} - - -/// Internal - - -Map_Find_Result :: struct { - hash_index: int, - entry_prev: int, - entry_index: int, -} - -_map_add_entry :: proc(m: ^$M/Map($Key, $Value), key: Key) -> int where intrinsics.type_is_valid_map_key(Key) { - hasher := intrinsics.type_hasher_proc(Key) - - e: Map_Entry(Key, Value) - e.key = key - e.hash = hasher(&e.key, 0) - e.next = -1 - idx := array_len(m.entries) - array_push(&m.entries, e) - return idx -} - -_map_erase :: proc(m: ^$M/Map, fr: Map_Find_Result) { - if fr.entry_prev < 0 { - array_set(&m.hash, fr.hash_index, array_get(m.entries, fr.entry_index).next) - } else { - array_get_ptr(m.entries, fr.entry_prev).next = array_get(m.entries, fr.entry_index).next - } - - if fr.entry_index == array_len(m.entries)-1 { - array_pop_back(&m.entries) - return - } - - array_set(&m.entries, fr.entry_index, array_get(m.entries, array_len(m.entries)-1)) - last := _map_find_key(m^, array_get(m.entries, fr.entry_index).key) - - if last.entry_prev < 0 { - array_get_ptr(m.entries, last.entry_prev).next = fr.entry_index - } else { - array_set(&m.hash, last.hash_index, fr.entry_index) - } -} - - -_map_find_key :: proc(m: $M/Map($Key, $Value), key: Key) -> Map_Find_Result where intrinsics.type_is_valid_map_key(Key) { - fr: Map_Find_Result - fr.hash_index = -1 - fr.entry_prev = -1 - fr.entry_index = -1 - - if array_len(m.hash) == 0 { - return fr - } - - hasher := intrinsics.type_hasher_proc(Key) - - key := key - hash := hasher(&key, 0) - - fr.hash_index = int(hash % uintptr(array_len(m.hash))) - fr.entry_index = array_get(m.hash, fr.hash_index) - for fr.entry_index >= 0 { - it := array_get_ptr(m.entries, fr.entry_index) - if it.hash == hash && it.key == key { - return fr - } - fr.entry_prev = fr.entry_index - fr.entry_index = it.next - } - return fr -} - -_map_find_entry :: proc(m: ^$M/Map($Key, $Value), e: ^Map_Entry(Key, Value)) -> Map_Find_Result { - fr: Map_Find_Result - fr.hash_index = -1 - fr.entry_prev = -1 - fr.entry_index = -1 - - if array_len(m.hash) == 0 { - return fr - } - - fr.hash_index = int(e.hash % uintptr(array_len(m.hash))) - fr.entry_index = array_get(m.hash, fr.hash_index) - for fr.entry_index >= 0 { - it := array_get_ptr(m.entries, fr.entry_index) - if it == e { - return fr - } - fr.entry_prev = fr.entry_index - fr.entry_index = it.next - } - return fr -} - -_map_find_or_fail :: proc(m: $M/Map($Key, $Value), key: Key) -> int { - return _map_find_key(m, key).entry_index -} -_map_find_or_make :: proc(m: ^$M/Map($Key, $Value), key: Key) -> int { - fr := _map_find_key(m^, key) - if fr.entry_index >= 0 { - return fr.entry_index - } - - i := _map_add_entry(m, key) - if fr.entry_prev < 0 { - array_set(&m.hash, fr.hash_index, i) - } else { - array_get_ptr(m.entries, fr.entry_prev).next = i - } - return i -} - - -_map_make :: proc(m: ^$M/Map($Key, $Value), key: Key) -> int { - fr := _map_find_key(m^, key) - i := _map_add_entry(m, key) - - if fr.entry_prev < 0 { - array_set(&m.hash, fr.hash_index, i) - } else { - array_get_ptr(m.entries, fr.entry_prev).next = i - } - - array_get_ptr(m.entries, i).next = fr.entry_index - - return i -} - - -_map_full :: proc(m: $M/Map($Key, $Value)) -> bool { - // TODO(bill): Determine good max load factor - return array_len(m.entries) >= (array_len(m.hash) / 4)*3 -} - -_map_grow :: proc(m: ^$M/Map($Key, $Value)) { - new_size := array_len(m.entries) * 4 + 7 // TODO(bill): Determine good grow rate - map_reserve(m, new_size) -} - - diff --git a/core/container/priority_queue.odin b/core/container/priority_queue.odin deleted file mode 100644 index c54e964a6..000000000 --- a/core/container/priority_queue.odin +++ /dev/null @@ -1,121 +0,0 @@ -package container - -Priority_Queue :: struct($T: typeid) { - data: Array(T), - len: int, - priority: proc(item: T) -> int, -} - -priority_queue_init_none :: proc(q: ^$Q/Priority_Queue($T), f: proc(item: T) -> int, allocator := context.allocator) { - queue_init_len(q, f, 0, allocator) -} -priority_queue_init_len :: proc(q: ^$Q/Priority_Queue($T), f: proc(item: T) -> int, len: int, allocator := context.allocator) { - queue_init_len_cap(q, f, 0, 16, allocator) -} -priority_queue_init_len_cap :: proc(q: ^$Q/Priority_Queue($T), f: proc(item: T) -> int, len: int, cap: int, allocator := context.allocator) { - array_init(&q.data, len, cap, allocator) - q.len = len - q.priority = f -} - -priority_queue_init :: proc{priority_queue_init_none, priority_queue_init_len, priority_queue_init_len_cap} - - -priority_queue_delete :: proc(q: $Q/Priority_Queue($T)) { - array_delete(q.data) -} - -priority_queue_clear :: proc(q: ^$Q/Priority_Queue($T)) { - q.len = 0 -} - -priority_queue_len :: proc(q: $Q/Priority_Queue($T)) -> int { - return q.len -} - -priority_queue_cap :: proc(q: $Q/Priority_Queue($T)) -> int { - return array_cap(q.data) -} - -priority_queue_space :: proc(q: $Q/Priority_Queue($T)) -> int { - return array_len(q.data) - q.len -} - -priority_queue_reserve :: proc(q: ^$Q/Priority_Queue($T), capacity: int) { - if capacity > q.len { - array_resize(&q.data, new_capacity) - } -} - -priority_queue_resize :: proc(q: ^$Q/Priority_Queue($T), length: int) { - if length > q.len { - array_resize(&q.data, new_capacity) - } - q.len = length -} - -_priority_queue_grow :: proc(q: ^$Q/Priority_Queue($T), min_capacity: int = 0) { - new_capacity := max(array_len(q.data)*2 + 8, min_capacity) - array_resize(&q.data, new_capacity) -} - - -priority_queue_push :: proc(q: ^$Q/Priority_Queue($T), item: T) { - if array_len(q.data) - q.len == 0 { - _priority_queue_grow(q) - } - - s := array_slice(q.data) - s[q.len] = item - - i := q.len - for i > 0 { - p := (i - 1) / 2 - if q.priority(s[p]) <= q.priority(item) { - break - } - s[i] = s[p] - i = p - } - - q.len += 1 - if q.len > 0 { - s[i] = item - } -} - - - -priority_queue_pop :: proc(q: ^$Q/Priority_Queue($T)) -> T { - assert(q.len > 0) - - s := array_slice(q.data) - min := s[0] - root := s[q.len-1] - q.len -= 1 - - i := 0 - for i * 2 + 1 < q.len { - a := i * 2 + 1 - b := i * 2 + 2 - c := b < q.len && q.priority(s[b]) < q.priority(s[a]) ? b : a - - if q.priority(s[c]) >= q.priority(root) { - break - } - s[i] = s[c] - i = c - } - - if q.len > 0 { - s[i] = root - } - return min -} - -priority_queue_peek :: proc(q: ^$Q/Priority_Queue($T)) -> T { - assert(q.len > 0) - - s := array_slice(q.data) - return s[0] -} diff --git a/core/container/priority_queue/priority_queue.odin b/core/container/priority_queue/priority_queue.odin new file mode 100644 index 000000000..e324287f3 --- /dev/null +++ b/core/container/priority_queue/priority_queue.odin @@ -0,0 +1,143 @@ +package container_priority_queue + +import "core:builtin" + +Priority_Queue :: struct($T: typeid) { + queue: [dynamic]T, + + less: proc(a, b: T) -> bool, + swap: proc(q: []T, i, j: int), +} + +DEFAULT_CAPACITY :: 16 + +default_swap_proc :: proc($T: typeid) -> proc(q: []T, i, j: int) { + return proc(q: []T, i, j: int) { + q[i], q[j] = q[j], q[i] + } +} + +init :: proc(pq: ^$Q/Priority_Queue($T), less: proc(a, b: T) -> bool, swap: proc(q: []T, i, j: int), capacity := DEFAULT_CAPACITY, allocator := context.allocator) { + if pq.queue.allocator.procedure == nil { + pq.queue.allocator = allocator + } + reserve(pq, capacity) + pq.less = less + pq.swap = swap +} + +init_from_dynamic_array :: proc(pq: ^$Q/Priority_Queue($T), queue: [dynamic]T, less: proc(a, b: T) -> bool, swap: proc(q: []T, i, j: int)) { + pq.queue = queue + pq.less = less + pq.swap = swap + n := builtin.len(pq.queue) + for i := n/2 - 1; i >= 0; i -= 1 { + _shift_down(pq, i, n) + } +} + +destroy :: proc(pq: ^$Q/Priority_Queue($T)) { + clear(pq) + delete(pq.queue) +} + +reserve :: proc(pq: ^$Q/Priority_Queue($T), capacity: int) { + builtin.reserve(&pq.queue, capacity) +} +clear :: proc(pq: ^$Q/Priority_Queue($T)) { + builtin.clear(&pq.queue) +} +len :: proc(pq: $Q/Priority_Queue($T)) -> int { + return builtin.len(pq.queue) +} +cap :: proc(pq: $Q/Priority_Queue($T)) -> int { + return builtin.cap(pq.queue) +} + +_shift_down :: proc(pq: ^$Q/Priority_Queue($T), i0, n: int) -> bool { + // O(n log n) + if 0 > i0 || i0 > n { + return false + } + + i := i0 + queue := pq.queue[:] + + for { + j1 := 2*i + 1 + if j1 < 0 || j1 >= n { + break + } + j := j1 + if j2 := j1+1; j2 < n && pq.less(queue[j2], queue[j1]) { + j = j2 + } + if !pq.less(queue[j], queue[i]) { + break + } + + pq.swap(queue, i, j) + i = j + } + return i > i0 +} + +_shift_up :: proc(pq: ^$Q/Priority_Queue($T), j: int) { + j := j + queue := pq.queue[:] + n := builtin.len(queue) + for 0 <= j { + i := (j-1)/2 + if i == j || !pq.less(queue[j], queue[i]) { + break + } + pq.swap(queue, i, j) + j = i + } +} + +// NOTE(bill): When an element at index 'i' has changed its value, this will fix the +// the heap ordering. This is using a basic "heapsort" with shift up and a shift down parts. +fix :: proc(pq: ^$Q/Priority_Queue($T), i: int) { + if !_shift_down(pq, i, builtin.len(pq.queue)) { + _shift_up(pq, i) + } +} + +push :: proc(pq: ^$Q/Priority_Queue($T), value: T) { + append(&pq.queue, value) + _shift_up(pq, builtin.len(pq.queue)-1) +} + +pop :: proc(pq: ^$Q/Priority_Queue($T), loc := #caller_location) -> (value: T) { + assert(condition=builtin.len(pq.queue)>0, loc=loc) + + n := builtin.len(pq.queue)-1 + pq.swap(pq.queue[:], 0, n) + _shift_down(pq, 0, n) + return builtin.pop(&pq.queue) +} + +pop_safe :: proc(pq: ^$Q/Priority_Queue($T), loc := #caller_location) -> (value: T, ok: bool) { + if builtin.len(pq.queue) > 0 { + n := builtin.len(pq.queue)-1 + pq.swap(pq.queue[:], 0, n) + _shift_down(pq, 0, n) + return builtin.pop_safe(&pq.queue) + } + return +} + +remove :: proc(pq: ^$Q/Priority_Queue($T), i: int) -> (value: T, ok: bool) { + n := builtin.len(pq.queue) + if 0 <= i && i < n { + if n != i { + pq.swap(pq.queue[:], i, n) + _shift_down(pq, i, n) + _shift_up(pq, i) + } + value, ok = builtin.pop_safe(&pq.queue) + } + return +} + diff --git a/core/container/queue.odin b/core/container/queue.odin deleted file mode 100644 index bab4a18e6..000000000 --- a/core/container/queue.odin +++ /dev/null @@ -1,175 +0,0 @@ -package container - -Queue :: struct($T: typeid) { - data: Array(T), - len: int, - offset: int, -} - -/* -queue_init :: proc{ - queue_init_none, - queue_init_len, - queue_init_len_cap, -} -queue_delete -queue_clear -queue_len -queue_cap -queue_space -queue_get -queue_set -queue_reserve -queue_resize -queue_push :: proc{ - queue_push_back, - queue_push_elems, -}; -queue_push_front -queue_pop_front -queue_pop_back -queue_consume -*/ - -queue_init_none :: proc(q: ^$Q/Queue($T), allocator := context.allocator) { - queue_init_len(q, 0, allocator) -} -queue_init_len :: proc(q: ^$Q/Queue($T), len: int, allocator := context.allocator) { - queue_init_len_cap(q, 0, 16, allocator) -} -queue_init_len_cap :: proc(q: ^$Q/Queue($T), len: int, cap: int, allocator := context.allocator) { - array_init(&q.data, len, cap, allocator) - q.len = len - q.offset = 0 -} - -queue_init :: proc{queue_init_none, queue_init_len, queue_init_len_cap} - -queue_delete :: proc(q: $Q/Queue($T)) { - array_delete(q.data) -} - -queue_clear :: proc(q: ^$Q/Queue($T)) { - q.len = 0 -} - -queue_len :: proc(q: $Q/Queue($T)) -> int { - return q.len -} - -queue_cap :: proc(q: $Q/Queue($T)) -> int { - return array_cap(q.data) -} - -queue_space :: proc(q: $Q/Queue($T)) -> int { - return array_len(q.data) - q.len -} - -queue_get :: proc(q: $Q/Queue($T), index: int) -> T { - i := (index + q.offset) % array_len(q.data) - data := array_slice(q.data) - return data[i] -} - -queue_set :: proc(q: ^$Q/Queue($T), index: int, item: T) { - i := (index + q.offset) % array_len(q.data) - data := array_slice(q.data) - data[i] = item -} - - -queue_reserve :: proc(q: ^$Q/Queue($T), capacity: int) { - if capacity > q.len { - _queue_increase_capacity(q, capacity) - } -} - -queue_resize :: proc(q: ^$Q/Queue($T), length: int) { - if length > q.len { - _queue_increase_capacity(q, length) - } - q.len = length -} - -queue_push_back :: proc(q: ^$Q/Queue($T), item: T) { - if queue_space(q^) == 0 { - _queue_grow(q) - } - - queue_set(q, q.len, item) - q.len += 1 -} - -queue_push_front :: proc(q: ^$Q/Queue($T), item: T) { - if queue_space(q^) == 0 { - _queue_grow(q) - } - - q.offset = (q.offset - 1 + array_len(q.data)) % array_len(q.data) - q.len += 1 - queue_set(q, 0, item) -} - -queue_pop_front :: proc(q: ^$Q/Queue($T)) -> T { - assert(q.len > 0) - item := queue_get(q^, 0) - q.offset = (q.offset + 1) % array_len(q.data) - q.len -= 1 - if q.len == 0 { - q.offset = 0 - } - return item -} - -queue_pop_back :: proc(q: ^$Q/Queue($T)) -> T { - assert(q.len > 0) - item := queue_get(q^, q.len-1) - q.len -= 1 - return item -} - -queue_consume :: proc(q: ^$Q/Queue($T), count: int) { - q.offset = (q.offset + count) & array_len(q.data) - q.len -= count -} - - -queue_push_elems :: proc(q: ^$Q/Queue($T), items: ..T) { - if queue_space(q^) < len(items) { - _queue_grow(q, q.len + len(items)) - } - size := array_len(q.data) - insert := (q.offset + q.len) % size - - to_insert := len(items) - if insert + to_insert > size { - to_insert = size - insert - } - - the_items := items[:] - - data := array_slice(q.data) - - q.len += copy(data[insert:][:to_insert], the_items) - the_items = the_items[to_insert:] - q.len += copy(data[:], the_items) -} - -queue_push :: proc{queue_push_back, queue_push_elems} - - - -_queue_increase_capacity :: proc(q: ^$Q/Queue($T), new_capacity: int) { - end := array_len(q.data) - array_resize(&q.data, new_capacity) - if q.offset + q.len > end { - end_items := q.len + end - data := array_slice(q.data) - copy(data[new_capacity-end_items:][:end_items], data[q.offset:][:end_items]) - q.offset += new_capacity - end - } -} -_queue_grow :: proc(q: ^$Q/Queue($T), min_capacity: int = 0) { - new_capacity := max(array_len(q.data)*2 + 8, min_capacity) - _queue_increase_capacity(q, new_capacity) -} diff --git a/core/container/queue/queue.odin b/core/container/queue/queue.odin new file mode 100644 index 000000000..8ca3a85ac --- /dev/null +++ b/core/container/queue/queue.odin @@ -0,0 +1,209 @@ +package container_queue + +import "core:builtin" +import "core:runtime" +_ :: runtime + +// Dynamically resizable double-ended queue/ring-buffer +Queue :: struct($T: typeid) { + data: [dynamic]T, + len: uint, + offset: uint, +} + +DEFAULT_CAPACITY :: 16 + +// Procedure to initialize a queue +init :: proc(q: ^$Q/Queue($T), capacity := DEFAULT_CAPACITY, allocator := context.allocator) -> bool { + if q.data.allocator.procedure == nil { + q.data.allocator = allocator + } + clear(q) + return reserve(q, capacity) +} + +// Procedure to initialize a queue from a fixed backing slice +init_from_slice :: proc(q: ^$Q/Queue($T), backing: []T) -> bool { + clear(q) + q.data = transmute([dynamic]T)runtime.Raw_Dynamic_Array{ + data = raw_data(backing), + len = builtin.len(backing), + cap = builtin.len(backing), + allocator = {procedure=runtime.nil_allocator_proc, data=nil}, + } + return true +} + +// Procedure to destroy a queue +destroy :: proc(q: ^$Q/Queue($T)) { + delete(q.data) +} + +// The length of the queue +len :: proc(q: $Q/Queue($T)) -> int { + return int(q.len) +} + +// The current capacity of the queue +cap :: proc(q: $Q/Queue($T)) -> int { + return builtin.len(q.data) +} + +// Remaining space in the queue (cap-len) +space :: proc(q: $Q/Queue($T)) -> int { + return builtin.len(q.data) - int(q.len) +} + +// Reserve enough space for at least the specified capacity +reserve :: proc(q: ^$Q/Queue($T), capacity: int) -> bool { + if uint(capacity) > q.len { + return _grow(q, uint(capacity)) + } + return true +} + + +get :: proc(q: ^$Q/Queue($T), #any_int i: int, loc := #caller_location) -> T { + runtime.bounds_check_error_loc(loc, i, builtin.len(q.data)) + + idx := (uint(i)+q.offset)%builtin.len(q.data) + return q.data[idx] +} +set :: proc(q: ^$Q/Queue($T), #any_int i: int, val: T, loc := #caller_location) { + runtime.bounds_check_error_loc(loc, i, builtin.len(q.data)) + + idx := (uint(i)+q.offset)%builtin.len(q.data) + q.data[idx] = val +} +get_ptr :: proc(q: ^$Q/Queue($T), #any_int i: int, loc := #caller_location) -> ^T { + runtime.bounds_check_error_loc(loc, i, builtin.len(q.data)) + + idx := (uint(i)+q.offset)%builtin.len(q.data) + return &q.data[idx] +} + +// Push an element to the back of the queue +push_back :: proc(q: ^$Q/Queue($T), elem: T) -> bool { + if space(q^) == 0 { + _grow(q) or_return + } + idx := (q.offset+uint(q.len))%builtin.len(q.data) + q.data[idx] = elem + q.len += 1 + return true +} + +// Push an element to the front of the queue +push_front :: proc(q: ^$Q/Queue($T), elem: T) -> bool { + if space(q^) == 0 { + _grow(q) or_return + } + q.offset = uint(q.offset - 1 + builtin.len(q.data)) % builtin.len(q.data) + q.len += 1 + q.data[q.offset] = elem + return true +} + + +// Pop an element from the back of the queue +pop_back :: proc(q: ^$Q/Queue($T), loc := #caller_location) -> (elem: T) { + assert(condition=q.len > 0, loc=loc) + q.len -= 1 + idx := (q.offset+uint(q.len))%builtin.len(q.data) + elem = q.data[idx] + return +} +// Safely pop an element from the back of the queue +pop_back_safe :: proc(q: ^$Q/Queue($T)) -> (elem: T, ok: bool) { + if q.len > 0 { + q.len -= 1 + idx := (q.offset+uint(q.len))%builtin.len(q.data) + elem = q.data[idx] + ok = true + } + return +} + +// Pop an element from the front of the queue +pop_front :: proc(q: ^$Q/Queue($T), loc := #caller_location) -> (elem: T) { + assert(condition=q.len > 0, loc=loc) + elem = q.data[q.offset] + q.offset = (q.offset+1)%builtin.len(q.data) + q.len -= 1 + return +} +// Safely pop an element from the front of the queue +pop_front_safe :: proc(q: ^$Q/Queue($T)) -> (elem: T, ok: bool) { + if q.len > 0 { + elem = q.data[q.offset] + q.offset = (q.offset+1)%builtin.len(q.data) + q.len -= 1 + ok = true + } + return +} + +// Push multiple elements to the front of the queue +push_back_elems :: proc(q: ^$Q/Queue($T), elems: ..T) -> bool { + n := uint(builtin.len(elems)) + if space(q^) < int(n) { + _grow(q, q.len + n) or_return + } + + sz := uint(builtin.len(q.data)) + insert_from := (q.offset + q.len) % sz + insert_to := n + if insert_from + insert_to > sz { + insert_to = sz - insert_from + } + copy(q.data[insert_from:], elems[:insert_to]) + copy(q.data[:insert_from], elems[insert_to:]) + q.len += n + return true +} + +// Consume `n` elements from the front of the queue +consume_front :: proc(q: ^$Q/Queue($T), n: int, loc := #caller_location) { + assert(condition=int(q.len) >= n, loc=loc) + if n > 0 { + nu := uint(n) + q.offset = (q.offset + nu) % builtin.len(q.data) + q.len -= nu + } +} + +// Consume `n` elements from the back of the queue +consume_back :: proc(q: ^$Q/Queue($T), n: int, loc := #caller_location) { + assert(condition=int(q.len) >= n, loc=loc) + if n > 0 { + q.len -= uint(n) + } +} + + + +append_elem :: push_back +append_elems :: push_back_elems +push :: proc{push_back, push_back_elems} +append :: proc{push_back, push_back_elems} + + +// Clear the contents of the queue +clear :: proc(q: ^$Q/Queue($T)) { + q.len = 0 + q.offset = 0 +} + + +// Internal growinh procedure +_grow :: proc(q: ^$Q/Queue($T), min_capacity: uint = 0) -> bool { + new_capacity := max(min_capacity, uint(8), uint(builtin.len(q.data))*2) + n := uint(builtin.len(q.data)) + builtin.resize(&q.data, int(new_capacity)) or_return + if q.offset + q.len > n { + diff := n - q.offset + copy(q.data[new_capacity-diff:], q.data[q.offset:][:diff]) + q.offset += new_capacity - n + } + return true +} diff --git a/core/container/ring.odin b/core/container/ring.odin deleted file mode 100644 index 61492ec84..000000000 --- a/core/container/ring.odin +++ /dev/null @@ -1,74 +0,0 @@ -package container - - -Ring :: struct($T: typeid) { - next, prev: ^Ring(T), - value: T, -} - -ring_init :: proc(r: ^$R/Ring) -> ^R { - r.prev, r.next = r, r - return r -} - -ring_next :: proc(r: ^$R/Ring) -> ^R { - if r.next == nil { - return ring_init(r) - } - return r.next -} -ring_prev :: proc(r: ^$R/Ring) -> ^R { - if r.prev == nil { - return ring_init(r) - } - return r.prev -} - - -ring_move :: proc(r: ^$R/Ring, n: int) -> ^R { - r := r - if r.next == nil { - return ring_init(r) - } - - switch { - case n < 0: - for _ in n..<0 { - r = r.prev - } - case n > 0: - for _ in 0.. ^R { - n := ring_next(r) - if s != nil { - p := ring_prev(s) - r.next = s - s.prev = r - n.prev = p - p.next = n - } - return n -} -ring_unlink :: proc(r: ^$R/Ring, n: int) -> ^R { - if n <= 0 { - return nil - } - return ring_link(r, ring_move(r, n+1)) -} -ring_len :: proc(r: ^$R/Ring) -> int { - n := 0 - if r != nil { - n = 1 - for p := ring_next(r); p != r; p = p.next { - n += 1 - } - } - return n -} - diff --git a/core/container/set.odin b/core/container/set.odin deleted file mode 100644 index 562ac5409..000000000 --- a/core/container/set.odin +++ /dev/null @@ -1,240 +0,0 @@ -package container - -Set :: struct { - hash: Array(int), - entries: Array(Set_Entry), -} - -Set_Entry :: struct { - key: u64, - next: int, -} - - -/* -set_init :: proc{ - set_init_none, - set_init_cap, -} -set_delete - -set_in -set_not_in -set_add -set_remove -set_reserve -set_clear -*/ - -set_init :: proc{set_init_none, set_init_cap} - -set_init_none :: proc(m: ^Set, allocator := context.allocator) { - m.hash.allocator = allocator - m.entries.allocator = allocator -} - -set_init_cap :: proc(m: ^Set, cap: int, allocator := context.allocator) { - m.hash.allocator = allocator - m.entries.allocator = allocator - set_reserve(m, cap) -} - -set_delete :: proc(m: Set) { - array_delete(m.hash) - array_delete(m.entries) -} - - -set_in :: proc(m: Set, key: u64) -> bool { - return _set_find_or_fail(m, key) >= 0 -} -set_not_in :: proc(m: Set, key: u64) -> bool { - return _set_find_or_fail(m, key) < 0 -} - -set_add :: proc(m: ^Set, key: u64) { - if array_len(m.hash) == 0 { - _set_grow(m) - } - - _ = _set_find_or_make(m, key) - if _set_full(m^) { - _set_grow(m) - } -} - -set_remove :: proc(m: ^Set, key: u64) { - fr := _set_find_key(m^, key) - if fr.entry_index >= 0 { - _set_erase(m, fr) - } -} - - -set_reserve :: proc(m: ^Set, new_size: int) { - nm: Set - set_init(&nm, m.hash.allocator) - array_resize(&nm.hash, new_size) - array_reserve(&nm.entries, array_len(m.entries)) - - for i in 0.. bool { - a_entries := array_slice(a.entries) - b_entries := array_slice(b.entries) - if len(a_entries) != len(b_entries) { - return false - } - for e in a_entries { - if set_not_in(b, e.key) { - return false - } - } - - return true -} - - - -/// Internal - -_set_add_entry :: proc(m: ^Set, key: u64) -> int { - e: Set_Entry - e.key = key - e.next = -1 - idx := array_len(m.entries) - array_push(&m.entries, e) - return idx -} - -_set_erase :: proc(m: ^Set, fr: Map_Find_Result) { - if fr.entry_prev < 0 { - array_set(&m.hash, fr.hash_index, array_get(m.entries, fr.entry_index).next) - } else { - array_get_ptr(m.entries, fr.entry_prev).next = array_get(m.entries, fr.entry_index).next - } - - if fr.entry_index == array_len(m.entries)-1 { - array_pop_back(&m.entries) - return - } - - array_set(&m.entries, fr.entry_index, array_get(m.entries, array_len(m.entries)-1)) - last := _set_find_key(m^, array_get(m.entries, fr.entry_index).key) - - if last.entry_prev < 0 { - array_get_ptr(m.entries, last.entry_prev).next = fr.entry_index - } else { - array_set(&m.hash, last.hash_index, fr.entry_index) - } -} - - -_set_find_key :: proc(m: Set, key: u64) -> Map_Find_Result { - fr: Map_Find_Result - fr.hash_index = -1 - fr.entry_prev = -1 - fr.entry_index = -1 - - if array_len(m.hash) == 0 { - return fr - } - - fr.hash_index = int(key % u64(array_len(m.hash))) - fr.entry_index = array_get(m.hash, fr.hash_index) - for fr.entry_index >= 0 { - it := array_get_ptr(m.entries, fr.entry_index) - if it.key == key { - return fr - } - fr.entry_prev = fr.entry_index - fr.entry_index = it.next - } - return fr -} - -_set_find_entry :: proc(m: ^Set, e: ^Set_Entry) -> Map_Find_Result { - fr: Map_Find_Result - fr.hash_index = -1 - fr.entry_prev = -1 - fr.entry_index = -1 - - if array_len(m.hash) == 0 { - return fr - } - - fr.hash_index = int(e.key % u64(array_len(m.hash))) - fr.entry_index = array_get(m.hash, fr.hash_index) - for fr.entry_index >= 0 { - it := array_get_ptr(m.entries, fr.entry_index) - if it == e { - return fr - } - fr.entry_prev = fr.entry_index - fr.entry_index = it.next - } - return fr -} - -_set_find_or_fail :: proc(m: Set, key: u64) -> int { - return _set_find_key(m, key).entry_index -} -_set_find_or_make :: proc(m: ^Set, key: u64) -> int { - fr := _set_find_key(m^, key) - if fr.entry_index >= 0 { - return fr.entry_index - } - - i := _set_add_entry(m, key) - if fr.entry_prev < 0 { - array_set(&m.hash, fr.hash_index, i) - } else { - array_get_ptr(m.entries, fr.entry_prev).next = i - } - return i -} - - -_set_make :: proc(m: ^Set, key: u64) -> int { - fr := _set_find_key(m^, key) - i := _set_add_entry(m, key) - - if fr.entry_prev < 0 { - array_set(&m.hash, fr.hash_index, i) - } else { - array_get_ptr(m.entries, fr.entry_prev).next = i - } - - array_get_ptr(m.entries, i).next = fr.entry_index - - return i -} - - -_set_full :: proc(m: Set) -> bool { - // TODO(bill): Determine good max load factor - return array_len(m.entries) >= (array_len(m.hash) / 4)*3 -} - -_set_grow :: proc(m: ^Set) { - new_size := array_len(m.entries) * 4 + 7 // TODO(bill): Determine good grow rate - set_reserve(m, new_size) -} - - diff --git a/core/container/small_array.odin b/core/container/small_array.odin deleted file mode 100644 index 43b879d2d..000000000 --- a/core/container/small_array.odin +++ /dev/null @@ -1,95 +0,0 @@ -package container - -Small_Array :: struct($N: int, $T: typeid) where N >= 0 { - data: [N]T, - len: int, -} - - -small_array_len :: proc(a: $A/Small_Array) -> int { - return a.len -} - -small_array_cap :: proc(a: $A/Small_Array) -> int { - return len(a.data) -} - -small_array_space :: proc(a: $A/Small_Array) -> int { - return len(a.data) - a.len -} - -small_array_slice :: proc(a: ^$A/Small_Array($N, $T)) -> []T { - return a.data[:a.len] -} - - -small_array_get :: proc(a: $A/Small_Array($N, $T), index: int, loc := #caller_location) -> T { - return a.data[index] -} -small_array_get_ptr :: proc(a: $A/Small_Array($N, $T), index: int, loc := #caller_location) -> ^T { - return &a.data[index] -} - -small_array_set :: proc(a: ^$A/Small_Array($N, $T), index: int, item: T, loc := #caller_location) { - a.data[index] = item -} - -small_array_resize :: proc(a: ^$A/Small_Array, length: int) { - a.len = min(length, len(a.data)) -} - - -small_array_push_back :: proc(a: ^$A/Small_Array($N, $T), item: T) -> bool { - if a.len < len(a.data) { - a.len += 1 - a.data[a.len-1] = item - return true - } - return false -} - -small_array_push_front :: proc(a: ^$A/Small_Array($N, $T), item: T) -> bool { - if a.len < len(a.data) { - a.len += 1 - data := small_array_slice(a) - copy(data[1:], data[:]) - data[0] = item - return true - } - return false -} - -small_array_pop_back :: proc(a: ^$A/Small_Array($N, $T), loc := #caller_location) -> T { - assert(condition=a.len > 0, loc=loc) - item := a.data[a.len-1] - a.len -= 1 - return item -} - -small_array_pop_front :: proc(a: ^$A/Small_Array($N, $T), loc := #caller_location) -> T { - assert(condition=a.len > 0, loc=loc) - item := a.data[0] - s := small_array_slice(a) - copy(s[:], s[1:]) - a.len -= 1 - return item -} - - -small_array_consume :: proc(a: ^$A/Small_Array($N, $T), count: int, loc := #caller_location) { - assert(condition=a.len >= count, loc=loc) - a.len -= count -} - -small_array_clear :: proc(a: ^$A/Small_Array($N, $T)) { - small_array_resize(a, 0) -} - -small_array_push_back_elems :: proc(a: ^$A/Small_Array($N, $T), items: ..T) { - n := copy(a.data[a.len:], items[:]) - a.len += n -} - -small_array_push :: proc{small_array_push_back, small_array_push_back_elems} -small_array_append :: proc{small_array_push_back, small_array_push_back_elems} - diff --git a/core/container/small_array/small_array.odin b/core/container/small_array/small_array.odin new file mode 100644 index 000000000..5cd421c84 --- /dev/null +++ b/core/container/small_array/small_array.odin @@ -0,0 +1,117 @@ +package container_small_array + +import "core:builtin" + +Small_Array :: struct($N: int, $T: typeid) where N >= 0 { + data: [N]T, + len: int, +} + + +len :: proc(a: $A/Small_Array) -> int { + return a.len +} + +cap :: proc(a: $A/Small_Array) -> int { + return builtin.len(a.data) +} + +space :: proc(a: $A/Small_Array) -> int { + return builtin.len(a.data) - a.len +} + +slice :: proc(a: ^$A/Small_Array($N, $T)) -> []T { + return a.data[:a.len] +} + + +get :: proc(a: $A/Small_Array($N, $T), index: int) -> T { + return a.data[index] +} +get_ptr :: proc(a: ^$A/Small_Array($N, $T), index: int) -> ^T { + return &a.data[index] +} + +set :: proc(a: ^$A/Small_Array($N, $T), index: int, item: T) { + a.data[index] = item +} + +resize :: proc(a: ^$A/Small_Array, length: int) { + a.len = min(length, builtin.len(a.data)) +} + + +push_back :: proc(a: ^$A/Small_Array($N, $T), item: T) -> bool { + if a.len < cap(a^) { + a.data[a.len] = item + a.len += 1 + return true + } + return false +} + +push_front :: proc(a: ^$A/Small_Array($N, $T), item: T) -> bool { + if a.len < cap(a^) { + a.len += 1 + data := slice(a) + copy(data[1:], data[:]) + data[0] = item + return true + } + return false +} + +pop_back :: proc(a: ^$A/Small_Array($N, $T), loc := #caller_location) -> T { + assert(condition=(N > 0 && a.len > 0), loc=loc) + item := a.data[a.len-1] + a.len -= 1 + return item +} + +pop_front :: proc(a: ^$A/Small_Array($N, $T), loc := #caller_location) -> T { + assert(condition=(N > 0 && a.len > 0), loc=loc) + item := a.data[0] + s := slice(a) + copy(s[:], s[1:]) + a.len -= 1 + return item +} + +pop_back_safe :: proc(a: ^$A/Small_Array($N, $T)) -> (item: T, ok: bool) { + if N > 0 && a.len > 0 { + item = a.data[a.len-1] + a.len -= 1 + ok = true + } + return +} + +pop_front_safe :: proc(a: ^$A/Small_Array($N, $T)) -> (T, bool) { + if N > 0 && a.len > 0 { + item = a.data[0] + s := slice(a) + copy(s[:], s[1:]) + a.len -= 1 + ok = true + } + return +} + +consume :: proc(a: ^$A/Small_Array($N, $T), count: int, loc := #caller_location) { + assert(condition=a.len >= count, loc=loc) + a.len -= count +} + +clear :: proc(a: ^$A/Small_Array($N, $T)) { + resize(a, 0) +} + +push_back_elems :: proc(a: ^$A/Small_Array($N, $T), items: ..T) { + n := copy(a.data[a.len:], items[:]) + a.len += n +} + +append_elem :: push_back +append_elems :: push_back_elems +push :: proc{push_back, push_back_elems} +append :: proc{push_back, push_back_elems} \ No newline at end of file diff --git a/core/container/topological_sort/topological_sort.odin b/core/container/topological_sort/topological_sort.odin new file mode 100644 index 000000000..4b69930d5 --- /dev/null +++ b/core/container/topological_sort/topological_sort.odin @@ -0,0 +1,98 @@ +// The following is a generic O(V+E) topological sorter implementation. +// This is the fastest known method for topological sorting and Odin's +// map type is being used to accelerate lookups. +package container_topological_sort + +import "core:intrinsics" +import "core:runtime" +_ :: intrinsics +_ :: runtime + + +Relations :: struct($K: typeid) where intrinsics.type_is_valid_map_key(K) { + dependents: map[K]bool, + dependencies: int, +} + +Sorter :: struct(K: typeid) where intrinsics.type_is_valid_map_key(K) { + relations: map[K]Relations(K), + dependents_allocator: runtime.Allocator, +} + +@(private="file") +make_relations :: proc(sorter: ^$S/Sorter($K)) -> (r: Relations(K)) { + r.dependents.allocator = sorter.dependents_allocator + return +} + + +init :: proc(sorter: ^$S/Sorter($K)) { + sorter.relations = make(map[K]Relations(K)) + sorter.dependents_allocator = context.allocator +} + +destroy :: proc(sorter: ^$S/Sorter($K)) { + for _, v in &sorter.relations { + delete(v.dependents) + } + delete(sorter.relations) +} + +add_key :: proc(sorter: ^$S/Sorter($K), key: K) -> bool { + if key in sorter.relations { + return false + } + sorter.relations[key] = make_relations(sorter) + return true +} + +add_dependency :: proc(sorter: ^$S/Sorter($K), key, dependency: K) -> bool { + if key == dependency { + return false + } + + find := &sorter.relations[dependency] + if find == nil { + find = map_insert(&sorter.relations, dependency, make_relations(sorter)) + } + + if find.dependents[key] { + return true + } + find.dependents[key] = true + + find = &sorter.relations[key] + if find == nil { + find = map_insert(&sorter.relations, key, make_relations(sorter)) + } + + find.dependencies += 1 + + return true +} + +sort :: proc(sorter: ^$S/Sorter($K)) -> (sorted, cycled: [dynamic]K) { + relations := &sorter.relations + + for k, v in relations { + if v.dependencies == 0 { + append(&sorted, k) + } + } + + for root in &sorted do for k, _ in relations[root].dependents { + relation := &relations[k] + relation.dependencies -= 1 + if relation.dependencies == 0 { + append(&sorted, k) + } + } + + for k, v in relations { + if v.dependencies != 0 { + append(&cycled, k) + } + } + + return +} \ No newline at end of file diff --git a/core/crypto/README.md b/core/crypto/README.md index 5955f9c56..ddcb12d81 100644 --- a/core/crypto/README.md +++ b/core/crypto/README.md @@ -32,9 +32,11 @@ Please see the chart below for the options. #### High level API Each hash algorithm contains a procedure group named `hash`, or if the algorithm provides more than one digest size `hash_`\*. -Included in these groups are four procedures. +Included in these groups are six procedures. * `hash_string` - Hash a given string and return the computed hash. Just calls `hash_bytes` internally * `hash_bytes` - Hash a given byte slice and return the computed hash +* `hash_string_to_buffer` - Hash a given string and put the computed hash in the second proc parameter. Just calls `hash_bytes_to_buffer` internally +* `hash_bytes_to_buffer` - Hash a given string and put the computed hash in the second proc parameter. The destination buffer has to be at least as big as the digest size of the hash * `hash_stream` - Takes a stream from io.Stream and returns the computed hash from it * `hash_file` - Takes a file handle and returns the computed hash from it. A second optional boolean parameter controls if the file is streamed (this is the default) or read at once (set to true) @@ -59,6 +61,10 @@ main :: proc() { // Compute the hash, using the high level API computed_hash := md4.hash(input) + // Variant that takes a destination buffer, instead of returning the computed hash + hash := make([]byte, md4.DIGEST_SIZE) // @note: Destination buffer has to be at least as big as the digest size of the hash + md4.hash(input, hash[:]) + // Compute the hash, using the low level API ctx: md4.Md4_Context computed_hash_low: [16]byte diff --git a/core/crypto/_fiat/field_poly1305/field.odin b/core/crypto/_fiat/field_poly1305/field.odin index bfb7cf1f9..ca458e079 100644 --- a/core/crypto/_fiat/field_poly1305/field.odin +++ b/core/crypto/_fiat/field_poly1305/field.odin @@ -22,7 +22,7 @@ fe_from_bytes :: #force_inline proc (out1: ^Tight_Field_Element, arg1: []byte, a assert(len(arg1) == 16) - when ODIN_ARCH == "386" || ODIN_ARCH == "amd64" { + when ODIN_ARCH == .i386 || ODIN_ARCH == .amd64 { // While it may be unwise to do deserialization here on our // own when fiat-crypto provides equivalent functionality, // doing it this way provides a little under 3x performance diff --git a/core/crypto/_sha3/_sha3.odin b/core/crypto/_sha3/_sha3.odin index 76e09bf24..9846aca42 100644 --- a/core/crypto/_sha3/_sha3.odin +++ b/core/crypto/_sha3/_sha3.odin @@ -52,7 +52,7 @@ keccakf :: proc "contextless" (st: ^[25]u64) { t: u64 = --- bc: [5]u64 = --- - when ODIN_ENDIAN != "little" { + when ODIN_ENDIAN != .Little { v: uintptr = --- for i = 0; i < 25; i += 1 { v := uintptr(&st[i]) @@ -98,7 +98,7 @@ keccakf :: proc "contextless" (st: ^[25]u64) { st[0] ~= keccakf_rndc[r] } - when ODIN_ENDIAN != "little" { + when ODIN_ENDIAN != .Little { for i = 0; i < 25; i += 1 { v = uintptr(&st[i]) t = st[i] diff --git a/core/crypto/blake/blake.odin b/core/crypto/blake/blake.odin index 9d53f8a89..5fc0a02b9 100644 --- a/core/crypto/blake/blake.odin +++ b/core/crypto/blake/blake.odin @@ -17,16 +17,21 @@ import "core:io" High level API */ +DIGEST_SIZE_224 :: 28 +DIGEST_SIZE_256 :: 32 +DIGEST_SIZE_384 :: 48 +DIGEST_SIZE_512 :: 64 + // hash_string_224 will hash the given input and return the // computed hash -hash_string_224 :: proc "contextless" (data: string) -> [28]byte { +hash_string_224 :: proc "contextless" (data: string) -> [DIGEST_SIZE_224]byte { return hash_bytes_224(transmute([]byte)(data)) } // hash_bytes_224 will hash the given input and return the // computed hash -hash_bytes_224 :: proc "contextless" (data: []byte) -> [28]byte { - hash: [28]byte +hash_bytes_224 :: proc "contextless" (data: []byte) -> [DIGEST_SIZE_224]byte { + hash: [DIGEST_SIZE_224]byte ctx: Blake256_Context ctx.is224 = true init(&ctx) @@ -35,10 +40,29 @@ hash_bytes_224 :: proc "contextless" (data: []byte) -> [28]byte { return hash } +// hash_string_to_buffer_224 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_224 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_224(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_224 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_224 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_224, "Size of destination buffer is smaller than the digest size") + ctx: Blake256_Context + ctx.is224 = true + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_224 will read the stream in chunks and compute a // hash from its contents -hash_stream_224 :: proc(s: io.Stream) -> ([28]byte, bool) { - hash: [28]byte +hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { + hash: [DIGEST_SIZE_224]byte ctx: Blake256_Context ctx.is224 = true init(&ctx) @@ -57,7 +81,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([28]byte, bool) { // hash_file_224 will read the file provided by the given handle // and compute a hash -hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool) { +hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_224]byte, bool) { if !load_at_once { return hash_stream_224(os.stream_from_handle(hd)) } else { @@ -65,7 +89,7 @@ hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool) return hash_bytes_224(buf[:]), ok } } - return [28]byte{}, false + return [DIGEST_SIZE_224]byte{}, false } hash_224 :: proc { @@ -73,18 +97,20 @@ hash_224 :: proc { hash_file_224, hash_bytes_224, hash_string_224, + hash_bytes_to_buffer_224, + hash_string_to_buffer_224, } // hash_string_256 will hash the given input and return the // computed hash -hash_string_256 :: proc "contextless" (data: string) -> [32]byte { +hash_string_256 :: proc "contextless" (data: string) -> [DIGEST_SIZE_256]byte { return hash_bytes_256(transmute([]byte)(data)) } // hash_bytes_256 will hash the given input and return the // computed hash -hash_bytes_256 :: proc "contextless" (data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes_256 :: proc "contextless" (data: []byte) -> [DIGEST_SIZE_256]byte { + hash: [DIGEST_SIZE_256]byte ctx: Blake256_Context ctx.is224 = false init(&ctx) @@ -93,10 +119,29 @@ hash_bytes_256 :: proc "contextless" (data: []byte) -> [32]byte { return hash } +// hash_string_to_buffer_256 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_256 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_256(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_256 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_256 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_256, "Size of destination buffer is smaller than the digest size") + ctx: Blake256_Context + ctx.is224 = false + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_256 will read the stream in chunks and compute a // hash from its contents -hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { + hash: [DIGEST_SIZE_256]byte ctx: Blake256_Context ctx.is224 = false init(&ctx) @@ -115,7 +160,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file_256 will read the file provided by the given handle // and compute a hash -hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_256]byte, bool) { if !load_at_once { return hash_stream_256(os.stream_from_handle(hd)) } else { @@ -123,7 +168,7 @@ hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) return hash_bytes_256(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE_256]byte{}, false } hash_256 :: proc { @@ -131,18 +176,20 @@ hash_256 :: proc { hash_file_256, hash_bytes_256, hash_string_256, + hash_bytes_to_buffer_256, + hash_string_to_buffer_256, } // hash_string_384 will hash the given input and return the // computed hash -hash_string_384 :: proc "contextless" (data: string) -> [48]byte { +hash_string_384 :: proc "contextless" (data: string) -> [DIGEST_SIZE_384]byte { return hash_bytes_384(transmute([]byte)(data)) } // hash_bytes_384 will hash the given input and return the // computed hash -hash_bytes_384 :: proc "contextless" (data: []byte) -> [48]byte { - hash: [48]byte +hash_bytes_384 :: proc "contextless" (data: []byte) -> [DIGEST_SIZE_384]byte { + hash: [DIGEST_SIZE_384]byte ctx: Blake512_Context ctx.is384 = true init(&ctx) @@ -151,10 +198,29 @@ hash_bytes_384 :: proc "contextless" (data: []byte) -> [48]byte { return hash } +// hash_string_to_buffer_384 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_384 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_384(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_384 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_384 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_384, "Size of destination buffer is smaller than the digest size") + ctx: Blake512_Context + ctx.is384 = true + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_384 will read the stream in chunks and compute a // hash from its contents -hash_stream_384 :: proc(s: io.Stream) -> ([48]byte, bool) { - hash: [48]byte +hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) { + hash: [DIGEST_SIZE_384]byte ctx: Blake512_Context ctx.is384 = true init(&ctx) @@ -173,7 +239,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([48]byte, bool) { // hash_file_384 will read the file provided by the given handle // and compute a hash -hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([48]byte, bool) { +hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_384]byte, bool) { if !load_at_once { return hash_stream_384(os.stream_from_handle(hd)) } else { @@ -181,7 +247,7 @@ hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([48]byte, bool) return hash_bytes_384(buf[:]), ok } } - return [48]byte{}, false + return [DIGEST_SIZE_384]byte{}, false } hash_384 :: proc { @@ -189,18 +255,20 @@ hash_384 :: proc { hash_file_384, hash_bytes_384, hash_string_384, + hash_bytes_to_buffer_384, + hash_string_to_buffer_384, } // hash_string_512 will hash the given input and return the // computed hash -hash_string_512 :: proc "contextless" (data: string) -> [64]byte { +hash_string_512 :: proc "contextless" (data: string) -> [DIGEST_SIZE_512]byte { return hash_bytes_512(transmute([]byte)(data)) } // hash_bytes_512 will hash the given input and return the // computed hash -hash_bytes_512 :: proc "contextless" (data: []byte) -> [64]byte { - hash: [64]byte +hash_bytes_512 :: proc "contextless" (data: []byte) -> [DIGEST_SIZE_512]byte { + hash: [DIGEST_SIZE_512]byte ctx: Blake512_Context ctx.is384 = false init(&ctx) @@ -209,10 +277,29 @@ hash_bytes_512 :: proc "contextless" (data: []byte) -> [64]byte { return hash } +// hash_string_to_buffer_512 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_512 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_512(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_512 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_512 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_512, "Size of destination buffer is smaller than the digest size") + ctx: Blake512_Context + ctx.is384 = false + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_512 will read the stream in chunks and compute a // hash from its contents -hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { - hash: [64]byte +hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { + hash: [DIGEST_SIZE_512]byte ctx: Blake512_Context ctx.is384 = false init(&ctx) @@ -231,7 +318,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { // hash_file_512 will read the file provided by the given handle // and compute a hash -hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) { +hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_512]byte, bool) { if !load_at_once { return hash_stream_512(os.stream_from_handle(hd)) } else { @@ -239,7 +326,7 @@ hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) return hash_bytes_512(buf[:]), ok } } - return [64]byte{}, false + return [DIGEST_SIZE_512]byte{}, false } hash_512 :: proc { @@ -247,6 +334,8 @@ hash_512 :: proc { hash_file_512, hash_bytes_512, hash_string_512, + hash_bytes_to_buffer_512, + hash_string_to_buffer_512, } /* diff --git a/core/crypto/blake2b/blake2b.odin b/core/crypto/blake2b/blake2b.odin index 85f9611f9..e75d74197 100644 --- a/core/crypto/blake2b/blake2b.odin +++ b/core/crypto/blake2b/blake2b.odin @@ -20,16 +20,18 @@ import "../_blake2" High level API */ +DIGEST_SIZE :: 64 + // hash_string will hash the given input and return the // computed hash -hash_string :: proc(data: string) -> [64]byte { +hash_string :: proc(data: string) -> [DIGEST_SIZE]byte { return hash_bytes(transmute([]byte)(data)) } // hash_bytes will hash the given input and return the // computed hash -hash_bytes :: proc(data: []byte) -> [64]byte { - hash: [64]byte +hash_bytes :: proc(data: []byte) -> [DIGEST_SIZE]byte { + hash: [DIGEST_SIZE]byte ctx: _blake2.Blake2b_Context cfg: _blake2.Blake2_Config cfg.size = _blake2.BLAKE2B_SIZE @@ -40,10 +42,32 @@ hash_bytes :: proc(data: []byte) -> [64]byte { return hash } +// hash_string_to_buffer will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") + ctx: _blake2.Blake2b_Context + cfg: _blake2.Blake2_Config + cfg.size = _blake2.BLAKE2B_SIZE + ctx.cfg = cfg + _blake2.init(&ctx) + _blake2.update(&ctx, data) + _blake2.final(&ctx, hash) +} + + // hash_stream will read the stream in chunks and compute a // hash from its contents -hash_stream :: proc(s: io.Stream) -> ([64]byte, bool) { - hash: [64]byte +hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { + hash: [DIGEST_SIZE]byte ctx: _blake2.Blake2b_Context cfg: _blake2.Blake2_Config cfg.size = _blake2.BLAKE2B_SIZE @@ -64,7 +88,7 @@ hash_stream :: proc(s: io.Stream) -> ([64]byte, bool) { // hash_file will read the file provided by the given handle // and compute a hash -hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) { +hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE]byte, bool) { if !load_at_once { return hash_stream(os.stream_from_handle(hd)) } else { @@ -72,7 +96,7 @@ hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) { return hash_bytes(buf[:]), ok } } - return [64]byte{}, false + return [DIGEST_SIZE]byte{}, false } hash :: proc { @@ -80,6 +104,8 @@ hash :: proc { hash_file, hash_bytes, hash_string, + hash_bytes_to_buffer, + hash_string_to_buffer, } /* diff --git a/core/crypto/blake2s/blake2s.odin b/core/crypto/blake2s/blake2s.odin index 72d15b227..831335081 100644 --- a/core/crypto/blake2s/blake2s.odin +++ b/core/crypto/blake2s/blake2s.odin @@ -20,16 +20,18 @@ import "../_blake2" High level API */ +DIGEST_SIZE :: 32 + // hash_string will hash the given input and return the // computed hash -hash_string :: proc(data: string) -> [32]byte { +hash_string :: proc(data: string) -> [DIGEST_SIZE]byte { return hash_bytes(transmute([]byte)(data)) } // hash_bytes will hash the given input and return the // computed hash -hash_bytes :: proc(data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes :: proc(data: []byte) -> [DIGEST_SIZE]byte { + hash: [DIGEST_SIZE]byte ctx: _blake2.Blake2s_Context cfg: _blake2.Blake2_Config cfg.size = _blake2.BLAKE2S_SIZE @@ -40,10 +42,32 @@ hash_bytes :: proc(data: []byte) -> [32]byte { return hash } + +// hash_string_to_buffer will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") + ctx: _blake2.Blake2s_Context + cfg: _blake2.Blake2_Config + cfg.size = _blake2.BLAKE2S_SIZE + ctx.cfg = cfg + _blake2.init(&ctx) + _blake2.update(&ctx, data) + _blake2.final(&ctx, hash) +} + // hash_stream will read the stream in chunks and compute a // hash from its contents -hash_stream :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { + hash: [DIGEST_SIZE]byte ctx: _blake2.Blake2s_Context cfg: _blake2.Blake2_Config cfg.size = _blake2.BLAKE2S_SIZE @@ -64,7 +88,7 @@ hash_stream :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file will read the file provided by the given handle // and compute a hash -hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE]byte, bool) { if !load_at_once { return hash_stream(os.stream_from_handle(hd)) } else { @@ -72,7 +96,7 @@ hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { return hash_bytes(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE]byte{}, false } hash :: proc { @@ -80,6 +104,8 @@ hash :: proc { hash_file, hash_bytes, hash_string, + hash_bytes_to_buffer, + hash_string_to_buffer, } /* diff --git a/core/crypto/chacha20/chacha20.odin b/core/crypto/chacha20/chacha20.odin index f6f551692..229949c22 100644 --- a/core/crypto/chacha20/chacha20.odin +++ b/core/crypto/chacha20/chacha20.odin @@ -346,7 +346,7 @@ _do_blocks :: proc (ctx: ^Context, dst, src: []byte, nr_blocks: int) { // Until dedicated assembly can be written leverage the fact that // the callers of this routine ensure that src/dst are valid. - when ODIN_ARCH == "386" || ODIN_ARCH == "amd64" { + when ODIN_ARCH == .i386 || ODIN_ARCH == .amd64 { // util.PUT_U32_LE/util.U32_LE are not required on little-endian // systems that also happen to not be strict about aligned // memory access. diff --git a/core/crypto/gost/gost.odin b/core/crypto/gost/gost.odin index c687e9080..1d0274fae 100644 --- a/core/crypto/gost/gost.odin +++ b/core/crypto/gost/gost.odin @@ -18,16 +18,18 @@ import "core:io" High level API */ +DIGEST_SIZE :: 32 + // hash_string will hash the given input and return the // computed hash -hash_string :: proc(data: string) -> [32]byte { +hash_string :: proc(data: string) -> [DIGEST_SIZE]byte { return hash_bytes(transmute([]byte)(data)) } // hash_bytes will hash the given input and return the // computed hash -hash_bytes :: proc(data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes :: proc(data: []byte) -> [DIGEST_SIZE]byte { + hash: [DIGEST_SIZE]byte ctx: Gost_Context init(&ctx) update(&ctx, data) @@ -35,10 +37,28 @@ hash_bytes :: proc(data: []byte) -> [32]byte { return hash } +// hash_string_to_buffer will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") + ctx: Gost_Context + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream will read the stream in chunks and compute a // hash from its contents -hash_stream :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { + hash: [DIGEST_SIZE]byte ctx: Gost_Context init(&ctx) buf := make([]byte, 512) @@ -56,7 +76,7 @@ hash_stream :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file will read the file provided by the given handle // and compute a hash -hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE]byte, bool) { if !load_at_once { return hash_stream(os.stream_from_handle(hd)) } else { @@ -64,7 +84,7 @@ hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { return hash_bytes(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE]byte{}, false } hash :: proc { @@ -72,6 +92,8 @@ hash :: proc { hash_file, hash_bytes, hash_string, + hash_bytes_to_buffer, + hash_string_to_buffer, } /* diff --git a/core/crypto/groestl/groestl.odin b/core/crypto/groestl/groestl.odin index 0d305a1d1..8e5a2440d 100644 --- a/core/crypto/groestl/groestl.odin +++ b/core/crypto/groestl/groestl.odin @@ -17,16 +17,21 @@ import "core:io" High level API */ +DIGEST_SIZE_224 :: 28 +DIGEST_SIZE_256 :: 32 +DIGEST_SIZE_384 :: 48 +DIGEST_SIZE_512 :: 64 + // hash_string_224 will hash the given input and return the // computed hash -hash_string_224 :: proc(data: string) -> [28]byte { +hash_string_224 :: proc(data: string) -> [DIGEST_SIZE_224]byte { return hash_bytes_224(transmute([]byte)(data)) } // hash_bytes_224 will hash the given input and return the // computed hash -hash_bytes_224 :: proc(data: []byte) -> [28]byte { - hash: [28]byte +hash_bytes_224 :: proc(data: []byte) -> [DIGEST_SIZE_224]byte { + hash: [DIGEST_SIZE_224]byte ctx: Groestl_Context ctx.hashbitlen = 224 init(&ctx) @@ -35,10 +40,29 @@ hash_bytes_224 :: proc(data: []byte) -> [28]byte { return hash } +// hash_string_to_buffer_224 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_224 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_224(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_224 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_224 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_224, "Size of destination buffer is smaller than the digest size") + ctx: Groestl_Context + ctx.hashbitlen = 224 + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_224 will read the stream in chunks and compute a // hash from its contents -hash_stream_224 :: proc(s: io.Stream) -> ([28]byte, bool) { - hash: [28]byte +hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { + hash: [DIGEST_SIZE_224]byte ctx: Groestl_Context ctx.hashbitlen = 224 init(&ctx) @@ -57,7 +81,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([28]byte, bool) { // hash_file_224 will read the file provided by the given handle // and compute a hash -hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool) { +hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_224]byte, bool) { if !load_at_once { return hash_stream_224(os.stream_from_handle(hd)) } else { @@ -65,7 +89,7 @@ hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool) return hash_bytes_224(buf[:]), ok } } - return [28]byte{}, false + return [DIGEST_SIZE_224]byte{}, false } hash_224 :: proc { @@ -73,18 +97,20 @@ hash_224 :: proc { hash_file_224, hash_bytes_224, hash_string_224, + hash_bytes_to_buffer_224, + hash_string_to_buffer_224, } // hash_string_256 will hash the given input and return the // computed hash -hash_string_256 :: proc(data: string) -> [32]byte { +hash_string_256 :: proc(data: string) -> [DIGEST_SIZE_256]byte { return hash_bytes_256(transmute([]byte)(data)) } // hash_bytes_256 will hash the given input and return the // computed hash -hash_bytes_256 :: proc(data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes_256 :: proc(data: []byte) -> [DIGEST_SIZE_256]byte { + hash: [DIGEST_SIZE_256]byte ctx: Groestl_Context ctx.hashbitlen = 256 init(&ctx) @@ -93,10 +119,29 @@ hash_bytes_256 :: proc(data: []byte) -> [32]byte { return hash } +// hash_string_to_buffer_256 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_256 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_256(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_256 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_256 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_256, "Size of destination buffer is smaller than the digest size") + ctx: Groestl_Context + ctx.hashbitlen = 256 + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_256 will read the stream in chunks and compute a // hash from its contents -hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { + hash: [DIGEST_SIZE_256]byte ctx: Groestl_Context ctx.hashbitlen = 256 init(&ctx) @@ -115,7 +160,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file_256 will read the file provided by the given handle // and compute a hash -hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_256]byte, bool) { if !load_at_once { return hash_stream_256(os.stream_from_handle(hd)) } else { @@ -123,7 +168,7 @@ hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) return hash_bytes_256(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE_256]byte{}, false } hash_256 :: proc { @@ -131,18 +176,20 @@ hash_256 :: proc { hash_file_256, hash_bytes_256, hash_string_256, + hash_bytes_to_buffer_256, + hash_string_to_buffer_256, } // hash_string_384 will hash the given input and return the // computed hash -hash_string_384 :: proc(data: string) -> [48]byte { +hash_string_384 :: proc(data: string) -> [DIGEST_SIZE_384]byte { return hash_bytes_384(transmute([]byte)(data)) } // hash_bytes_384 will hash the given input and return the // computed hash -hash_bytes_384 :: proc(data: []byte) -> [48]byte { - hash: [48]byte +hash_bytes_384 :: proc(data: []byte) -> [DIGEST_SIZE_384]byte { + hash: [DIGEST_SIZE_384]byte ctx: Groestl_Context ctx.hashbitlen = 384 init(&ctx) @@ -151,10 +198,29 @@ hash_bytes_384 :: proc(data: []byte) -> [48]byte { return hash } +// hash_string_to_buffer_384 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_384 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_384(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_384 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_384 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_384, "Size of destination buffer is smaller than the digest size") + ctx: Groestl_Context + ctx.hashbitlen = 384 + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_384 will read the stream in chunks and compute a // hash from its contents -hash_stream_384 :: proc(s: io.Stream) -> ([48]byte, bool) { - hash: [48]byte +hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) { + hash: [DIGEST_SIZE_384]byte ctx: Groestl_Context ctx.hashbitlen = 384 init(&ctx) @@ -173,7 +239,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([48]byte, bool) { // hash_file_384 will read the file provided by the given handle // and compute a hash -hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([48]byte, bool) { +hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_384]byte, bool) { if !load_at_once { return hash_stream_384(os.stream_from_handle(hd)) } else { @@ -181,7 +247,7 @@ hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([48]byte, bool) return hash_bytes_384(buf[:]), ok } } - return [48]byte{}, false + return [DIGEST_SIZE_384]byte{}, false } hash_384 :: proc { @@ -189,18 +255,20 @@ hash_384 :: proc { hash_file_384, hash_bytes_384, hash_string_384, + hash_bytes_to_buffer_384, + hash_string_to_buffer_384, } // hash_string_512 will hash the given input and return the // computed hash -hash_string_512 :: proc(data: string) -> [64]byte { +hash_string_512 :: proc(data: string) -> [DIGEST_SIZE_512]byte { return hash_bytes_512(transmute([]byte)(data)) } // hash_bytes_512 will hash the given input and return the // computed hash -hash_bytes_512 :: proc(data: []byte) -> [64]byte { - hash: [64]byte +hash_bytes_512 :: proc(data: []byte) -> [DIGEST_SIZE_512]byte { + hash: [DIGEST_SIZE_512]byte ctx: Groestl_Context ctx.hashbitlen = 512 init(&ctx) @@ -209,10 +277,29 @@ hash_bytes_512 :: proc(data: []byte) -> [64]byte { return hash } +// hash_string_to_buffer_512 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_512 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_512(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_512 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_512 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_512, "Size of destination buffer is smaller than the digest size") + ctx: Groestl_Context + ctx.hashbitlen = 512 + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_512 will read the stream in chunks and compute a // hash from its contents -hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { - hash: [64]byte +hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { + hash: [DIGEST_SIZE_512]byte ctx: Groestl_Context ctx.hashbitlen = 512 init(&ctx) @@ -231,7 +318,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { // hash_file_512 will read the file provided by the given handle // and compute a hash -hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) { +hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_512]byte, bool) { if !load_at_once { return hash_stream_512(os.stream_from_handle(hd)) } else { @@ -239,7 +326,7 @@ hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) return hash_bytes_512(buf[:]), ok } } - return [64]byte{}, false + return [DIGEST_SIZE_512]byte{}, false } hash_512 :: proc { @@ -247,6 +334,8 @@ hash_512 :: proc { hash_file_512, hash_bytes_512, hash_string_512, + hash_bytes_to_buffer_512, + hash_string_to_buffer_512, } /* diff --git a/core/crypto/haval/haval.odin b/core/crypto/haval/haval.odin index 76532d4cd..811ecf95d 100644 --- a/core/crypto/haval/haval.odin +++ b/core/crypto/haval/haval.odin @@ -20,16 +20,22 @@ import "../util" High level API */ +DIGEST_SIZE_128 :: 16 +DIGEST_SIZE_160 :: 20 +DIGEST_SIZE_192 :: 24 +DIGEST_SIZE_224 :: 28 +DIGEST_SIZE_256 :: 32 + // hash_string_128_3 will hash the given input and return the // computed hash -hash_string_128_3 :: proc(data: string) -> [16]byte { +hash_string_128_3 :: proc(data: string) -> [DIGEST_SIZE_128]byte { return hash_bytes_128_3(transmute([]byte)(data)) } // hash_bytes_128_3 will hash the given input and return the // computed hash -hash_bytes_128_3 :: proc(data: []byte) -> [16]byte { - hash: [16]byte +hash_bytes_128_3 :: proc(data: []byte) -> [DIGEST_SIZE_128]byte { + hash: [DIGEST_SIZE_128]byte ctx: Haval_Context ctx.hashbitlen = 128 ctx.rounds = 3 @@ -40,10 +46,31 @@ hash_bytes_128_3 :: proc(data: []byte) -> [16]byte { return hash } +// hash_string_to_buffer_128_3 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_128_3 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_128_3(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_128_3 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_128_3 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_128, "Size of destination buffer is smaller than the digest size") + ctx: Haval_Context + ctx.hashbitlen = 128 + ctx.rounds = 3 + init(&ctx) + ctx.str_len = u32(len(data)) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_128_3 will read the stream in chunks and compute a // hash from its contents -hash_stream_128_3 :: proc(s: io.Stream) -> ([16]byte, bool) { - hash: [16]byte +hash_stream_128_3 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) { + hash: [DIGEST_SIZE_128]byte ctx: Haval_Context ctx.hashbitlen = 128 ctx.rounds = 3 @@ -64,7 +91,7 @@ hash_stream_128_3 :: proc(s: io.Stream) -> ([16]byte, bool) { // hash_file_128_3 will read the file provided by the given handle // and compute a hash -hash_file_128_3 :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) { +hash_file_128_3 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_128]byte, bool) { if !load_at_once { return hash_stream_128_3(os.stream_from_handle(hd)) } else { @@ -72,7 +99,7 @@ hash_file_128_3 :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool return hash_bytes_128_3(buf[:]), ok } } - return [16]byte{}, false + return [DIGEST_SIZE_128]byte{}, false } hash_128_3 :: proc { @@ -80,18 +107,20 @@ hash_128_3 :: proc { hash_file_128_3, hash_bytes_128_3, hash_string_128_3, + hash_bytes_to_buffer_128_3, + hash_string_to_buffer_128_3, } // hash_string_128_4 will hash the given input and return the // computed hash -hash_string_128_4 :: proc(data: string) -> [16]byte { +hash_string_128_4 :: proc(data: string) -> [DIGEST_SIZE_128]byte { return hash_bytes_128_4(transmute([]byte)(data)) } // hash_bytes_128_4 will hash the given input and return the // computed hash -hash_bytes_128_4 :: proc(data: []byte) -> [16]byte { - hash: [16]byte +hash_bytes_128_4 :: proc(data: []byte) -> [DIGEST_SIZE_128]byte { + hash: [DIGEST_SIZE_128]byte ctx: Haval_Context ctx.hashbitlen = 128 ctx.rounds = 4 @@ -102,10 +131,31 @@ hash_bytes_128_4 :: proc(data: []byte) -> [16]byte { return hash } +// hash_string_to_buffer_128_4 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_128_4 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_128_4(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_128_4 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_128_4 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_128, "Size of destination buffer is smaller than the digest size") + ctx: Haval_Context + ctx.hashbitlen = 128 + ctx.rounds = 4 + init(&ctx) + ctx.str_len = u32(len(data)) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_128_4 will read the stream in chunks and compute a // hash from its contents -hash_stream_128_4 :: proc(s: io.Stream) -> ([16]byte, bool) { - hash: [16]byte +hash_stream_128_4 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) { + hash: [DIGEST_SIZE_128]byte ctx: Haval_Context ctx.hashbitlen = 128 ctx.rounds = 4 @@ -126,7 +176,7 @@ hash_stream_128_4 :: proc(s: io.Stream) -> ([16]byte, bool) { // hash_file_128_4 will read the file provided by the given handle // and compute a hash -hash_file_128_4 :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) { +hash_file_128_4 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_128]byte, bool) { if !load_at_once { return hash_stream_128_4(os.stream_from_handle(hd)) } else { @@ -134,7 +184,7 @@ hash_file_128_4 :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool return hash_bytes_128_4(buf[:]), ok } } - return [16]byte{}, false + return [DIGEST_SIZE_128]byte{}, false } hash_128_4 :: proc { @@ -142,18 +192,20 @@ hash_128_4 :: proc { hash_file_128_4, hash_bytes_128_4, hash_string_128_4, + hash_bytes_to_buffer_128_4, + hash_string_to_buffer_128_4, } // hash_string_128_5 will hash the given input and return the // computed hash -hash_string_128_5 :: proc(data: string) -> [16]byte { +hash_string_128_5 :: proc(data: string) -> [DIGEST_SIZE_128]byte { return hash_bytes_128_5(transmute([]byte)(data)) } // hash_bytes_128_5 will hash the given input and return the // computed hash -hash_bytes_128_5 :: proc(data: []byte) -> [16]byte { - hash: [16]byte +hash_bytes_128_5 :: proc(data: []byte) -> [DIGEST_SIZE_128]byte { + hash: [DIGEST_SIZE_128]byte ctx: Haval_Context ctx.hashbitlen = 128 ctx.rounds = 5 @@ -164,10 +216,31 @@ hash_bytes_128_5 :: proc(data: []byte) -> [16]byte { return hash } +// hash_string_to_buffer_128_5 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_128_5 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_128_5(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_128_5 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_128_5 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_128, "Size of destination buffer is smaller than the digest size") + ctx: Haval_Context + ctx.hashbitlen = 128 + ctx.rounds = 5 + init(&ctx) + ctx.str_len = u32(len(data)) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_128_5 will read the stream in chunks and compute a // hash from its contents -hash_stream_128_5 :: proc(s: io.Stream) -> ([16]byte, bool) { - hash: [16]byte +hash_stream_128_5 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) { + hash: [DIGEST_SIZE_128]byte ctx: Haval_Context ctx.hashbitlen = 128 ctx.rounds = 5 @@ -188,7 +261,7 @@ hash_stream_128_5 :: proc(s: io.Stream) -> ([16]byte, bool) { // hash_file_128_5 will read the file provided by the given handle // and compute a hash -hash_file_128_5 :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) { +hash_file_128_5 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_128]byte, bool) { if !load_at_once { return hash_stream_128_5(os.stream_from_handle(hd)) } else { @@ -196,7 +269,7 @@ hash_file_128_5 :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool return hash_bytes_128_5(buf[:]), ok } } - return [16]byte{}, false + return [DIGEST_SIZE_128]byte{}, false } hash_128_5 :: proc { @@ -204,18 +277,20 @@ hash_128_5 :: proc { hash_file_128_5, hash_bytes_128_5, hash_string_128_5, + hash_bytes_to_buffer_128_5, + hash_string_to_buffer_128_5, } // hash_string_160_3 will hash the given input and return the // computed hash -hash_string_160_3 :: proc(data: string) -> [20]byte { +hash_string_160_3 :: proc(data: string) -> [DIGEST_SIZE_160]byte { return hash_bytes_160_3(transmute([]byte)(data)) } // hash_bytes_160_3 will hash the given input and return the // computed hash -hash_bytes_160_3 :: proc(data: []byte) -> [20]byte { - hash: [20]byte +hash_bytes_160_3 :: proc(data: []byte) -> [DIGEST_SIZE_160]byte { + hash: [DIGEST_SIZE_160]byte ctx: Haval_Context ctx.hashbitlen = 160 ctx.rounds = 3 @@ -226,10 +301,31 @@ hash_bytes_160_3 :: proc(data: []byte) -> [20]byte { return hash } +// hash_string_to_buffer_160_3 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_160_3 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_160_3(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_160_3 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_160_3 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_160, "Size of destination buffer is smaller than the digest size") + ctx: Haval_Context + ctx.hashbitlen = 160 + ctx.rounds = 3 + init(&ctx) + ctx.str_len = u32(len(data)) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_160_3 will read the stream in chunks and compute a // hash from its contents -hash_stream_160_3 :: proc(s: io.Stream) -> ([20]byte, bool) { - hash: [20]byte +hash_stream_160_3 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) { + hash: [DIGEST_SIZE_160]byte ctx: Haval_Context ctx.hashbitlen = 160 ctx.rounds = 3 @@ -250,7 +346,7 @@ hash_stream_160_3 :: proc(s: io.Stream) -> ([20]byte, bool) { // hash_file_160_3 will read the file provided by the given handle // and compute a hash -hash_file_160_3 :: proc(hd: os.Handle, load_at_once := false) -> ([20]byte, bool) { +hash_file_160_3 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_160]byte, bool) { if !load_at_once { return hash_stream_160_3(os.stream_from_handle(hd)) } else { @@ -258,7 +354,7 @@ hash_file_160_3 :: proc(hd: os.Handle, load_at_once := false) -> ([20]byte, bool return hash_bytes_160_3(buf[:]), ok } } - return [20]byte{}, false + return [DIGEST_SIZE_160]byte{}, false } hash_160_3 :: proc { @@ -266,18 +362,20 @@ hash_160_3 :: proc { hash_file_160_3, hash_bytes_160_3, hash_string_160_3, + hash_bytes_to_buffer_160_3, + hash_string_to_buffer_160_3, } // hash_string_160_4 will hash the given input and return the // computed hash -hash_string_160_4 :: proc(data: string) -> [20]byte { +hash_string_160_4 :: proc(data: string) -> [DIGEST_SIZE_160]byte { return hash_bytes_160_4(transmute([]byte)(data)) } // hash_bytes_160_4 will hash the given input and return the // computed hash -hash_bytes_160_4 :: proc(data: []byte) -> [20]byte { - hash: [20]byte +hash_bytes_160_4 :: proc(data: []byte) -> [DIGEST_SIZE_160]byte { + hash: [DIGEST_SIZE_160]byte ctx: Haval_Context ctx.hashbitlen = 160 ctx.rounds = 4 @@ -288,10 +386,31 @@ hash_bytes_160_4 :: proc(data: []byte) -> [20]byte { return hash } +// hash_string_to_buffer_160_4 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_160_4 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_160_4(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_160_4 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_160_4 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_160, "Size of destination buffer is smaller than the digest size") + ctx: Haval_Context + ctx.hashbitlen = 160 + ctx.rounds = 4 + init(&ctx) + ctx.str_len = u32(len(data)) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_160_4 will read the stream in chunks and compute a // hash from its contents -hash_stream_160_4 :: proc(s: io.Stream) -> ([20]byte, bool) { - hash: [20]byte +hash_stream_160_4 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) { + hash: [DIGEST_SIZE_160]byte ctx: Haval_Context ctx.hashbitlen = 160 ctx.rounds = 4 @@ -312,7 +431,7 @@ hash_stream_160_4 :: proc(s: io.Stream) -> ([20]byte, bool) { // hash_file_160_4 will read the file provided by the given handle // and compute a hash -hash_file_160_4 :: proc(hd: os.Handle, load_at_once := false) -> ([20]byte, bool) { +hash_file_160_4 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_160]byte, bool) { if !load_at_once { return hash_stream_160_4(os.stream_from_handle(hd)) } else { @@ -320,7 +439,7 @@ hash_file_160_4 :: proc(hd: os.Handle, load_at_once := false) -> ([20]byte, bool return hash_bytes_160_4(buf[:]), ok } } - return [20]byte{}, false + return [DIGEST_SIZE_160]byte{}, false } hash_160_4 :: proc { @@ -328,18 +447,20 @@ hash_160_4 :: proc { hash_file_160_4, hash_bytes_160_4, hash_string_160_4, + hash_bytes_to_buffer_160_4, + hash_string_to_buffer_160_4, } // hash_string_160_5 will hash the given input and return the // computed hash -hash_string_160_5 :: proc(data: string) -> [20]byte { +hash_string_160_5 :: proc(data: string) -> [DIGEST_SIZE_160]byte { return hash_bytes_160_5(transmute([]byte)(data)) } // hash_bytes_160_5 will hash the given input and return the // computed hash -hash_bytes_160_5 :: proc(data: []byte) -> [20]byte { - hash: [20]byte +hash_bytes_160_5 :: proc(data: []byte) -> [DIGEST_SIZE_160]byte { + hash: [DIGEST_SIZE_160]byte ctx: Haval_Context ctx.hashbitlen = 160 ctx.rounds = 5 @@ -350,10 +471,31 @@ hash_bytes_160_5 :: proc(data: []byte) -> [20]byte { return hash } +// hash_string_to_buffer_160_5 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_160_5 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_160_5(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_160_5 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_160_5 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_160, "Size of destination buffer is smaller than the digest size") + ctx: Haval_Context + ctx.hashbitlen = 160 + ctx.rounds = 5 + init(&ctx) + ctx.str_len = u32(len(data)) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_160_5 will read the stream in chunks and compute a // hash from its contents -hash_stream_160_5 :: proc(s: io.Stream) -> ([20]byte, bool) { - hash: [20]byte +hash_stream_160_5 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) { + hash: [DIGEST_SIZE_160]byte ctx: Haval_Context ctx.hashbitlen = 160 ctx.rounds = 5 @@ -374,7 +516,7 @@ hash_stream_160_5 :: proc(s: io.Stream) -> ([20]byte, bool) { // hash_file_160_5 will read the file provided by the given handle // and compute a hash -hash_file_160_5 :: proc(hd: os.Handle, load_at_once := false) -> ([20]byte, bool) { +hash_file_160_5 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_160]byte, bool) { if !load_at_once { return hash_stream_160_5(os.stream_from_handle(hd)) } else { @@ -382,7 +524,7 @@ hash_file_160_5 :: proc(hd: os.Handle, load_at_once := false) -> ([20]byte, bool return hash_bytes_160_5(buf[:]), ok } } - return [20]byte{}, false + return [DIGEST_SIZE_160]byte{}, false } hash_160_5 :: proc { @@ -390,18 +532,20 @@ hash_160_5 :: proc { hash_file_160_5, hash_bytes_160_5, hash_string_160_5, + hash_bytes_to_buffer_160_5, + hash_string_to_buffer_160_5, } // hash_string_192_3 will hash the given input and return the // computed hash -hash_string_192_3 :: proc(data: string) -> [24]byte { +hash_string_192_3 :: proc(data: string) -> [DIGEST_SIZE_192]byte { return hash_bytes_192_3(transmute([]byte)(data)) } // hash_bytes_192_3 will hash the given input and return the // computed hash -hash_bytes_192_3 :: proc(data: []byte) -> [24]byte { - hash: [24]byte +hash_bytes_192_3 :: proc(data: []byte) -> [DIGEST_SIZE_192]byte { + hash: [DIGEST_SIZE_192]byte ctx: Haval_Context ctx.hashbitlen = 192 ctx.rounds = 3 @@ -412,10 +556,31 @@ hash_bytes_192_3 :: proc(data: []byte) -> [24]byte { return hash } +// hash_string_to_buffer_192_3 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_192_3 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_192_3(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_192_3 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_192_3 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_192, "Size of destination buffer is smaller than the digest size") + ctx: Haval_Context + ctx.hashbitlen = 192 + ctx.rounds = 3 + init(&ctx) + ctx.str_len = u32(len(data)) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_192_3 will read the stream in chunks and compute a // hash from its contents -hash_stream_192_3 :: proc(s: io.Stream) -> ([24]byte, bool) { - hash: [24]byte +hash_stream_192_3 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) { + hash: [DIGEST_SIZE_192]byte ctx: Haval_Context ctx.hashbitlen = 192 ctx.rounds = 3 @@ -436,7 +601,7 @@ hash_stream_192_3 :: proc(s: io.Stream) -> ([24]byte, bool) { // hash_file_192_3 will read the file provided by the given handle // and compute a hash -hash_file_192_3 :: proc(hd: os.Handle, load_at_once := false) -> ([24]byte, bool) { +hash_file_192_3 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_192]byte, bool) { if !load_at_once { return hash_stream_192_3(os.stream_from_handle(hd)) } else { @@ -444,7 +609,7 @@ hash_file_192_3 :: proc(hd: os.Handle, load_at_once := false) -> ([24]byte, bool return hash_bytes_192_3(buf[:]), ok } } - return [24]byte{}, false + return [DIGEST_SIZE_192]byte{}, false } hash_192_3 :: proc { @@ -452,18 +617,20 @@ hash_192_3 :: proc { hash_file_192_3, hash_bytes_192_3, hash_string_192_3, + hash_bytes_to_buffer_192_3, + hash_string_to_buffer_192_3, } // hash_string_192_4 will hash the given input and return the // computed hash -hash_string_192_4 :: proc(data: string) -> [24]byte { +hash_string_192_4 :: proc(data: string) -> [DIGEST_SIZE_192]byte { return hash_bytes_192_4(transmute([]byte)(data)) } // hash_bytes_192_4 will hash the given input and return the // computed hash -hash_bytes_192_4 :: proc(data: []byte) -> [24]byte { - hash: [24]byte +hash_bytes_192_4 :: proc(data: []byte) -> [DIGEST_SIZE_192]byte { + hash: [DIGEST_SIZE_192]byte ctx: Haval_Context ctx.hashbitlen = 192 ctx.rounds = 4 @@ -474,10 +641,31 @@ hash_bytes_192_4 :: proc(data: []byte) -> [24]byte { return hash } +// hash_string_to_buffer_192_4 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_192_4 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_192_4(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_192_4 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_192_4 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_192, "Size of destination buffer is smaller than the digest size") + ctx: Haval_Context + ctx.hashbitlen = 192 + ctx.rounds = 4 + init(&ctx) + ctx.str_len = u32(len(data)) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_192_4 will read the stream in chunks and compute a // hash from its contents -hash_stream_192_4 :: proc(s: io.Stream) -> ([24]byte, bool) { - hash: [24]byte +hash_stream_192_4 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) { + hash: [DIGEST_SIZE_192]byte ctx: Haval_Context ctx.hashbitlen = 192 ctx.rounds = 4 @@ -498,7 +686,7 @@ hash_stream_192_4 :: proc(s: io.Stream) -> ([24]byte, bool) { // hash_file_192_4 will read the file provided by the given handle // and compute a hash -hash_file_192_4 :: proc(hd: os.Handle, load_at_once := false) -> ([24]byte, bool) { +hash_file_192_4 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_192]byte, bool) { if !load_at_once { return hash_stream_192_4(os.stream_from_handle(hd)) } else { @@ -506,7 +694,7 @@ hash_file_192_4 :: proc(hd: os.Handle, load_at_once := false) -> ([24]byte, bool return hash_bytes_192_4(buf[:]), ok } } - return [24]byte{}, false + return [DIGEST_SIZE_192]byte{}, false } hash_192_4 :: proc { @@ -514,18 +702,20 @@ hash_192_4 :: proc { hash_file_192_4, hash_bytes_192_4, hash_string_192_4, + hash_bytes_to_buffer_192_4, + hash_string_to_buffer_192_4, } // hash_string_192_5 will hash the given input and return the // computed hash -hash_string_192_5 :: proc(data: string) -> [24]byte { +hash_string_192_5 :: proc(data: string) -> [DIGEST_SIZE_192]byte { return hash_bytes_192_5(transmute([]byte)(data)) } -// hash_bytes_224_5 will hash the given input and return the +// hash_bytes_2DIGEST_SIZE_192_5 will hash the given input and return the // computed hash -hash_bytes_192_5 :: proc(data: []byte) -> [24]byte { - hash: [24]byte +hash_bytes_192_5 :: proc(data: []byte) -> [DIGEST_SIZE_192]byte { + hash: [DIGEST_SIZE_192]byte ctx: Haval_Context ctx.hashbitlen = 192 ctx.rounds = 5 @@ -536,10 +726,31 @@ hash_bytes_192_5 :: proc(data: []byte) -> [24]byte { return hash } +// hash_string_to_buffer_192_5 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_192_5 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_192_5(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_192_5 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_192_5 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_192, "Size of destination buffer is smaller than the digest size") + ctx: Haval_Context + ctx.hashbitlen = 192 + ctx.rounds = 5 + init(&ctx) + ctx.str_len = u32(len(data)) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_192_5 will read the stream in chunks and compute a // hash from its contents -hash_stream_192_5 :: proc(s: io.Stream) -> ([24]byte, bool) { - hash: [24]byte +hash_stream_192_5 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) { + hash: [DIGEST_SIZE_192]byte ctx: Haval_Context ctx.hashbitlen = 192 ctx.rounds = 5 @@ -560,7 +771,7 @@ hash_stream_192_5 :: proc(s: io.Stream) -> ([24]byte, bool) { // hash_file_192_5 will read the file provided by the given handle // and compute a hash -hash_file_192_5 :: proc(hd: os.Handle, load_at_once := false) -> ([24]byte, bool) { +hash_file_192_5 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_192]byte, bool) { if !load_at_once { return hash_stream_192_5(os.stream_from_handle(hd)) } else { @@ -568,7 +779,7 @@ hash_file_192_5 :: proc(hd: os.Handle, load_at_once := false) -> ([24]byte, bool return hash_bytes_192_5(buf[:]), ok } } - return [24]byte{}, false + return [DIGEST_SIZE_192]byte{}, false } hash_192_5 :: proc { @@ -576,18 +787,20 @@ hash_192_5 :: proc { hash_file_192_5, hash_bytes_192_5, hash_string_192_5, + hash_bytes_to_buffer_192_5, + hash_string_to_buffer_192_5, } // hash_string_224_3 will hash the given input and return the // computed hash -hash_string_224_3 :: proc(data: string) -> [28]byte { +hash_string_224_3 :: proc(data: string) -> [DIGEST_SIZE_224]byte { return hash_bytes_224_3(transmute([]byte)(data)) } // hash_bytes_224_3 will hash the given input and return the // computed hash -hash_bytes_224_3 :: proc(data: []byte) -> [28]byte { - hash: [28]byte +hash_bytes_224_3 :: proc(data: []byte) -> [DIGEST_SIZE_224]byte { + hash: [DIGEST_SIZE_224]byte ctx: Haval_Context ctx.hashbitlen = 224 ctx.rounds = 3 @@ -598,10 +811,31 @@ hash_bytes_224_3 :: proc(data: []byte) -> [28]byte { return hash } +// hash_string_to_buffer_224_3 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_224_3 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_224_3(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_224_3 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_224_3 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_224, "Size of destination buffer is smaller than the digest size") + ctx: Haval_Context + ctx.hashbitlen = 224 + ctx.rounds = 3 + init(&ctx) + ctx.str_len = u32(len(data)) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_224_3 will read the stream in chunks and compute a // hash from its contents -hash_stream_224_3 :: proc(s: io.Stream) -> ([28]byte, bool) { - hash: [28]byte +hash_stream_224_3 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { + hash: [DIGEST_SIZE_224]byte ctx: Haval_Context ctx.hashbitlen = 224 ctx.rounds = 3 @@ -622,7 +856,7 @@ hash_stream_224_3 :: proc(s: io.Stream) -> ([28]byte, bool) { // hash_file_224_3 will read the file provided by the given handle // and compute a hash -hash_file_224_3 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool) { +hash_file_224_3 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_224]byte, bool) { if !load_at_once { return hash_stream_224_3(os.stream_from_handle(hd)) } else { @@ -630,7 +864,7 @@ hash_file_224_3 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool return hash_bytes_224_3(buf[:]), ok } } - return [28]byte{}, false + return [DIGEST_SIZE_224]byte{}, false } hash_224_3 :: proc { @@ -638,18 +872,20 @@ hash_224_3 :: proc { hash_file_224_3, hash_bytes_224_3, hash_string_224_3, + hash_bytes_to_buffer_224_3, + hash_string_to_buffer_224_3, } // hash_string_224_4 will hash the given input and return the // computed hash -hash_string_224_4 :: proc(data: string) -> [28]byte { +hash_string_224_4 :: proc(data: string) -> [DIGEST_SIZE_224]byte { return hash_bytes_224_4(transmute([]byte)(data)) } // hash_bytes_224_4 will hash the given input and return the // computed hash -hash_bytes_224_4 :: proc(data: []byte) -> [28]byte { - hash: [28]byte +hash_bytes_224_4 :: proc(data: []byte) -> [DIGEST_SIZE_224]byte { + hash: [DIGEST_SIZE_224]byte ctx: Haval_Context ctx.hashbitlen = 224 ctx.rounds = 4 @@ -660,10 +896,31 @@ hash_bytes_224_4 :: proc(data: []byte) -> [28]byte { return hash } +// hash_string_to_buffer_224_4 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_224_4 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_224_4(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_224_4 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_224_4 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_224, "Size of destination buffer is smaller than the digest size") + ctx: Haval_Context + ctx.hashbitlen = 224 + ctx.rounds = 4 + init(&ctx) + ctx.str_len = u32(len(data)) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_224_4 will read the stream in chunks and compute a // hash from its contents -hash_stream_224_4 :: proc(s: io.Stream) -> ([28]byte, bool) { - hash: [28]byte +hash_stream_224_4 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { + hash: [DIGEST_SIZE_224]byte ctx: Haval_Context ctx.hashbitlen = 224 ctx.rounds = 4 @@ -684,7 +941,7 @@ hash_stream_224_4 :: proc(s: io.Stream) -> ([28]byte, bool) { // hash_file_224_4 will read the file provided by the given handle // and compute a hash -hash_file_224_4 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool) { +hash_file_224_4 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_224]byte, bool) { if !load_at_once { return hash_stream_224_4(os.stream_from_handle(hd)) } else { @@ -692,7 +949,7 @@ hash_file_224_4 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool return hash_bytes_224_4(buf[:]), ok } } - return [28]byte{}, false + return [DIGEST_SIZE_224]byte{}, false } hash_224_4 :: proc { @@ -700,18 +957,20 @@ hash_224_4 :: proc { hash_file_224_4, hash_bytes_224_4, hash_string_224_4, + hash_bytes_to_buffer_224_4, + hash_string_to_buffer_224_4, } // hash_string_224_5 will hash the given input and return the // computed hash -hash_string_224_5 :: proc(data: string) -> [28]byte { +hash_string_224_5 :: proc(data: string) -> [DIGEST_SIZE_224]byte { return hash_bytes_224_5(transmute([]byte)(data)) } // hash_bytes_224_5 will hash the given input and return the // computed hash -hash_bytes_224_5 :: proc(data: []byte) -> [28]byte { - hash: [28]byte +hash_bytes_224_5 :: proc(data: []byte) -> [DIGEST_SIZE_224]byte { + hash: [DIGEST_SIZE_224]byte ctx: Haval_Context ctx.hashbitlen = 224 ctx.rounds = 5 @@ -722,10 +981,31 @@ hash_bytes_224_5 :: proc(data: []byte) -> [28]byte { return hash } +// hash_string_to_buffer_224_5 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_224_5 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_224_5(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_224_5 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_224_5 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_224, "Size of destination buffer is smaller than the digest size") + ctx: Haval_Context + ctx.hashbitlen = 224 + ctx.rounds = 5 + init(&ctx) + ctx.str_len = u32(len(data)) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_224_5 will read the stream in chunks and compute a // hash from its contents -hash_stream_224_5 :: proc(s: io.Stream) -> ([28]byte, bool) { - hash: [28]byte +hash_stream_224_5 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { + hash: [DIGEST_SIZE_224]byte ctx: Haval_Context ctx.hashbitlen = 224 ctx.rounds = 5 @@ -746,7 +1026,7 @@ hash_stream_224_5 :: proc(s: io.Stream) -> ([28]byte, bool) { // hash_file_224_5 will read the file provided by the given handle // and compute a hash -hash_file_224_5 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool) { +hash_file_224_5 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_224]byte, bool) { if !load_at_once { return hash_stream_224_5(os.stream_from_handle(hd)) } else { @@ -754,7 +1034,7 @@ hash_file_224_5 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool return hash_bytes_224_5(buf[:]), ok } } - return [28]byte{}, false + return [DIGEST_SIZE_224]byte{}, false } hash_224_5 :: proc { @@ -762,18 +1042,20 @@ hash_224_5 :: proc { hash_file_224_5, hash_bytes_224_5, hash_string_224_5, + hash_bytes_to_buffer_224_5, + hash_string_to_buffer_224_5, } // hash_string_256_3 will hash the given input and return the // computed hash -hash_string_256_3 :: proc(data: string) -> [32]byte { +hash_string_256_3 :: proc(data: string) -> [DIGEST_SIZE_256]byte { return hash_bytes_256_3(transmute([]byte)(data)) } // hash_bytes_256_3 will hash the given input and return the // computed hash -hash_bytes_256_3 :: proc(data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes_256_3 :: proc(data: []byte) -> [DIGEST_SIZE_256]byte { + hash: [DIGEST_SIZE_256]byte ctx: Haval_Context ctx.hashbitlen = 256 ctx.rounds = 3 @@ -784,10 +1066,31 @@ hash_bytes_256_3 :: proc(data: []byte) -> [32]byte { return hash } +// hash_string_to_buffer_256_3 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_256_3 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_256_3(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_256_3 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_256_3 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_256, "Size of destination buffer is smaller than the digest size") + ctx: Haval_Context + ctx.hashbitlen = 256 + ctx.rounds = 3 + init(&ctx) + ctx.str_len = u32(len(data)) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_256_3 will read the stream in chunks and compute a // hash from its contents -hash_stream_256_3 :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream_256_3 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { + hash: [DIGEST_SIZE_256]byte ctx: Haval_Context ctx.hashbitlen = 256 ctx.rounds = 3 @@ -808,7 +1111,7 @@ hash_stream_256_3 :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file_256_3 will read the file provided by the given handle // and compute a hash -hash_file_256_3 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file_256_3 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_256]byte, bool) { if !load_at_once { return hash_stream_256_3(os.stream_from_handle(hd)) } else { @@ -816,7 +1119,7 @@ hash_file_256_3 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool return hash_bytes_256_3(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE_256]byte{}, false } hash_256_3 :: proc { @@ -824,18 +1127,20 @@ hash_256_3 :: proc { hash_file_256_3, hash_bytes_256_3, hash_string_256_3, + hash_bytes_to_buffer_256_3, + hash_string_to_buffer_256_3, } // hash_string_256_4 will hash the given input and return the // computed hash -hash_string_256_4 :: proc(data: string) -> [32]byte { +hash_string_256_4 :: proc(data: string) -> [DIGEST_SIZE_256]byte { return hash_bytes_256_4(transmute([]byte)(data)) } // hash_bytes_256_4 will hash the given input and return the // computed hash -hash_bytes_256_4 :: proc(data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes_256_4 :: proc(data: []byte) -> [DIGEST_SIZE_256]byte { + hash: [DIGEST_SIZE_256]byte ctx: Haval_Context ctx.hashbitlen = 256 ctx.rounds = 4 @@ -846,10 +1151,31 @@ hash_bytes_256_4 :: proc(data: []byte) -> [32]byte { return hash } +// hash_string_to_buffer_256_4 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_256_4 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_256_4(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_256_4 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_256_4 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_256, "Size of destination buffer is smaller than the digest size") + ctx: Haval_Context + ctx.hashbitlen = 256 + ctx.rounds = 4 + init(&ctx) + ctx.str_len = u32(len(data)) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_256_4 will read the stream in chunks and compute a // hash from its contents -hash_stream_256_4 :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream_256_4 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { + hash: [DIGEST_SIZE_256]byte ctx: Haval_Context ctx.hashbitlen = 256 ctx.rounds = 4 @@ -870,7 +1196,7 @@ hash_stream_256_4 :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file_256_4 will read the file provided by the given handle // and compute a hash -hash_file_256_4 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file_256_4 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_256]byte, bool) { if !load_at_once { return hash_stream_256_4(os.stream_from_handle(hd)) } else { @@ -878,7 +1204,7 @@ hash_file_256_4 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool return hash_bytes_256_4(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE_256]byte{}, false } hash_256_4 :: proc { @@ -886,18 +1212,20 @@ hash_256_4 :: proc { hash_file_256_4, hash_bytes_256_4, hash_string_256_4, + hash_bytes_to_buffer_256_4, + hash_string_to_buffer_256_4, } // hash_string_256_5 will hash the given input and return the // computed hash -hash_string_256_5 :: proc(data: string) -> [32]byte { +hash_string_256_5 :: proc(data: string) -> [DIGEST_SIZE_256]byte { return hash_bytes_256_5(transmute([]byte)(data)) } // hash_bytes_256_5 will hash the given input and return the // computed hash -hash_bytes_256_5 :: proc(data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes_256_5 :: proc(data: []byte) -> [DIGEST_SIZE_256]byte { + hash: [DIGEST_SIZE_256]byte ctx: Haval_Context ctx.hashbitlen = 256 ctx.rounds = 5 @@ -908,10 +1236,32 @@ hash_bytes_256_5 :: proc(data: []byte) -> [32]byte { return hash } +// hash_string_to_buffer_256_5 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_256_5 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_256_5(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_256_5 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_256_5 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_256, "Size of destination buffer is smaller than the digest size") + ctx: Haval_Context + ctx.hashbitlen = 256 + ctx.rounds = 5 + init(&ctx) + ctx.str_len = u32(len(data)) + update(&ctx, data) + final(&ctx, hash) +} + + // hash_stream_256_5 will read the stream in chunks and compute a // hash from its contents -hash_stream_256_5 :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream_256_5 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { + hash: [DIGEST_SIZE_256]byte ctx: Haval_Context ctx.hashbitlen = 256 ctx.rounds = 5 @@ -932,7 +1282,7 @@ hash_stream_256_5 :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file_256_5 will read the file provided by the given handle // and compute a hash -hash_file_256_5 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file_256_5 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_256]byte, bool) { if !load_at_once { return hash_stream_256_5(os.stream_from_handle(hd)) } else { @@ -940,7 +1290,7 @@ hash_file_256_5 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool return hash_bytes_256_5(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE_256]byte{}, false } hash_256_5 :: proc { @@ -948,6 +1298,8 @@ hash_256_5 :: proc { hash_file_256_5, hash_bytes_256_5, hash_string_256_5, + hash_bytes_to_buffer_256_5, + hash_string_to_buffer_256_5, } /* @@ -980,7 +1332,7 @@ update :: proc(ctx: ^Haval_Context, data: []byte) { } ctx.count[1] += str_len >> 29 - when ODIN_ENDIAN == "little" { + when ODIN_ENDIAN == .Little { if rmd_len + str_len >= 128 { copy(util.slice_to_bytes(ctx.block[:])[rmd_len:], data[:fill_len]) block(ctx, ctx.rounds) diff --git a/core/crypto/jh/jh.odin b/core/crypto/jh/jh.odin index f251424d2..42c2d1d34 100644 --- a/core/crypto/jh/jh.odin +++ b/core/crypto/jh/jh.odin @@ -17,16 +17,21 @@ import "core:io" High level API */ +DIGEST_SIZE_224 :: 28 +DIGEST_SIZE_256 :: 32 +DIGEST_SIZE_384 :: 48 +DIGEST_SIZE_512 :: 64 + // hash_string_224 will hash the given input and return the // computed hash -hash_string_224 :: proc(data: string) -> [28]byte { +hash_string_224 :: proc(data: string) -> [DIGEST_SIZE_224]byte { return hash_bytes_224(transmute([]byte)(data)) } // hash_bytes_224 will hash the given input and return the // computed hash -hash_bytes_224 :: proc(data: []byte) -> [28]byte { - hash: [28]byte +hash_bytes_224 :: proc(data: []byte) -> [DIGEST_SIZE_224]byte { + hash: [DIGEST_SIZE_224]byte ctx: Jh_Context ctx.hashbitlen = 224 init(&ctx) @@ -35,10 +40,29 @@ hash_bytes_224 :: proc(data: []byte) -> [28]byte { return hash } +// hash_string_to_buffer_224 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_224 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_224(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_224 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_224 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_224, "Size of destination buffer is smaller than the digest size") + ctx: Jh_Context + ctx.hashbitlen = 224 + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_224 will read the stream in chunks and compute a // hash from its contents -hash_stream_224 :: proc(s: io.Stream) -> ([28]byte, bool) { - hash: [28]byte +hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { + hash: [DIGEST_SIZE_224]byte ctx: Jh_Context ctx.hashbitlen = 224 init(&ctx) @@ -57,7 +81,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([28]byte, bool) { // hash_file_224 will read the file provided by the given handle // and compute a hash -hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool) { +hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_224]byte, bool) { if !load_at_once { return hash_stream_224(os.stream_from_handle(hd)) } else { @@ -65,7 +89,7 @@ hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool) return hash_bytes_224(buf[:]), ok } } - return [28]byte{}, false + return [DIGEST_SIZE_224]byte{}, false } hash_224 :: proc { @@ -73,18 +97,20 @@ hash_224 :: proc { hash_file_224, hash_bytes_224, hash_string_224, + hash_bytes_to_buffer_224, + hash_string_to_buffer_224, } // hash_string_256 will hash the given input and return the // computed hash -hash_string_256 :: proc(data: string) -> [32]byte { +hash_string_256 :: proc(data: string) -> [DIGEST_SIZE_256]byte { return hash_bytes_256(transmute([]byte)(data)) } // hash_bytes_256 will hash the given input and return the // computed hash -hash_bytes_256 :: proc(data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes_256 :: proc(data: []byte) -> [DIGEST_SIZE_256]byte { + hash: [DIGEST_SIZE_256]byte ctx: Jh_Context ctx.hashbitlen = 256 init(&ctx) @@ -93,10 +119,29 @@ hash_bytes_256 :: proc(data: []byte) -> [32]byte { return hash } +// hash_string_to_buffer_256 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_256 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_256(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_256 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_256 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_256, "Size of destination buffer is smaller than the digest size") + ctx: Jh_Context + ctx.hashbitlen = 256 + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_256 will read the stream in chunks and compute a // hash from its contents -hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { + hash: [DIGEST_SIZE_256]byte ctx: Jh_Context ctx.hashbitlen = 256 init(&ctx) @@ -115,7 +160,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file_256 will read the file provided by the given handle // and compute a hash -hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_256]byte, bool) { if !load_at_once { return hash_stream_256(os.stream_from_handle(hd)) } else { @@ -123,7 +168,7 @@ hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) return hash_bytes_256(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE_256]byte{}, false } hash_256 :: proc { @@ -131,18 +176,20 @@ hash_256 :: proc { hash_file_256, hash_bytes_256, hash_string_256, + hash_bytes_to_buffer_256, + hash_string_to_buffer_256, } // hash_string_384 will hash the given input and return the // computed hash -hash_string_384 :: proc(data: string) -> [48]byte { +hash_string_384 :: proc(data: string) -> [DIGEST_SIZE_384]byte { return hash_bytes_384(transmute([]byte)(data)) } // hash_bytes_384 will hash the given input and return the // computed hash -hash_bytes_384 :: proc(data: []byte) -> [48]byte { - hash: [48]byte +hash_bytes_384 :: proc(data: []byte) -> [DIGEST_SIZE_384]byte { + hash: [DIGEST_SIZE_384]byte ctx: Jh_Context ctx.hashbitlen = 384 init(&ctx) @@ -151,10 +198,29 @@ hash_bytes_384 :: proc(data: []byte) -> [48]byte { return hash } +// hash_string_to_buffer_384 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_384 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_384(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_384 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_384 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_384, "Size of destination buffer is smaller than the digest size") + ctx: Jh_Context + ctx.hashbitlen = 384 + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_384 will read the stream in chunks and compute a // hash from its contents -hash_stream_384 :: proc(s: io.Stream) -> ([48]byte, bool) { - hash: [48]byte +hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) { + hash: [DIGEST_SIZE_384]byte ctx: Jh_Context ctx.hashbitlen = 384 init(&ctx) @@ -173,7 +239,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([48]byte, bool) { // hash_file_384 will read the file provided by the given handle // and compute a hash -hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([48]byte, bool) { +hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_384]byte, bool) { if !load_at_once { return hash_stream_384(os.stream_from_handle(hd)) } else { @@ -181,7 +247,7 @@ hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([48]byte, bool) return hash_bytes_384(buf[:]), ok } } - return [48]byte{}, false + return [DIGEST_SIZE_384]byte{}, false } hash_384 :: proc { @@ -189,18 +255,20 @@ hash_384 :: proc { hash_file_384, hash_bytes_384, hash_string_384, + hash_bytes_to_buffer_384, + hash_string_to_buffer_384, } // hash_string_512 will hash the given input and return the // computed hash -hash_string_512 :: proc(data: string) -> [64]byte { +hash_string_512 :: proc(data: string) -> [DIGEST_SIZE_512]byte { return hash_bytes_512(transmute([]byte)(data)) } // hash_bytes_512 will hash the given input and return the // computed hash -hash_bytes_512 :: proc(data: []byte) -> [64]byte { - hash: [64]byte +hash_bytes_512 :: proc(data: []byte) -> [DIGEST_SIZE_512]byte { + hash: [DIGEST_SIZE_512]byte ctx: Jh_Context ctx.hashbitlen = 512 init(&ctx) @@ -209,10 +277,29 @@ hash_bytes_512 :: proc(data: []byte) -> [64]byte { return hash } +// hash_string_to_buffer_512 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_512 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_512(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_512 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_512 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_512, "Size of destination buffer is smaller than the digest size") + ctx: Jh_Context + ctx.hashbitlen = 512 + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_512 will read the stream in chunks and compute a // hash from its contents -hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { - hash: [64]byte +hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { + hash: [DIGEST_SIZE_512]byte ctx: Jh_Context ctx.hashbitlen = 512 init(&ctx) @@ -231,7 +318,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { // hash_file_512 will read the file provided by the given handle // and compute a hash -hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) { +hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_512]byte, bool) { if !load_at_once { return hash_stream_512(os.stream_from_handle(hd)) } else { @@ -239,7 +326,7 @@ hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) return hash_bytes_512(buf[:]), ok } } - return [64]byte{}, false + return [DIGEST_SIZE_512]byte{}, false } hash_512 :: proc { @@ -247,6 +334,8 @@ hash_512 :: proc { hash_file_512, hash_bytes_512, hash_string_512, + hash_bytes_to_buffer_512, + hash_string_to_buffer_512, } /* diff --git a/core/crypto/keccak/keccak.odin b/core/crypto/keccak/keccak.odin index 19c4c7dda..aeb5aac52 100644 --- a/core/crypto/keccak/keccak.odin +++ b/core/crypto/keccak/keccak.odin @@ -21,18 +21,23 @@ import "../_sha3" High level API */ +DIGEST_SIZE_224 :: 28 +DIGEST_SIZE_256 :: 32 +DIGEST_SIZE_384 :: 48 +DIGEST_SIZE_512 :: 64 + // hash_string_224 will hash the given input and return the // computed hash -hash_string_224 :: proc(data: string) -> [28]byte { +hash_string_224 :: proc(data: string) -> [DIGEST_SIZE_224]byte { return hash_bytes_224(transmute([]byte)(data)) } // hash_bytes_224 will hash the given input and return the // computed hash -hash_bytes_224 :: proc(data: []byte) -> [28]byte { - hash: [28]byte +hash_bytes_224 :: proc(data: []byte) -> [DIGEST_SIZE_224]byte { + hash: [DIGEST_SIZE_224]byte ctx: _sha3.Sha3_Context - ctx.mdlen = 28 + ctx.mdlen = DIGEST_SIZE_224 ctx.is_keccak = true _sha3.init(&ctx) _sha3.update(&ctx, data) @@ -40,12 +45,32 @@ hash_bytes_224 :: proc(data: []byte) -> [28]byte { return hash } +// hash_string_to_buffer_224 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_224 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_224(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_224 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_224 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_224, "Size of destination buffer is smaller than the digest size") + ctx: _sha3.Sha3_Context + ctx.mdlen = DIGEST_SIZE_224 + ctx.is_keccak = true + _sha3.init(&ctx) + _sha3.update(&ctx, data) + _sha3.final(&ctx, hash) +} + // hash_stream_224 will read the stream in chunks and compute a // hash from its contents -hash_stream_224 :: proc(s: io.Stream) -> ([28]byte, bool) { - hash: [28]byte +hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { + hash: [DIGEST_SIZE_224]byte ctx: _sha3.Sha3_Context - ctx.mdlen = 28 + ctx.mdlen = DIGEST_SIZE_224 ctx.is_keccak = true _sha3.init(&ctx) buf := make([]byte, 512) @@ -63,7 +88,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([28]byte, bool) { // hash_file_224 will read the file provided by the given handle // and compute a hash -hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool) { +hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_224]byte, bool) { if !load_at_once { return hash_stream_224(os.stream_from_handle(hd)) } else { @@ -71,7 +96,7 @@ hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool) return hash_bytes_224(buf[:]), ok } } - return [28]byte{}, false + return [DIGEST_SIZE_224]byte{}, false } hash_224 :: proc { @@ -79,20 +104,22 @@ hash_224 :: proc { hash_file_224, hash_bytes_224, hash_string_224, + hash_bytes_to_buffer_224, + hash_string_to_buffer_224, } // hash_string_256 will hash the given input and return the // computed hash -hash_string_256 :: proc(data: string) -> [32]byte { +hash_string_256 :: proc(data: string) -> [DIGEST_SIZE_256]byte { return hash_bytes_256(transmute([]byte)(data)) } // hash_bytes_256 will hash the given input and return the // computed hash -hash_bytes_256 :: proc(data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes_256 :: proc(data: []byte) -> [DIGEST_SIZE_256]byte { + hash: [DIGEST_SIZE_256]byte ctx: _sha3.Sha3_Context - ctx.mdlen = 32 + ctx.mdlen = DIGEST_SIZE_256 ctx.is_keccak = true _sha3.init(&ctx) _sha3.update(&ctx, data) @@ -100,12 +127,32 @@ hash_bytes_256 :: proc(data: []byte) -> [32]byte { return hash } +// hash_string_to_buffer_256 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_256 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_256(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_256 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_256 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_256, "Size of destination buffer is smaller than the digest size") + ctx: _sha3.Sha3_Context + ctx.mdlen = DIGEST_SIZE_256 + ctx.is_keccak = true + _sha3.init(&ctx) + _sha3.update(&ctx, data) + _sha3.final(&ctx, hash) +} + // hash_stream_256 will read the stream in chunks and compute a // hash from its contents -hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { + hash: [DIGEST_SIZE_256]byte ctx: _sha3.Sha3_Context - ctx.mdlen = 32 + ctx.mdlen = DIGEST_SIZE_256 ctx.is_keccak = true _sha3.init(&ctx) buf := make([]byte, 512) @@ -123,7 +170,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file_256 will read the file provided by the given handle // and compute a hash -hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_256]byte, bool) { if !load_at_once { return hash_stream_256(os.stream_from_handle(hd)) } else { @@ -131,7 +178,7 @@ hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) return hash_bytes_256(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE_256]byte{}, false } hash_256 :: proc { @@ -139,20 +186,22 @@ hash_256 :: proc { hash_file_256, hash_bytes_256, hash_string_256, + hash_bytes_to_buffer_256, + hash_string_to_buffer_256, } // hash_string_384 will hash the given input and return the // computed hash -hash_string_384 :: proc(data: string) -> [48]byte { +hash_string_384 :: proc(data: string) -> [DIGEST_SIZE_384]byte { return hash_bytes_384(transmute([]byte)(data)) } // hash_bytes_384 will hash the given input and return the // computed hash -hash_bytes_384 :: proc(data: []byte) -> [48]byte { - hash: [48]byte +hash_bytes_384 :: proc(data: []byte) -> [DIGEST_SIZE_384]byte { + hash: [DIGEST_SIZE_384]byte ctx: _sha3.Sha3_Context - ctx.mdlen = 48 + ctx.mdlen = DIGEST_SIZE_384 ctx.is_keccak = true _sha3.init(&ctx) _sha3.update(&ctx, data) @@ -160,12 +209,32 @@ hash_bytes_384 :: proc(data: []byte) -> [48]byte { return hash } +// hash_string_to_buffer_384 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_384 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_384(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_384 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_384 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_384, "Size of destination buffer is smaller than the digest size") + ctx: _sha3.Sha3_Context + ctx.mdlen = DIGEST_SIZE_384 + ctx.is_keccak = true + _sha3.init(&ctx) + _sha3.update(&ctx, data) + _sha3.final(&ctx, hash) +} + // hash_stream_384 will read the stream in chunks and compute a // hash from its contents -hash_stream_384 :: proc(s: io.Stream) -> ([48]byte, bool) { - hash: [48]byte +hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) { + hash: [DIGEST_SIZE_384]byte ctx: _sha3.Sha3_Context - ctx.mdlen = 48 + ctx.mdlen = DIGEST_SIZE_384 ctx.is_keccak = true _sha3.init(&ctx) buf := make([]byte, 512) @@ -183,7 +252,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([48]byte, bool) { // hash_file_384 will read the file provided by the given handle // and compute a hash -hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([48]byte, bool) { +hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_384]byte, bool) { if !load_at_once { return hash_stream_384(os.stream_from_handle(hd)) } else { @@ -191,7 +260,7 @@ hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([48]byte, bool) return hash_bytes_384(buf[:]), ok } } - return [48]byte{}, false + return [DIGEST_SIZE_384]byte{}, false } hash_384 :: proc { @@ -199,20 +268,22 @@ hash_384 :: proc { hash_file_384, hash_bytes_384, hash_string_384, + hash_bytes_to_buffer_384, + hash_string_to_buffer_384, } // hash_string_512 will hash the given input and return the // computed hash -hash_string_512 :: proc(data: string) -> [64]byte { +hash_string_512 :: proc(data: string) -> [DIGEST_SIZE_512]byte { return hash_bytes_512(transmute([]byte)(data)) } // hash_bytes_512 will hash the given input and return the // computed hash -hash_bytes_512 :: proc(data: []byte) -> [64]byte { - hash: [64]byte +hash_bytes_512 :: proc(data: []byte) -> [DIGEST_SIZE_512]byte { + hash: [DIGEST_SIZE_512]byte ctx: _sha3.Sha3_Context - ctx.mdlen = 64 + ctx.mdlen = DIGEST_SIZE_512 ctx.is_keccak = true _sha3.init(&ctx) _sha3.update(&ctx, data) @@ -220,12 +291,32 @@ hash_bytes_512 :: proc(data: []byte) -> [64]byte { return hash } +// hash_string_to_buffer_512 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_512 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_512(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_512 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_512 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_512, "Size of destination buffer is smaller than the digest size") + ctx: _sha3.Sha3_Context + ctx.mdlen = DIGEST_SIZE_512 + ctx.is_keccak = true + _sha3.init(&ctx) + _sha3.update(&ctx, data) + _sha3.final(&ctx, hash) +} + // hash_stream_512 will read the stream in chunks and compute a // hash from its contents -hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { - hash: [64]byte +hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { + hash: [DIGEST_SIZE_512]byte ctx: _sha3.Sha3_Context - ctx.mdlen = 64 + ctx.mdlen = DIGEST_SIZE_512 ctx.is_keccak = true _sha3.init(&ctx) buf := make([]byte, 512) @@ -243,7 +334,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { // hash_file_512 will read the file provided by the given handle // and compute a hash -hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) { +hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_512]byte, bool) { if !load_at_once { return hash_stream_512(os.stream_from_handle(hd)) } else { @@ -251,7 +342,7 @@ hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) return hash_bytes_512(buf[:]), ok } } - return [64]byte{}, false + return [DIGEST_SIZE_512]byte{}, false } hash_512 :: proc { @@ -259,13 +350,15 @@ hash_512 :: proc { hash_file_512, hash_bytes_512, hash_string_512, + hash_bytes_to_buffer_512, + hash_string_to_buffer_512, } /* Low level API */ -Sha3_Context :: _sha3.Sha3_Context +Keccak_Context :: _sha3.Sha3_Context init :: proc(ctx: ^_sha3.Sha3_Context) { ctx.is_keccak = true diff --git a/core/crypto/md2/md2.odin b/core/crypto/md2/md2.odin index 5e027c13c..711e6e9f6 100644 --- a/core/crypto/md2/md2.odin +++ b/core/crypto/md2/md2.odin @@ -17,16 +17,18 @@ import "core:io" High level API */ +DIGEST_SIZE :: 16 + // hash_string will hash the given input and return the // computed hash -hash_string :: proc(data: string) -> [16]byte { +hash_string :: proc(data: string) -> [DIGEST_SIZE]byte { return hash_bytes(transmute([]byte)(data)) } // hash_bytes will hash the given input and return the // computed hash -hash_bytes :: proc(data: []byte) -> [16]byte { - hash: [16]byte +hash_bytes :: proc(data: []byte) -> [DIGEST_SIZE]byte { + hash: [DIGEST_SIZE]byte ctx: Md2_Context // init(&ctx) No-op update(&ctx, data) @@ -34,10 +36,28 @@ hash_bytes :: proc(data: []byte) -> [16]byte { return hash } +// hash_string_to_buffer will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") + ctx: Md2_Context + // init(&ctx) No-op + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream will read the stream in chunks and compute a // hash from its contents -hash_stream :: proc(s: io.Stream) -> ([16]byte, bool) { - hash: [16]byte +hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { + hash: [DIGEST_SIZE]byte ctx: Md2_Context // init(&ctx) No-op buf := make([]byte, 512) @@ -55,7 +75,7 @@ hash_stream :: proc(s: io.Stream) -> ([16]byte, bool) { // hash_file will read the file provided by the given handle // and compute a hash -hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) { +hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE]byte, bool) { if !load_at_once { return hash_stream(os.stream_from_handle(hd)) } else { @@ -63,7 +83,7 @@ hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) { return hash_bytes(buf[:]), ok } } - return [16]byte{}, false + return [DIGEST_SIZE]byte{}, false } hash :: proc { @@ -71,6 +91,8 @@ hash :: proc { hash_file, hash_bytes, hash_string, + hash_bytes_to_buffer, + hash_string_to_buffer, } /* @@ -86,7 +108,7 @@ update :: proc(ctx: ^Md2_Context, data: []byte) { for i := 0; i < len(data); i += 1 { ctx.data[ctx.datalen] = data[i] ctx.datalen += 1 - if (ctx.datalen == 16) { + if (ctx.datalen == DIGEST_SIZE) { transform(ctx, ctx.data[:]) ctx.datalen = 0 } @@ -94,14 +116,14 @@ update :: proc(ctx: ^Md2_Context, data: []byte) { } final :: proc(ctx: ^Md2_Context, hash: []byte) { - to_pad := byte(16 - ctx.datalen) - for ctx.datalen < 16 { + to_pad := byte(DIGEST_SIZE - ctx.datalen) + for ctx.datalen < DIGEST_SIZE { ctx.data[ctx.datalen] = to_pad ctx.datalen += 1 } transform(ctx, ctx.data[:]) transform(ctx, ctx.checksum[:]) - for i := 0; i < 16; i += 1 { + for i := 0; i < DIGEST_SIZE; i += 1 { hash[i] = ctx.state[i] } } @@ -111,9 +133,9 @@ final :: proc(ctx: ^Md2_Context, hash: []byte) { */ Md2_Context :: struct { - data: [16]byte, - state: [16 * 3]byte, - checksum: [16]byte, + data: [DIGEST_SIZE]byte, + state: [DIGEST_SIZE * 3]byte, + checksum: [DIGEST_SIZE]byte, datalen: int, } @@ -140,20 +162,20 @@ PI_TABLE := [?]byte { transform :: proc(ctx: ^Md2_Context, data: []byte) { j,k,t: byte - for j = 0; j < 16; j += 1 { - ctx.state[j + 16] = data[j] - ctx.state[j + 16 * 2] = (ctx.state[j + 16] ~ ctx.state[j]) + for j = 0; j < DIGEST_SIZE; j += 1 { + ctx.state[j + DIGEST_SIZE] = data[j] + ctx.state[j + DIGEST_SIZE * 2] = (ctx.state[j + DIGEST_SIZE] ~ ctx.state[j]) } t = 0 - for j = 0; j < 16 + 2; j += 1 { - for k = 0; k < 16 * 3; k += 1 { + for j = 0; j < DIGEST_SIZE + 2; j += 1 { + for k = 0; k < DIGEST_SIZE * 3; k += 1 { ctx.state[k] ~= PI_TABLE[t] t = ctx.state[k] } t = (t + j) & 0xff } - t = ctx.checksum[16 - 1] - for j = 0; j < 16; j += 1 { + t = ctx.checksum[DIGEST_SIZE - 1] + for j = 0; j < DIGEST_SIZE; j += 1 { ctx.checksum[j] ~= PI_TABLE[data[j] ~ t] t = ctx.checksum[j] } diff --git a/core/crypto/md4/md4.odin b/core/crypto/md4/md4.odin index 813db578a..b2651225b 100644 --- a/core/crypto/md4/md4.odin +++ b/core/crypto/md4/md4.odin @@ -21,16 +21,18 @@ import "../util" High level API */ +DIGEST_SIZE :: 16 + // hash_string will hash the given input and return the // computed hash -hash_string :: proc(data: string) -> [16]byte { +hash_string :: proc(data: string) -> [DIGEST_SIZE]byte { return hash_bytes(transmute([]byte)(data)) } // hash_bytes will hash the given input and return the // computed hash -hash_bytes :: proc(data: []byte) -> [16]byte { - hash: [16]byte +hash_bytes :: proc(data: []byte) -> [DIGEST_SIZE]byte { + hash: [DIGEST_SIZE]byte ctx: Md4_Context init(&ctx) update(&ctx, data) @@ -38,10 +40,28 @@ hash_bytes :: proc(data: []byte) -> [16]byte { return hash } +// hash_string_to_buffer will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") + ctx: Md4_Context + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream will read the stream in chunks and compute a // hash from its contents -hash_stream :: proc(s: io.Stream) -> ([16]byte, bool) { - hash: [16]byte +hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { + hash: [DIGEST_SIZE]byte ctx: Md4_Context init(&ctx) buf := make([]byte, 512) @@ -59,7 +79,7 @@ hash_stream :: proc(s: io.Stream) -> ([16]byte, bool) { // hash_file will read the file provided by the given handle // and compute a hash -hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) { +hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE]byte, bool) { if !load_at_once { return hash_stream(os.stream_from_handle(hd)) } else { @@ -67,7 +87,7 @@ hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) { return hash_bytes(buf[:]), ok } } - return [16]byte{}, false + return [DIGEST_SIZE]byte{}, false } hash :: proc { @@ -75,6 +95,8 @@ hash :: proc { hash_file, hash_bytes, hash_string, + hash_bytes_to_buffer, + hash_string_to_buffer, } /* @@ -171,9 +193,9 @@ HH :: #force_inline proc "contextless"(a, b, c, d, x: u32, s : int) -> u32 { transform :: proc(ctx: ^Md4_Context, data: []byte) { a, b, c, d, i, j: u32 - m: [16]u32 + m: [DIGEST_SIZE]u32 - for i, j = 0, 0; i < 16; i += 1 { + for i, j = 0, 0; i < DIGEST_SIZE; i += 1 { m[i] = u32(data[j]) | (u32(data[j + 1]) << 8) | (u32(data[j + 2]) << 16) | (u32(data[j + 3]) << 24) j += 4 } diff --git a/core/crypto/md5/md5.odin b/core/crypto/md5/md5.odin index a41ed16f8..30a556102 100644 --- a/core/crypto/md5/md5.odin +++ b/core/crypto/md5/md5.odin @@ -20,16 +20,18 @@ import "../util" High level API */ +DIGEST_SIZE :: 16 + // hash_string will hash the given input and return the // computed hash -hash_string :: proc(data: string) -> [16]byte { +hash_string :: proc(data: string) -> [DIGEST_SIZE]byte { return hash_bytes(transmute([]byte)(data)) } // hash_bytes will hash the given input and return the // computed hash -hash_bytes :: proc(data: []byte) -> [16]byte { - hash: [16]byte +hash_bytes :: proc(data: []byte) -> [DIGEST_SIZE]byte { + hash: [DIGEST_SIZE]byte ctx: Md5_Context init(&ctx) update(&ctx, data) @@ -37,10 +39,28 @@ hash_bytes :: proc(data: []byte) -> [16]byte { return hash } +// hash_string_to_buffer will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") + ctx: Md5_Context + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream will read the stream in chunks and compute a // hash from its contents -hash_stream :: proc(s: io.Stream) -> ([16]byte, bool) { - hash: [16]byte +hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { + hash: [DIGEST_SIZE]byte ctx: Md5_Context init(&ctx) buf := make([]byte, 512) @@ -58,7 +78,7 @@ hash_stream :: proc(s: io.Stream) -> ([16]byte, bool) { // hash_file will read the file provided by the given handle // and compute a hash -hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) { +hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE]byte, bool) { if !load_at_once { return hash_stream(os.stream_from_handle(hd)) } else { @@ -66,7 +86,7 @@ hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) { return hash_bytes(buf[:]), ok } } - return [16]byte{}, false + return [DIGEST_SIZE]byte{}, false } hash :: proc { @@ -74,6 +94,8 @@ hash :: proc { hash_file, hash_bytes, hash_string, + hash_bytes_to_buffer, + hash_string_to_buffer, } /* @@ -176,9 +198,9 @@ II :: #force_inline proc "contextless" (a, b, c, d, m: u32, s: int, t: u32) -> u transform :: proc(ctx: ^Md5_Context, data: []byte) { i, j: u32 - m: [16]u32 + m: [DIGEST_SIZE]u32 - for i, j = 0, 0; i < 16; i+=1 { + for i, j = 0, 0; i < DIGEST_SIZE; i+=1 { m[i] = u32(data[j]) + u32(data[j + 1]) << 8 + u32(data[j + 2]) << 16 + u32(data[j + 3]) << 24 j += 4 } diff --git a/core/crypto/rand_generic.odin b/core/crypto/rand_generic.odin index 98890b5b1..52abfe4d7 100644 --- a/core/crypto/rand_generic.odin +++ b/core/crypto/rand_generic.odin @@ -1,6 +1,6 @@ package crypto -when ODIN_OS != "linux" { +when ODIN_OS != .Linux && ODIN_OS != .OpenBSD && ODIN_OS != .Windows { _rand_bytes :: proc (dst: []byte) { unimplemented("crypto: rand_bytes not supported on this OS") } diff --git a/core/crypto/rand_openbsd.odin b/core/crypto/rand_openbsd.odin new file mode 100644 index 000000000..bae97e8f0 --- /dev/null +++ b/core/crypto/rand_openbsd.odin @@ -0,0 +1,12 @@ +package crypto + +import "core:c" + +foreign import libc "system:c" +foreign libc { + arc4random_buf :: proc "c" (buf: rawptr, nbytes: c.size_t) --- +} + +_rand_bytes :: proc (dst: []byte) { + arc4random_buf(raw_data(dst), len(dst)) +} diff --git a/core/crypto/rand_windows.odin b/core/crypto/rand_windows.odin new file mode 100644 index 000000000..53b58c776 --- /dev/null +++ b/core/crypto/rand_windows.odin @@ -0,0 +1,23 @@ +package crypto + +import win32 "core:sys/windows" +import "core:os" +import "core:fmt" + +_rand_bytes :: proc(dst: []byte) { + ret := (os.Errno)(win32.BCryptGenRandom(nil, raw_data(dst), u32(len(dst)), win32.BCRYPT_USE_SYSTEM_PREFERRED_RNG)) + if ret != os.ERROR_NONE { + switch ret { + case os.ERROR_INVALID_HANDLE: + // The handle to the first parameter is invalid. + // This should not happen here, since we explicitly pass nil to it + panic("crypto: BCryptGenRandom Invalid handle for hAlgorithm") + case os.ERROR_INVALID_PARAMETER: + // One of the parameters was invalid + panic("crypto: BCryptGenRandom Invalid parameter") + case: + // Unknown error + panic(fmt.tprintf("crypto: BCryptGenRandom failed: %d\n", ret)) + } + } +} diff --git a/core/crypto/ripemd/ripemd.odin b/core/crypto/ripemd/ripemd.odin index a9a5d1126..702d29037 100644 --- a/core/crypto/ripemd/ripemd.odin +++ b/core/crypto/ripemd/ripemd.odin @@ -19,16 +19,21 @@ import "../util" High level API */ +DIGEST_SIZE_128 :: 16 +DIGEST_SIZE_160 :: 20 +DIGEST_SIZE_256 :: 32 +DIGEST_SIZE_320 :: 40 + // hash_string_128 will hash the given input and return the // computed hash -hash_string_128 :: proc(data: string) -> [16]byte { +hash_string_128 :: proc(data: string) -> [DIGEST_SIZE_128]byte { return hash_bytes_128(transmute([]byte)(data)) } // hash_bytes_128 will hash the given input and return the // computed hash -hash_bytes_128 :: proc(data: []byte) -> [16]byte { - hash: [16]byte +hash_bytes_128 :: proc(data: []byte) -> [DIGEST_SIZE_128]byte { + hash: [DIGEST_SIZE_128]byte ctx: Ripemd128_Context init(&ctx) update(&ctx, data) @@ -36,10 +41,28 @@ hash_bytes_128 :: proc(data: []byte) -> [16]byte { return hash } +// hash_string_to_buffer_128 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_128 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_128(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_128 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_128 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_128, "Size of destination buffer is smaller than the digest size") + ctx: Ripemd128_Context + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_128 will read the stream in chunks and compute a // hash from its contents -hash_stream_128 :: proc(s: io.Stream) -> ([16]byte, bool) { - hash: [16]byte +hash_stream_128 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) { + hash: [DIGEST_SIZE_128]byte ctx: Ripemd128_Context init(&ctx) buf := make([]byte, 512) @@ -57,7 +80,7 @@ hash_stream_128 :: proc(s: io.Stream) -> ([16]byte, bool) { // hash_file_128 will read the file provided by the given handle // and compute a hash -hash_file_128 :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) { +hash_file_128 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_128]byte, bool) { if !load_at_once { return hash_stream_128(os.stream_from_handle(hd)) } else { @@ -65,7 +88,7 @@ hash_file_128 :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) return hash_bytes_128(buf[:]), ok } } - return [16]byte{}, false + return [DIGEST_SIZE_128]byte{}, false } hash_128 :: proc { @@ -73,18 +96,20 @@ hash_128 :: proc { hash_file_128, hash_bytes_128, hash_string_128, + hash_bytes_to_buffer_128, + hash_string_to_buffer_128, } // hash_string_160 will hash the given input and return the // computed hash -hash_string_160 :: proc(data: string) -> [20]byte { +hash_string_160 :: proc(data: string) -> [DIGEST_SIZE_160]byte { return hash_bytes_160(transmute([]byte)(data)) } // hash_bytes_160 will hash the given input and return the // computed hash -hash_bytes_160 :: proc(data: []byte) -> [20]byte { - hash: [20]byte +hash_bytes_160 :: proc(data: []byte) -> [DIGEST_SIZE_160]byte { + hash: [DIGEST_SIZE_160]byte ctx: Ripemd160_Context init(&ctx) update(&ctx, data) @@ -92,10 +117,28 @@ hash_bytes_160 :: proc(data: []byte) -> [20]byte { return hash } +// hash_string_to_buffer_160 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_160 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_160(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_160 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_160 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_160, "Size of destination buffer is smaller than the digest size") + ctx: Ripemd160_Context + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_160 will read the stream in chunks and compute a // hash from its contents -hash_stream_160 :: proc(s: io.Stream) -> ([20]byte, bool) { - hash: [20]byte +hash_stream_160 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) { + hash: [DIGEST_SIZE_160]byte ctx: Ripemd160_Context init(&ctx) buf := make([]byte, 512) @@ -113,7 +156,7 @@ hash_stream_160 :: proc(s: io.Stream) -> ([20]byte, bool) { // hash_file_160 will read the file provided by the given handle // and compute a hash -hash_file_160 :: proc(hd: os.Handle, load_at_once := false) -> ([20]byte, bool) { +hash_file_160 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_160]byte, bool) { if !load_at_once { return hash_stream_160(os.stream_from_handle(hd)) } else { @@ -121,7 +164,7 @@ hash_file_160 :: proc(hd: os.Handle, load_at_once := false) -> ([20]byte, bool) return hash_bytes_160(buf[:]), ok } } - return [20]byte{}, false + return [DIGEST_SIZE_160]byte{}, false } hash_160 :: proc { @@ -129,18 +172,20 @@ hash_160 :: proc { hash_file_160, hash_bytes_160, hash_string_160, + hash_bytes_to_buffer_160, + hash_string_to_buffer_160, } // hash_string_256 will hash the given input and return the // computed hash -hash_string_256 :: proc(data: string) -> [32]byte { +hash_string_256 :: proc(data: string) -> [DIGEST_SIZE_256]byte { return hash_bytes_256(transmute([]byte)(data)) } // hash_bytes_256 will hash the given input and return the // computed hash -hash_bytes_256 :: proc(data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes_256 :: proc(data: []byte) -> [DIGEST_SIZE_256]byte { + hash: [DIGEST_SIZE_256]byte ctx: Ripemd256_Context init(&ctx) update(&ctx, data) @@ -148,10 +193,28 @@ hash_bytes_256 :: proc(data: []byte) -> [32]byte { return hash } +// hash_string_to_buffer_256 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_256 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_256(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_256 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_256 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_256, "Size of destination buffer is smaller than the digest size") + ctx: Ripemd256_Context + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_256 will read the stream in chunks and compute a // hash from its contents -hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { + hash: [DIGEST_SIZE_256]byte ctx: Ripemd256_Context init(&ctx) buf := make([]byte, 512) @@ -169,7 +232,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file_256 will read the file provided by the given handle // and compute a hash -hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_256]byte, bool) { if !load_at_once { return hash_stream_256(os.stream_from_handle(hd)) } else { @@ -177,7 +240,7 @@ hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) return hash_bytes_256(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE_256]byte{}, false } hash_256 :: proc { @@ -185,18 +248,20 @@ hash_256 :: proc { hash_file_256, hash_bytes_256, hash_string_256, + hash_bytes_to_buffer_256, + hash_string_to_buffer_256, } // hash_string_320 will hash the given input and return the // computed hash -hash_string_320 :: proc(data: string) -> [40]byte { +hash_string_320 :: proc(data: string) -> [DIGEST_SIZE_320]byte { return hash_bytes_320(transmute([]byte)(data)) } // hash_bytes_320 will hash the given input and return the // computed hash -hash_bytes_320 :: proc(data: []byte) -> [40]byte { - hash: [40]byte +hash_bytes_320 :: proc(data: []byte) -> [DIGEST_SIZE_320]byte { + hash: [DIGEST_SIZE_320]byte ctx: Ripemd320_Context init(&ctx) update(&ctx, data) @@ -204,10 +269,28 @@ hash_bytes_320 :: proc(data: []byte) -> [40]byte { return hash } +// hash_string_to_buffer_320 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_320 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_320(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_320 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_320 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_320, "Size of destination buffer is smaller than the digest size") + ctx: Ripemd320_Context + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_320 will read the stream in chunks and compute a // hash from its contents -hash_stream_320 :: proc(s: io.Stream) -> ([40]byte, bool) { - hash: [40]byte +hash_stream_320 :: proc(s: io.Stream) -> ([DIGEST_SIZE_320]byte, bool) { + hash: [DIGEST_SIZE_320]byte ctx: Ripemd320_Context init(&ctx) buf := make([]byte, 512) @@ -225,7 +308,7 @@ hash_stream_320 :: proc(s: io.Stream) -> ([40]byte, bool) { // hash_file_320 will read the file provided by the given handle // and compute a hash -hash_file_320 :: proc(hd: os.Handle, load_at_once := false) -> ([40]byte, bool) { +hash_file_320 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_320]byte, bool) { if !load_at_once { return hash_stream_320(os.stream_from_handle(hd)) } else { @@ -233,7 +316,7 @@ hash_file_320 :: proc(hd: os.Handle, load_at_once := false) -> ([40]byte, bool) return hash_bytes_320(buf[:]), ok } } - return [40]byte{}, false + return [DIGEST_SIZE_320]byte{}, false } hash_320 :: proc { @@ -241,6 +324,8 @@ hash_320 :: proc { hash_file_320, hash_bytes_320, hash_string_320, + hash_bytes_to_buffer_320, + hash_string_to_buffer_320, } /* diff --git a/core/crypto/sha1/sha1.odin b/core/crypto/sha1/sha1.odin index 736b207a3..b0dbd7dc8 100644 --- a/core/crypto/sha1/sha1.odin +++ b/core/crypto/sha1/sha1.odin @@ -19,16 +19,19 @@ import "../util" /* High level API */ + +DIGEST_SIZE :: 20 + // hash_string will hash the given input and return the // computed hash -hash_string :: proc(data: string) -> [20]byte { +hash_string :: proc(data: string) -> [DIGEST_SIZE]byte { return hash_bytes(transmute([]byte)(data)) } // hash_bytes will hash the given input and return the // computed hash -hash_bytes :: proc(data: []byte) -> [20]byte { - hash: [20]byte +hash_bytes :: proc(data: []byte) -> [DIGEST_SIZE]byte { + hash: [DIGEST_SIZE]byte ctx: Sha1_Context init(&ctx) update(&ctx, data) @@ -36,10 +39,28 @@ hash_bytes :: proc(data: []byte) -> [20]byte { return hash } +// hash_string_to_buffer will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") + ctx: Sha1_Context + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream will read the stream in chunks and compute a // hash from its contents -hash_stream :: proc(s: io.Stream) -> ([20]byte, bool) { - hash: [20]byte +hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { + hash: [DIGEST_SIZE]byte ctx: Sha1_Context init(&ctx) buf := make([]byte, 512) @@ -57,7 +78,7 @@ hash_stream :: proc(s: io.Stream) -> ([20]byte, bool) { // hash_file will read the file provided by the given handle // and compute a hash -hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([20]byte, bool) { +hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE]byte, bool) { if !load_at_once { return hash_stream(os.stream_from_handle(hd)) } else { @@ -65,7 +86,7 @@ hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([20]byte, bool) { return hash_bytes(buf[:]), ok } } - return [20]byte{}, false + return [DIGEST_SIZE]byte{}, false } hash :: proc { @@ -73,6 +94,8 @@ hash :: proc { hash_file, hash_bytes, hash_string, + hash_bytes_to_buffer, + hash_string_to_buffer, } /* diff --git a/core/crypto/sha2/sha2.odin b/core/crypto/sha2/sha2.odin index 8b7ccf38a..7c7b2da81 100644 --- a/core/crypto/sha2/sha2.odin +++ b/core/crypto/sha2/sha2.odin @@ -21,16 +21,21 @@ import "../util" High level API */ +DIGEST_SIZE_224 :: 28 +DIGEST_SIZE_256 :: 32 +DIGEST_SIZE_384 :: 48 +DIGEST_SIZE_512 :: 64 + // hash_string_224 will hash the given input and return the // computed hash -hash_string_224 :: proc(data: string) -> [28]byte { +hash_string_224 :: proc(data: string) -> [DIGEST_SIZE_224]byte { return hash_bytes_224(transmute([]byte)(data)) } // hash_bytes_224 will hash the given input and return the // computed hash -hash_bytes_224 :: proc(data: []byte) -> [28]byte { - hash: [28]byte +hash_bytes_224 :: proc(data: []byte) -> [DIGEST_SIZE_224]byte { + hash: [DIGEST_SIZE_224]byte ctx: Sha256_Context ctx.is224 = true init(&ctx) @@ -39,10 +44,29 @@ hash_bytes_224 :: proc(data: []byte) -> [28]byte { return hash } +// hash_string_to_buffer_224 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_224 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_224(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_224 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_224 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_224, "Size of destination buffer is smaller than the digest size") + ctx: Sha256_Context + ctx.is224 = true + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_224 will read the stream in chunks and compute a // hash from its contents -hash_stream_224 :: proc(s: io.Stream) -> ([28]byte, bool) { - hash: [28]byte +hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { + hash: [DIGEST_SIZE_224]byte ctx: Sha512_Context ctx.is384 = false init(&ctx) @@ -61,7 +85,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([28]byte, bool) { // hash_file_224 will read the file provided by the given handle // and compute a hash -hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool) { +hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_224]byte, bool) { if !load_at_once { return hash_stream_224(os.stream_from_handle(hd)) } else { @@ -69,7 +93,7 @@ hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool) return hash_bytes_224(buf[:]), ok } } - return [28]byte{}, false + return [DIGEST_SIZE_224]byte{}, false } hash_224 :: proc { @@ -77,18 +101,20 @@ hash_224 :: proc { hash_file_224, hash_bytes_224, hash_string_224, + hash_bytes_to_buffer_224, + hash_string_to_buffer_224, } // hash_string_256 will hash the given input and return the // computed hash -hash_string_256 :: proc(data: string) -> [32]byte { +hash_string_256 :: proc(data: string) -> [DIGEST_SIZE_256]byte { return hash_bytes_256(transmute([]byte)(data)) } // hash_bytes_256 will hash the given input and return the // computed hash -hash_bytes_256 :: proc(data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes_256 :: proc(data: []byte) -> [DIGEST_SIZE_256]byte { + hash: [DIGEST_SIZE_256]byte ctx: Sha256_Context ctx.is224 = false init(&ctx) @@ -97,10 +123,29 @@ hash_bytes_256 :: proc(data: []byte) -> [32]byte { return hash } +// hash_string_to_buffer_256 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_256 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_256(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_256 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_256 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_256, "Size of destination buffer is smaller than the digest size") + ctx: Sha256_Context + ctx.is224 = false + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_256 will read the stream in chunks and compute a // hash from its contents -hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { + hash: [DIGEST_SIZE_256]byte ctx: Sha512_Context ctx.is384 = false init(&ctx) @@ -119,7 +164,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file_256 will read the file provided by the given handle // and compute a hash -hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_256]byte, bool) { if !load_at_once { return hash_stream_256(os.stream_from_handle(hd)) } else { @@ -127,7 +172,7 @@ hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) return hash_bytes_256(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE_256]byte{}, false } hash_256 :: proc { @@ -135,18 +180,20 @@ hash_256 :: proc { hash_file_256, hash_bytes_256, hash_string_256, + hash_bytes_to_buffer_256, + hash_string_to_buffer_256, } // hash_string_384 will hash the given input and return the // computed hash -hash_string_384 :: proc(data: string) -> [48]byte { +hash_string_384 :: proc(data: string) -> [DIGEST_SIZE_384]byte { return hash_bytes_384(transmute([]byte)(data)) } // hash_bytes_384 will hash the given input and return the // computed hash -hash_bytes_384 :: proc(data: []byte) -> [48]byte { - hash: [48]byte +hash_bytes_384 :: proc(data: []byte) -> [DIGEST_SIZE_384]byte { + hash: [DIGEST_SIZE_384]byte ctx: Sha512_Context ctx.is384 = true init(&ctx) @@ -155,10 +202,29 @@ hash_bytes_384 :: proc(data: []byte) -> [48]byte { return hash } +// hash_string_to_buffer_384 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_384 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_384(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_384 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_384 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_384, "Size of destination buffer is smaller than the digest size") + ctx: Sha512_Context + ctx.is384 = true + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_384 will read the stream in chunks and compute a // hash from its contents -hash_stream_384 :: proc(s: io.Stream) -> ([48]byte, bool) { - hash: [48]byte +hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) { + hash: [DIGEST_SIZE_384]byte ctx: Sha512_Context ctx.is384 = true init(&ctx) @@ -177,7 +243,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([48]byte, bool) { // hash_file_384 will read the file provided by the given handle // and compute a hash -hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([48]byte, bool) { +hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_384]byte, bool) { if !load_at_once { return hash_stream_384(os.stream_from_handle(hd)) } else { @@ -185,7 +251,7 @@ hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([48]byte, bool) return hash_bytes_384(buf[:]), ok } } - return [48]byte{}, false + return [DIGEST_SIZE_384]byte{}, false } hash_384 :: proc { @@ -193,18 +259,20 @@ hash_384 :: proc { hash_file_384, hash_bytes_384, hash_string_384, + hash_bytes_to_buffer_384, + hash_string_to_buffer_384, } // hash_string_512 will hash the given input and return the // computed hash -hash_string_512 :: proc(data: string) -> [64]byte { +hash_string_512 :: proc(data: string) -> [DIGEST_SIZE_512]byte { return hash_bytes_512(transmute([]byte)(data)) } // hash_bytes_512 will hash the given input and return the // computed hash -hash_bytes_512 :: proc(data: []byte) -> [64]byte { - hash: [64]byte +hash_bytes_512 :: proc(data: []byte) -> [DIGEST_SIZE_512]byte { + hash: [DIGEST_SIZE_512]byte ctx: Sha512_Context ctx.is384 = false init(&ctx) @@ -213,10 +281,29 @@ hash_bytes_512 :: proc(data: []byte) -> [64]byte { return hash } +// hash_string_to_buffer_512 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_512 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_512(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_512 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_512 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_512, "Size of destination buffer is smaller than the digest size") + ctx: Sha512_Context + ctx.is384 = false + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream_512 will read the stream in chunks and compute a // hash from its contents -hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { - hash: [64]byte +hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { + hash: [DIGEST_SIZE_512]byte ctx: Sha512_Context ctx.is384 = false init(&ctx) @@ -235,7 +322,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { // hash_file_512 will read the file provided by the given handle // and compute a hash -hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) { +hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_512]byte, bool) { if !load_at_once { return hash_stream_512(os.stream_from_handle(hd)) } else { @@ -243,7 +330,7 @@ hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) return hash_bytes_512(buf[:]), ok } } - return [64]byte{}, false + return [DIGEST_SIZE_512]byte{}, false } hash_512 :: proc { @@ -251,6 +338,8 @@ hash_512 :: proc { hash_file_512, hash_bytes_512, hash_string_512, + hash_bytes_to_buffer_512, + hash_string_to_buffer_512, } /* diff --git a/core/crypto/sha3/sha3.odin b/core/crypto/sha3/sha3.odin index 1becf7640..1202f8b23 100644 --- a/core/crypto/sha3/sha3.odin +++ b/core/crypto/sha3/sha3.odin @@ -20,30 +20,54 @@ import "../_sha3" High level API */ +DIGEST_SIZE_224 :: 28 +DIGEST_SIZE_256 :: 32 +DIGEST_SIZE_384 :: 48 +DIGEST_SIZE_512 :: 64 + // hash_string_224 will hash the given input and return the // computed hash -hash_string_224 :: proc(data: string) -> [28]byte { +hash_string_224 :: proc(data: string) -> [DIGEST_SIZE_224]byte { return hash_bytes_224(transmute([]byte)(data)) } // hash_bytes_224 will hash the given input and return the // computed hash -hash_bytes_224 :: proc(data: []byte) -> [28]byte { - hash: [28]byte +hash_bytes_224 :: proc(data: []byte) -> [DIGEST_SIZE_224]byte { + hash: [DIGEST_SIZE_224]byte ctx: _sha3.Sha3_Context - ctx.mdlen = 28 + ctx.mdlen = DIGEST_SIZE_224 _sha3.init(&ctx) _sha3.update(&ctx, data) _sha3.final(&ctx, hash[:]) return hash } +// hash_string_to_buffer_224 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_224 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_224(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_224 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_224 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_224, "Size of destination buffer is smaller than the digest size") + ctx: _sha3.Sha3_Context + ctx.mdlen = DIGEST_SIZE_224 + _sha3.init(&ctx) + _sha3.update(&ctx, data) + _sha3.final(&ctx, hash) +} + // hash_stream_224 will read the stream in chunks and compute a // hash from its contents -hash_stream_224 :: proc(s: io.Stream) -> ([28]byte, bool) { - hash: [28]byte +hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { + hash: [DIGEST_SIZE_224]byte ctx: _sha3.Sha3_Context - ctx.mdlen = 28 + ctx.mdlen = DIGEST_SIZE_224 _sha3.init(&ctx) buf := make([]byte, 512) defer delete(buf) @@ -60,7 +84,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([28]byte, bool) { // hash_file_224 will read the file provided by the given handle // and compute a hash -hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool) { +hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_224]byte, bool) { if !load_at_once { return hash_stream_224(os.stream_from_handle(hd)) } else { @@ -68,7 +92,7 @@ hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool) return hash_bytes_224(buf[:]), ok } } - return [28]byte{}, false + return [DIGEST_SIZE_224]byte{}, false } hash_224 :: proc { @@ -76,32 +100,53 @@ hash_224 :: proc { hash_file_224, hash_bytes_224, hash_string_224, + hash_bytes_to_buffer_224, + hash_string_to_buffer_224, } // hash_string_256 will hash the given input and return the // computed hash -hash_string_256 :: proc(data: string) -> [32]byte { +hash_string_256 :: proc(data: string) -> [DIGEST_SIZE_256]byte { return hash_bytes_256(transmute([]byte)(data)) } // hash_bytes_256 will hash the given input and return the // computed hash -hash_bytes_256 :: proc(data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes_256 :: proc(data: []byte) -> [DIGEST_SIZE_256]byte { + hash: [DIGEST_SIZE_256]byte ctx: _sha3.Sha3_Context - ctx.mdlen = 32 + ctx.mdlen = DIGEST_SIZE_256 _sha3.init(&ctx) _sha3.update(&ctx, data) _sha3.final(&ctx, hash[:]) return hash } +// hash_string_to_buffer_256 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_256 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_256(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_256 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_256 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_256, "Size of destination buffer is smaller than the digest size") + ctx: _sha3.Sha3_Context + ctx.mdlen = DIGEST_SIZE_256 + _sha3.init(&ctx) + _sha3.update(&ctx, data) + _sha3.final(&ctx, hash) +} + // hash_stream_256 will read the stream in chunks and compute a // hash from its contents -hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { + hash: [DIGEST_SIZE_256]byte ctx: _sha3.Sha3_Context - ctx.mdlen = 32 + ctx.mdlen = DIGEST_SIZE_256 _sha3.init(&ctx) buf := make([]byte, 512) defer delete(buf) @@ -118,7 +163,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file_256 will read the file provided by the given handle // and compute a hash -hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_256]byte, bool) { if !load_at_once { return hash_stream_256(os.stream_from_handle(hd)) } else { @@ -126,7 +171,7 @@ hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) return hash_bytes_256(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE_256]byte{}, false } hash_256 :: proc { @@ -134,32 +179,53 @@ hash_256 :: proc { hash_file_256, hash_bytes_256, hash_string_256, + hash_bytes_to_buffer_256, + hash_string_to_buffer_256, } // hash_string_384 will hash the given input and return the // computed hash -hash_string_384 :: proc(data: string) -> [48]byte { +hash_string_384 :: proc(data: string) -> [DIGEST_SIZE_384]byte { return hash_bytes_384(transmute([]byte)(data)) } // hash_bytes_384 will hash the given input and return the // computed hash -hash_bytes_384 :: proc(data: []byte) -> [48]byte { - hash: [48]byte +hash_bytes_384 :: proc(data: []byte) -> [DIGEST_SIZE_384]byte { + hash: [DIGEST_SIZE_384]byte ctx: _sha3.Sha3_Context - ctx.mdlen = 48 + ctx.mdlen = DIGEST_SIZE_384 _sha3.init(&ctx) _sha3.update(&ctx, data) _sha3.final(&ctx, hash[:]) return hash } +// hash_string_to_buffer_384 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_384 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_384(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_384 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_384 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_384, "Size of destination buffer is smaller than the digest size") + ctx: _sha3.Sha3_Context + ctx.mdlen = DIGEST_SIZE_384 + _sha3.init(&ctx) + _sha3.update(&ctx, data) + _sha3.final(&ctx, hash) +} + // hash_stream_384 will read the stream in chunks and compute a // hash from its contents -hash_stream_384 :: proc(s: io.Stream) -> ([48]byte, bool) { - hash: [48]byte +hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) { + hash: [DIGEST_SIZE_384]byte ctx: _sha3.Sha3_Context - ctx.mdlen = 48 + ctx.mdlen = DIGEST_SIZE_384 _sha3.init(&ctx) buf := make([]byte, 512) defer delete(buf) @@ -176,7 +242,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([48]byte, bool) { // hash_file_384 will read the file provided by the given handle // and compute a hash -hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([48]byte, bool) { +hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_384]byte, bool) { if !load_at_once { return hash_stream_384(os.stream_from_handle(hd)) } else { @@ -184,7 +250,7 @@ hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([48]byte, bool) return hash_bytes_384(buf[:]), ok } } - return [48]byte{}, false + return [DIGEST_SIZE_384]byte{}, false } hash_384 :: proc { @@ -192,32 +258,53 @@ hash_384 :: proc { hash_file_384, hash_bytes_384, hash_string_384, + hash_bytes_to_buffer_384, + hash_string_to_buffer_384, } // hash_string_512 will hash the given input and return the // computed hash -hash_string_512 :: proc(data: string) -> [64]byte { +hash_string_512 :: proc(data: string) -> [DIGEST_SIZE_512]byte { return hash_bytes_512(transmute([]byte)(data)) } // hash_bytes_512 will hash the given input and return the // computed hash -hash_bytes_512 :: proc(data: []byte) -> [64]byte { - hash: [64]byte +hash_bytes_512 :: proc(data: []byte) -> [DIGEST_SIZE_512]byte { + hash: [DIGEST_SIZE_512]byte ctx: _sha3.Sha3_Context - ctx.mdlen = 64 + ctx.mdlen = DIGEST_SIZE_512 _sha3.init(&ctx) _sha3.update(&ctx, data) _sha3.final(&ctx, hash[:]) return hash } +// hash_string_to_buffer_512 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_512 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_512(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_512 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_512 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_512, "Size of destination buffer is smaller than the digest size") + ctx: _sha3.Sha3_Context + ctx.mdlen = DIGEST_SIZE_512 + _sha3.init(&ctx) + _sha3.update(&ctx, data) + _sha3.final(&ctx, hash) +} + // hash_stream_512 will read the stream in chunks and compute a // hash from its contents -hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { - hash: [64]byte +hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { + hash: [DIGEST_SIZE_512]byte ctx: _sha3.Sha3_Context - ctx.mdlen = 64 + ctx.mdlen = DIGEST_SIZE_512 _sha3.init(&ctx) buf := make([]byte, 512) defer delete(buf) @@ -234,7 +321,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { // hash_file_512 will read the file provided by the given handle // and compute a hash -hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) { +hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_512]byte, bool) { if !load_at_once { return hash_stream_512(os.stream_from_handle(hd)) } else { @@ -242,7 +329,7 @@ hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) return hash_bytes_512(buf[:]), ok } } - return [64]byte{}, false + return [DIGEST_SIZE_512]byte{}, false } hash_512 :: proc { @@ -250,6 +337,8 @@ hash_512 :: proc { hash_file_512, hash_bytes_512, hash_string_512, + hash_bytes_to_buffer_512, + hash_string_to_buffer_512, } /* diff --git a/core/crypto/shake/shake.odin b/core/crypto/shake/shake.odin index ff477b1a9..525dcfbd3 100644 --- a/core/crypto/shake/shake.odin +++ b/core/crypto/shake/shake.odin @@ -20,18 +20,21 @@ import "../_sha3" High level API */ +DIGEST_SIZE_128 :: 16 +DIGEST_SIZE_256 :: 32 + // hash_string_128 will hash the given input and return the // computed hash -hash_string_128 :: proc(data: string) -> [16]byte { +hash_string_128 :: proc(data: string) -> [DIGEST_SIZE_128]byte { return hash_bytes_128(transmute([]byte)(data)) } // hash_bytes_128 will hash the given input and return the // computed hash -hash_bytes_128 :: proc(data: []byte) -> [16]byte { - hash: [16]byte +hash_bytes_128 :: proc(data: []byte) -> [DIGEST_SIZE_128]byte { + hash: [DIGEST_SIZE_128]byte ctx: _sha3.Sha3_Context - ctx.mdlen = 16 + ctx.mdlen = DIGEST_SIZE_128 _sha3.init(&ctx) _sha3.update(&ctx, data) _sha3.shake_xof(&ctx) @@ -39,12 +42,32 @@ hash_bytes_128 :: proc(data: []byte) -> [16]byte { return hash } +// hash_string_to_buffer_128 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_128 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_128(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_128 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_128 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_128, "Size of destination buffer is smaller than the digest size") + ctx: _sha3.Sha3_Context + ctx.mdlen = DIGEST_SIZE_128 + _sha3.init(&ctx) + _sha3.update(&ctx, data) + _sha3.shake_xof(&ctx) + _sha3.shake_out(&ctx, hash) +} + // hash_stream_128 will read the stream in chunks and compute a // hash from its contents -hash_stream_128 :: proc(s: io.Stream) -> ([16]byte, bool) { - hash: [16]byte +hash_stream_128 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) { + hash: [DIGEST_SIZE_128]byte ctx: _sha3.Sha3_Context - ctx.mdlen = 16 + ctx.mdlen = DIGEST_SIZE_128 _sha3.init(&ctx) buf := make([]byte, 512) defer delete(buf) @@ -62,7 +85,7 @@ hash_stream_128 :: proc(s: io.Stream) -> ([16]byte, bool) { // hash_file_128 will read the file provided by the given handle // and compute a hash -hash_file_128 :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) { +hash_file_128 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_128]byte, bool) { if !load_at_once { return hash_stream_128(os.stream_from_handle(hd)) } else { @@ -70,7 +93,7 @@ hash_file_128 :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) return hash_bytes_128(buf[:]), ok } } - return [16]byte{}, false + return [DIGEST_SIZE_128]byte{}, false } hash_128 :: proc { @@ -78,20 +101,22 @@ hash_128 :: proc { hash_file_128, hash_bytes_128, hash_string_128, + hash_bytes_to_buffer_128, + hash_string_to_buffer_128, } // hash_string_256 will hash the given input and return the // computed hash -hash_string_256 :: proc(data: string) -> [32]byte { +hash_string_256 :: proc(data: string) -> [DIGEST_SIZE_256]byte { return hash_bytes_256(transmute([]byte)(data)) } // hash_bytes_256 will hash the given input and return the // computed hash -hash_bytes_256 :: proc(data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes_256 :: proc(data: []byte) -> [DIGEST_SIZE_256]byte { + hash: [DIGEST_SIZE_256]byte ctx: _sha3.Sha3_Context - ctx.mdlen = 32 + ctx.mdlen = DIGEST_SIZE_256 _sha3.init(&ctx) _sha3.update(&ctx, data) _sha3.shake_xof(&ctx) @@ -99,12 +124,32 @@ hash_bytes_256 :: proc(data: []byte) -> [32]byte { return hash } +// hash_string_to_buffer_256 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_256 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_256(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_256 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_256 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_256, "Size of destination buffer is smaller than the digest size") + ctx: _sha3.Sha3_Context + ctx.mdlen = DIGEST_SIZE_256 + _sha3.init(&ctx) + _sha3.update(&ctx, data) + _sha3.shake_xof(&ctx) + _sha3.shake_out(&ctx, hash) +} + // hash_stream_256 will read the stream in chunks and compute a // hash from its contents -hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { + hash: [DIGEST_SIZE_256]byte ctx: _sha3.Sha3_Context - ctx.mdlen = 32 + ctx.mdlen = DIGEST_SIZE_256 _sha3.init(&ctx) buf := make([]byte, 512) defer delete(buf) @@ -122,7 +167,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file_256 will read the file provided by the given handle // and compute a hash -hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_256]byte, bool) { if !load_at_once { return hash_stream_256(os.stream_from_handle(hd)) } else { @@ -130,7 +175,7 @@ hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) return hash_bytes_256(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE_256]byte{}, false } hash_256 :: proc { @@ -138,13 +183,15 @@ hash_256 :: proc { hash_file_256, hash_bytes_256, hash_string_256, + hash_bytes_to_buffer_256, + hash_string_to_buffer_256, } /* Low level API */ -Sha3_Context :: _sha3.Sha3_Context +Shake_Context :: _sha3.Sha3_Context init :: proc(ctx: ^_sha3.Sha3_Context) { _sha3.init(ctx) diff --git a/core/crypto/siphash/siphash.odin b/core/crypto/siphash/siphash.odin new file mode 100644 index 000000000..a6c75f315 --- /dev/null +++ b/core/crypto/siphash/siphash.odin @@ -0,0 +1,335 @@ +package siphash + +/* + Copyright 2022 zhibog + Made available under the BSD-3 license. + + List of contributors: + zhibog: Initial implementation. + + Implementation of the SipHash hashing algorithm, as defined at and + + Use the specific procedures for a certain setup. The generic procdedures will default to Siphash 2-4 +*/ + +import "core:crypto" +import "core:crypto/util" + +/* + High level API +*/ + +KEY_SIZE :: 16 +DIGEST_SIZE :: 8 + +// sum_string_1_3 will hash the given message with the key and return +// the computed hash as a u64 +sum_string_1_3 :: proc(msg, key: string) -> u64 { + return sum_bytes_1_3(transmute([]byte)(msg), transmute([]byte)(key)) +} + +// sum_bytes_1_3 will hash the given message with the key and return +// the computed hash as a u64 +sum_bytes_1_3 :: proc (msg, key: []byte) -> u64 { + ctx: Context + hash: u64 + init(&ctx, key, 1, 3) + update(&ctx, msg) + final(&ctx, &hash) + return hash +} + +// sum_string_to_buffer_1_3 will hash the given message with the key and write +// the computed hash into the provided destination buffer +sum_string_to_buffer_1_3 :: proc(msg, key: string, dst: []byte) { + sum_bytes_to_buffer_1_3(transmute([]byte)(msg), transmute([]byte)(key), dst) +} + +// sum_bytes_to_buffer_1_3 will hash the given message with the key and write +// the computed hash into the provided destination buffer +sum_bytes_to_buffer_1_3 :: proc(msg, key, dst: []byte) { + assert(len(dst) >= DIGEST_SIZE, "crypto/siphash: Destination buffer needs to be at least of size 8") + hash := sum_bytes_1_3(msg, key) + _collect_output(dst[:], hash) +} + +sum_1_3 :: proc { + sum_string_1_3, + sum_bytes_1_3, + sum_string_to_buffer_1_3, + sum_bytes_to_buffer_1_3, +} + +// verify_u64_1_3 will check if the supplied tag matches with the output you +// will get from the provided message and key +verify_u64_1_3 :: proc (tag: u64 msg, key: []byte) -> bool { + return sum_bytes_1_3(msg, key) == tag +} + +// verify_bytes will check if the supplied tag matches with the output you +// will get from the provided message and key +verify_bytes_1_3 :: proc (tag, msg, key: []byte) -> bool { + derived_tag: [8]byte + sum_bytes_to_buffer_1_3(msg, key, derived_tag[:]) + return crypto.compare_constant_time(derived_tag[:], tag) == 1 +} + +verify_1_3 :: proc { + verify_bytes_1_3, + verify_u64_1_3, +} + +// sum_string_2_4 will hash the given message with the key and return +// the computed hash as a u64 +sum_string_2_4 :: proc(msg, key: string) -> u64 { + return sum_bytes_2_4(transmute([]byte)(msg), transmute([]byte)(key)) +} + +// sum_bytes_2_4 will hash the given message with the key and return +// the computed hash as a u64 +sum_bytes_2_4 :: proc (msg, key: []byte) -> u64 { + ctx: Context + hash: u64 + init(&ctx, key, 2, 4) + update(&ctx, msg) + final(&ctx, &hash) + return hash +} + +// sum_string_to_buffer_2_4 will hash the given message with the key and write +// the computed hash into the provided destination buffer +sum_string_to_buffer_2_4 :: proc(msg, key: string, dst: []byte) { + sum_bytes_to_buffer_2_4(transmute([]byte)(msg), transmute([]byte)(key), dst) +} + +// sum_bytes_to_buffer_2_4 will hash the given message with the key and write +// the computed hash into the provided destination buffer +sum_bytes_to_buffer_2_4 :: proc(msg, key, dst: []byte) { + assert(len(dst) >= DIGEST_SIZE, "crypto/siphash: Destination buffer needs to be at least of size 8") + hash := sum_bytes_2_4(msg, key) + _collect_output(dst[:], hash) +} + +sum_2_4 :: proc { + sum_string_2_4, + sum_bytes_2_4, + sum_string_to_buffer_2_4, + sum_bytes_to_buffer_2_4, +} + +sum_string :: sum_string_2_4 +sum_bytes :: sum_bytes_2_4 +sum_string_to_buffer :: sum_string_to_buffer_2_4 +sum_bytes_to_buffer :: sum_bytes_to_buffer_2_4 +sum :: proc { + sum_string, + sum_bytes, + sum_string_to_buffer, + sum_bytes_to_buffer, +} + +// verify_u64_2_4 will check if the supplied tag matches with the output you +// will get from the provided message and key +verify_u64_2_4 :: proc (tag: u64 msg, key: []byte) -> bool { + return sum_bytes_2_4(msg, key) == tag +} + +// verify_bytes will check if the supplied tag matches with the output you +// will get from the provided message and key +verify_bytes_2_4 :: proc (tag, msg, key: []byte) -> bool { + derived_tag: [8]byte + sum_bytes_to_buffer_2_4(msg, key, derived_tag[:]) + return crypto.compare_constant_time(derived_tag[:], tag) == 1 +} + +verify_2_4 :: proc { + verify_bytes_2_4, + verify_u64_2_4, +} + +verify_bytes :: verify_bytes_2_4 +verify_u64 :: verify_u64_2_4 +verify :: proc { + verify_bytes, + verify_u64, +} + +// sum_string_4_8 will hash the given message with the key and return +// the computed hash as a u64 +sum_string_4_8 :: proc(msg, key: string) -> u64 { + return sum_bytes_4_8(transmute([]byte)(msg), transmute([]byte)(key)) +} + +// sum_bytes_4_8 will hash the given message with the key and return +// the computed hash as a u64 +sum_bytes_4_8 :: proc (msg, key: []byte) -> u64 { + ctx: Context + hash: u64 + init(&ctx, key, 4, 8) + update(&ctx, msg) + final(&ctx, &hash) + return hash +} + +// sum_string_to_buffer_4_8 will hash the given message with the key and write +// the computed hash into the provided destination buffer +sum_string_to_buffer_4_8 :: proc(msg, key: string, dst: []byte) { + sum_bytes_to_buffer_4_8(transmute([]byte)(msg), transmute([]byte)(key), dst) +} + +// sum_bytes_to_buffer_4_8 will hash the given message with the key and write +// the computed hash into the provided destination buffer +sum_bytes_to_buffer_4_8 :: proc(msg, key, dst: []byte) { + assert(len(dst) >= DIGEST_SIZE, "crypto/siphash: Destination buffer needs to be at least of size 8") + hash := sum_bytes_4_8(msg, key) + _collect_output(dst[:], hash) +} + +sum_4_8 :: proc { + sum_string_4_8, + sum_bytes_4_8, + sum_string_to_buffer_4_8, + sum_bytes_to_buffer_4_8, +} + +// verify_u64_4_8 will check if the supplied tag matches with the output you +// will get from the provided message and key +verify_u64_4_8 :: proc (tag: u64 msg, key: []byte) -> bool { + return sum_bytes_4_8(msg, key) == tag +} + +// verify_bytes will check if the supplied tag matches with the output you +// will get from the provided message and key +verify_bytes_4_8 :: proc (tag, msg, key: []byte) -> bool { + derived_tag: [8]byte + sum_bytes_to_buffer_4_8(msg, key, derived_tag[:]) + return crypto.compare_constant_time(derived_tag[:], tag) == 1 +} + +verify_4_8 :: proc { + verify_bytes_4_8, + verify_u64_4_8, +} + +/* + Low level API +*/ + +init :: proc(ctx: ^Context, key: []byte, c_rounds, d_rounds: int) { + assert(len(key) == KEY_SIZE, "crypto/siphash: Invalid key size, want 16") + ctx.c_rounds = c_rounds + ctx.d_rounds = d_rounds + is_valid_setting := (ctx.c_rounds == 1 && ctx.d_rounds == 3) || + (ctx.c_rounds == 2 && ctx.d_rounds == 4) || + (ctx.c_rounds == 4 && ctx.d_rounds == 8) + assert(is_valid_setting, "crypto/siphash: Incorrect rounds set up. Valid pairs are (1,3), (2,4) and (4,8)") + ctx.k0 = util.U64_LE(key[:8]) + ctx.k1 = util.U64_LE(key[8:]) + ctx.v0 = 0x736f6d6570736575 ~ ctx.k0 + ctx.v1 = 0x646f72616e646f6d ~ ctx.k1 + ctx.v2 = 0x6c7967656e657261 ~ ctx.k0 + ctx.v3 = 0x7465646279746573 ~ ctx.k1 + ctx.is_initialized = true +} + +update :: proc(ctx: ^Context, data: []byte) { + assert(ctx.is_initialized, "crypto/siphash: Context is not initalized") + ctx.last_block = len(data) / 8 * 8 + ctx.buf = data + i := 0 + m: u64 + for i < ctx.last_block { + m = u64(ctx.buf[i] & 0xff) + i += 1 + + for r in u64(1)..<8 { + m |= u64(ctx.buf[i] & 0xff) << (r * 8) + i += 1 + } + + ctx.v3 ~= m + for _ in 0..= ctx.last_block; i -= 1 { + m <<= 8 + m |= u64(ctx.buf[i] & 0xff) + } + m |= u64(len(ctx.buf) << 56) + + ctx.v3 ~= m + + for _ in 0.. byte { + return byte(into >> (((~byte_num) & (size_of(u64) - 1)) << 3)) +} + +_collect_output :: #force_inline proc "contextless" (dst: []byte, hash: u64) { + dst[0] = _get_byte(7, hash) + dst[1] = _get_byte(6, hash) + dst[2] = _get_byte(5, hash) + dst[3] = _get_byte(4, hash) + dst[4] = _get_byte(3, hash) + dst[5] = _get_byte(2, hash) + dst[6] = _get_byte(1, hash) + dst[7] = _get_byte(0, hash) +} + +_compress :: #force_inline proc "contextless" (ctx: ^Context) { + ctx.v0 += ctx.v1 + ctx.v1 = util.ROTL64(ctx.v1, 13) + ctx.v1 ~= ctx.v0 + ctx.v0 = util.ROTL64(ctx.v0, 32) + ctx.v2 += ctx.v3 + ctx.v3 = util.ROTL64(ctx.v3, 16) + ctx.v3 ~= ctx.v2 + ctx.v0 += ctx.v3 + ctx.v3 = util.ROTL64(ctx.v3, 21) + ctx.v3 ~= ctx.v0 + ctx.v2 += ctx.v1 + ctx.v1 = util.ROTL64(ctx.v1, 17) + ctx.v1 ~= ctx.v2 + ctx.v2 = util.ROTL64(ctx.v2, 32) +} diff --git a/core/crypto/sm3/sm3.odin b/core/crypto/sm3/sm3.odin index c72bd4f15..74c9f22e2 100644 --- a/core/crypto/sm3/sm3.odin +++ b/core/crypto/sm3/sm3.odin @@ -15,16 +15,22 @@ import "core:io" import "../util" +/* + High level API +*/ + +DIGEST_SIZE :: 32 + // hash_string will hash the given input and return the // computed hash -hash_string :: proc(data: string) -> [32]byte { +hash_string :: proc(data: string) -> [DIGEST_SIZE]byte { return hash_bytes(transmute([]byte)(data)) } // hash_bytes will hash the given input and return the // computed hash -hash_bytes :: proc(data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes :: proc(data: []byte) -> [DIGEST_SIZE]byte { + hash: [DIGEST_SIZE]byte ctx: Sm3_Context init(&ctx) update(&ctx, data) @@ -32,10 +38,28 @@ hash_bytes :: proc(data: []byte) -> [32]byte { return hash } +// hash_string_to_buffer will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") + ctx: Sm3_Context + init(&ctx) + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream will read the stream in chunks and compute a // hash from its contents -hash_stream :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { + hash: [DIGEST_SIZE]byte ctx: Sm3_Context init(&ctx) buf := make([]byte, 512) @@ -53,7 +77,7 @@ hash_stream :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file will read the file provided by the given handle // and compute a hash -hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE]byte, bool) { if !load_at_once { return hash_stream(os.stream_from_handle(hd)) } else { @@ -61,7 +85,7 @@ hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { return hash_bytes(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE]byte{}, false } hash :: proc { @@ -69,6 +93,8 @@ hash :: proc { hash_file, hash_bytes, hash_string, + hash_bytes_to_buffer, + hash_string_to_buffer, } /* @@ -146,9 +172,6 @@ Sm3_Context :: struct { length: u64, } -BLOCK_SIZE_IN_BYTES :: 64 -BLOCK_SIZE_IN_32 :: 16 - IV := [8]u32 { 0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600, 0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e, diff --git a/core/crypto/streebog/streebog.odin b/core/crypto/streebog/streebog.odin index b90ef8e86..f85977cba 100644 --- a/core/crypto/streebog/streebog.odin +++ b/core/crypto/streebog/streebog.odin @@ -19,16 +19,19 @@ import "../util" High level API */ +DIGEST_SIZE_256 :: 32 +DIGEST_SIZE_512 :: 64 + // hash_string_256 will hash the given input and return the // computed hash -hash_string_256 :: proc(data: string) -> [32]byte { +hash_string_256 :: proc(data: string) -> [DIGEST_SIZE_256]byte { return hash_bytes_256(transmute([]byte)(data)) } // hash_bytes_256 will hash the given input and return the // computed hash -hash_bytes_256 :: proc(data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes_256 :: proc(data: []byte) -> [DIGEST_SIZE_256]byte { + hash: [DIGEST_SIZE_256]byte ctx: Streebog_Context ctx.is256 = true init(&ctx) @@ -37,10 +40,29 @@ hash_bytes_256 :: proc(data: []byte) -> [32]byte { return hash } +// hash_string_to_buffer_256 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_256 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_256(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_256 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_256 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_256, "Size of destination buffer is smaller than the digest size") + ctx: Streebog_Context + ctx.is256 = true + init(&ctx) + update(&ctx, data) + final(&ctx, hash[:]) +} + // hash_stream_256 will read the stream in chunks and compute a // hash from its contents -hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { + hash: [DIGEST_SIZE_256]byte ctx: Streebog_Context ctx.is256 = true init(&ctx) @@ -59,7 +81,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file_256 will read the file provided by the given handle // and compute a hash -hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_256]byte, bool) { if !load_at_once { return hash_stream_256(os.stream_from_handle(hd)) } else { @@ -67,7 +89,7 @@ hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) return hash_bytes_256(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE_256]byte{}, false } hash_256 :: proc { @@ -75,18 +97,20 @@ hash_256 :: proc { hash_file_256, hash_bytes_256, hash_string_256, + hash_bytes_to_buffer_256, + hash_string_to_buffer_256, } // hash_string_512 will hash the given input and return the // computed hash -hash_string_512 :: proc(data: string) -> [64]byte { +hash_string_512 :: proc(data: string) -> [DIGEST_SIZE_512]byte { return hash_bytes_512(transmute([]byte)(data)) } // hash_bytes_512 will hash the given input and return the // computed hash -hash_bytes_512 :: proc(data: []byte) -> [64]byte { - hash: [64]byte +hash_bytes_512 :: proc(data: []byte) -> [DIGEST_SIZE_512]byte { + hash: [DIGEST_SIZE_512]byte ctx: Streebog_Context init(&ctx) update(&ctx, data) @@ -94,10 +118,28 @@ hash_bytes_512 :: proc(data: []byte) -> [64]byte { return hash } +// hash_string_to_buffer_512 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_512 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_512(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_512 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_512 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_512, "Size of destination buffer is smaller than the digest size") + ctx: Streebog_Context + init(&ctx) + update(&ctx, data) + final(&ctx, hash[:]) +} + // hash_stream_512 will read the stream in chunks and compute a // hash from its contents -hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { - hash: [64]byte +hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { + hash: [DIGEST_SIZE_512]byte ctx: Streebog_Context init(&ctx) buf := make([]byte, 512) @@ -115,7 +157,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { // hash_file_512 will read the file provided by the given handle // and compute a hash -hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) { +hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_512]byte, bool) { if !load_at_once { return hash_stream_512(os.stream_from_handle(hd)) } else { @@ -123,7 +165,7 @@ hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) return hash_bytes_512(buf[:]), ok } } - return [64]byte{}, false + return [DIGEST_SIZE_512]byte{}, false } hash_512 :: proc { @@ -131,6 +173,8 @@ hash_512 :: proc { hash_file_512, hash_bytes_512, hash_string_512, + hash_bytes_to_buffer_512, + hash_string_to_buffer_512, } /* diff --git a/core/crypto/tiger/tiger.odin b/core/crypto/tiger/tiger.odin index ecd7f5583..cf6159fad 100644 --- a/core/crypto/tiger/tiger.odin +++ b/core/crypto/tiger/tiger.odin @@ -19,16 +19,20 @@ import "../_tiger" High level API */ +DIGEST_SIZE_128 :: 16 +DIGEST_SIZE_160 :: 20 +DIGEST_SIZE_192 :: 24 + // hash_string_128 will hash the given input and return the // computed hash -hash_string_128 :: proc(data: string) -> [16]byte { +hash_string_128 :: proc(data: string) -> [DIGEST_SIZE_128]byte { return hash_bytes_128(transmute([]byte)(data)) } // hash_bytes_128 will hash the given input and return the // computed hash -hash_bytes_128 :: proc(data: []byte) -> [16]byte { - hash: [16]byte +hash_bytes_128 :: proc(data: []byte) -> [DIGEST_SIZE_128]byte { + hash: [DIGEST_SIZE_128]byte ctx: _tiger.Tiger_Context ctx.ver = 1 _tiger.init(&ctx) @@ -37,10 +41,29 @@ hash_bytes_128 :: proc(data: []byte) -> [16]byte { return hash } +// hash_string_to_buffer_128 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_128 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_128(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_128 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_128 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_128, "Size of destination buffer is smaller than the digest size") + ctx: _tiger.Tiger_Context + ctx.ver = 1 + _tiger.init(&ctx) + _tiger.update(&ctx, data) + _tiger.final(&ctx, hash) +} + // hash_stream_128 will read the stream in chunks and compute a // hash from its contents -hash_stream_128 :: proc(s: io.Stream) -> ([16]byte, bool) { - hash: [16]byte +hash_stream_128 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) { + hash: [DIGEST_SIZE_128]byte ctx: _tiger.Tiger_Context ctx.ver = 1 _tiger.init(&ctx) @@ -59,7 +82,7 @@ hash_stream_128 :: proc(s: io.Stream) -> ([16]byte, bool) { // hash_file_128 will read the file provided by the given handle // and compute a hash -hash_file_128 :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) { +hash_file_128 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_128]byte, bool) { if !load_at_once { return hash_stream_128(os.stream_from_handle(hd)) } else { @@ -67,7 +90,7 @@ hash_file_128 :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) return hash_bytes_128(buf[:]), ok } } - return [16]byte{}, false + return [DIGEST_SIZE_128]byte{}, false } hash_128 :: proc { @@ -75,18 +98,20 @@ hash_128 :: proc { hash_file_128, hash_bytes_128, hash_string_128, + hash_bytes_to_buffer_128, + hash_string_to_buffer_128, } // hash_string_160 will hash the given input and return the // computed hash -hash_string_160 :: proc(data: string) -> [20]byte { +hash_string_160 :: proc(data: string) -> [DIGEST_SIZE_160]byte { return hash_bytes_160(transmute([]byte)(data)) } // hash_bytes_160 will hash the given input and return the // computed hash -hash_bytes_160 :: proc(data: []byte) -> [20]byte { - hash: [20]byte +hash_bytes_160 :: proc(data: []byte) -> [DIGEST_SIZE_160]byte { + hash: [DIGEST_SIZE_160]byte ctx: _tiger.Tiger_Context ctx.ver = 1 _tiger.init(&ctx) @@ -95,10 +120,29 @@ hash_bytes_160 :: proc(data: []byte) -> [20]byte { return hash } +// hash_string_to_buffer_160 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_160 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_160(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_160 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_160 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_160, "Size of destination buffer is smaller than the digest size") + ctx: _tiger.Tiger_Context + ctx.ver = 1 + _tiger.init(&ctx) + _tiger.update(&ctx, data) + _tiger.final(&ctx, hash) +} + // hash_stream_160 will read the stream in chunks and compute a // hash from its contents -hash_stream_160 :: proc(s: io.Stream) -> ([20]byte, bool) { - hash: [20]byte +hash_stream_160 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) { + hash: [DIGEST_SIZE_160]byte ctx: _tiger.Tiger_Context ctx.ver = 1 _tiger.init(&ctx) @@ -117,7 +161,7 @@ hash_stream_160 :: proc(s: io.Stream) -> ([20]byte, bool) { // hash_file_160 will read the file provided by the given handle // and compute a hash -hash_file_160 :: proc(hd: os.Handle, load_at_once := false) -> ([20]byte, bool) { +hash_file_160 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_160]byte, bool) { if !load_at_once { return hash_stream_160(os.stream_from_handle(hd)) } else { @@ -125,7 +169,7 @@ hash_file_160 :: proc(hd: os.Handle, load_at_once := false) -> ([20]byte, bool) return hash_bytes_160(buf[:]), ok } } - return [20]byte{}, false + return [DIGEST_SIZE_160]byte{}, false } hash_160 :: proc { @@ -133,18 +177,20 @@ hash_160 :: proc { hash_file_160, hash_bytes_160, hash_string_160, + hash_bytes_to_buffer_160, + hash_string_to_buffer_160, } // hash_string_192 will hash the given input and return the // computed hash -hash_string_192 :: proc(data: string) -> [24]byte { +hash_string_192 :: proc(data: string) -> [DIGEST_SIZE_192]byte { return hash_bytes_192(transmute([]byte)(data)) } // hash_bytes_192 will hash the given input and return the // computed hash -hash_bytes_192 :: proc(data: []byte) -> [24]byte { - hash: [24]byte +hash_bytes_192 :: proc(data: []byte) -> [DIGEST_SIZE_192]byte { + hash: [DIGEST_SIZE_192]byte ctx: _tiger.Tiger_Context ctx.ver = 1 _tiger.init(&ctx) @@ -153,10 +199,29 @@ hash_bytes_192 :: proc(data: []byte) -> [24]byte { return hash } +// hash_string_to_buffer_192 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_192 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_192(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_192 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_192 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_192, "Size of destination buffer is smaller than the digest size") + ctx: _tiger.Tiger_Context + ctx.ver = 1 + _tiger.init(&ctx) + _tiger.update(&ctx, data) + _tiger.final(&ctx, hash) +} + // hash_stream_192 will read the stream in chunks and compute a // hash from its contents -hash_stream_192 :: proc(s: io.Stream) -> ([24]byte, bool) { - hash: [24]byte +hash_stream_192 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) { + hash: [DIGEST_SIZE_192]byte ctx: _tiger.Tiger_Context ctx.ver = 1 _tiger.init(&ctx) @@ -175,7 +240,7 @@ hash_stream_192 :: proc(s: io.Stream) -> ([24]byte, bool) { // hash_file_192 will read the file provided by the given handle // and compute a hash -hash_file_192 :: proc(hd: os.Handle, load_at_once := false) -> ([24]byte, bool) { +hash_file_192 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_192]byte, bool) { if !load_at_once { return hash_stream_192(os.stream_from_handle(hd)) } else { @@ -183,7 +248,7 @@ hash_file_192 :: proc(hd: os.Handle, load_at_once := false) -> ([24]byte, bool) return hash_bytes_192(buf[:]), ok } } - return [24]byte{}, false + return [DIGEST_SIZE_192]byte{}, false } hash_192 :: proc { @@ -191,6 +256,8 @@ hash_192 :: proc { hash_file_192, hash_bytes_192, hash_string_192, + hash_bytes_to_buffer_192, + hash_string_to_buffer_192, } /* diff --git a/core/crypto/tiger2/tiger2.odin b/core/crypto/tiger2/tiger2.odin index a93e19319..e8f2c4edb 100644 --- a/core/crypto/tiger2/tiger2.odin +++ b/core/crypto/tiger2/tiger2.odin @@ -19,16 +19,20 @@ import "../_tiger" High level API */ +DIGEST_SIZE_128 :: 16 +DIGEST_SIZE_160 :: 20 +DIGEST_SIZE_192 :: 24 + // hash_string_128 will hash the given input and return the // computed hash -hash_string_128 :: proc(data: string) -> [16]byte { +hash_string_128 :: proc(data: string) -> [DIGEST_SIZE_128]byte { return hash_bytes_128(transmute([]byte)(data)) } // hash_bytes_128 will hash the given input and return the // computed hash -hash_bytes_128 :: proc(data: []byte) -> [16]byte { - hash: [16]byte +hash_bytes_128 :: proc(data: []byte) -> [DIGEST_SIZE_128]byte { + hash: [DIGEST_SIZE_128]byte ctx: _tiger.Tiger_Context ctx.ver = 2 _tiger.init(&ctx) @@ -37,10 +41,29 @@ hash_bytes_128 :: proc(data: []byte) -> [16]byte { return hash } +// hash_string_to_buffer_128 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_128 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_128(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_128 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_128 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_128, "Size of destination buffer is smaller than the digest size") + ctx: _tiger.Tiger_Context + ctx.ver = 2 + _tiger.init(&ctx) + _tiger.update(&ctx, data) + _tiger.final(&ctx, hash) +} + // hash_stream_128 will read the stream in chunks and compute a // hash from its contents -hash_stream_128 :: proc(s: io.Stream) -> ([16]byte, bool) { - hash: [16]byte +hash_stream_128 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) { + hash: [DIGEST_SIZE_128]byte ctx: _tiger.Tiger_Context ctx.ver = 2 _tiger.init(&ctx) @@ -59,7 +82,7 @@ hash_stream_128 :: proc(s: io.Stream) -> ([16]byte, bool) { // hash_file_128 will read the file provided by the given handle // and compute a hash -hash_file_128 :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) { +hash_file_128 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_128]byte, bool) { if !load_at_once { return hash_stream_128(os.stream_from_handle(hd)) } else { @@ -67,7 +90,7 @@ hash_file_128 :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) return hash_bytes_128(buf[:]), ok } } - return [16]byte{}, false + return [DIGEST_SIZE_128]byte{}, false } hash_128 :: proc { @@ -75,18 +98,20 @@ hash_128 :: proc { hash_file_128, hash_bytes_128, hash_string_128, + hash_bytes_to_buffer_128, + hash_string_to_buffer_128, } // hash_string_160 will hash the given input and return the // computed hash -hash_string_160 :: proc(data: string) -> [20]byte { +hash_string_160 :: proc(data: string) -> [DIGEST_SIZE_160]byte { return hash_bytes_160(transmute([]byte)(data)) } // hash_bytes_160 will hash the given input and return the // computed hash -hash_bytes_160 :: proc(data: []byte) -> [20]byte { - hash: [20]byte +hash_bytes_160 :: proc(data: []byte) -> [DIGEST_SIZE_160]byte { + hash: [DIGEST_SIZE_160]byte ctx: _tiger.Tiger_Context ctx.ver = 2 _tiger.init(&ctx) @@ -95,10 +120,29 @@ hash_bytes_160 :: proc(data: []byte) -> [20]byte { return hash } +// hash_string_to_buffer_160 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_160 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_160(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_160 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_160 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_160, "Size of destination buffer is smaller than the digest size") + ctx: _tiger.Tiger_Context + ctx.ver = 2 + _tiger.init(&ctx) + _tiger.update(&ctx, data) + _tiger.final(&ctx, hash) +} + // hash_stream_160 will read the stream in chunks and compute a // hash from its contents -hash_stream_160 :: proc(s: io.Stream) -> ([20]byte, bool) { - hash: [20]byte +hash_stream_160 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) { + hash: [DIGEST_SIZE_160]byte ctx: _tiger.Tiger_Context ctx.ver = 2 _tiger.init(&ctx) @@ -117,7 +161,7 @@ hash_stream_160 :: proc(s: io.Stream) -> ([20]byte, bool) { // hash_file_160 will read the file provided by the given handle // and compute a hash -hash_file_160 :: proc(hd: os.Handle, load_at_once := false) -> ([20]byte, bool) { +hash_file_160 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_160]byte, bool) { if !load_at_once { return hash_stream_160(os.stream_from_handle(hd)) } else { @@ -125,7 +169,7 @@ hash_file_160 :: proc(hd: os.Handle, load_at_once := false) -> ([20]byte, bool) return hash_bytes_160(buf[:]), ok } } - return [20]byte{}, false + return [DIGEST_SIZE_160]byte{}, false } hash_160 :: proc { @@ -133,18 +177,20 @@ hash_160 :: proc { hash_file_160, hash_bytes_160, hash_string_160, + hash_bytes_to_buffer_160, + hash_string_to_buffer_160, } // hash_string_192 will hash the given input and return the // computed hash -hash_string_192 :: proc(data: string) -> [24]byte { +hash_string_192 :: proc(data: string) -> [DIGEST_SIZE_192]byte { return hash_bytes_192(transmute([]byte)(data)) } // hash_bytes_192 will hash the given input and return the // computed hash -hash_bytes_192 :: proc(data: []byte) -> [24]byte { - hash: [24]byte +hash_bytes_192 :: proc(data: []byte) -> [DIGEST_SIZE_192]byte { + hash: [DIGEST_SIZE_192]byte ctx: _tiger.Tiger_Context ctx.ver = 2 _tiger.init(&ctx) @@ -153,10 +199,29 @@ hash_bytes_192 :: proc(data: []byte) -> [24]byte { return hash } +// hash_string_to_buffer_192 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_192 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_192(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_192 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_192 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_192, "Size of destination buffer is smaller than the digest size") + ctx: _tiger.Tiger_Context + ctx.ver = 2 + _tiger.init(&ctx) + _tiger.update(&ctx, data) + _tiger.final(&ctx, hash) +} + // hash_stream_192 will read the stream in chunks and compute a // hash from its contents -hash_stream_192 :: proc(s: io.Stream) -> ([24]byte, bool) { - hash: [24]byte +hash_stream_192 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) { + hash: [DIGEST_SIZE_192]byte ctx: _tiger.Tiger_Context ctx.ver = 2 _tiger.init(&ctx) @@ -175,7 +240,7 @@ hash_stream_192 :: proc(s: io.Stream) -> ([24]byte, bool) { // hash_file_192 will read the file provided by the given handle // and compute a hash -hash_file_192 :: proc(hd: os.Handle, load_at_once := false) -> ([24]byte, bool) { +hash_file_192 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_192]byte, bool) { if !load_at_once { return hash_stream_192(os.stream_from_handle(hd)) } else { @@ -183,7 +248,7 @@ hash_file_192 :: proc(hd: os.Handle, load_at_once := false) -> ([24]byte, bool) return hash_bytes_192(buf[:]), ok } } - return [24]byte{}, false + return [DIGEST_SIZE_192]byte{}, false } hash_192 :: proc { @@ -191,6 +256,8 @@ hash_192 :: proc { hash_file_192, hash_bytes_192, hash_string_192, + hash_bytes_to_buffer_192, + hash_string_to_buffer_192, } /* diff --git a/core/crypto/whirlpool/whirlpool.odin b/core/crypto/whirlpool/whirlpool.odin index 43ad2a0a5..0cfef7c6b 100644 --- a/core/crypto/whirlpool/whirlpool.odin +++ b/core/crypto/whirlpool/whirlpool.odin @@ -19,16 +19,18 @@ import "../util" High level API */ +DIGEST_SIZE :: 64 + // hash_string will hash the given input and return the // computed hash -hash_string :: proc(data: string) -> [64]byte { +hash_string :: proc(data: string) -> [DIGEST_SIZE]byte { return hash_bytes(transmute([]byte)(data)) } // hash_bytes will hash the given input and return the // computed hash -hash_bytes :: proc(data: []byte) -> [64]byte { - hash: [64]byte +hash_bytes :: proc(data: []byte) -> [DIGEST_SIZE]byte { + hash: [DIGEST_SIZE]byte ctx: Whirlpool_Context // init(&ctx) No-op update(&ctx, data) @@ -36,10 +38,28 @@ hash_bytes :: proc(data: []byte) -> [64]byte { return hash } +// hash_string_to_buffer will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") + ctx: Whirlpool_Context + // init(&ctx) No-op + update(&ctx, data) + final(&ctx, hash) +} + // hash_stream will read the stream in chunks and compute a // hash from its contents -hash_stream :: proc(s: io.Stream) -> ([64]byte, bool) { - hash: [64]byte +hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { + hash: [DIGEST_SIZE]byte ctx: Whirlpool_Context // init(&ctx) No-op buf := make([]byte, 512) @@ -57,7 +77,7 @@ hash_stream :: proc(s: io.Stream) -> ([64]byte, bool) { // hash_file will read the file provided by the given handle // and compute a hash -hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) { +hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE]byte, bool) { if !load_at_once { return hash_stream(os.stream_from_handle(hd)) } else { @@ -65,7 +85,7 @@ hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) { return hash_bytes(buf[:]), ok } } - return [64]byte{}, false + return [DIGEST_SIZE]byte{}, false } hash :: proc { @@ -73,6 +93,8 @@ hash :: proc { hash_file, hash_bytes, hash_string, + hash_bytes_to_buffer, + hash_string_to_buffer, } /* diff --git a/core/dynlib/lib_unix.odin b/core/dynlib/lib_unix.odin index bb8affb79..e52ade153 100644 --- a/core/dynlib/lib_unix.odin +++ b/core/dynlib/lib_unix.odin @@ -1,4 +1,4 @@ -// +build linux, darwin, freebsd +// +build linux, darwin, freebsd, openbsd package dynlib import "core:os" diff --git a/core/encoding/hxa/doc.odin b/core/encoding/hxa/doc.odin index 16b94a243..230d6ea66 100644 --- a/core/encoding/hxa/doc.odin +++ b/core/encoding/hxa/doc.odin @@ -27,7 +27,7 @@ // Construction history, or BSP trees would make the format too large to serve its purpose. // The facilities of the formats to store meta data should make the format flexible enough // for most uses. Adding HxA support should be something anyone can do in a days work. - +// // Structure: // ---------- // HxA is designed to be extremely simple to parse, and is therefore based around conventions. It has @@ -45,17 +45,17 @@ // of a number of named layers. All layers in the stack have the same number of elements. Each layer // describes one property of the primitive. Each layer can have multiple channels and each layer can // store data of a different type. - +// // HaX stores 3 kinds of nodes // - Pixel data. // - Polygon geometry data. // - Meta data only. - +// // Pixel Nodes stores pixels in a layer stack. A layer may store things like Albedo, Roughness, // Reflectance, Light maps, Masks, Normal maps, and Displacement. Layers use the channels of the // layers to store things like color. The length of the layer stack is determined by the type and // dimensions stored in the - +// // Geometry data is stored in 3 separate layer stacks for: vertex data, corner data and face data. The // vertex data stores things like verities, blend shapes, weight maps, and vertex colors. The first // layer in a vertex stack has to be a 3 channel layer named "position" describing the base position @@ -63,7 +63,7 @@ // for things like UV, normals, and adjacency. The first layer in a corner stack has to be a 1 channel // integer layer named "index" describing the vertices used to form polygons. The last value in each // polygon has a negative - 1 index to indicate the end of the polygon. - +// // Example: // A quad and a tri with the vertex index: // [0, 1, 2, 3] [1, 4, 2] @@ -72,7 +72,7 @@ // The face stack stores values per face. the length of the face stack has to match the number of // negative values in the index layer in the corner stack. The face stack can be used to store things // like material index. - +// // Storage // ------- // All data is stored in little endian byte order with no padding. The layout mirrors the structs diff --git a/core/encoding/hxa/read.odin b/core/encoding/hxa/read.odin index ef7edc8b7..abe295530 100644 --- a/core/encoding/hxa/read.odin +++ b/core/encoding/hxa/read.odin @@ -39,6 +39,9 @@ read :: proc(data: []byte, filename := "", print_error := false, allocato read_value :: proc(r: ^Reader, $T: typeid) -> (value: T, err: Read_Error) { remaining := len(r.data) - r.offset if remaining < size_of(T) { + if r.print_error { + fmt.eprintf("file '%s' failed to read value at offset %v\n", r.filename, r.offset) + } err = .Short_Read return } @@ -51,6 +54,10 @@ read :: proc(data: []byte, filename := "", print_error := false, allocato read_array :: proc(r: ^Reader, $T: typeid, count: int) -> (value: []T, err: Read_Error) { remaining := len(r.data) - r.offset if remaining < size_of(T)*count { + if r.print_error { + fmt.eprintf("file '%s' failed to read array of %d elements at offset %v\n", + r.filename, count, r.offset) + } err = .Short_Read return } @@ -82,7 +89,8 @@ read :: proc(data: []byte, filename := "", print_error := false, allocato type := read_value(r, Meta_Value_Type) or_return if type > max(Meta_Value_Type) { if r.print_error { - fmt.eprintf("HxA Error: file '%s' has meta value type %d. Maximum value is ", r.filename, u8(type), u8(max(Meta_Value_Type))) + fmt.eprintf("HxA Error: file '%s' has meta value type %d. Maximum value is %d\n", + r.filename, u8(type), u8(max(Meta_Value_Type))) } err = .Invalid_Data return @@ -114,7 +122,8 @@ read :: proc(data: []byte, filename := "", print_error := false, allocato type := read_value(r, Layer_Data_Type) or_return if type > max(type) { if r.print_error { - fmt.eprintf("HxA Error: file '%s' has layer data type %d. Maximum value is ", r.filename, u8(type), u8(max(Layer_Data_Type))) + fmt.eprintf("HxA Error: file '%s' has layer data type %d. Maximum value is %d\n", + r.filename, u8(type), u8(max(Layer_Data_Type))) } err = .Invalid_Data return @@ -134,13 +143,23 @@ read :: proc(data: []byte, filename := "", print_error := false, allocato } if len(data) < size_of(Header) { + if print_error { + fmt.eprintf("HxA Error: file '%s' has no header\n", filename) + } + err = .Short_Read return } context.allocator = allocator header := cast(^Header)raw_data(data) - assert(header.magic_number == MAGIC_NUMBER) + if (header.magic_number != MAGIC_NUMBER) { + if print_error { + fmt.eprintf("HxA Error: file '%s' has invalid magic number 0x%x\n", filename, header.magic_number) + } + err = .Invalid_Data + return + } r := &Reader{ filename = filename, @@ -150,6 +169,7 @@ read :: proc(data: []byte, filename := "", print_error := false, allocato } node_count := 0 + file.header = header^ file.nodes = make([]Node, header.internal_node_count) defer if err != nil { nodes_destroy(file.nodes) @@ -162,7 +182,8 @@ read :: proc(data: []byte, filename := "", print_error := false, allocato type := read_value(r, Node_Type) or_return if type > max(Node_Type) { if r.print_error { - fmt.eprintf("HxA Error: file '%s' has node type %d. Maximum value is ", r.filename, u8(type), u8(max(Node_Type))) + fmt.eprintf("HxA Error: file '%s' has node type %d. Maximum value is %d\n", + r.filename, u8(type), u8(max(Node_Type))) } err = .Invalid_Data return diff --git a/core/encoding/hxa/write.odin b/core/encoding/hxa/write.odin index e774018b2..5bb950e81 100644 --- a/core/encoding/hxa/write.odin +++ b/core/encoding/hxa/write.odin @@ -84,7 +84,7 @@ write_internal :: proc(w: ^Writer, file: File) { write_metadata :: proc(w: ^Writer, meta_data: []Meta) { for m in meta_data { - name_len := max(len(m.name), 255) + name_len := min(len(m.name), 255) write_value(w, u8(name_len)) write_string(w, m.name[:name_len]) @@ -127,7 +127,7 @@ write_internal :: proc(w: ^Writer, file: File) { write_layer_stack :: proc(w: ^Writer, layers: Layer_Stack) { write_value(w, u32(len(layers))) for layer in layers { - name_len := max(len(layer.name), 255) + name_len := min(len(layer.name), 255) write_value(w, u8(name_len)) write_string(w, layer .name[:name_len]) @@ -152,7 +152,7 @@ write_internal :: proc(w: ^Writer, file: File) { return } - write_value(w, &Header{ + write_value(w, Header{ magic_number = MAGIC_NUMBER, version = LATEST_VERSION, internal_node_count = u32le(len(file.nodes)), diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index adbcb95be..9c54f35f0 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -8,17 +8,18 @@ import "core:strings" import "core:io" Marshal_Data_Error :: enum { + None, Unsupported_Type, } -Marshal_Error :: union { +Marshal_Error :: union #shared_nil { Marshal_Data_Error, io.Error, } marshal :: proc(v: any, allocator := context.allocator) -> (data: []byte, err: Marshal_Error) { b := strings.make_builder(allocator) - defer if err != .None { + defer if err != nil { strings.destroy_builder(&b) } @@ -27,7 +28,7 @@ marshal :: proc(v: any, allocator := context.allocator) -> (data: []byte, err: M if len(b.buf) != 0 { data = b.buf[:] } - return data, .None + return data, nil } marshal_to_builder :: proc(b: ^strings.Builder, v: any) -> Marshal_Error { @@ -285,8 +286,8 @@ marshal_to_writer :: proc(w: io.Writer, v: any) -> (err: Marshal_Error) { case runtime.Type_Info_Integer: switch info.endianness { case .Platform: return false - case .Little: return ODIN_ENDIAN != "little" - case .Big: return ODIN_ENDIAN != "big" + case .Little: return ODIN_ENDIAN != .Little + case .Big: return ODIN_ENDIAN != .Big } } return false diff --git a/core/encoding/json/parser.odin b/core/encoding/json/parser.odin index c682ec9bd..7bf88c565 100644 --- a/core/encoding/json/parser.odin +++ b/core/encoding/json/parser.odin @@ -354,6 +354,12 @@ unquote_string :: proc(token: Token, spec: Specification, allocator := context.a b := bytes_make(len(s) + 2*utf8.UTF_MAX, 1, allocator) or_return w := copy(b, s[0:i]) + + if len(b) == 0 && allocator.data == nil { + // `unmarshal_count_array` calls us with a nil allocator + return string(b[:w]), nil + } + loop: for i < len(s) { c := s[i] switch { diff --git a/core/encoding/json/unmarshal.odin b/core/encoding/json/unmarshal.odin index fe3137b7e..bd48011f1 100644 --- a/core/encoding/json/unmarshal.odin +++ b/core/encoding/json/unmarshal.odin @@ -52,11 +52,11 @@ unmarshal_any :: proc(data: []byte, v: any, spec := DEFAULT_SPECIFICATION, alloc if p.spec == .MJSON { #partial switch p.curr_token.kind { case .Ident, .String: - return unmarsal_object(&p, data, .EOF) + return unmarshal_object(&p, data, .EOF) } } - return unmarsal_value(&p, data) + return unmarshal_value(&p, data) } @@ -148,7 +148,7 @@ assign_float :: proc(val: any, f: $T) -> bool { @(private) -unmarsal_string :: proc(p: ^Parser, val: any, str: string, ti: ^reflect.Type_Info) -> bool { +unmarshal_string_token :: proc(p: ^Parser, val: any, str: string, ti: ^reflect.Type_Info) -> bool { val := val switch dst in &val { case string: @@ -198,7 +198,7 @@ unmarsal_string :: proc(p: ^Parser, val: any, str: string, ti: ^reflect.Type_Inf @(private) -unmarsal_value :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) { +unmarshal_value :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) { UNSUPPORTED_TYPE := Unsupported_Type_Error{v.id, p.curr_token} token := p.curr_token @@ -257,7 +257,7 @@ unmarsal_value :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) { case .Ident: advance_token(p) if p.spec == .MJSON { - if unmarsal_string(p, any{v.data, ti.id}, token.text, ti) { + if unmarshal_string_token(p, any{v.data, ti.id}, token.text, ti) { return nil } } @@ -266,7 +266,7 @@ unmarsal_value :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) { case .String: advance_token(p) str := unquote_string(token, p.spec, p.allocator) or_return - if unmarsal_string(p, any{v.data, ti.id}, str, ti) { + if unmarshal_string_token(p, any{v.data, ti.id}, str, ti) { return nil } delete(str, p.allocator) @@ -274,10 +274,10 @@ unmarsal_value :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) { case .Open_Brace: - return unmarsal_object(p, v, .Close_Brace) + return unmarshal_object(p, v, .Close_Brace) case .Open_Bracket: - return unmarsal_array(p, v) + return unmarshal_array(p, v) case: if p.spec != .JSON { @@ -312,16 +312,16 @@ unmarsal_value :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) { @(private) -unmarsal_expect_token :: proc(p: ^Parser, kind: Token_Kind, loc := #caller_location) -> Token { +unmarshal_expect_token :: proc(p: ^Parser, kind: Token_Kind, loc := #caller_location) -> Token { prev := p.curr_token err := expect_token(p, kind) - assert(err == nil, "unmarsal_expect_token") + assert(err == nil, "unmarshal_expect_token") return prev } @(private) -unmarsal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unmarshal_Error) { +unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unmarshal_Error) { UNSUPPORTED_TYPE := Unsupported_Type_Error{v.id, p.curr_token} if end_token == .Close_Brace { @@ -342,7 +342,7 @@ unmarsal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unma key, _ := parse_object_key(p, p.allocator) defer delete(key, p.allocator) - unmarsal_expect_token(p, .Colon) + unmarshal_expect_token(p, .Colon) fields := reflect.struct_fields_zipped(ti.id) @@ -378,7 +378,7 @@ unmarsal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unma field_ptr := rawptr(uintptr(v.data) + offset) field := any{field_ptr, type.id} - unmarsal_value(p, field) or_return + unmarshal_value(p, field) or_return if parse_comma(p) { break struct_loop @@ -407,11 +407,11 @@ unmarsal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unma map_loop: for p.curr_token.kind != end_token { key, _ := parse_object_key(p, p.allocator) - unmarsal_expect_token(p, .Colon) + unmarshal_expect_token(p, .Colon) mem.zero_slice(elem_backing) - if err := unmarsal_value(p, map_backing_value); err != nil { + if err := unmarshal_value(p, map_backing_value); err != nil { delete(key, p.allocator) return err } @@ -443,7 +443,7 @@ unmarsal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unma enumerated_array_loop: for p.curr_token.kind != end_token { key, _ := parse_object_key(p, p.allocator) - unmarsal_expect_token(p, .Colon) + unmarshal_expect_token(p, .Colon) defer delete(key, p.allocator) index := -1 @@ -460,7 +460,7 @@ unmarsal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unma index_ptr := rawptr(uintptr(v.data) + uintptr(index*t.elem_size)) index_any := any{index_ptr, t.elem.id} - unmarsal_value(p, index_any) or_return + unmarshal_value(p, index_any) or_return if parse_comma(p) { break enumerated_array_loop @@ -480,10 +480,10 @@ unmarsal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unma @(private) -unmarsal_count_array :: proc(p: ^Parser) -> (length: uintptr) { +unmarshal_count_array :: proc(p: ^Parser) -> (length: uintptr) { p_backup := p^ p.allocator = mem.nil_allocator() - unmarsal_expect_token(p, .Open_Bracket) + unmarshal_expect_token(p, .Open_Bracket) array_length_loop: for p.curr_token.kind != .Close_Bracket { _, _ = parse_value(p) length += 1 @@ -497,9 +497,9 @@ unmarsal_count_array :: proc(p: ^Parser) -> (length: uintptr) { } @(private) -unmarsal_array :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) { +unmarshal_array :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) { assign_array :: proc(p: ^Parser, base: rawptr, elem: ^reflect.Type_Info, length: uintptr) -> Unmarshal_Error { - unmarsal_expect_token(p, .Open_Bracket) + unmarshal_expect_token(p, .Open_Bracket) for idx: uintptr = 0; p.curr_token.kind != .Close_Bracket; idx += 1 { assert(idx < length) @@ -507,14 +507,14 @@ unmarsal_array :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) { elem_ptr := rawptr(uintptr(base) + idx*uintptr(elem.size)) elem := any{elem_ptr, elem.id} - unmarsal_value(p, elem) or_return + unmarshal_value(p, elem) or_return if parse_comma(p) { break } } - unmarsal_expect_token(p, .Close_Bracket) + unmarshal_expect_token(p, .Close_Bracket) return nil @@ -524,7 +524,7 @@ unmarsal_array :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) { ti := reflect.type_info_base(type_info_of(v.id)) - length := unmarsal_count_array(p) + length := unmarshal_count_array(p) #partial switch t in ti.variant { case reflect.Type_Info_Slice: @@ -578,4 +578,4 @@ unmarsal_array :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) { } return UNSUPPORTED_TYPE -} \ No newline at end of file +} diff --git a/core/encoding/varint/doc.odin b/core/encoding/varint/doc.odin new file mode 100644 index 000000000..5e4708a59 --- /dev/null +++ b/core/encoding/varint/doc.odin @@ -0,0 +1,28 @@ +/* + Implementation of the LEB128 variable integer encoding as used by DWARF encoding and DEX files, among others. + + Author of this Odin package: Jeroen van Rijn + + Example: + ```odin + import "core:encoding/varint" + import "core:fmt" + + main :: proc() { + buf: [varint.LEB128_MAX_BYTES]u8 + + value := u128(42) + + encode_size, encode_err := varint.encode_uleb128(buf[:], value) + assert(encode_size == 1 && encode_err == .None) + + fmt.printf("Encoded as %v\n", buf[:encode_size]) + decoded_val, decode_size, decode_err := varint.decode_uleb128(buf[:]) + + assert(decoded_val == value && decode_size == encode_size && decode_err == .None) + fmt.printf("Decoded as %v, using %v byte%v\n", decoded_val, decode_size, "" if decode_size == 1 else "s") + } + ``` + +*/ +package varint \ No newline at end of file diff --git a/core/encoding/varint/leb128.odin b/core/encoding/varint/leb128.odin new file mode 100644 index 000000000..f8fcc7de5 --- /dev/null +++ b/core/encoding/varint/leb128.odin @@ -0,0 +1,165 @@ +/* + Copyright 2022 Jeroen van Rijn . + Made available under Odin's BSD-3 license. + + List of contributors: + Jeroen van Rijn: Initial implementation. +*/ + +// package varint implements variable length integer encoding and decoding using +// the LEB128 format as used by DWARF debug info, Android .dex and other file formats. +package varint + +// In theory we should use the bigint package. In practice, varints bigger than this indicate a corrupted file. +// Instead we'll set limits on the values we'll encode/decode +// 18 * 7 bits = 126, which means that a possible 19th byte may at most be `0b0000_0011`. +LEB128_MAX_BYTES :: 19 + +Error :: enum { + None = 0, + Buffer_Too_Small = 1, + Value_Too_Large = 2, +} + +// Decode a slice of bytes encoding an unsigned LEB128 integer into value and number of bytes used. +// Returns `size` == 0 for an invalid value, empty slice, or a varint > 18 bytes. +decode_uleb128_buffer :: proc(buf: []u8) -> (val: u128, size: int, err: Error) { + if len(buf) == 0 { + return 0, 0, .Buffer_Too_Small + } + + for v in buf { + val, size, err = decode_uleb128_byte(v, size, val) + if err != .Buffer_Too_Small { + return + } + } + + if err == .Buffer_Too_Small { + val, size = 0, 0 + } + return +} + +// Decodes an unsigned LEB128 integer into value a byte at a time. +// Returns `.None` when decoded properly, `.Value_Too_Large` when they value +// exceeds the limits of a u128, and `.Buffer_Too_Small` when it's not yet fully decoded. +decode_uleb128_byte :: proc(input: u8, offset: int, accumulator: u128) -> (val: u128, size: int, err: Error) { + size = offset + 1 + + // 18 * 7 bits = 126, which means that a possible 19th byte may at most be 0b0000_0011. + if size > LEB128_MAX_BYTES || size == LEB128_MAX_BYTES && input > 0b0000_0011 { + return 0, 0, .Value_Too_Large + } + + val = accumulator | u128(input & 0x7f) << uint(offset * 7) + + if input < 128 { + // We're done + return + } + + // If the buffer runs out before the number ends, return an error. + return val, size, .Buffer_Too_Small +} +decode_uleb128 :: proc {decode_uleb128_buffer, decode_uleb128_byte} + +// Decode a slice of bytes encoding a signed LEB128 integer into value and number of bytes used. +// Returns `size` == 0 for an invalid value, empty slice, or a varint > 18 bytes. +decode_ileb128_buffer :: proc(buf: []u8) -> (val: i128, size: int, err: Error) { + if len(buf) == 0 { + return 0, 0, .Buffer_Too_Small + } + + for v in buf { + val, size, err = decode_ileb128_byte(v, size, val) + if err != .Buffer_Too_Small { + return + } + } + + if err == .Buffer_Too_Small { + val, size = 0, 0 + } + return +} + +// Decode a a signed LEB128 integer into value and number of bytes used, one byte at a time. +// Returns `size` == 0 for an invalid value, empty slice, or a varint > 18 bytes. +decode_ileb128_byte :: proc(input: u8, offset: int, accumulator: i128) -> (val: i128, size: int, err: Error) { + size = offset + 1 + shift := uint(offset * 7) + + // 18 * 7 bits = 126, which including sign means we can have a 19th byte. + if size > LEB128_MAX_BYTES || size == LEB128_MAX_BYTES && input > 0x7f { + return 0, 0, .Value_Too_Large + } + + val = accumulator | i128(input & 0x7f) << shift + + if input < 128 { + if input & 0x40 == 0x40 { + val |= max(i128) << (shift + 7) + } + return val, size, .None + } + return val, size, .Buffer_Too_Small +} +decode_ileb128 :: proc{decode_ileb128_buffer, decode_ileb128_byte} + +// Encode `val` into `buf` as an unsigned LEB128 encoded series of bytes. +// `buf` must be appropriately sized. +encode_uleb128 :: proc(buf: []u8, val: u128) -> (size: int, err: Error) { + val := val + + for { + size += 1 + + if size > len(buf) { + return 0, .Buffer_Too_Small + } + + low := val & 0x7f + val >>= 7 + + if val > 0 { + low |= 0x80 // more bytes to follow + } + buf[size - 1] = u8(low) + + if val == 0 { break } + } + return +} + +@(private) +SIGN_MASK :: (i128(1) << 121) // sign extend mask + +// Encode `val` into `buf` as a signed LEB128 encoded series of bytes. +// `buf` must be appropriately sized. +encode_ileb128 :: proc(buf: []u8, val: i128) -> (size: int, err: Error) { + val := val + more := true + + for more { + size += 1 + + if size > len(buf) { + return 0, .Buffer_Too_Small + } + + low := val & 0x7f + val >>= 7 + + low = (low ~ SIGN_MASK) - SIGN_MASK + + if (val == 0 && low & 0x40 != 0x40) || (val == -1 && low & 0x40 == 0x40) { + more = false + } else { + low |= 0x80 + } + + buf[size - 1] = u8(low) + } + return +} \ No newline at end of file diff --git a/core/fmt/doc.odin b/core/fmt/doc.odin index 5984da950..668fc9bc6 100644 --- a/core/fmt/doc.odin +++ b/core/fmt/doc.odin @@ -64,6 +64,7 @@ If not present, the width is whatever is necessary to represent the value. Precision is specified after the (optional) width followed by a period followed by a decimal number. If no period is present, a default precision is used. A period with no following number specifies a precision of 0. + Examples: %f default width, default precision %8f width 8, default precision @@ -84,7 +85,6 @@ Other flags: add leading 0z for dozenal (%#z) add leading 0x or 0X for hexadecimal (%#x or %#X) remove leading 0x for %p (%#p) - ' ' (space) leave a space for elided sign in numbers (% d) 0 pad with leading zeros rather than spaces diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index a9ff6ca47..d006d0ef8 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -11,6 +11,7 @@ import "core:time" import "core:unicode/utf8" import "core:intrinsics" +// Internal data structure that stores the required information for formatted printing Info :: struct { minus: bool, plus: bool, @@ -31,6 +32,8 @@ Info :: struct { writer: io.Writer, arg: any, // Temporary record_level: int, + + n: int, // bytes written } // Custom formatter signature. It returns true if the formatting was successful and false when it could not be done @@ -46,9 +49,13 @@ Register_User_Formatter_Error :: enum { // it is prefixed with `_` rather than marked with a private attribute so that users can access it if necessary _user_formatters: ^map[typeid]User_Formatter +// set_user_formatters assigns m to a global value allowing the user have custom print formatting for specific +// types set_user_formatters :: proc(m: ^map[typeid]User_Formatter) { _user_formatters = m } +// register_user_formatter assigns a formatter to a specific typeid. set_user_formatters must be called +// before any use of this procedure. register_user_formatter :: proc(id: typeid, formatter: User_Formatter) -> Register_User_Formatter_Error { if _user_formatters == nil { return .No_User_Formatter @@ -61,7 +68,7 @@ register_user_formatter :: proc(id: typeid, formatter: User_Formatter) -> Regist } -// aprint* procedures return a string that was allocated with the current context +// aprint procedure return a string that was allocated with the current context // They must be freed accordingly aprint :: proc(args: ..any, sep := " ") -> string { str: strings.Builder @@ -69,12 +76,16 @@ aprint :: proc(args: ..any, sep := " ") -> string { sbprint(buf=&str, args=args, sep=sep) return strings.to_string(str) } +// aprintln procedure return a string that was allocated with the current context +// They must be freed accordingly aprintln :: proc(args: ..any, sep := " ") -> string { str: strings.Builder strings.init_builder(&str) sbprintln(buf=&str, args=args, sep=sep) return strings.to_string(str) } +// aprintf procedure return a string that was allocated with the current context +// They must be freed accordingly aprintf :: proc(fmt: string, args: ..any) -> string { str: strings.Builder strings.init_builder(&str) @@ -83,19 +94,21 @@ aprintf :: proc(fmt: string, args: ..any) -> string { } -// tprint* procedures return a string that was allocated with the current context's temporary allocator +// tprint procedure return a string that was allocated with the current context's temporary allocator tprint :: proc(args: ..any, sep := " ") -> string { str: strings.Builder strings.init_builder(&str, context.temp_allocator) sbprint(buf=&str, args=args, sep=sep) return strings.to_string(str) } +// tprintln procedure return a string that was allocated with the current context's temporary allocator tprintln :: proc(args: ..any, sep := " ") -> string { str: strings.Builder strings.init_builder(&str, context.temp_allocator) sbprintln(buf=&str, args=args, sep=sep) return strings.to_string(str) } +// tprintf procedure return a string that was allocated with the current context's temporary allocator tprintf :: proc(fmt: string, args: ..any) -> string { str: strings.Builder strings.init_builder(&str, context.temp_allocator) @@ -104,21 +117,24 @@ tprintf :: proc(fmt: string, args: ..any) -> string { } -// bprint* procedures return a string using a buffer from an array +// bprint procedures return a string using a buffer from an array bprint :: proc(buf: []byte, args: ..any, sep := " ") -> string { sb := strings.builder_from_slice(buf[0:len(buf)]) return sbprint(buf=&sb, args=args, sep=sep) } +// bprintln procedures return a string using a buffer from an array bprintln :: proc(buf: []byte, args: ..any, sep := " ") -> string { sb := strings.builder_from_slice(buf[0:len(buf)]) return sbprintln(buf=&sb, args=args, sep=sep) } +// bprintf procedures return a string using a buffer from an array bprintf :: proc(buf: []byte, fmt: string, args: ..any) -> string { sb := strings.builder_from_slice(buf[0:len(buf)]) return sbprintf(&sb, fmt, ..args) } +// formatted assert assertf :: proc(condition: bool, fmt: string, args: ..any, loc := #caller_location) -> bool { if !condition { p := context.assertion_failure_proc @@ -131,6 +147,7 @@ assertf :: proc(condition: bool, fmt: string, args: ..any, loc := #caller_locati return condition } +// formatted panic panicf :: proc(fmt: string, args: ..any, loc := #caller_location) -> ! { p := context.assertion_failure_proc if p == nil { @@ -142,24 +159,26 @@ panicf :: proc(fmt: string, args: ..any, loc := #caller_location) -> ! { - - +// sbprint formats using the default print settings and writes to buf sbprint :: proc(buf: ^strings.Builder, args: ..any, sep := " ") -> string { wprint(w=strings.to_writer(buf), args=args, sep=sep) return strings.to_string(buf^) } +// sbprintln formats using the default print settings and writes to buf sbprintln :: proc(buf: ^strings.Builder, args: ..any, sep := " ") -> string { wprintln(w=strings.to_writer(buf), args=args, sep=sep) return strings.to_string(buf^) } +// sbprintf formats according to the specififed format string and writes to buf sbprintf :: proc(buf: ^strings.Builder, fmt: string, args: ..any) -> string { wprintf(w=strings.to_writer(buf), fmt=fmt, args=args) return strings.to_string(buf^) } +// wprint formats using the default print settings and writes to w wprint :: proc(w: io.Writer, args: ..any, sep := " ") -> int { fi: Info fi.writer = w @@ -179,49 +198,42 @@ wprint :: proc(w: io.Writer, args: ..any, sep := " ") -> int { // so I am going to keep the same behaviour as `*println` for `*print` - size0 := io.size(auto_cast w) - for _, i in args { if i > 0 { - io.write_string(fi.writer, sep) + io.write_string(fi.writer, sep, &fi.n) } fmt_value(&fi, args[i], 'v') } io.flush(auto_cast w) - size1 := io.size(auto_cast w) - return int(size1 - size0) + return fi.n } +// wprintln formats using the default print settings and writes to w wprintln :: proc(w: io.Writer, args: ..any, sep := " ") -> int { fi: Info fi.writer = w - size0 := io.size(auto_cast w) - for _, i in args { if i > 0 { - io.write_string(fi.writer, sep) + io.write_string(fi.writer, sep, &fi.n) } fmt_value(&fi, args[i], 'v') } - io.write_byte(fi.writer, '\n') + io.write_byte(fi.writer, '\n', &fi.n) io.flush(auto_cast w) - - size1 := io.size(auto_cast w) - return int(size1 - size0) + return fi.n } +// wprintf formats according to the specififed format string and writes to w wprintf :: proc(w: io.Writer, fmt: string, args: ..any) -> int { fi: Info arg_index: int = 0 end := len(fmt) was_prev_index := false - size0 := io.size(auto_cast w) - loop: for i := 0; i < end; /**/ { fi = Info{writer = w, good_arg_index = true, reordered = fi.reordered} @@ -230,7 +242,7 @@ wprintf :: proc(w: io.Writer, fmt: string, args: ..any) -> int { i += 1 } if i > prev_i { - io.write_string(fi.writer, fmt[prev_i:i]) + io.write_string(fi.writer, fmt[prev_i:i], &fi.n) } if i >= end { break loop @@ -245,13 +257,13 @@ wprintf :: proc(w: io.Writer, fmt: string, args: ..any) -> int { // Skip extra one i += 1 } - io.write_byte(fi.writer, char) + io.write_byte(fi.writer, char, &fi.n) continue loop } else if char == '{' { if i < end && fmt[i] == char { // Skip extra one i += 1 - io.write_byte(fi.writer, char) + io.write_byte(fi.writer, char, &fi.n) continue loop } } @@ -282,7 +294,7 @@ wprintf :: proc(w: io.Writer, fmt: string, args: ..any) -> int { i += 1 fi.width, arg_index, fi.width_set = int_from_arg(args, arg_index) if !fi.width_set { - io.write_string(w, "%!(BAD WIDTH)") + io.write_string(w, "%!(BAD WIDTH)", &fi.n) } if fi.width < 0 { @@ -313,7 +325,7 @@ wprintf :: proc(w: io.Writer, fmt: string, args: ..any) -> int { fi.prec_set = false } if !fi.prec_set { - io.write_string(fi.writer, "%!(BAD PRECISION)") + io.write_string(fi.writer, "%!(BAD PRECISION)", &fi.n) } was_prev_index = false } else { @@ -326,7 +338,7 @@ wprintf :: proc(w: io.Writer, fmt: string, args: ..any) -> int { } if i >= end { - io.write_string(fi.writer, "%!(NO VERB)") + io.write_string(fi.writer, "%!(NO VERB)", &fi.n) break loop } @@ -335,11 +347,11 @@ wprintf :: proc(w: io.Writer, fmt: string, args: ..any) -> int { switch { case verb == '%': - io.write_byte(fi.writer, '%') + io.write_byte(fi.writer, '%', &fi.n) case !fi.good_arg_index: - io.write_string(fi.writer, "%!(BAD ARGUMENT NUMBER)") + io.write_string(fi.writer, "%!(BAD ARGUMENT NUMBER)", &fi.n) case arg_index >= len(args): - io.write_string(fi.writer, "%!(MISSING ARGUMENT)") + io.write_string(fi.writer, "%!(MISSING ARGUMENT)", &fi.n) case: fmt_arg(&fi, args[arg_index], verb) arg_index += 1 @@ -355,14 +367,14 @@ wprintf :: proc(w: io.Writer, fmt: string, args: ..any) -> int { arg_index = new_arg_index i = new_i } else { - io.write_string(fi.writer, "%!(BAD ARGUMENT NUMBER ") + io.write_string(fi.writer, "%!(BAD ARGUMENT NUMBER ", &fi.n) // Skip over the bad argument start_index := i for i < end && fmt[i] != '}' && fmt[i] != ':' { i += 1 } fmt_arg(&fi, fmt[start_index:i], 'v') - io.write_string(fi.writer, ")") + io.write_string(fi.writer, ")", &fi.n) } } @@ -395,7 +407,7 @@ wprintf :: proc(w: io.Writer, fmt: string, args: ..any) -> int { i += 1 fi.width, arg_index, fi.width_set = int_from_arg(args, arg_index) if !fi.width_set { - io.write_string(fi.writer, "%!(BAD WIDTH)") + io.write_string(fi.writer, "%!(BAD WIDTH)", &fi.n) } if fi.width < 0 { @@ -426,7 +438,7 @@ wprintf :: proc(w: io.Writer, fmt: string, args: ..any) -> int { fi.prec_set = false } if !fi.prec_set { - io.write_string(fi.writer, "%!(BAD PRECISION)") + io.write_string(fi.writer, "%!(BAD PRECISION)", &fi.n) } was_prev_index = false } else { @@ -440,7 +452,7 @@ wprintf :: proc(w: io.Writer, fmt: string, args: ..any) -> int { if i >= end { - io.write_string(fi.writer, "%!(NO VERB)") + io.write_string(fi.writer, "%!(NO VERB)", &fi.n) break loop } @@ -450,7 +462,7 @@ wprintf :: proc(w: io.Writer, fmt: string, args: ..any) -> int { } if i >= end { - io.write_string(fi.writer, "%!(MISSING CLOSE BRACE)") + io.write_string(fi.writer, "%!(MISSING CLOSE BRACE)", &fi.n) break loop } @@ -459,11 +471,11 @@ wprintf :: proc(w: io.Writer, fmt: string, args: ..any) -> int { switch { case brace != '}': - io.write_string(fi.writer, "%!(MISSING CLOSE BRACE)") + io.write_string(fi.writer, "%!(MISSING CLOSE BRACE)", &fi.n) case !fi.good_arg_index: - io.write_string(fi.writer, "%!(BAD ARGUMENT NUMBER)") + io.write_string(fi.writer, "%!(BAD ARGUMENT NUMBER)", &fi.n) case arg_index >= len(args): - io.write_string(fi.writer, "%!(MISSING ARGUMENT)") + io.write_string(fi.writer, "%!(MISSING ARGUMENT)", &fi.n) case: fmt_arg(&fi, args[arg_index], verb) arg_index += 1 @@ -472,32 +484,33 @@ wprintf :: proc(w: io.Writer, fmt: string, args: ..any) -> int { } if !fi.reordered && arg_index < len(args) { - io.write_string(fi.writer, "%!(EXTRA ") + io.write_string(fi.writer, "%!(EXTRA ", &fi.n) for arg, index in args[arg_index:] { if index > 0 { - io.write_string(fi.writer, ", ") + io.write_string(fi.writer, ", ", &fi.n) } if arg == nil { - io.write_string(fi.writer, "") + io.write_string(fi.writer, "", &fi.n) } else { fmt_arg(&fi, args[index], 'v') } } - io.write_string(fi.writer, ")") + io.write_string(fi.writer, ")", &fi.n) } io.flush(auto_cast w) - size1 := io.size(auto_cast w) - return int(size1 - size0) + return fi.n } +// wprint_type is a utility procedure to write a ^runtime.Type_Info value to w wprint_type :: proc(w: io.Writer, info: ^runtime.Type_Info) -> (int, io.Error) { n, err := reflect.write_type(w, info) io.flush(auto_cast w) return n, err } +// wprint_typeid is a utility procedure to write a typeid value to w wprint_typeid :: proc(w: io.Writer, id: typeid) -> (int, io.Error) { n, err := reflect.write_type(w, type_info_of(id)) io.flush(auto_cast w) @@ -576,23 +589,23 @@ int_from_arg :: proc(args: []any, arg_index: int) -> (int, int, bool) { fmt_bad_verb :: proc(using fi: ^Info, verb: rune) { - io.write_string(writer, "%!") - io.write_rune(writer, verb) - io.write_byte(writer, '(') + io.write_string(writer, "%!", &fi.n) + io.write_rune(writer, verb, &fi.n) + io.write_byte(writer, '(', &fi.n) if arg.id != nil { - reflect.write_typeid(writer, arg.id) - io.write_byte(writer, '=') + reflect.write_typeid(writer, arg.id, &fi.n) + io.write_byte(writer, '=', &fi.n) fmt_value(fi, arg, 'v') } else { - io.write_string(writer, "") + io.write_string(writer, "", &fi.n) } - io.write_byte(writer, ')') + io.write_byte(writer, ')', &fi.n) } fmt_bool :: proc(using fi: ^Info, b: bool, verb: rune) { switch verb { case 't', 'v': - io.write_string(writer, b ? "true" : "false") + fmt_string(fi, b ? "true" : "false", 's') case: fmt_bad_verb(fi, verb) } @@ -610,7 +623,7 @@ fmt_write_padding :: proc(fi: ^Info, width: int) { } for i := 0; i < width; i += 1 { - io.write_byte(fi.writer, pad_byte) + io.write_byte(fi.writer, pad_byte, &fi.n) } } @@ -669,8 +682,8 @@ _fmt_int :: proc(fi: ^Info, u: u64, base: int, is_signed: bool, bit_size: int, d case 16: c = 'x' } if c != 0 { - io.write_byte(fi.writer, '0') - io.write_byte(fi.writer, c) + io.write_byte(fi.writer, '0', &fi.n) + io.write_byte(fi.writer, c, &fi.n) } } @@ -735,8 +748,8 @@ _fmt_int_128 :: proc(fi: ^Info, u: u128, base: int, is_signed: bool, bit_size: i case 16: c = 'x' } if c != 0 { - io.write_byte(fi.writer, '0') - io.write_byte(fi.writer, c) + io.write_byte(fi.writer, '0', &fi.n) + io.write_byte(fi.writer, c, &fi.n) } } @@ -752,9 +765,9 @@ __DIGITS_UPPER := "0123456789ABCDEFX" fmt_rune :: proc(fi: ^Info, r: rune, verb: rune) { switch verb { case 'c', 'r', 'v': - io.write_rune(fi.writer, r) + io.write_rune(fi.writer, r, &fi.n) case 'q': - strings.write_quoted_rune(fi.writer, r) + fi.n += strings.write_quoted_rune(fi.writer, r) case: fmt_int(fi, u64(r), false, 32, verb) } @@ -776,7 +789,7 @@ fmt_int :: proc(fi: ^Info, u: u64, is_signed: bool, bit_size: int, verb: rune) { if r < 0 || r > utf8.MAX_RUNE { fmt_bad_verb(fi, verb) } else { - io.write_string(fi.writer, "U+") + io.write_string(fi.writer, "U+", &fi.n) _fmt_int(fi, u, 16, false, bit_size, __DIGITS_UPPER) } @@ -801,7 +814,7 @@ fmt_int_128 :: proc(fi: ^Info, u: u128, is_signed: bool, bit_size: int, verb: ru if r < 0 || r > utf8.MAX_RUNE { fmt_bad_verb(fi, verb) } else { - io.write_string(fi.writer, "U+") + io.write_string(fi.writer, "U+", &fi.n) _fmt_int_128(fi, u, 16, false, bit_size, __DIGITS_UPPER) } @@ -812,24 +825,24 @@ fmt_int_128 :: proc(fi: ^Info, u: u128, is_signed: bool, bit_size: int, verb: ru _pad :: proc(fi: ^Info, s: string) { if !fi.width_set { - io.write_string(fi.writer, s) + io.write_string(fi.writer, s, &fi.n) return } width := fi.width - utf8.rune_count_in_string(s) if fi.minus { // right pad - io.write_string(fi.writer, s) + io.write_string(fi.writer, s, &fi.n) fmt_write_padding(fi, width) } else { // left pad fmt_write_padding(fi, width) - io.write_string(fi.writer, s) + io.write_string(fi.writer, s, &fi.n) } } fmt_float :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune) { switch verb { - case 'f', 'F', 'v': + case 'f', 'F', 'g', 'G', 'v': prec: int = 3 if fi.prec_set { prec = fi.prec @@ -849,15 +862,15 @@ fmt_float :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune) { } if len(b) > 1 && (b[1] == 'N' || b[1] == 'I') { - io.write_string(fi.writer, string(b)) + io.write_string(fi.writer, string(b), &fi.n) return } if fi.plus || b[0] != '+' { if fi.zero && fi.width_set && fi.width > len(b) { - io.write_byte(fi.writer, b[0]) + io.write_byte(fi.writer, b[0], &fi.n) fmt_write_padding(fi, fi.width - len(b)) - io.write_string(fi.writer, string(b[1:])) + io.write_string(fi.writer, string(b[1:]), &fi.n) } else { _pad(fi, string(b)) } @@ -885,15 +898,15 @@ fmt_float :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune) { } if len(b) > 1 && (b[1] == 'N' || b[1] == 'I') { - io.write_string(fi.writer, string(b)) + io.write_string(fi.writer, string(b), &fi.n) return } if fi.plus || str[0] != '+' { if fi.zero && fi.width_set && fi.width > len(b) { - io.write_byte(fi.writer, b[0]) + io.write_byte(fi.writer, b[0], &fi.n) fmt_write_padding(fi, fi.width - len(b)) - io.write_string(fi.writer, string(b[1:])) + io.write_string(fi.writer, string(b[1:]), &fi.n) } else { _pad(fi, string(b)) } @@ -917,7 +930,7 @@ fmt_float :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune) { case: panic("Unhandled float size") } - io.write_string(fi.writer, "0h") + io.write_string(fi.writer, "0h", &fi.n) _fmt_int(fi, u, 16, false, bit_size, __DIGITS_LOWER if verb == 'h' else __DIGITS_UPPER) @@ -930,15 +943,31 @@ fmt_float :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune) { fmt_string :: proc(fi: ^Info, s: string, verb: rune) { switch verb { case 's', 'v': - io.write_string(fi.writer, s) - if fi.width_set && len(s) < fi.width { - for _ in 0.. len(s) { + if fi.minus { + io.write_string(fi.writer, s, &fi.n) + } + + for _ in 0.. 0 && space { - io.write_byte(fi.writer, ' ') + io.write_byte(fi.writer, ' ', &fi.n) } char_set := __DIGITS_UPPER if verb == 'x' { @@ -969,7 +998,7 @@ fmt_pointer :: proc(fi: ^Info, p: rawptr, verb: rune) { switch verb { case 'p', 'v': if !fi.hash || verb == 'v' { - io.write_string(fi.writer, "0x") + io.write_string(fi.writer, "0x", &fi.n) } _fmt_int(fi, u, 16, false, 8*size_of(rawptr), __DIGITS_UPPER) @@ -1031,7 +1060,7 @@ string_to_enum_value :: proc($T: typeid, s: string) -> (T, bool) { fmt_enum :: proc(fi: ^Info, v: any, verb: rune) { if v.id == nil || v.data == nil { - io.write_string(fi.writer, "") + io.write_string(fi.writer, "", &fi.n) return } @@ -1044,11 +1073,13 @@ fmt_enum :: proc(fi: ^Info, v: any, verb: rune) { case 'i', 'd', 'f': fmt_arg(fi, any{v.data, runtime.type_info_base(e.base).id}, verb) case 's', 'v': - str, ok := enum_value_to_string(v) - if !ok { - str = "%!(BAD ENUM VALUE)" + if str, ok := enum_value_to_string(v); ok { + fmt_string(fi, str, 's') + } else { + io.write_string(fi.writer, "%!(BAD ENUM VALUE=", &fi.n) + fmt_arg(fi, any{v.data, runtime.type_info_base(e.base).id}, 'i') + io.write_string(fi.writer, ")", &fi.n) } - io.write_string(fi.writer, str) } } } @@ -1092,8 +1123,8 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "") { case runtime.Type_Info_Integer: switch info.endianness { case .Platform: return false - case .Little: return ODIN_ENDIAN != "little" - case .Big: return ODIN_ENDIAN != "big" + case .Little: return ODIN_ENDIAN != .Little + case .Big: return ODIN_ENDIAN != .Big } } return false @@ -1141,12 +1172,12 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "") { et := runtime.type_info_base(info.elem) if name != "" { - io.write_string(fi.writer, name) + io.write_string(fi.writer, name, &fi.n) } else { - reflect.write_type(fi.writer, type_info) + reflect.write_type(fi.writer, type_info, &fi.n) } - io.write_byte(fi.writer, '{') - defer io.write_byte(fi.writer, '}') + io.write_byte(fi.writer, '{', &fi.n) + defer io.write_byte(fi.writer, '}', &fi.n) e, is_enum := et.variant.(runtime.Type_Info_Enum) commas := 0 @@ -1156,21 +1187,21 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "") { } if commas > 0 { - io.write_string(fi.writer, ", ") + io.write_string(fi.writer, ", ", &fi.n) } if is_enum { for ev, evi in e.values { v := u64(ev) if v == u64(i) { - io.write_string(fi.writer, e.names[evi]) + io.write_string(fi.writer, e.names[evi], &fi.n) commas += 1 continue loop } } } v := i64(i) + info.lower - io.write_i64(fi.writer, v, 10) + io.write_i64(fi.writer, v, 10, &fi.n) commas += 1 } } @@ -1178,20 +1209,20 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "") { fmt_write_indent :: proc(fi: ^Info) { for in 0.. 0 { io.write_string(fi.writer, ", ") } + if i > 0 { io.write_string(fi.writer, ", ", &fi.n) } data := uintptr(array_data) + uintptr(i*elem_size) fmt_arg(fi, any{rawptr(data), elem_id}, verb) @@ -1223,14 +1254,14 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { n -= 1 } for in 0..") + io.write_string(fi.writer, "", &fi.n) return } @@ -1256,12 +1287,12 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { // Built-in Custom Formatters for core library types switch a in v { case runtime.Source_Code_Location: - io.write_string(fi.writer, a.file_path) - io.write_byte(fi.writer, '(') - io.write_int(fi.writer, int(a.line)) - io.write_byte(fi.writer, ':') - io.write_int(fi.writer, int(a.column)) - io.write_byte(fi.writer, ')') + io.write_string(fi.writer, a.file_path, &fi.n) + io.write_byte(fi.writer, '(', &fi.n) + io.write_int(fi.writer, int(a.line), 10, &fi.n) + io.write_byte(fi.writer, ':', &fi.n) + io.write_int(fi.writer, int(a.column), 10, &fi.n) + io.write_byte(fi.writer, ')', &fi.n) return case time.Duration: @@ -1315,7 +1346,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { w -= 1 switch { case u == 0: - io.write_string(fi.writer, "0s") + io.write_string(fi.writer, "0s", &fi.n) return case u < u64(time.Microsecond): prec = 0 @@ -1354,7 +1385,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { w -= 1 buf[w] = '-' } - io.write_string(fi.writer, string(buf[w:])) + io.write_string(fi.writer, string(buf[w:]), &fi.n) return case time.Time: @@ -1363,20 +1394,20 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { h, min, s := time.clock(t) ns := (t._nsec - (t._nsec/1e9 + time.UNIX_TO_ABSOLUTE)*1e9) % 1e9 write_padded_number(fi, i64(y), 4) - io.write_byte(fi.writer, '-') + io.write_byte(fi.writer, '-', &fi.n) write_padded_number(fi, i64(mon), 2) - io.write_byte(fi.writer, '-') + io.write_byte(fi.writer, '-', &fi.n) write_padded_number(fi, i64(d), 2) - io.write_byte(fi.writer, ' ') + io.write_byte(fi.writer, ' ', &fi.n) write_padded_number(fi, i64(h), 2) - io.write_byte(fi.writer, ':') + io.write_byte(fi.writer, ':', &fi.n) write_padded_number(fi, i64(min), 2) - io.write_byte(fi.writer, ':') + io.write_byte(fi.writer, ':', &fi.n) write_padded_number(fi, i64(s), 2) - io.write_byte(fi.writer, '.') + io.write_byte(fi.writer, '.', &fi.n) write_padded_number(fi, (ns), 9) - io.write_string(fi.writer, " +0000 UTC") + io.write_string(fi.writer, " +0000 UTC", &fi.n) return } @@ -1387,15 +1418,15 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { return } if b.is_raw_union { - io.write_string(fi.writer, info.name) - io.write_string(fi.writer, "{}") + io.write_string(fi.writer, info.name, &fi.n) + io.write_string(fi.writer, "{}", &fi.n) return } is_soa := b.soa_kind != .None - io.write_string(fi.writer, info.name) - io.write_byte(fi.writer, '[' if is_soa else '{') + io.write_string(fi.writer, info.name, &fi.n) + io.write_byte(fi.writer, '[' if is_soa else '{', &fi.n) hash := fi.hash; defer fi.hash = hash indent := fi.indent; defer fi.indent -= 1 @@ -1404,13 +1435,13 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { fi.indent += 1 if hash { - io.write_byte(fi.writer, '\n') + io.write_byte(fi.writer, '\n', &fi.n) } defer { if hash { - for in 0.. 0 { io.write_string(fi.writer, ", ") } + if !hash && index > 0 { io.write_string(fi.writer, ", ", &fi.n) } field_count := -1 - if !hash && field_count > 0 { io.write_string(fi.writer, ", ") } + if !hash && field_count > 0 { io.write_string(fi.writer, ", ", &fi.n) } - io.write_string(fi.writer, base_type_name) - io.write_byte(fi.writer, '{') - defer io.write_byte(fi.writer, '}') + io.write_string(fi.writer, base_type_name, &fi.n) + io.write_byte(fi.writer, '{', &fi.n) + defer io.write_byte(fi.writer, '}', &fi.n) for name, i in b.names { field_count += 1 - if !hash && field_count > 0 { io.write_string(fi.writer, ", ") } + if !hash && field_count > 0 { io.write_string(fi.writer, ", ", &fi.n) } if hash { fmt_write_indent(fi) } - io.write_string(fi.writer, name) - io.write_string(fi.writer, " = ") + io.write_string(fi.writer, name, &fi.n) + io.write_string(fi.writer, " = ", &fi.n) t := b.types[i].variant.(runtime.Type_Info_Array).elem t_size := uintptr(t.size) if reflect.is_any(t) { - io.write_string(fi.writer, "any{}") + io.write_string(fi.writer, "any{}", &fi.n) } else { data := rawptr(uintptr(v.data) + b.offsets[i] + index*t_size) fmt_arg(fi, any{data, t.id}, 'v') } - if hash { io.write_string(fi.writer, ",\n") } + if hash { io.write_string(fi.writer, ",\n", &fi.n) } } } } else { @@ -1466,17 +1497,17 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { fmt_write_indent(fi) } - io.write_string(fi.writer, name) - io.write_string(fi.writer, " = ") + io.write_string(fi.writer, name, &fi.n) + io.write_string(fi.writer, " = ", &fi.n) if t := b.types[i]; reflect.is_any(t) { - io.write_string(fi.writer, "any{}") + io.write_string(fi.writer, "any{}", &fi.n) } else { data := rawptr(uintptr(v.data) + b.offsets[i]) fmt_arg(fi, any{data, t.id}, 'v') } - if hash { io.write_string(fi.writer, ",\n") } + if hash { io.write_string(fi.writer, ",\n", &fi.n) } } } @@ -1496,7 +1527,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { case runtime.Type_Info_Pointer: if v.id == typeid_of(^runtime.Type_Info) { - reflect.write_type(fi.writer, (^^runtime.Type_Info)(v.data)^) + reflect.write_type(fi.writer, (^^runtime.Type_Info)(v.data)^, &fi.n) } else { ptr := (^rawptr)(v.data)^ if verb != 'p' && info.elem != nil { @@ -1510,7 +1541,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { runtime.Type_Info_Dynamic_Array, runtime.Type_Info_Map: if ptr == nil { - io.write_string(fi.writer, "") + io.write_string(fi.writer, "", &fi.n) return } if fi.record_level < 1 { @@ -1524,13 +1555,13 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { case runtime.Type_Info_Struct, runtime.Type_Info_Union: if ptr == nil { - io.write_string(fi.writer, "") + io.write_string(fi.writer, "", &fi.n) return } if fi.record_level < 1 { fi.record_level += 1 defer fi.record_level -= 1 - io.write_byte(fi.writer, '&') + io.write_byte(fi.writer, '&', &fi.n) fmt_value(fi, a, verb) return } @@ -1553,13 +1584,13 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { runtime.Type_Info_Dynamic_Array, runtime.Type_Info_Map: if ptr == nil { - io.write_string(fi.writer, "") + io.write_string(fi.writer, "", &fi.n) return } if fi.record_level < 1 { fi.record_level += 1 defer fi.record_level -= 1 - io.write_byte(fi.writer, '&') + io.write_byte(fi.writer, '&', &fi.n) fmt_value(fi, a, verb) return } @@ -1567,13 +1598,13 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { case runtime.Type_Info_Struct, runtime.Type_Info_Union: if ptr == nil { - io.write_string(fi.writer, "") + io.write_string(fi.writer, "", &fi.n) return } if fi.record_level < 1 { fi.record_level += 1 defer fi.record_level -= 1 - io.write_byte(fi.writer, '&') + io.write_byte(fi.writer, '&', &fi.n) fmt_value(fi, a, verb) return } @@ -1592,11 +1623,11 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { case runtime.Type_Info_Enumerated_Array: if fi.hash { - io.write_string(fi.writer, "[\n") + io.write_string(fi.writer, "[\n", &fi.n) defer { - io.write_byte(fi.writer, '\n') + io.write_byte(fi.writer, '\n', &fi.n) fmt_write_indent(fi) - io.write_byte(fi.writer, ']') + io.write_byte(fi.writer, ']', &fi.n) } indent := fi.indent fi.indent += 1 @@ -1607,32 +1638,32 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { idx, ok := stored_enum_value_to_string(info.index, info.min_value, i) if ok { - io.write_byte(fi.writer, '.') - io.write_string(fi.writer, idx) + io.write_byte(fi.writer, '.', &fi.n) + io.write_string(fi.writer, idx, &fi.n) } else { - io.write_i64(fi.writer, i64(info.min_value)+i64(i)) + io.write_i64(fi.writer, i64(info.min_value)+i64(i), 10, &fi.n) } - io.write_string(fi.writer, " = ") + io.write_string(fi.writer, " = ", &fi.n) data := uintptr(v.data) + uintptr(i*info.elem_size) fmt_arg(fi, any{rawptr(data), info.elem.id}, verb) - io.write_string(fi.writer, ",\n") + io.write_string(fi.writer, ",\n", &fi.n) } } else { - io.write_byte(fi.writer, '[') - defer io.write_byte(fi.writer, ']') + io.write_byte(fi.writer, '[', &fi.n) + defer io.write_byte(fi.writer, ']', &fi.n) for i in 0.. 0 { io.write_string(fi.writer, ", ") } + if i > 0 { io.write_string(fi.writer, ", ", &fi.n) } idx, ok := stored_enum_value_to_string(info.index, info.min_value, i) if ok { - io.write_byte(fi.writer, '.') - io.write_string(fi.writer, idx) + io.write_byte(fi.writer, '.', &fi.n) + io.write_string(fi.writer, idx, &fi.n) } else { - io.write_i64(fi.writer, i64(info.min_value)+i64(i)) + io.write_i64(fi.writer, i64(info.min_value)+i64(i), 10, &fi.n) } - io.write_string(fi.writer, " = ") + io.write_string(fi.writer, " = ", &fi.n) data := uintptr(v.data) + uintptr(i*info.elem_size) fmt_arg(fi, any{rawptr(data), info.elem.id}, verb) @@ -1651,10 +1682,10 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { } case runtime.Type_Info_Simd_Vector: - io.write_byte(fi.writer, '<') - defer io.write_byte(fi.writer, '>') + io.write_byte(fi.writer, '<', &fi.n) + defer io.write_byte(fi.writer, '>', &fi.n) for i in 0.. 0 { io.write_string(fi.writer, ", ") } + if i > 0 { io.write_string(fi.writer, ", ", &fi.n) } data := uintptr(v.data) + uintptr(i*info.elem_size) fmt_arg(fi, any{rawptr(data), info.elem.id}, verb) @@ -1677,8 +1708,8 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { return } - io.write_string(fi.writer, "map[") - defer io.write_byte(fi.writer, ']') + io.write_string(fi.writer, "map[", &fi.n) + defer io.write_byte(fi.writer, ']', &fi.n) m := (^mem.Raw_Map)(v.data) if m != nil { @@ -1692,14 +1723,14 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { entry_size := ed.elem_size for i in 0.. 0 { io.write_string(fi.writer, ", ") } + if i > 0 { io.write_string(fi.writer, ", ", &fi.n) } data := uintptr(entries.data) + uintptr(i*entry_size) key := data + entry_type.offsets[2] fmt_arg(&Info{writer = fi.writer}, any{rawptr(key), info.key.id}, 'v') - io.write_string(fi.writer, "=") + io.write_string(fi.writer, "=", &fi.n) value := data + entry_type.offsets[3] fmt_arg(fi, any{rawptr(value), info.value.id}, 'v') @@ -1708,21 +1739,21 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { case runtime.Type_Info_Struct: if info.is_raw_union { - io.write_string(fi.writer, "(raw_union)") + io.write_string(fi.writer, "(raw_union)", &fi.n) return } is_soa := info.soa_kind != .None - io.write_byte(fi.writer, '[' if is_soa else '{') - defer io.write_byte(fi.writer, ']' if is_soa else '}') + io.write_byte(fi.writer, '[' if is_soa else '{', &fi.n) + defer io.write_byte(fi.writer, ']' if is_soa else '}', &fi.n) fi.indent += 1; defer fi.indent -= 1 hash := fi.hash; defer fi.hash = hash // fi.hash = false; - if hash { io.write_byte(fi.writer, '\n') } + if hash { io.write_byte(fi.writer, '\n', &fi.n) } if is_soa { fi.indent += 1 @@ -1751,33 +1782,33 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { for index in 0.. 0 { io.write_string(fi.writer, ", ") } + if !hash && index > 0 { io.write_string(fi.writer, ", ", &fi.n) } field_count := -1 - if !hash && field_count > 0 { io.write_string(fi.writer, ", ") } + if !hash && field_count > 0 { io.write_string(fi.writer, ", ", &fi.n) } - io.write_string(fi.writer, base_type_name) - io.write_byte(fi.writer, '{') - defer io.write_byte(fi.writer, '}') + io.write_string(fi.writer, base_type_name, &fi.n) + io.write_byte(fi.writer, '{', &fi.n) + defer io.write_byte(fi.writer, '}', &fi.n) for i in 0.. 0 { io.write_string(fi.writer, ", ") } + if !hash && field_count > 0 { io.write_string(fi.writer, ", ", &fi.n) } if hash { fmt_write_indent(fi) } - io.write_string(fi.writer, name) - io.write_string(fi.writer, " = ") + io.write_string(fi.writer, name, &fi.n) + io.write_string(fi.writer, " = ", &fi.n) if info.soa_kind == .Fixed { t := info.types[i].variant.(runtime.Type_Info_Array).elem t_size := uintptr(t.size) if reflect.is_any(t) { - io.write_string(fi.writer, "any{}") + io.write_string(fi.writer, "any{}", &fi.n) } else { data := rawptr(uintptr(v.data) + info.offsets[i] + index*t_size) fmt_arg(fi, any{data, t.id}, 'v') @@ -1786,7 +1817,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { t := info.types[i].variant.(runtime.Type_Info_Pointer).elem t_size := uintptr(t.size) if reflect.is_any(t) { - io.write_string(fi.writer, "any{}") + io.write_string(fi.writer, "any{}", &fi.n) } else { field_ptr := (^^byte)(uintptr(v.data) + info.offsets[i])^ data := rawptr(uintptr(field_ptr) + index*t_size) @@ -1794,7 +1825,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { } } - if hash { io.write_string(fi.writer, ",\n") } + if hash { io.write_string(fi.writer, ",\n", &fi.n) } } } } else { @@ -1802,23 +1833,23 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { for name, i in info.names { field_count += 1 - if !hash && field_count > 0 { io.write_string(fi.writer, ", ") } + if !hash && field_count > 0 { io.write_string(fi.writer, ", ", &fi.n) } if hash { fmt_write_indent(fi) } - io.write_string(fi.writer, name) - io.write_string(fi.writer, " = ") + io.write_string(fi.writer, name, &fi.n) + io.write_string(fi.writer, " = ", &fi.n) if t := info.types[i]; reflect.is_any(t) { - io.write_string(fi.writer, "any{}") + io.write_string(fi.writer, "any{}", &fi.n) } else { data := rawptr(uintptr(v.data) + info.offsets[i]) fmt_arg(fi, any{data, t.id}, 'v') } if hash { - io.write_string(fi.writer, ",\n") + io.write_string(fi.writer, ",\n", &fi.n) } } } @@ -1826,14 +1857,14 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { case runtime.Type_Info_Union: if type_info.size == 0 { - io.write_string(fi.writer, "nil") + io.write_string(fi.writer, "nil", &fi.n) return } if reflect.type_info_union_is_pure_maybe(info) { if v.data == nil { - io.write_string(fi.writer, "nil") + io.write_string(fi.writer, "nil", &fi.n) } else { id := info.variants[0].id fmt_arg(fi, any{v.data, id}, verb) @@ -1859,12 +1890,12 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { assert(tag >= 0) if v.data == nil { - io.write_string(fi.writer, "nil") + io.write_string(fi.writer, "nil", &fi.n) } else if info.no_nil { id := info.variants[tag].id fmt_arg(fi, any{v.data, id}, verb) } else if tag == 0 { - io.write_string(fi.writer, "nil") + io.write_string(fi.writer, "nil", &fi.n) } else { id := info.variants[tag-1].id fmt_arg(fi, any{v.data, id}, verb) @@ -1876,16 +1907,16 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { case runtime.Type_Info_Procedure: ptr := (^rawptr)(v.data)^ if ptr == nil { - io.write_string(fi.writer, "nil") + io.write_string(fi.writer, "nil", &fi.n) } else { - reflect.write_typeid(fi.writer, v.id) - io.write_string(fi.writer, " @ ") + reflect.write_typeid(fi.writer, v.id, &fi.n) + io.write_string(fi.writer, " @ ", &fi.n) fmt_pointer(fi, ptr, 'p') } case runtime.Type_Info_Type_Id: id := (^typeid)(v.data)^ - reflect.write_typeid(fi.writer, id) + reflect.write_typeid(fi.writer, id, &fi.n) case runtime.Type_Info_Bit_Set: fmt_bit_set(fi, v) @@ -1902,18 +1933,18 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { if verb == 'p' { fmt_pointer(fi, ptr, 'p') } else if ptr == nil { - io.write_string(fi.writer, "[]") + io.write_string(fi.writer, "[]", &fi.n) } else { len_ptr := uintptr(v.data) + uintptr(info.base_integer.size) len_any := any{rawptr(len_ptr), info.base_integer.id} len, _ := reflect.as_int(len_any) slice_type := reflect.type_info_base(info.slice).variant.(runtime.Type_Info_Slice) - io.write_byte(fi.writer, '[') - defer io.write_byte(fi.writer, ']') + io.write_byte(fi.writer, '[', &fi.n) + defer io.write_byte(fi.writer, ']', &fi.n) for i in 0.. 0 { io.write_string(fi.writer, ", ") } + if i > 0 { io.write_string(fi.writer, ", ", &fi.n) } data := uintptr(ptr) + uintptr(i*slice_type.elem_size) fmt_arg(fi, any{rawptr(data), slice_type.elem.id}, verb) @@ -1921,32 +1952,32 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { } case runtime.Type_Info_Matrix: - io.write_string(fi.writer, "matrix[") - defer io.write_byte(fi.writer, ']') + io.write_string(fi.writer, "matrix[", &fi.n) + defer io.write_byte(fi.writer, ']', &fi.n) fi.indent += 1 if fi.hash { // Printed as it is written - io.write_byte(fi.writer, '\n') + io.write_byte(fi.writer, '\n', &fi.n) for row in 0.. 0 { io.write_string(fi.writer, ", ") } + if col > 0 { io.write_string(fi.writer, ", ", &fi.n) } offset := (row + col*info.elem_stride)*info.elem_size data := uintptr(v.data) + uintptr(offset) fmt_arg(fi, any{rawptr(data), info.elem.id}, verb) } - io.write_string(fi.writer, ",\n") + io.write_string(fi.writer, ",\n", &fi.n) } } else { // Printed in Row-Major layout to match text layout for row in 0.. 0 { io.write_string(fi.writer, "; ") } + if row > 0 { io.write_string(fi.writer, "; ", &fi.n) } for col in 0.. 0 { io.write_string(fi.writer, ", ") } + if col > 0 { io.write_string(fi.writer, ", ", &fi.n) } offset := (row + col*info.elem_stride)*info.elem_size @@ -1970,10 +2001,10 @@ fmt_complex :: proc(fi: ^Info, c: complex128, bits: int, verb: rune) { r, i := real(c), imag(c) fmt_float(fi, r, bits/2, verb) if !fi.plus && i >= 0 { - io.write_rune(fi.writer, '+') + io.write_rune(fi.writer, '+', &fi.n) } fmt_float(fi, i, bits/2, verb) - io.write_rune(fi.writer, 'i') + io.write_rune(fi.writer, 'i', &fi.n) case: fmt_bad_verb(fi, verb) @@ -1989,22 +2020,22 @@ fmt_quaternion :: proc(fi: ^Info, q: quaternion256, bits: int, verb: rune) { fmt_float(fi, r, bits/4, verb) if !fi.plus && i >= 0 { - io.write_rune(fi.writer, '+') + io.write_rune(fi.writer, '+', &fi.n) } fmt_float(fi, i, bits/4, verb) - io.write_rune(fi.writer, 'i') + io.write_rune(fi.writer, 'i', &fi.n) if !fi.plus && j >= 0 { - io.write_rune(fi.writer, '+') + io.write_rune(fi.writer, '+', &fi.n) } fmt_float(fi, j, bits/4, verb) - io.write_rune(fi.writer, 'j') + io.write_rune(fi.writer, 'j', &fi.n) if !fi.plus && k >= 0 { - io.write_rune(fi.writer, '+') + io.write_rune(fi.writer, '+', &fi.n) } fmt_float(fi, k, bits/4, verb) - io.write_rune(fi.writer, 'k') + io.write_rune(fi.writer, 'k', &fi.n) case: fmt_bad_verb(fi, verb) @@ -2024,7 +2055,7 @@ fmt_arg :: proc(fi: ^Info, arg: any, verb: rune) { switch a in arg { case ^runtime.Type_Info: ti = a } - reflect.write_type(fi.writer, ti) + reflect.write_type(fi.writer, ti, &fi.n) return } @@ -2042,12 +2073,12 @@ fmt_arg :: proc(fi: ^Info, arg: any, verb: rune) { custom_types: switch a in arg { case runtime.Source_Code_Location: if fi.hash && verb == 'v' { - io.write_string(fi.writer, a.file_path) - io.write_byte(fi.writer, '(') - io.write_i64(fi.writer, i64(a.line), 10) - io.write_byte(fi.writer, ':') - io.write_i64(fi.writer, i64(a.column), 10) - io.write_byte(fi.writer, ')') + io.write_string(fi.writer, a.file_path, &fi.n) + io.write_byte(fi.writer, '(', &fi.n) + io.write_i64(fi.writer, i64(a.line), 10, &fi.n) + io.write_byte(fi.writer, ':', &fi.n) + io.write_i64(fi.writer, i64(a.column), 10, &fi.n) + io.write_byte(fi.writer, ')', &fi.n) return } } @@ -2099,7 +2130,7 @@ fmt_arg :: proc(fi: ^Info, arg: any, verb: rune) { case string: fmt_string(fi, a, verb) case cstring: fmt_cstring(fi, a, verb) - case typeid: reflect.write_typeid(fi.writer, a) + case typeid: reflect.write_typeid(fi.writer, a, &fi.n) case i16le: fmt_int(fi, u64(a), true, 16, verb) case u16le: fmt_int(fi, u64(a), false, 16, verb) diff --git a/core/fmt/fmt_js.odin b/core/fmt/fmt_js.odin index bcd9688a1..7a9876127 100644 --- a/core/fmt/fmt_js.odin +++ b/core/fmt/fmt_js.odin @@ -34,11 +34,16 @@ stderr := io.Writer{ }, } -// print* procedures return the number of bytes written +// print formats using the default print settings and writes to stdout print :: proc(args: ..any, sep := " ") -> int { return wprint(w=stdout, args=args, sep=sep) } +// println formats using the default print settings and writes to stdout println :: proc(args: ..any, sep := " ") -> int { return wprintln(w=stdout, args=args, sep=sep) } +// printf formats according to the specififed format string and writes to stdout printf :: proc(fmt: string, args: ..any) -> int { return wprintf(stdout, fmt, ..args) } +// eprint formats using the default print settings and writes to stderr eprint :: proc(args: ..any, sep := " ") -> int { return wprint(w=stderr, args=args, sep=sep) } +// eprintln formats using the default print settings and writes to stderr eprintln :: proc(args: ..any, sep := " ") -> int { return wprintln(w=stderr, args=args, sep=sep) } +// eprintf formats according to the specififed format string and writes to stderr eprintf :: proc(fmt: string, args: ..any) -> int { return wprintf(stderr, fmt, ..args) } diff --git a/core/fmt/fmt_os.odin b/core/fmt/fmt_os.odin index 7434d939d..f5c8d75bd 100644 --- a/core/fmt/fmt_os.odin +++ b/core/fmt/fmt_os.odin @@ -5,15 +5,18 @@ import "core:runtime" import "core:os" import "core:io" +// fprint formats using the default print settings and writes to fd fprint :: proc(fd: os.Handle, args: ..any, sep := " ") -> int { w := io.to_writer(os.stream_from_handle(fd)) return wprint(w=w, args=args, sep=sep) } +// fprintln formats using the default print settings and writes to fd fprintln :: proc(fd: os.Handle, args: ..any, sep := " ") -> int { w := io.to_writer(os.stream_from_handle(fd)) return wprintln(w=w, args=args, sep=sep) } +// fprintf formats according to the specififed format string and writes to fd fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int { w := io.to_writer(os.stream_from_handle(fd)) return wprintf(w, fmt, ..args) @@ -27,11 +30,16 @@ fprint_typeid :: proc(fd: os.Handle, id: typeid) -> (n: int, err: io.Error) { return wprint_typeid(w, id) } -// print* procedures return the number of bytes written +// print formats using the default print settings and writes to os.stdout print :: proc(args: ..any, sep := " ") -> int { return fprint(fd=os.stdout, args=args, sep=sep) } +// println formats using the default print settings and writes to os.stdout println :: proc(args: ..any, sep := " ") -> int { return fprintln(fd=os.stdout, args=args, sep=sep) } +// printf formats according to the specififed format string and writes to os.stdout printf :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stdout, fmt, ..args) } +// eprint formats using the default print settings and writes to os.stderr eprint :: proc(args: ..any, sep := " ") -> int { return fprint(fd=os.stderr, args=args, sep=sep) } +// eprintln formats using the default print settings and writes to os.stderr eprintln :: proc(args: ..any, sep := " ") -> int { return fprintln(fd=os.stderr, args=args, sep=sep) } +// eprintf formats according to the specififed format string and writes to os.stderr eprintf :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stderr, fmt, ..args) } diff --git a/core/hash/hash.odin b/core/hash/hash.odin index f0d01bd25..f2152f1b6 100644 --- a/core/hash/hash.odin +++ b/core/hash/hash.odin @@ -55,6 +55,23 @@ djb2 :: proc(data: []byte, seed := u32(5381)) -> u32 { return hash } +djbx33a :: proc(data: []byte, seed := u32(5381)) -> (result: [16]byte) #no_bounds_check { + state := [4]u32{seed, seed, seed, seed} + + s: u32 = 0 + for p in data { + state[s] = (state[s] << 5) + state[s] + u32(p) // hash * 33 + u32(b) + s = (s + 1) & 3 + } + + + (^u32le)(&result[0])^ = u32le(state[0]) + (^u32le)(&result[4])^ = u32le(state[1]) + (^u32le)(&result[8])^ = u32le(state[2]) + (^u32le)(&result[12])^ = u32le(state[3]) + return +} + @(optimization_mode="speed") fnv32 :: proc(data: []byte, seed := u32(0x811c9dc5)) -> u32 { h: u32 = seed @@ -134,7 +151,7 @@ murmur32 :: proc(data: []byte, seed := u32(0)) -> u32 { k1 ~= u32(tail[2]) << 16 fallthrough case 2: - k1 ~= u32(tail[2]) << 8 + k1 ~= u32(tail[1]) << 8 fallthrough case 1: k1 ~= u32(tail[0]) diff --git a/core/hash/xxhash/streaming.odin b/core/hash/xxhash/streaming.odin index 737e37eae..d6df1089f 100644 --- a/core/hash/xxhash/streaming.odin +++ b/core/hash/xxhash/streaming.odin @@ -96,7 +96,7 @@ XXH3_128_canonical_from_hash :: proc(hash: XXH128_hash_t) -> (canonical: XXH128_ #assert(size_of(XXH128_canonical) == size_of(XXH128_hash_t)) t := hash - when ODIN_ENDIAN == "little" { + when ODIN_ENDIAN == .Little { t.high = byte_swap(t.high) t.low = byte_swap(t.low) } diff --git a/core/image/common.odin b/core/image/common.odin index 3ec8e15be..8c77ec48a 100644 --- a/core/image/common.odin +++ b/core/image/common.odin @@ -6,6 +6,8 @@ Jeroen van Rijn: Initial implementation, optimization. Ginger Bill: Cosmetic changes. */ + +// package image implements a general 2D image library to be used with other image related packages package image import "core:bytes" @@ -13,6 +15,32 @@ import "core:mem" import "core:compress" import "core:runtime" +/* + 67_108_864 pixels max by default. + + For QOI, the Worst case scenario means all pixels will be encoded as RGBA literals, costing 5 bytes each. + This caps memory usage at 320 MiB. + + The tunable is limited to 4_294_836_225 pixels maximum, or 4 GiB per 8-bit channel. + It is not advised to tune it this large. + + The 64 Megapixel default is considered to be a decent upper bound you won't run into in practice, + except in very specific circumstances. + +*/ +MAX_DIMENSIONS :: min(#config(MAX_DIMENSIONS, 8192 * 8192), 65535 * 65535) + +// Color +RGB_Pixel :: [3]u8 +RGBA_Pixel :: [4]u8 +RGB_Pixel_16 :: [3]u16 +RGBA_Pixel_16 :: [4]u16 +// Grayscale +G_Pixel :: [1]u8 +GA_Pixel :: [2]u8 +G_Pixel_16 :: [1]u16 +GA_Pixel_16 :: [2]u16 + Image :: struct { width: int, height: int, @@ -24,15 +52,17 @@ Image :: struct { For convenience, we return them as u16 so we don't need to switch on the type in our viewer, and can just test against nil. */ - background: Maybe([3]u16), - + background: Maybe(RGB_Pixel_16), metadata: Image_Metadata, } Image_Metadata :: union { ^PNG_Info, + ^QOI_Info, } + + /* IMPORTANT: `.do_not_expand_*` options currently skip handling of the `alpha_*` options, therefore Gray+Alpha will be returned as such even if you add `.alpha_drop_if_present`, @@ -44,13 +74,13 @@ Image_Metadata :: union { /* Image_Option: `.info` - This option behaves as `.return_ihdr` and `.do_not_decompress_image` and can be used + This option behaves as `.return_metadata` and `.do_not_decompress_image` and can be used to gather an image's dimensions and color information. `.return_header` - Fill out img.sidecar.header with the image's format-specific header struct. + Fill out img.metadata.header with the image's format-specific header struct. If we only care about the image specs, we can set `.return_header` + - `.do_not_decompress_image`, or `.info`, which works as if both of these were set. + `.do_not_decompress_image`, or `.info`. `.return_metadata` Returns all chunks not needed to decode the data. @@ -86,7 +116,7 @@ Image_Option: `.alpha_premultiply` If the image has an alpha channel, returns image data as follows: - RGB *= A, Gray = Gray *= A + RGB *= A, Gray = Gray *= A `.blend_background` If a bKGD chunk is present in a PNG, we normally just set `img.background` @@ -101,24 +131,29 @@ Image_Option: */ Option :: enum { + // LOAD OPTIONS info = 0, do_not_decompress_image, return_header, return_metadata, - alpha_add_if_missing, - alpha_drop_if_present, - alpha_premultiply, - blend_background, + alpha_add_if_missing, // Ignored for QOI. Always returns RGBA8. + alpha_drop_if_present, // Unimplemented for QOI. Returns error. + alpha_premultiply, // Unimplemented for QOI. Returns error. + blend_background, // Ignored for non-PNG formats // Unimplemented do_not_expand_grayscale, do_not_expand_indexed, do_not_expand_channels, + + // SAVE OPTIONS + qoi_all_channels_linear, // QOI, informative info. If not set, defaults to sRGB with linear alpha. } Options :: distinct bit_set[Option] -Error :: union { +Error :: union #shared_nil { General_Image_Error, PNG_Error, + QOI_Error, compress.Error, compress.General_Error, @@ -132,9 +167,15 @@ General_Image_Error :: enum { Invalid_Image_Dimensions, Image_Dimensions_Too_Large, Image_Does_Not_Adhere_to_Spec, + Invalid_Input_Image, + Invalid_Output, } +/* + PNG-specific definitions +*/ PNG_Error :: enum { + None = 0, Invalid_PNG_Signature, IHDR_Not_First_Chunk, IHDR_Corrupt, @@ -144,7 +185,9 @@ PNG_Error :: enum { IDAT_Size_Too_Large, PLTE_Encountered_Unexpectedly, PLTE_Invalid_Length, + PLTE_Missing, TRNS_Encountered_Unexpectedly, + TNRS_Invalid_Length, BKGD_Invalid_Length, Unknown_Color_Type, Invalid_Color_Bit_Depth_Combo, @@ -155,9 +198,6 @@ PNG_Error :: enum { Invalid_Chunk_Length, } -/* - PNG-specific structs -*/ PNG_Info :: struct { header: PNG_IHDR, chunks: [dynamic]PNG_Chunk, @@ -220,7 +260,7 @@ PNG_Chunk_Type :: enum u32be { */ iDOT = 'i' << 24 | 'D' << 16 | 'O' << 8 | 'T', - CbGI = 'C' << 24 | 'b' << 16 | 'H' << 8 | 'I', + CgBI = 'C' << 24 | 'g' << 16 | 'B' << 8 | 'I', } PNG_IHDR :: struct #packed { @@ -248,16 +288,58 @@ PNG_Interlace_Method :: enum u8 { } /* - Functions to help with image buffer calculations + QOI-specific definitions */ +QOI_Error :: enum { + None = 0, + Invalid_QOI_Signature, + Invalid_Number_Of_Channels, // QOI allows 3 or 4 channel data. + Invalid_Bit_Depth, // QOI supports only 8-bit images, error only returned from writer. + Invalid_Color_Space, // QOI allows 0 = sRGB or 1 = linear. + Corrupt, // More data than pixels to decode into, for example. + Missing_Or_Corrupt_Trailer, // Image seemed to have decoded okay, but trailer is missing or corrupt. +} + +QOI_Magic :: u32be(0x716f6966) // "qoif" + +QOI_Color_Space :: enum u8 { + sRGB = 0, + Linear = 1, +} + +QOI_Header :: struct #packed { + magic: u32be, + width: u32be, + height: u32be, + channels: u8, + color_space: QOI_Color_Space, +} +#assert(size_of(QOI_Header) == 14) + +QOI_Info :: struct { + header: QOI_Header, +} + +TGA_Header :: struct #packed { + id_length: u8, + color_map_type: u8, + data_type_code: u8, + color_map_origin: u16le, + color_map_length: u16le, + color_map_depth: u8, + origin: [2]u16le, + dimensions: [2]u16le, + bits_per_pixel: u8, + image_descriptor: u8, +} +#assert(size_of(TGA_Header) == 18) + +// Function to help with image buffer calculations compute_buffer_size :: proc(width, height, channels, depth: int, extra_row_bytes := int(0)) -> (size: int) { size = ((((channels * width * depth) + 7) >> 3) + extra_row_bytes) * height return } -/* - For when you have an RGB(A) image, but want a particular channel. -*/ Channel :: enum u8 { R = 1, G = 2, @@ -265,7 +347,13 @@ Channel :: enum u8 { A = 4, } +// When you have an RGB(A) image, but want a particular channel. return_single_channel :: proc(img: ^Image, channel: Channel) -> (res: ^Image, ok: bool) { + // Were we actually given a valid image? + if img == nil { + return nil, false + } + ok = false t: bytes.Buffer @@ -295,7 +383,7 @@ return_single_channel :: proc(img: ^Image, channel: Channel) -> (res: ^Image, ok o = o[1:] } case 16: - buffer_size := compute_buffer_size(img.width, img.height, 2, 8) + buffer_size := compute_buffer_size(img.width, img.height, 1, 16) t = bytes.Buffer{} resize(&t.buf, buffer_size) @@ -323,3 +411,724 @@ return_single_channel :: proc(img: ^Image, channel: Channel) -> (res: ^Image, ok return res, true } + +// Does the image have 1 or 2 channels, a valid bit depth (8 or 16), +// Is the pointer valid, are the dimenions valid? +is_valid_grayscale_image :: proc(img: ^Image) -> (ok: bool) { + // Were we actually given a valid image? + if img == nil { + return false + } + + // Are we a Gray or Gray + Alpha image? + if img.channels != 1 && img.channels != 2 { + return false + } + + // Do we have an acceptable bit depth? + if img.depth != 8 && img.depth != 16 { + return false + } + + // This returns 0 if any of the inputs is zero. + bytes_expected := compute_buffer_size(img.width, img.height, img.channels, img.depth) + + // If the dimenions are invalid or the buffer size doesn't match the image characteristics, bail. + if bytes_expected == 0 || bytes_expected != len(img.pixels.buf) || img.width * img.height > MAX_DIMENSIONS { + return false + } + + return true +} + +// Does the image have 3 or 4 channels, a valid bit depth (8 or 16), +// Is the pointer valid, are the dimenions valid? +is_valid_color_image :: proc(img: ^Image) -> (ok: bool) { + // Were we actually given a valid image? + if img == nil { + return false + } + + // Are we an RGB or RGBA image? + if img.channels != 3 && img.channels != 4 { + return false + } + + // Do we have an acceptable bit depth? + if img.depth != 8 && img.depth != 16 { + return false + } + + // This returns 0 if any of the inputs is zero. + bytes_expected := compute_buffer_size(img.width, img.height, img.channels, img.depth) + + // If the dimenions are invalid or the buffer size doesn't match the image characteristics, bail. + if bytes_expected == 0 || bytes_expected != len(img.pixels.buf) || img.width * img.height > MAX_DIMENSIONS { + return false + } + + return true +} + +// Does the image have 1..4 channels, a valid bit depth (8 or 16), +// Is the pointer valid, are the dimenions valid? +is_valid_image :: proc(img: ^Image) -> (ok: bool) { + // Were we actually given a valid image? + if img == nil { + return false + } + + return is_valid_color_image(img) || is_valid_grayscale_image(img) +} + +Alpha_Key :: union { + GA_Pixel, + RGBA_Pixel, + GA_Pixel_16, + RGBA_Pixel_16, +} + +/* + Add alpha channel if missing, in-place. + + Expects 1..4 channels (Gray, Gray + Alpha, RGB, RGBA). + Any other number of channels will be considered an error, returning `false` without modifying the image. + If the input image already has an alpha channel, it'll return `true` early (without considering optional keyed alpha). + + If an image doesn't already have an alpha channel: + If the optional `alpha_key` is provided, it will be resolved as follows: + - For RGB, if pix = key.rgb -> pix = {0, 0, 0, key.a} + - For Gray, if pix = key.r -> pix = {0, key.g} + Otherwise, an opaque alpha channel will be added. +*/ +alpha_add_if_missing :: proc(img: ^Image, alpha_key := Alpha_Key{}, allocator := context.allocator) -> (ok: bool) { + context.allocator = allocator + + if !is_valid_image(img) { + return false + } + + // We should now have a valid Image with 1..4 channels. Do we already have alpha? + if img.channels == 2 || img.channels == 4 { + // We're done. + return true + } + + channels := img.channels + 1 + bytes_wanted := compute_buffer_size(img.width, img.height, channels, img.depth) + + buf := bytes.Buffer{} + + // Can we allocate the return buffer? + if !resize(&buf.buf, bytes_wanted) { + delete(buf.buf) + return false + } + + switch img.depth { + case 8: + switch channels { + case 2: + // Turn Gray into Gray + Alpha + inp := mem.slice_data_cast([]G_Pixel, img.pixels.buf[:]) + out := mem.slice_data_cast([]GA_Pixel, buf.buf[:]) + + if key, key_ok := alpha_key.(GA_Pixel); key_ok { + // We have keyed alpha. + o: GA_Pixel + for p in inp { + if p == key.r { + o = GA_Pixel{0, key.g} + } else { + o = GA_Pixel{p.r, 255} + } + out[0] = o + out = out[1:] + } + } else { + // No keyed alpha, just make all pixels opaque. + o := GA_Pixel{0, 255} + for p in inp { + o.r = p.r + out[0] = o + out = out[1:] + } + } + + case 4: + // Turn RGB into RGBA + inp := mem.slice_data_cast([]RGB_Pixel, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGBA_Pixel, buf.buf[:]) + + if key, key_ok := alpha_key.(RGBA_Pixel); key_ok { + // We have keyed alpha. + o: RGBA_Pixel + for p in inp { + if p == key.rgb { + o = RGBA_Pixel{0, 0, 0, key.a} + } else { + o = RGBA_Pixel{p.r, p.g, p.b, 255} + } + out[0] = o + out = out[1:] + } + } else { + // No keyed alpha, just make all pixels opaque. + o := RGBA_Pixel{0, 0, 0, 255} + for p in inp { + o.rgb = p + out[0] = o + out = out[1:] + } + } + case: + // We shouldn't get here. + unreachable() + } + case 16: + switch channels { + case 2: + // Turn Gray into Gray + Alpha + inp := mem.slice_data_cast([]G_Pixel_16, img.pixels.buf[:]) + out := mem.slice_data_cast([]GA_Pixel_16, buf.buf[:]) + + if key, key_ok := alpha_key.(GA_Pixel_16); key_ok { + // We have keyed alpha. + o: GA_Pixel_16 + for p in inp { + if p == key.r { + o = GA_Pixel_16{0, key.g} + } else { + o = GA_Pixel_16{p.r, 65535} + } + out[0] = o + out = out[1:] + } + } else { + // No keyed alpha, just make all pixels opaque. + o := GA_Pixel_16{0, 65535} + for p in inp { + o.r = p.r + out[0] = o + out = out[1:] + } + } + + case 4: + // Turn RGB into RGBA + inp := mem.slice_data_cast([]RGB_Pixel_16, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGBA_Pixel_16, buf.buf[:]) + + if key, key_ok := alpha_key.(RGBA_Pixel_16); key_ok { + // We have keyed alpha. + o: RGBA_Pixel_16 + for p in inp { + if p == key.rgb { + o = RGBA_Pixel_16{0, 0, 0, key.a} + } else { + o = RGBA_Pixel_16{p.r, p.g, p.b, 65535} + } + out[0] = o + out = out[1:] + } + } else { + // No keyed alpha, just make all pixels opaque. + o := RGBA_Pixel_16{0, 0, 0, 65535} + for p in inp { + o.rgb = p + out[0] = o + out = out[1:] + } + } + case: + // We shouldn't get here. + unreachable() + } + } + + // If we got here, that means we've now got a buffer with the alpha channel added. + // Destroy the old pixel buffer and replace it with the new one, and update the channel count. + bytes.buffer_destroy(&img.pixels) + img.pixels = buf + img.channels = channels + return true +} +alpha_apply_keyed_alpha :: alpha_add_if_missing + +/* + Drop alpha channel if present, in-place. + + Expects 1..4 channels (Gray, Gray + Alpha, RGB, RGBA). + Any other number of channels will be considered an error, returning `false` without modifying the image. + + Of the `options`, the following are considered: + `.alpha_premultiply` + If the image has an alpha channel, returns image data as follows: + RGB *= A, Gray = Gray *= A + + `.blend_background` + If `img.background` is set, it'll be blended in like this: + RGB = (1 - A) * Background + A * RGB + + If an image has 1 (Gray) or 3 (RGB) channels, it'll return early without modifying the image, + with one exception: `alpha_key` and `img.background` are present, and `.blend_background` is set. + + In this case a keyed alpha pixel will be replaced with the background color. +*/ +alpha_drop_if_present :: proc(img: ^Image, options := Options{}, alpha_key := Alpha_Key{}, allocator := context.allocator) -> (ok: bool) { + context.allocator = allocator + + if !is_valid_image(img) { + return false + } + + // Do we have a background to blend? + will_it_blend := false + switch v in img.background { + case RGB_Pixel_16: will_it_blend = true if .blend_background in options else false + } + + // Do we have keyed alpha? + keyed := false + switch v in alpha_key { + case GA_Pixel: keyed = true if img.channels == 1 && img.depth == 8 else false + case RGBA_Pixel: keyed = true if img.channels == 3 && img.depth == 8 else false + case GA_Pixel_16: keyed = true if img.channels == 1 && img.depth == 16 else false + case RGBA_Pixel_16: keyed = true if img.channels == 3 && img.depth == 16 else false + } + + // We should now have a valid Image with 1..4 channels. Do we have alpha? + if img.channels == 1 || img.channels == 3 { + if !(will_it_blend && keyed) { + // We're done + return true + } + } + + // # of destination channels + channels := 1 if img.channels < 3 else 3 + + bytes_wanted := compute_buffer_size(img.width, img.height, channels, img.depth) + buf := bytes.Buffer{} + + // Can we allocate the return buffer? + if !resize(&buf.buf, bytes_wanted) { + delete(buf.buf) + return false + } + + switch img.depth { + case 8: + switch img.channels { + case 1: // Gray to Gray, but we should have keyed alpha + background. + inp := mem.slice_data_cast([]G_Pixel, img.pixels.buf[:]) + out := mem.slice_data_cast([]G_Pixel, buf.buf[:]) + + key := alpha_key.(GA_Pixel).r + bg := G_Pixel{} + if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok { + // Background is RGB 16-bit, take just the red channel's topmost byte. + bg = u8(temp_bg.r >> 8) + } + + for p in inp { + out[0] = bg if p == key else p + out = out[1:] + } + + case 2: // Gray + Alpha to Gray, no keyed alpha but we can have a background. + inp := mem.slice_data_cast([]GA_Pixel, img.pixels.buf[:]) + out := mem.slice_data_cast([]G_Pixel, buf.buf[:]) + + if will_it_blend { + // Blend with background "color", then drop alpha. + bg := f32(0.0) + if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok { + // Background is RGB 16-bit, take just the red channel's topmost byte. + bg = f32(temp_bg.r >> 8) + } + + for p in inp { + a := f32(p.g) / 255.0 + c := ((1.0 - a) * bg + a * f32(p.r)) + out[0] = u8(c) + out = out[1:] + } + + } else if .alpha_premultiply in options { + // Premultiply component with alpha, then drop alpha. + for p in inp { + a := f32(p.g) / 255.0 + c := f32(p.r) * a + out[0] = u8(c) + out = out[1:] + } + } else { + // Just drop alpha on the floor. + for p in inp { + out[0] = p.r + out = out[1:] + } + } + + case 3: // RGB to RGB, but we should have keyed alpha + background. + inp := mem.slice_data_cast([]RGB_Pixel, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGB_Pixel, buf.buf[:]) + + key := alpha_key.(RGBA_Pixel) + bg := RGB_Pixel{} + if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok { + // Background is RGB 16-bit, squash down to 8 bits. + bg = {u8(temp_bg.r >> 8), u8(temp_bg.g >> 8), u8(temp_bg.b >> 8)} + } + + for p in inp { + out[0] = bg if p == key.rgb else p + out = out[1:] + } + + case 4: // RGBA to RGB, no keyed alpha but we can have a background or need to premultiply. + inp := mem.slice_data_cast([]RGBA_Pixel, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGB_Pixel, buf.buf[:]) + + if will_it_blend { + // Blend with background "color", then drop alpha. + bg := [3]f32{} + if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok { + // Background is RGB 16-bit, take just the red channel's topmost byte. + bg = {f32(temp_bg.r >> 8), f32(temp_bg.g >> 8), f32(temp_bg.b >> 8)} + } + + for p in inp { + a := f32(p.a) / 255.0 + rgb := [3]f32{f32(p.r), f32(p.g), f32(p.b)} + c := ((1.0 - a) * bg + a * rgb) + + out[0] = {u8(c.r), u8(c.g), u8(c.b)} + out = out[1:] + } + + } else if .alpha_premultiply in options { + // Premultiply component with alpha, then drop alpha. + for p in inp { + a := f32(p.a) / 255.0 + rgb := [3]f32{f32(p.r), f32(p.g), f32(p.b)} + c := rgb * a + + out[0] = {u8(c.r), u8(c.g), u8(c.b)} + out = out[1:] + } + } else { + // Just drop alpha on the floor. + for p in inp { + out[0] = p.rgb + out = out[1:] + } + } + } + + case 16: + switch img.channels { + case 1: // Gray to Gray, but we should have keyed alpha + background. + inp := mem.slice_data_cast([]G_Pixel_16, img.pixels.buf[:]) + out := mem.slice_data_cast([]G_Pixel_16, buf.buf[:]) + + key := alpha_key.(GA_Pixel_16).r + bg := G_Pixel_16{} + if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok { + // Background is RGB 16-bit, take just the red channel. + bg = temp_bg.r + } + + for p in inp { + out[0] = bg if p == key else p + out = out[1:] + } + + case 2: // Gray + Alpha to Gray, no keyed alpha but we can have a background. + inp := mem.slice_data_cast([]GA_Pixel_16, img.pixels.buf[:]) + out := mem.slice_data_cast([]G_Pixel_16, buf.buf[:]) + + if will_it_blend { + // Blend with background "color", then drop alpha. + bg := f32(0.0) + if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok { + // Background is RGB 16-bit, take just the red channel. + bg = f32(temp_bg.r) + } + + for p in inp { + a := f32(p.g) / 65535.0 + c := ((1.0 - a) * bg + a * f32(p.r)) + out[0] = u16(c) + out = out[1:] + } + + } else if .alpha_premultiply in options { + // Premultiply component with alpha, then drop alpha. + for p in inp { + a := f32(p.g) / 65535.0 + c := f32(p.r) * a + out[0] = u16(c) + out = out[1:] + } + } else { + // Just drop alpha on the floor. + for p in inp { + out[0] = p.r + out = out[1:] + } + } + + case 3: // RGB to RGB, but we should have keyed alpha + background. + inp := mem.slice_data_cast([]RGB_Pixel_16, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGB_Pixel_16, buf.buf[:]) + + key := alpha_key.(RGBA_Pixel_16) + bg := img.background.(RGB_Pixel_16) + + for p in inp { + out[0] = bg if p == key.rgb else p + out = out[1:] + } + + case 4: // RGBA to RGB, no keyed alpha but we can have a background or need to premultiply. + inp := mem.slice_data_cast([]RGBA_Pixel_16, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGB_Pixel_16, buf.buf[:]) + + if will_it_blend { + // Blend with background "color", then drop alpha. + bg := [3]f32{} + if temp_bg, temp_bg_ok := img.background.(RGB_Pixel_16); temp_bg_ok { + // Background is RGB 16-bit, convert to [3]f32 to blend. + bg = {f32(temp_bg.r), f32(temp_bg.g), f32(temp_bg.b)} + } + + for p in inp { + a := f32(p.a) / 65535.0 + rgb := [3]f32{f32(p.r), f32(p.g), f32(p.b)} + c := ((1.0 - a) * bg + a * rgb) + + out[0] = {u16(c.r), u16(c.g), u16(c.b)} + out = out[1:] + } + + } else if .alpha_premultiply in options { + // Premultiply component with alpha, then drop alpha. + for p in inp { + a := f32(p.a) / 65535.0 + rgb := [3]f32{f32(p.r), f32(p.g), f32(p.b)} + c := rgb * a + + out[0] = {u16(c.r), u16(c.g), u16(c.b)} + out = out[1:] + } + } else { + // Just drop alpha on the floor. + for p in inp { + out[0] = p.rgb + out = out[1:] + } + } + } + + case: + unreachable() + } + + // If we got here, that means we've now got a buffer with the alpha channel dropped. + // Destroy the old pixel buffer and replace it with the new one, and update the channel count. + bytes.buffer_destroy(&img.pixels) + img.pixels = buf + img.channels = channels + return true +} + +// Apply palette to 8-bit single-channel image and return an 8-bit RGB image, in-place. +// If the image given is not a valid 8-bit single channel image, the procedure will return `false` early. +apply_palette_rgb :: proc(img: ^Image, palette: [256]RGB_Pixel, allocator := context.allocator) -> (ok: bool) { + context.allocator = allocator + + if img == nil || img.channels != 1 || img.depth != 8 { + return false + } + + bytes_expected := compute_buffer_size(img.width, img.height, 1, 8) + if bytes_expected == 0 || bytes_expected != len(img.pixels.buf) || img.width * img.height > MAX_DIMENSIONS { + return false + } + + // Can we allocate the return buffer? + buf := bytes.Buffer{} + bytes_wanted := compute_buffer_size(img.width, img.height, 3, 8) + if !resize(&buf.buf, bytes_wanted) { + delete(buf.buf) + return false + } + + out := mem.slice_data_cast([]RGB_Pixel, buf.buf[:]) + + // Apply the palette + for p, i in img.pixels.buf { + out[i] = palette[p] + } + + // If we got here, that means we've now got a buffer with the alpha channel dropped. + // Destroy the old pixel buffer and replace it with the new one, and update the channel count. + bytes.buffer_destroy(&img.pixels) + img.pixels = buf + img.channels = 3 + return true +} + +// Apply palette to 8-bit single-channel image and return an 8-bit RGBA image, in-place. +// If the image given is not a valid 8-bit single channel image, the procedure will return `false` early. +apply_palette_rgba :: proc(img: ^Image, palette: [256]RGBA_Pixel, allocator := context.allocator) -> (ok: bool) { + context.allocator = allocator + + if img == nil || img.channels != 1 || img.depth != 8 { + return false + } + + bytes_expected := compute_buffer_size(img.width, img.height, 1, 8) + if bytes_expected == 0 || bytes_expected != len(img.pixels.buf) || img.width * img.height > MAX_DIMENSIONS { + return false + } + + // Can we allocate the return buffer? + buf := bytes.Buffer{} + bytes_wanted := compute_buffer_size(img.width, img.height, 4, 8) + if !resize(&buf.buf, bytes_wanted) { + delete(buf.buf) + return false + } + + out := mem.slice_data_cast([]RGBA_Pixel, buf.buf[:]) + + // Apply the palette + for p, i in img.pixels.buf { + out[i] = palette[p] + } + + // If we got here, that means we've now got a buffer with the alpha channel dropped. + // Destroy the old pixel buffer and replace it with the new one, and update the channel count. + bytes.buffer_destroy(&img.pixels) + img.pixels = buf + img.channels = 4 + return true +} +apply_palette :: proc{apply_palette_rgb, apply_palette_rgba} + + +// Replicates grayscale values into RGB(A) 8- or 16-bit images as appropriate. +// Returns early with `false` if already an RGB(A) image. +expand_grayscale :: proc(img: ^Image, allocator := context.allocator) -> (ok: bool) { + context.allocator = allocator + + if !is_valid_grayscale_image(img) { + return false + } + + // We should have 1 or 2 channels of 8- or 16 bits now. We need to turn that into 3 or 4. + // Can we allocate the return buffer? + buf := bytes.Buffer{} + bytes_wanted := compute_buffer_size(img.width, img.height, img.channels + 2, img.depth) + if !resize(&buf.buf, bytes_wanted) { + delete(buf.buf) + return false + } + + switch img.depth { + case 8: + switch img.channels { + case 1: // Turn Gray into RGB + out := mem.slice_data_cast([]RGB_Pixel, buf.buf[:]) + + for p in img.pixels.buf { + out[0] = p // Broadcast gray value into RGB components. + out = out[1:] + } + + case 2: // Turn Gray + Alpha into RGBA + inp := mem.slice_data_cast([]GA_Pixel, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGBA_Pixel, buf.buf[:]) + + for p in inp { + out[0].rgb = p.r // Gray component. + out[0].a = p.g // Alpha component. + } + + case: + unreachable() + } + + case 16: + switch img.channels { + case 1: // Turn Gray into RGB + inp := mem.slice_data_cast([]u16, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGB_Pixel_16, buf.buf[:]) + + for p in inp { + out[0] = p // Broadcast gray value into RGB components. + out = out[1:] + } + + case 2: // Turn Gray + Alpha into RGBA + inp := mem.slice_data_cast([]GA_Pixel_16, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGBA_Pixel_16, buf.buf[:]) + + for p in inp { + out[0].rgb = p.r // Gray component. + out[0].a = p.g // Alpha component. + } + + case: + unreachable() + } + + case: + unreachable() + } + + + // If we got here, that means we've now got a buffer with the extra alpha channel. + // Destroy the old pixel buffer and replace it with the new one, and update the channel count. + bytes.buffer_destroy(&img.pixels) + img.pixels = buf + img.channels += 2 + return true +} + +/* + Helper functions to read and write data from/to a Context, etc. +*/ +@(optimization_mode="speed") +read_data :: proc(z: $C, $T: typeid) -> (res: T, err: compress.General_Error) { + if r, e := compress.read_data(z, T); e != .None { + return {}, .Stream_Too_Short + } else { + return r, nil + } +} + +@(optimization_mode="speed") +read_u8 :: proc(z: $C) -> (res: u8, err: compress.General_Error) { + if r, e := compress.read_u8(z); e != .None { + return {}, .Stream_Too_Short + } else { + return r, nil + } +} + +write_bytes :: proc(buf: ^bytes.Buffer, data: []u8) -> (err: compress.General_Error) { + if len(data) == 0 { + return nil + } else if len(data) == 1 { + if bytes.buffer_write_byte(buf, data[0]) != nil { + return compress.General_Error.Resize_Failed + } + } else if n, _ := bytes.buffer_write(buf, data); n != len(data) { + return compress.General_Error.Resize_Failed + } + return nil +} \ No newline at end of file diff --git a/core/image/png/example.odin b/core/image/png/example.odin index 5e7dca4c8..17436c260 100644 --- a/core/image/png/example.odin +++ b/core/image/png/example.odin @@ -189,7 +189,7 @@ write_image_as_ppm :: proc(filename: string, image: ^image.Image) -> (success: b img := image // PBM 16-bit images are big endian - when ODIN_ENDIAN == "little" { + when ODIN_ENDIAN == .Little { if img.depth == 16 { // The pixel components are in Big Endian. Let's byteswap back. input := mem.slice_data_cast([]u16, img.pixels.buf[:]) @@ -207,7 +207,7 @@ write_image_as_ppm :: proc(filename: string, image: ^image.Image) -> (success: b } mode: int = 0 - when ODIN_OS == "linux" || ODIN_OS == "darwin" { + when ODIN_OS == .Linux || ODIN_OS == .Darwin { // NOTE(justasd): 644 (owner read, write; group read; others read) mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH } diff --git a/core/image/png/helpers.odin b/core/image/png/helpers.odin index ecc0183bc..0ebf0b20b 100644 --- a/core/image/png/helpers.odin +++ b/core/image/png/helpers.odin @@ -242,17 +242,16 @@ srgb :: proc(c: image.PNG_Chunk) -> (res: sRGB, ok: bool) { } plte :: proc(c: image.PNG_Chunk) -> (res: PLTE, ok: bool) { - if c.header.type != .PLTE { + if c.header.type != .PLTE || c.header.length % 3 != 0 || c.header.length > 768 { return {}, false } - i := 0; j := 0; ok = true - for j < int(c.header.length) { - res.entries[i] = {c.data[j], c.data[j+1], c.data[j+2]} - i += 1; j += 3 + plte := mem.slice_data_cast([]image.RGB_Pixel, c.data[:]) + for color, i in plte { + res.entries[i] = color } - res.used = u16(i) - return + res.used = u16(len(plte)) + return res, true } splt :: proc(c: image.PNG_Chunk) -> (res: sPLT, ok: bool) { @@ -439,18 +438,18 @@ when false { flags: int = O_WRONLY|O_CREATE|O_TRUNC if len(image.pixels) == 0 || len(image.pixels) < image.width * image.height * int(image.channels) { - return E_PNG.Invalid_Image_Dimensions + return .Invalid_Image_Dimensions } mode: int = 0 - when ODIN_OS == "linux" || ODIN_OS == "darwin" { + when ODIN_OS == .Linux || ODIN_OS == .Darwin { // NOTE(justasd): 644 (owner read, write; group read; others read) mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH } fd, fderr := open(filename, flags, mode) if fderr != 0 { - return E_General.Cannot_Open_File + return .Cannot_Open_File } defer close(fd) @@ -473,7 +472,7 @@ when false { case 3: ihdr.color_type = Color_Type{.Color} case 4: ihdr.color_type = Color_Type{.Color, .Alpha} case:// Unhandled - return E_PNG.Unknown_Color_Type + return .Unknown_Color_Type } h := make_chunk(ihdr, .IHDR) write_chunk(fd, h) diff --git a/core/image/png/png.odin b/core/image/png/png.odin index f77bf7519..ba888cb78 100644 --- a/core/image/png/png.odin +++ b/core/image/png/png.odin @@ -6,6 +6,11 @@ Jeroen van Rijn: Initial implementation. Ginger Bill: Cosmetic changes. */ + + +// package png implements a PNG image reader +// +// The PNG specification is at https://www.w3.org/TR/PNG/. package png import "core:compress" @@ -20,16 +25,10 @@ import "core:io" import "core:mem" import "core:intrinsics" -/* - 67_108_864 pixels max by default. - Maximum allowed dimensions are capped at 65535 * 65535. -*/ -MAX_DIMENSIONS :: min(#config(PNG_MAX_DIMENSIONS, 8192 * 8192), 65535 * 65535) +// Limit chunk sizes. +// By default: IDAT = 8k x 8k x 16-bits + 8k filter bytes. +// The total number of pixels defaults to 64 Megapixel and can be tuned in image/common.odin. -/* - Limit chunk sizes. - By default: IDAT = 8k x 8k x 16-bits + 8k filter bytes. -*/ _MAX_IDAT_DEFAULT :: ( 8192 /* Width */ * 8192 /* Height */ * 2 /* 16-bit */) + 8192 /* Filter bytes */ _MAX_IDAT :: (65535 /* Width */ * 65535 /* Height */ * 2 /* 16-bit */) + 65535 /* Filter bytes */ @@ -59,7 +58,7 @@ Row_Filter :: enum u8 { Paeth = 4, } -PLTE_Entry :: [3]u8 +PLTE_Entry :: image.RGB_Pixel PLTE :: struct #packed { entries: [256]PLTE_Entry, @@ -254,7 +253,7 @@ read_header :: proc(ctx: ^$C) -> (image.PNG_IHDR, Error) { header := (^image.PNG_IHDR)(raw_data(c.data))^ // Validate IHDR using header - if width == 0 || height == 0 || u128(width) * u128(height) > MAX_DIMENSIONS { + if width == 0 || height == 0 || u128(width) * u128(height) > image.MAX_DIMENSIONS { return {}, .Invalid_Image_Dimensions } @@ -361,6 +360,10 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a options -= {.info} } + if .return_header in options && .return_metadata in options { + options -= {.return_header} + } + if .alpha_drop_if_present in options && .alpha_add_if_missing in options { return {}, compress.General_Error.Incompatible_Options } @@ -387,7 +390,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a idat_length := u64(0) - c: image.PNG_Chunk + c: image.PNG_Chunk ch: image.PNG_Chunk_Header e: io.Error @@ -468,6 +471,10 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a } info.header = h + if .return_header in options && .return_metadata not_in options && .do_not_decompress_image not_in options { + return img, nil + } + case .PLTE: seen_plte = true // PLTE must appear before IDAT and can't appear for color types 0, 4. @@ -535,9 +542,6 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a seen_iend = true case .bKGD: - - // TODO: Make sure that 16-bit bKGD + tRNS chunks return u16 instead of u16be - c = read_chunk(ctx) or_return seen_bkgd = true if .return_metadata in options { @@ -589,23 +593,36 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a */ final_image_channels += 1 - seen_trns = true + + if .Paletted in header.color_type { + if len(c.data) > 256 { + return img, .TNRS_Invalid_Length + } + } else if .Color in header.color_type { + if len(c.data) != 6 { + return img, .TNRS_Invalid_Length + } + } else if len(c.data) != 2 { + return img, .TNRS_Invalid_Length + } + if info.header.bit_depth < 8 && .Paletted not_in info.header.color_type { // Rescale tRNS data so key matches intensity - dsc := depth_scale_table + dsc := depth_scale_table scale := dsc[info.header.bit_depth] if scale != 1 { key := mem.slice_data_cast([]u16be, c.data)[0] * u16be(scale) c.data = []u8{0, u8(key & 255)} } } + trns = c - case .iDOT, .CbGI: + case .iDOT, .CgBI: /* iPhone PNG bastardization that doesn't adhere to spec with broken IDAT chunk. - We're not going to add support for it. If you have the misfortunte of coming + We're not going to add support for it. If you have the misfortune of coming across one of these files, use a utility to defry it. */ return img, .Image_Does_Not_Adhere_to_Spec @@ -630,6 +647,10 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a return img, .IDAT_Missing } + if .Paletted in header.color_type && !seen_plte { + return img, .PLTE_Missing + } + /* Calculate the expected output size, to help `inflate` make better decisions about the output buffer. We'll also use it to check the returned buffer size is what we expected it to be. @@ -678,15 +699,6 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a return {}, defilter_error } - /* - Now we'll handle the relocoring of paletted images, handling of tRNS chunks, - and we'll expand grayscale images to RGB(A). - - For the sake of convenience we return only RGB(A) images. In the future we - may supply an option to return Gray/Gray+Alpha as-is, in which case RGB(A) - will become the default. - */ - if .Paletted in header.color_type && .do_not_expand_indexed in options { return img, nil } @@ -694,7 +706,10 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a return img, nil } - + /* + Now we're going to optionally apply various post-processing stages, + to for example expand grayscale, apply a palette, premultiply alpha, etc. + */ raw_image_channels := img.channels out_image_channels := 3 @@ -1199,7 +1214,6 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a return img, nil } - filter_paeth :: #force_inline proc(left, up, up_left: u8) -> u8 { aa, bb, cc := i16(left), i16(up), i16(up_left) p := aa + bb - cc @@ -1611,7 +1625,7 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^image.PNG_IH } } } - when ODIN_ENDIAN == "little" { + when ODIN_ENDIAN == .Little { if img.depth == 16 { // The pixel components are in Big Endian. Let's byteswap. input := mem.slice_data_cast([]u16be, img.pixels.buf[:]) diff --git a/core/image/qoi/qoi.odin b/core/image/qoi/qoi.odin new file mode 100644 index 000000000..fdbaab686 --- /dev/null +++ b/core/image/qoi/qoi.odin @@ -0,0 +1,408 @@ +/* + Copyright 2022 Jeroen van Rijn . + Made available under Odin's BSD-3 license. + + List of contributors: + Jeroen van Rijn: Initial implementation. +*/ + + +// package qoi implements a QOI image reader +// +// The QOI specification is at https://qoiformat.org. +package qoi + +import "core:mem" +import "core:image" +import "core:compress" +import "core:bytes" +import "core:os" + +Error :: image.Error +General :: compress.General_Error +Image :: image.Image +Options :: image.Options + +RGB_Pixel :: image.RGB_Pixel +RGBA_Pixel :: image.RGBA_Pixel + +save_to_memory :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{}, allocator := context.allocator) -> (err: Error) { + context.allocator = allocator + + if img == nil { + return .Invalid_Input_Image + } + + if output == nil { + return .Invalid_Output + } + + pixels := img.width * img.height + if pixels == 0 || pixels > image.MAX_DIMENSIONS { + return .Invalid_Input_Image + } + + // QOI supports only 8-bit images with 3 or 4 channels. + if img.depth != 8 || img.channels < 3 || img.channels > 4 { + return .Invalid_Input_Image + } + + if img.channels * pixels != len(img.pixels.buf) { + return .Invalid_Input_Image + } + + written := 0 + + // Calculate and allocate maximum size. We'll reclaim space to actually written output at the end. + max_size := pixels * (img.channels + 1) + size_of(image.QOI_Header) + size_of(u64be) + + if !resize(&output.buf, max_size) { + return General.Resize_Failed + } + + header := image.QOI_Header{ + magic = image.QOI_Magic, + width = u32be(img.width), + height = u32be(img.height), + channels = u8(img.channels), + color_space = .Linear if .qoi_all_channels_linear in options else .sRGB, + } + header_bytes := transmute([size_of(image.QOI_Header)]u8)header + + copy(output.buf[written:], header_bytes[:]) + written += size_of(image.QOI_Header) + + /* + Encode loop starts here. + */ + seen: [64]RGBA_Pixel + pix := RGBA_Pixel{0, 0, 0, 255} + prev := pix + + seen[qoi_hash(pix)] = pix + + input := img.pixels.buf[:] + run := u8(0) + + for len(input) > 0 { + if img.channels == 4 { + pix = (^RGBA_Pixel)(raw_data(input))^ + } else { + pix.rgb = (^RGB_Pixel)(raw_data(input))^ + } + input = input[img.channels:] + + if pix == prev { + run += 1 + // As long as the pixel matches the last one, accumulate the run total. + // If we reach the max run length or the end of the image, write the run. + if run == 62 || len(input) == 0 { + // Encode and write run + output.buf[written] = u8(QOI_Opcode_Tag.RUN) | (run - 1) + written += 1 + run = 0 + } + } else { + if run > 0 { + // The pixel differs from the previous one, but we still need to write the pending run. + // Encode and write run + output.buf[written] = u8(QOI_Opcode_Tag.RUN) | (run - 1) + written += 1 + run = 0 + } + + index := qoi_hash(pix) + + if seen[index] == pix { + // Write indexed pixel + output.buf[written] = u8(QOI_Opcode_Tag.INDEX) | index + written += 1 + } else { + // Add pixel to index + seen[index] = pix + + // If the alpha matches the previous pixel's alpha, we don't need to write a full RGBA literal. + if pix.a == prev.a { + // Delta + d := pix.rgb - prev.rgb + + // DIFF, biased and modulo 256 + _d := d + 2 + + // LUMA, biased and modulo 256 + _l := RGB_Pixel{ d.r - d.g + 8, d.g + 32, d.b - d.g + 8 } + + if _d.r < 4 && _d.g < 4 && _d.b < 4 { + // Delta is between -2 and 1 inclusive + output.buf[written] = u8(QOI_Opcode_Tag.DIFF) | _d.r << 4 | _d.g << 2 | _d.b + written += 1 + } else if _l.r < 16 && _l.g < 64 && _l.b < 16 { + // Biased luma is between {-8..7, -32..31, -8..7} + output.buf[written ] = u8(QOI_Opcode_Tag.LUMA) | _l.g + output.buf[written + 1] = _l.r << 4 | _l.b + written += 2 + } else { + // Write RGB literal + output.buf[written] = u8(QOI_Opcode_Tag.RGB) + pix_bytes := transmute([4]u8)pix + copy(output.buf[written + 1:], pix_bytes[:3]) + written += 4 + } + } else { + // Write RGBA literal + output.buf[written] = u8(QOI_Opcode_Tag.RGBA) + pix_bytes := transmute([4]u8)pix + copy(output.buf[written + 1:], pix_bytes[:]) + written += 5 + } + } + } + prev = pix + } + + trailer := []u8{0, 0, 0, 0, 0, 0, 0, 1} + copy(output.buf[written:], trailer[:]) + written += len(trailer) + + resize(&output.buf, written) + return nil +} + +save_to_file :: proc(output: string, img: ^Image, options := Options{}, allocator := context.allocator) -> (err: Error) { + context.allocator = allocator + + out := &bytes.Buffer{} + defer bytes.buffer_destroy(out) + + save_to_memory(out, img, options) or_return + write_ok := os.write_entire_file(output, out.buf[:]) + + return nil if write_ok else General.Cannot_Open_File +} + +save :: proc{save_to_memory, save_to_file} + +load_from_slice :: proc(slice: []u8, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { + ctx := &compress.Context_Memory_Input{ + input_data = slice, + } + + img, err = load_from_context(ctx, options, allocator) + return img, err +} + +load_from_file :: proc(filename: string, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { + context.allocator = allocator + + data, ok := os.read_entire_file(filename) + defer delete(data) + + if ok { + return load_from_slice(data, options) + } else { + img = new(Image) + return img, compress.General_Error.File_Not_Found + } +} + +@(optimization_mode="speed") +load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { + context.allocator = allocator + options := options + + if .info in options { + options |= {.return_metadata, .do_not_decompress_image} + options -= {.info} + } + + if .return_header in options && .return_metadata in options { + options -= {.return_header} + } + + header := image.read_data(ctx, image.QOI_Header) or_return + if header.magic != image.QOI_Magic { + return img, .Invalid_QOI_Signature + } + + if img == nil { + img = new(Image) + } + + if .return_metadata in options { + info := new(image.QOI_Info) + info.header = header + img.metadata = info + } + + if header.channels != 3 && header.channels != 4 { + return img, .Invalid_Number_Of_Channels + } + + if header.color_space != .sRGB && header.color_space != .Linear { + return img, .Invalid_Color_Space + } + + if header.width == 0 || header.height == 0 { + return img, .Invalid_Image_Dimensions + } + + total_pixels := header.width * header.height + if total_pixels > image.MAX_DIMENSIONS { + return img, .Image_Dimensions_Too_Large + } + + img.width = int(header.width) + img.height = int(header.height) + img.channels = 4 if .alpha_add_if_missing in options else int(header.channels) + img.depth = 8 + + if .do_not_decompress_image in options { + img.channels = int(header.channels) + return + } + + bytes_needed := image.compute_buffer_size(int(header.width), int(header.height), img.channels, 8) + + if !resize(&img.pixels.buf, bytes_needed) { + return img, mem.Allocator_Error.Out_Of_Memory + } + + /* + Decode loop starts here. + */ + seen: [64]RGBA_Pixel + pix := RGBA_Pixel{0, 0, 0, 255} + seen[qoi_hash(pix)] = pix + pixels := img.pixels.buf[:] + + decode: for len(pixels) > 0 { + data := image.read_u8(ctx) or_return + + tag := QOI_Opcode_Tag(data) + #partial switch tag { + case .RGB: + pix.rgb = image.read_data(ctx, RGB_Pixel) or_return + + #no_bounds_check { + seen[qoi_hash(pix)] = pix + } + + case .RGBA: + pix = image.read_data(ctx, RGBA_Pixel) or_return + + #no_bounds_check { + seen[qoi_hash(pix)] = pix + } + + case: + // 2-bit tag + tag = QOI_Opcode_Tag(data & QOI_Opcode_Mask) + #partial switch tag { + case .INDEX: + pix = seen[data & 63] + + case .DIFF: + diff_r := ((data >> 4) & 3) - 2 + diff_g := ((data >> 2) & 3) - 2 + diff_b := ((data >> 0) & 3) - 2 + + pix += {diff_r, diff_g, diff_b, 0} + + #no_bounds_check { + seen[qoi_hash(pix)] = pix + } + + case .LUMA: + data2 := image.read_u8(ctx) or_return + + diff_g := (data & 63) - 32 + diff_r := diff_g - 8 + ((data2 >> 4) & 15) + diff_b := diff_g - 8 + (data2 & 15) + + pix += {diff_r, diff_g, diff_b, 0} + + #no_bounds_check { + seen[qoi_hash(pix)] = pix + } + + case .RUN: + if length := int(data & 63) + 1; (length * img.channels) > len(pixels) { + return img, .Corrupt + } else { + #no_bounds_check for in 0.. (index: u8) { + i1 := u16(pixel.r) * 3 + i2 := u16(pixel.g) * 5 + i3 := u16(pixel.b) * 7 + i4 := u16(pixel.a) * 11 + + return u8((i1 + i2 + i3 + i4) & 63) +} \ No newline at end of file diff --git a/core/image/tga/tga.odin b/core/image/tga/tga.odin new file mode 100644 index 000000000..3c860cb62 --- /dev/null +++ b/core/image/tga/tga.odin @@ -0,0 +1,103 @@ +/* + Copyright 2022 Jeroen van Rijn . + Made available under Odin's BSD-3 license. + + List of contributors: + Jeroen van Rijn: Initial implementation. +*/ + + +// package tga implements a TGA image writer for 8-bit RGB and RGBA images. +package tga + +import "core:mem" +import "core:image" +import "core:compress" +import "core:bytes" +import "core:os" + +Error :: image.Error +General :: compress.General_Error +Image :: image.Image +Options :: image.Options + +RGB_Pixel :: image.RGB_Pixel +RGBA_Pixel :: image.RGBA_Pixel + +save_to_memory :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{}, allocator := context.allocator) -> (err: Error) { + context.allocator = allocator + + if img == nil { + return .Invalid_Input_Image + } + + if output == nil { + return .Invalid_Output + } + + pixels := img.width * img.height + if pixels == 0 || pixels > image.MAX_DIMENSIONS || img.width > 65535 || img.height > 65535 { + return .Invalid_Input_Image + } + + // Our TGA writer supports only 8-bit images with 3 or 4 channels. + if img.depth != 8 || img.channels < 3 || img.channels > 4 { + return .Invalid_Input_Image + } + + if img.channels * pixels != len(img.pixels.buf) { + return .Invalid_Input_Image + } + + written := 0 + + // Calculate and allocate necessary space. + necessary := pixels * img.channels + size_of(image.TGA_Header) + + if !resize(&output.buf, necessary) { + return General.Resize_Failed + } + + header := image.TGA_Header{ + data_type_code = 0x02, // Color, uncompressed. + dimensions = {u16le(img.width), u16le(img.height)}, + bits_per_pixel = u8(img.depth * img.channels), + image_descriptor = 1 << 5, // Origin is top left. + } + header_bytes := transmute([size_of(image.TGA_Header)]u8)header + + copy(output.buf[written:], header_bytes[:]) + written += size_of(image.TGA_Header) + + /* + Encode loop starts here. + */ + if img.channels == 3 { + pix := mem.slice_data_cast([]RGB_Pixel, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGB_Pixel, output.buf[written:]) + for p, i in pix { + out[i] = p.bgr + } + } else if img.channels == 4 { + pix := mem.slice_data_cast([]RGBA_Pixel, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGBA_Pixel, output.buf[written:]) + for p, i in pix { + out[i] = p.bgra + } + } + return nil +} + +save_to_file :: proc(output: string, img: ^Image, options := Options{}, allocator := context.allocator) -> (err: Error) { + context.allocator = allocator + + out := &bytes.Buffer{} + defer bytes.buffer_destroy(out) + + save_to_memory(out, img, options) or_return + write_ok := os.write_entire_file(output, out.buf[:]) + + return nil if write_ok else General.Cannot_Open_File +} + +save :: proc{save_to_memory, save_to_file} \ No newline at end of file diff --git a/core/intrinsics/intrinsics.odin b/core/intrinsics/intrinsics.odin index 2da7a7439..c132d4095 100644 --- a/core/intrinsics/intrinsics.odin +++ b/core/intrinsics/intrinsics.odin @@ -41,6 +41,8 @@ mem_copy_non_overlapping :: proc(dst, src: rawptr, len: int) --- mem_zero :: proc(ptr: rawptr, len: int) --- mem_zero_volatile :: proc(ptr: rawptr, len: int) --- +unaligned_load :: proc(src: ^$T) -> T --- +unaligned_store :: proc(dst: ^$T, val: T) -> T --- fixed_point_mul :: proc(lhs, rhs: $T, #const scale: uint) -> T where type_is_integer(T) --- fixed_point_div :: proc(lhs, rhs: $T, #const scale: uint) -> T where type_is_integer(T) --- @@ -60,77 +62,46 @@ syscall :: proc(id: uintptr, args: ..uintptr) -> uintptr --- // Atomics -atomic_fence :: proc() --- -atomic_fence_acq :: proc() --- -atomic_fence_rel :: proc() --- -atomic_fence_acqrel :: proc() --- +Atomic_Memory_Order :: enum { + Relaxed = 0, // Unordered + Consume = 1, // Monotonic + Acquire = 2, + Release = 3, + Acq_Rel = 4, + Seq_Cst = 5, +} -atomic_store :: proc(dst: ^$T, val: T) --- -atomic_store_rel :: proc(dst: ^$T, val: T) --- -atomic_store_relaxed :: proc(dst: ^$T, val: T) --- -atomic_store_unordered :: proc(dst: ^$T, val: T) --- +atomic_type_is_lock_free :: proc($T: typeid) -> bool --- + +atomic_thread_fence :: proc(order: Atomic_Memory_Order) --- +atomic_signal_fence :: proc(order: Atomic_Memory_Order) --- + +atomic_store :: proc(dst: ^$T, val: T) --- +atomic_store_explicit :: proc(dst: ^$T, val: T, order: Atomic_Memory_Order) --- atomic_load :: proc(dst: ^$T) -> T --- -atomic_load_acq :: proc(dst: ^$T) -> T --- -atomic_load_relaxed :: proc(dst: ^$T) -> T --- -atomic_load_unordered :: proc(dst: ^$T) -> T --- +atomic_load_explicit :: proc(dst: ^$T, order: Atomic_Memory_Order) -> T --- -atomic_add :: proc(dst; ^$T, val: T) -> T --- -atomic_add_acq :: proc(dst; ^$T, val: T) -> T --- -atomic_add_rel :: proc(dst; ^$T, val: T) -> T --- -atomic_add_acqrel :: proc(dst; ^$T, val: T) -> T --- -atomic_add_relaxed :: proc(dst; ^$T, val: T) -> T --- -atomic_sub :: proc(dst; ^$T, val: T) -> T --- -atomic_sub_acq :: proc(dst; ^$T, val: T) -> T --- -atomic_sub_rel :: proc(dst; ^$T, val: T) -> T --- -atomic_sub_acqrel :: proc(dst; ^$T, val: T) -> T --- -atomic_sub_relaxed :: proc(dst; ^$T, val: T) -> T --- -atomic_and :: proc(dst; ^$T, val: T) -> T --- -atomic_and_acq :: proc(dst; ^$T, val: T) -> T --- -atomic_and_rel :: proc(dst; ^$T, val: T) -> T --- -atomic_and_acqrel :: proc(dst; ^$T, val: T) -> T --- -atomic_and_relaxed :: proc(dst; ^$T, val: T) -> T --- -atomic_nand :: proc(dst; ^$T, val: T) -> T --- -atomic_nand_acq :: proc(dst; ^$T, val: T) -> T --- -atomic_nand_rel :: proc(dst; ^$T, val: T) -> T --- -atomic_nand_acqrel :: proc(dst; ^$T, val: T) -> T --- -atomic_nand_relaxed :: proc(dst; ^$T, val: T) -> T --- -atomic_or :: proc(dst; ^$T, val: T) -> T --- -atomic_or_acq :: proc(dst; ^$T, val: T) -> T --- -atomic_or_rel :: proc(dst; ^$T, val: T) -> T --- -atomic_or_acqrel :: proc(dst; ^$T, val: T) -> T --- -atomic_or_relaxed :: proc(dst; ^$T, val: T) -> T --- -atomic_xor :: proc(dst; ^$T, val: T) -> T --- -atomic_xor_acq :: proc(dst; ^$T, val: T) -> T --- -atomic_xor_rel :: proc(dst; ^$T, val: T) -> T --- -atomic_xor_acqrel :: proc(dst; ^$T, val: T) -> T --- -atomic_xor_relaxed :: proc(dst; ^$T, val: T) -> T --- +atomic_add :: proc(dst; ^$T, val: T) -> T --- +atomic_add_explicit :: proc(dst; ^$T, val: T, order: Atomic_Memory_Order) -> T --- +atomic_sub :: proc(dst; ^$T, val: T) -> T --- +atomic_sub_explicit :: proc(dst; ^$T, val: T, order: Atomic_Memory_Order) -> T --- +atomic_and :: proc(dst; ^$T, val: T) -> T --- +atomic_and_explicit :: proc(dst; ^$T, val: T, order: Atomic_Memory_Order) -> T --- +atomic_nand :: proc(dst; ^$T, val: T) -> T --- +atomic_nand_explicit :: proc(dst; ^$T, val: T, order: Atomic_Memory_Order) -> T --- +atomic_or :: proc(dst; ^$T, val: T) -> T --- +atomic_or_explicit :: proc(dst; ^$T, val: T, order: Atomic_Memory_Order) -> T --- +atomic_xor :: proc(dst; ^$T, val: T) -> T --- +atomic_xor_explicit :: proc(dst; ^$T, val: T, order: Atomic_Memory_Order) -> T --- +atomic_exchange :: proc(dst; ^$T, val: T) -> T --- +atomic_exchange_explicit :: proc(dst; ^$T, val: T, order: Atomic_Memory_Order) -> T --- -atomic_xchg :: proc(dst; ^$T, val: T) -> T --- -atomic_xchg_acq :: proc(dst; ^$T, val: T) -> T --- -atomic_xchg_rel :: proc(dst; ^$T, val: T) -> T --- -atomic_xchg_acqrel :: proc(dst; ^$T, val: T) -> T --- -atomic_xchg_relaxed :: proc(dst; ^$T, val: T) -> T --- +atomic_compare_exchange_strong :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok --- +atomic_compare_exchange_strong_explicit :: proc(dst: ^$T, old, new: T, success, failure: Atomic_Memory_Order) -> (T, bool) #optional_ok --- +atomic_compare_exchange_weak :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok --- +atomic_compare_exchange_weak_explicit :: proc(dst: ^$T, old, new: T, success, failure: Atomic_Memory_Order) -> (T, bool) #optional_ok --- -atomic_cxchg :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok --- -atomic_cxchg_acq :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok --- -atomic_cxchg_rel :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok --- -atomic_cxchg_acqrel :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok --- -atomic_cxchg_relaxed :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok --- -atomic_cxchg_failrelaxed :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok --- -atomic_cxchg_failacq :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok --- -atomic_cxchg_acq_failrelaxed :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok --- -atomic_cxchg_acqrel_failrelaxed :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok --- - -atomic_cxchgweak :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok --- -atomic_cxchgweak_acq :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok --- -atomic_cxchgweak_rel :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok --- -atomic_cxchgweak_acqrel :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok --- -atomic_cxchgweak_relaxed :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok --- -atomic_cxchgweak_failrelaxed :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok --- -atomic_cxchgweak_failacq :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok --- -atomic_cxchgweak_acq_failrelaxed :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok --- -atomic_cxchgweak_acqrel_failrelaxed :: proc(dst: ^$T, old, new: T) -> (T, bool) #optional_ok --- // Constant type tests @@ -182,6 +153,7 @@ type_is_specialization_of :: proc($T, $S: typeid) -> bool --- type_is_variant_of :: proc($U, $V: typeid) -> bool where type_is_union(U) --- type_has_field :: proc($T: typeid, $name: string) -> bool --- +type_field_type :: proc($T: typeid, $name: string) -> typeid --- type_proc_parameter_count :: proc($T: typeid) -> int where type_is_proc(T) --- type_proc_return_count :: proc($T: typeid) -> int where type_is_proc(T) --- @@ -197,3 +169,12 @@ type_field_index_of :: proc($T: typeid, $name: string) -> uintptr --- type_equal_proc :: proc($T: typeid) -> (equal: proc "contextless" (rawptr, rawptr) -> bool) where type_is_comparable(T) --- type_hasher_proc :: proc($T: typeid) -> (hasher: proc "contextless" (data: rawptr, seed: uintptr) -> uintptr) where type_is_comparable(T) --- + + +// WASM targets only +wasm_memory_grow :: proc(index, delta: uintptr) -> int --- +wasm_memory_size :: proc(index: uintptr) -> int --- + +// Internal compiler use only + +__entry_point :: proc() --- \ No newline at end of file diff --git a/core/io/io.odin b/core/io/io.odin index b4757f8e5..e9d839efb 100644 --- a/core/io/io.odin +++ b/core/io/io.odin @@ -1,9 +1,13 @@ +// package io provides basic interfaces for generic data stream primitives. +// The purpose of this package is wrap existing data structures and their +// operations into an abstracted stream interface. package io import "core:intrinsics" import "core:runtime" import "core:unicode/utf8" +// Seek whence values Seek_From :: enum { Start = 0, // seek relative to the origin of the file Current = 1, // seek relative to the current offset @@ -139,6 +143,10 @@ destroy :: proc(s: Stream) -> Error { return .Empty } +// read reads up to len(p) bytes into s. It returns the number of bytes read and any error if occurred. +// +// When read encounters an .EOF or error after successfully reading n > 0 bytes, it returns the number of +// bytes read along with the error. read :: proc(s: Reader, p: []byte, n_read: ^int = nil) -> (n: int, err: Error) { if s.stream_vtable != nil && s.impl_read != nil { n, err = s->impl_read(p) @@ -150,6 +158,7 @@ read :: proc(s: Reader, p: []byte, n_read: ^int = nil) -> (n: int, err: Error) { return 0, .Empty } +// write writes up to len(p) bytes into s. It returns the number of bytes written and any error if occurred. write :: proc(s: Writer, p: []byte, n_written: ^int = nil) -> (n: int, err: Error) { if s.stream_vtable != nil && s.impl_write != nil { n, err = s->impl_write(p) @@ -161,6 +170,13 @@ write :: proc(s: Writer, p: []byte, n_written: ^int = nil) -> (n: int, err: Erro return 0, .Empty } +// seek sets the offset of the next read or write to offset. +// +// .Start means seek relative to the origin of the file. +// .Current means seek relative to the current offset. +// .End means seek relative to the end. +// +// seek returns the new offset to the start of the file/stream, and any error if occurred. seek :: proc(s: Seeker, offset: i64, whence: Seek_From) -> (n: i64, err: Error) { if s.stream_vtable != nil && s.impl_seek != nil { return s->impl_seek(offset, whence) @@ -168,6 +184,8 @@ seek :: proc(s: Seeker, offset: i64, whence: Seek_From) -> (n: i64, err: Error) return 0, .Empty } +// The behaviour of close after the first call is stream implementation defined. +// Different streams may document their own behaviour. close :: proc(s: Closer) -> Error { if s.stream_vtable != nil && s.impl_close != nil { return s->impl_close() @@ -184,6 +202,7 @@ flush :: proc(s: Flusher) -> Error { return .None } +// size returns the size of the stream. If the stream does not support querying its size, 0 will be returned. size :: proc(s: Stream) -> i64 { if s.stream_vtable == nil { return 0 @@ -214,7 +233,12 @@ size :: proc(s: Stream) -> i64 { - +// read_at reads len(p) bytes into p starting with the provided offset in the underlying Reader_At stream r. +// It returns the number of bytes read and any error if occurred. +// +// When read_at returns n < len(p), it returns a non-nil Error explaining why. +// +// If n == len(p), err may be either nil or .EOF read_at :: proc(r: Reader_At, p: []byte, offset: i64, n_read: ^int = nil) -> (n: int, err: Error) { defer if n_read != nil { n_read^ += n @@ -245,6 +269,11 @@ read_at :: proc(r: Reader_At, p: []byte, offset: i64, n_read: ^int = nil) -> (n: } +// write_at writes len(p) bytes into p starting with the provided offset in the underlying Writer_At stream w. +// It returns the number of bytes written and any error if occurred. +// +// If write_at is writing to a Writer_At which has a seek offset, then write_at should not affect the underlying +// seek offset. write_at :: proc(w: Writer_At, p: []byte, offset: i64, n_written: ^int = nil) -> (n: int, err: Error) { defer if n_written != nil { n_written^ += n @@ -294,6 +323,7 @@ read_from :: proc(w: Reader_From, r: Reader) -> (n: i64, err: Error) { } +// read_byte reads and returns the next byte from r. read_byte :: proc(r: Byte_Reader, n_read: ^int = nil) -> (b: byte, err: Error) { defer if err == nil && n_read != nil { n_read^ += 1 @@ -347,6 +377,7 @@ _write_byte :: proc(w: Byte_Writer, c: byte, n_written: ^int = nil) -> (err: Err return err } +// read_rune reads a single UTF-8 encoded Unicode codepoint and returns the rune and its size in bytes. read_rune :: proc(br: Rune_Reader, n_read: ^int = nil) -> (ch: rune, size: int, err: Error) { defer if err == nil && n_read != nil { n_read^ += size @@ -405,10 +436,12 @@ unread_rune :: proc(s: Rune_Scanner) -> Error { } +// write_string writes the contents of the string s to w. write_string :: proc(s: Writer, str: string, n_written: ^int = nil) -> (n: int, err: Error) { return write(s, transmute([]byte)str, n_written) } +// write_rune writes a UTF-8 encoded rune to w. write_rune :: proc(s: Writer, r: rune, n_written: ^int = nil) -> (size: int, err: Error) { defer if err == nil && n_written != nil { n_written^ += size @@ -430,12 +463,16 @@ write_rune :: proc(s: Writer, r: rune, n_written: ^int = nil) -> (size: int, err } - +// read_full expected exactly len(buf) bytes from r into buf. read_full :: proc(r: Reader, buf: []byte) -> (n: int, err: Error) { return read_at_least(r, buf, len(buf)) } +// read_at_least reads from r into buf until it has read at least min bytes. It returns the number +// of bytes copied and an error if fewer bytes were read. `.EOF` is only returned if no bytes were read. +// `.Unexpected_EOF` is returned when an `.EOF ` is returned by the passed Reader after reading +// fewer than min bytes. If len(buf) is less than min, `.Short_Buffer` is returned. read_at_least :: proc(r: Reader, buf: []byte, min: int) -> (n: int, err: Error) { if len(buf) < min { return 0, .Short_Buffer diff --git a/core/math/big/api.odin b/core/math/big/api.odin index c9be04da0..bf19e83b6 100644 --- a/core/math/big/api.odin +++ b/core/math/big/api.odin @@ -2,12 +2,10 @@ Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. - An arbitrary precision mathematics implementation in Odin. - For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3. - The code started out as an idiomatic source port of libTomMath, which is in the public domain, with thanks. - This file collects public proc maps and their aliases. */ + + package math_big /* diff --git a/core/math/big/common.odin b/core/math/big/common.odin index 5b7d162bc..74a641d83 100644 --- a/core/math/big/common.odin +++ b/core/math/big/common.odin @@ -1,11 +1,9 @@ /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. - - An arbitrary precision mathematics implementation in Odin. - For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3. - The code started out as an idiomatic source port of libTomMath, which is in the public domain, with thanks. */ + + package math_big import "core:intrinsics" @@ -158,13 +156,14 @@ Error :: enum int { Invalid_Pointer = 2, Invalid_Argument = 3, - Assignment_To_Immutable = 4, - Max_Iterations_Reached = 5, - Buffer_Overflow = 6, - Integer_Overflow = 7, + Assignment_To_Immutable = 10, + Max_Iterations_Reached = 11, + Buffer_Overflow = 12, + Integer_Overflow = 13, + Integer_Underflow = 14, - Division_by_Zero = 8, - Math_Domain_Error = 9, + Division_by_Zero = 30, + Math_Domain_Error = 31, Cannot_Open_File = 50, Cannot_Read_File = 51, @@ -173,7 +172,7 @@ Error :: enum int { Unimplemented = 127, } -Error_String :: #partial [Error]string{ +Error_String :: #sparse[Error]string{ .Okay = "Okay", .Out_Of_Memory = "Out of memory", .Invalid_Pointer = "Invalid pointer", @@ -183,6 +182,7 @@ Error_String :: #partial [Error]string{ .Max_Iterations_Reached = "Max iterations reached", .Buffer_Overflow = "Buffer overflow", .Integer_Overflow = "Integer overflow", + .Integer_Underflow = "Integer underflow", .Division_by_Zero = "Division by zero", .Math_Domain_Error = "Math domain error", @@ -215,7 +215,7 @@ _MIN_DIGIT_COUNT :: max(3, ((size_of(u128) + _DIGIT_BITS) - 1) / _DIGIT_BITS) /* Maximum number of digits. - Must be small enough such that `_bit_count` does not overflow. - - Must be small enough such that `_radix_size` for base 2 does not overflow. + - Must be small enough such that `_radix_size` for base 2 does not overflow. `_radix_size` needs two additional bytes for zero termination and sign. */ _MAX_BIT_COUNT :: (max(int) - 2) @@ -251,7 +251,7 @@ Order :: enum i8 { } Endianness :: enum i8 { - Little = -1, - Platform = 0, - Big = 1, -}; \ No newline at end of file + Little = -1, + Platform = 0, + Big = 1, +} \ No newline at end of file diff --git a/core/math/big/doc.odin b/core/math/big/doc.odin new file mode 100644 index 000000000..0f9b88d01 --- /dev/null +++ b/core/math/big/doc.odin @@ -0,0 +1,6 @@ +/* +A BigInt implementation in Odin. +For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3. +The code started out as an idiomatic source port of libTomMath, which is in the public domain, with thanks. +*/ +package math_big diff --git a/core/math/big/helpers.odin b/core/math/big/helpers.odin index 6d13d32bb..6c4b5dd01 100644 --- a/core/math/big/helpers.odin +++ b/core/math/big/helpers.odin @@ -1,11 +1,9 @@ /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. - - An arbitrary precision mathematics implementation in Odin. - For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3. - The code started out as an idiomatic source port of libTomMath, which is in the public domain, with thanks. */ + + package math_big import "core:intrinsics" diff --git a/core/math/big/internal.odin b/core/math/big/internal.odin index 4702e76a3..dbcd16509 100644 --- a/core/math/big/internal.odin +++ b/core/math/big/internal.odin @@ -1,12 +1,7 @@ -//+ignore /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. - A BigInt implementation in Odin. - For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3. - The code started out as an idiomatic source port of libTomMath, which is in the public domain, with thanks. - ========================== Low-level routines ========================== IMPORTANT: `internal_*` procedures make certain assumptions about their input. @@ -29,11 +24,15 @@ TODO: Handle +/- Infinity and NaN. */ + + +//+ignore package math_big import "core:mem" import "core:intrinsics" import rnd "core:math/rand" +import "core:builtin" /* Low-level addition, unsigned. Handbook of Applied Cryptography, algorithm 14.7. @@ -1880,8 +1879,6 @@ internal_int_set_from_integer :: proc(dest: ^Int, src: $T, minimize := false, al where intrinsics.type_is_integer(T) { context.allocator = allocator - src := src - internal_error_if_immutable(dest) or_return /* Most internal procs asssume an Int to have already been initialize, @@ -1892,13 +1889,27 @@ internal_int_set_from_integer :: proc(dest: ^Int, src: $T, minimize := false, al dest.flags = {} // We're not -Inf, Inf, NaN or Immutable. dest.used = 0 - dest.sign = .Zero_or_Positive if src >= 0 else .Negative - src = internal_abs(src) + dest.sign = .Negative if src < 0 else .Zero_or_Positive - #no_bounds_check for src != 0 { - dest.digit[dest.used] = DIGIT(src) & _MASK + temp := src + + is_maximally_negative := src == min(T) + if is_maximally_negative { + /* + Prevent overflow on abs() + */ + temp += 1 + } + temp = -temp if temp < 0 else temp + + #no_bounds_check for temp != 0 { + dest.digit[dest.used] = DIGIT(temp) & _MASK dest.used += 1 - src >>= _DIGIT_BITS + temp >>= _DIGIT_BITS + } + + if is_maximally_negative { + return internal_sub(dest, dest, 1) } internal_zero_unused(dest) return nil @@ -2307,28 +2318,69 @@ internal_int_get_i32 :: proc(a: ^Int) -> (res: i32, err: Error) { } internal_get_i32 :: proc { internal_int_get_i32, } +internal_get_low_u32 :: proc(a: ^Int) -> u32 #no_bounds_check { + if a == nil { + return 0 + } + + if a.used == 0 { + return 0 + } + + return u32(a.digit[0]) +} +internal_get_low_u64 :: proc(a: ^Int) -> u64 #no_bounds_check { + if a == nil { + return 0 + } + + if a.used == 0 { + return 0 + } + + v := u64(a.digit[0]) + when size_of(DIGIT) == 4 { + if a.used > 1 { + return u64(a.digit[1])<<32 | v + } + } + return v +} + /* TODO: Think about using `count_bits` to check if the value could be returned completely, and maybe return max(T), .Integer_Overflow if not? */ internal_int_get :: proc(a: ^Int, $T: typeid) -> (res: T, err: Error) where intrinsics.type_is_integer(T) { - size_in_bits := int(size_of(T) * 8) - i := int((size_in_bits + _DIGIT_BITS - 1) / _DIGIT_BITS) - i = min(int(a.used), i) - - #no_bounds_check for ; i >= 0; i -= 1 { - res <<= uint(0) if size_in_bits <= _DIGIT_BITS else _DIGIT_BITS - res |= T(a.digit[i]) - if size_in_bits <= _DIGIT_BITS { - break + /* + Calculate target bit size. + */ + target_bit_size := int(size_of(T) * 8) + when !intrinsics.type_is_unsigned(T) { + if a.sign == .Zero_or_Positive { + target_bit_size -= 1 + } + } else { + if a.sign == .Negative { + return 0, .Integer_Underflow } } + bits_used := internal_count_bits(a) + + if bits_used > target_bit_size { + if a.sign == .Negative { + return min(T), .Integer_Underflow + } + return max(T), .Integer_Overflow + } + + for i := a.used; i > 0; i -= 1 { + res <<= _DIGIT_BITS + res |= T(a.digit[i - 1]) + } + when !intrinsics.type_is_unsigned(T) { - /* - Mask off sign bit. - */ - res ~= 1 << uint(size_in_bits - 1) /* Set the sign. */ @@ -2594,7 +2646,7 @@ internal_int_shrmod :: proc(quotient, remainder, numerator: ^Int, bits: int, all Shift by as many digits in the bit count. */ if bits >= _DIGIT_BITS { - internal_shr_digit(quotient, bits / _DIGIT_BITS) or_return + _private_int_shr_leg(quotient, bits / _DIGIT_BITS) or_return } /* @@ -2633,37 +2685,6 @@ internal_int_shr :: proc(dest, source: ^Int, bits: int, allocator := context.all } internal_shr :: proc { internal_int_shr, } -/* - Shift right by `digits` * _DIGIT_BITS bits. -*/ -internal_int_shr_digit :: proc(quotient: ^Int, digits: int, allocator := context.allocator) -> (err: Error) { - context.allocator = allocator - - if digits <= 0 { return nil } - - /* - If digits > used simply zero and return. - */ - if digits > quotient.used { return internal_zero(quotient) } - - /* - Much like `int_shl_digit`, this is implemented using a sliding window, - except the window goes the other way around. - - b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> - /\ | ----> - \-------------------/ ----> - */ - - #no_bounds_check for x := 0; x < (quotient.used - digits); x += 1 { - quotient.digit[x] = quotient.digit[x + digits] - } - quotient.used -= digits - internal_zero_unused(quotient) - return internal_clamp(quotient) -} -internal_shr_digit :: proc { internal_int_shr_digit, } - /* Shift right by a certain bit count with sign extension. */ @@ -2702,7 +2723,7 @@ internal_int_shl :: proc(dest, src: ^Int, bits: int, allocator := context.alloca Shift by as many digits in the bit count as we have. */ if bits >= _DIGIT_BITS { - internal_shl_digit(dest, bits / _DIGIT_BITS) or_return + _private_int_shl_leg(dest, bits / _DIGIT_BITS) or_return } /* @@ -2732,45 +2753,6 @@ internal_int_shl :: proc(dest, src: ^Int, bits: int, allocator := context.alloca } internal_shl :: proc { internal_int_shl, } - -/* - Shift left by `digits` * _DIGIT_BITS bits. -*/ -internal_int_shl_digit :: proc(quotient: ^Int, digits: int, allocator := context.allocator) -> (err: Error) { - context.allocator = allocator - - if digits <= 0 { return nil } - - /* - No need to shift a zero. - */ - if #force_inline internal_is_zero(quotient) { - return nil - } - - /* - Resize `quotient` to accomodate extra digits. - */ - #force_inline internal_grow(quotient, quotient.used + digits) or_return - - /* - Increment the used by the shift amount then copy upwards. - */ - - /* - Much like `int_shr_digit`, this is implemented using a sliding window, - except the window goes the other way around. - */ - #no_bounds_check for x := quotient.used; x > 0; x -= 1 { - quotient.digit[x+digits-1] = quotient.digit[x-1] - } - - quotient.used += digits - mem.zero_slice(quotient.digit[:digits]) - return nil -} -internal_shl_digit :: proc { internal_int_shl_digit, } - /* Count bits in an `Int`. Assumes `a` not to be `nil` and to have been initialized. diff --git a/core/math/big/logical.odin b/core/math/big/logical.odin index dbcf566c8..b5de4cabf 100644 --- a/core/math/big/logical.odin +++ b/core/math/big/logical.odin @@ -8,6 +8,8 @@ This file contains logical operations like `and`, `or` and `xor`. */ + + package math_big /* @@ -86,21 +88,6 @@ int_shr :: proc(dest, source: ^Int, bits: int, allocator := context.allocator) - } shr :: proc { int_shr, } -/* - Shift right by `digits` * _DIGIT_BITS bits. -*/ -int_shr_digit :: proc(quotient: ^Int, digits: int, allocator := context.allocator) -> (err: Error) { - /* - Check that `quotient` is usable. - */ - assert_if_nil(quotient) - context.allocator = allocator - - internal_clear_if_uninitialized(quotient) or_return - return #force_inline internal_int_shr_digit(quotient, digits) -} -shr_digit :: proc { int_shr_digit, } - /* Shift right by a certain bit count with sign extension. */ @@ -124,20 +111,4 @@ int_shl :: proc(dest, src: ^Int, bits: int, allocator := context.allocator) -> ( internal_clear_if_uninitialized(dest, src) or_return return #force_inline internal_int_shl(dest, src, bits) } -shl :: proc { int_shl, } - - -/* - Shift left by `digits` * _DIGIT_BITS bits. -*/ -int_shl_digit :: proc(quotient: ^Int, digits: int, allocator := context.allocator) -> (err: Error) { - /* - Check that `quotient` is usable. - */ - assert_if_nil(quotient) - context.allocator = allocator - - internal_clear_if_uninitialized(quotient) or_return - return #force_inline internal_int_shl_digit(quotient, digits) -} -shl_digit :: proc { int_shl_digit, }; \ No newline at end of file +shl :: proc { int_shl, } \ No newline at end of file diff --git a/core/math/big/prime.odin b/core/math/big/prime.odin index eb0cd644c..3cce69675 100644 --- a/core/math/big/prime.odin +++ b/core/math/big/prime.odin @@ -8,6 +8,8 @@ This file contains prime finding operations. */ + + package math_big import rnd "core:math/rand" diff --git a/core/math/big/private.odin b/core/math/big/private.odin index 14a27f600..419f2103f 100644 --- a/core/math/big/private.odin +++ b/core/math/big/private.odin @@ -15,6 +15,8 @@ These aren't exported for the same reasons. */ + + package math_big import "core:intrinsics" @@ -211,12 +213,12 @@ _private_int_mul_toom :: proc(dest, a, b: ^Int, allocator := context.allocator) /* P = b1*x^4+ S2*x^3+ S1*x^2+ a1*x + a0; */ - internal_shl_digit(b1, 4 * B) or_return - internal_shl_digit(S2, 3 * B) or_return + _private_int_shl_leg(b1, 4 * B) or_return + _private_int_shl_leg(S2, 3 * B) or_return internal_add(b1, b1, S2) or_return - internal_shl_digit(S1, 2 * B) or_return + _private_int_shl_leg(S1, 2 * B) or_return internal_add(b1, b1, S1) or_return - internal_shl_digit(a1, 1 * B) or_return + _private_int_shl_leg(a1, 1 * B) or_return internal_add(b1, b1, a1) or_return internal_add(dest, b1, a0) or_return @@ -317,8 +319,8 @@ _private_int_mul_karatsuba :: proc(dest, a, b: ^Int, allocator := context.alloca /* shift by B. */ - internal_shl_digit(t1, B) or_return /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<= n then x = x - n @@ -2026,7 +2028,7 @@ _private_int_reduce :: proc(x, m, mu: ^Int, allocator := context.allocator) -> ( /* q1 = x / b**(k-1) */ - internal_shr_digit(q, um - 1) + _private_int_shr_leg(q, um - 1) /* According to HAC this optimization is ok. @@ -2040,7 +2042,7 @@ _private_int_reduce :: proc(x, m, mu: ^Int, allocator := context.allocator) -> ( /* q3 = q2 / b**(k+1) */ - internal_shr_digit(q, um + 1) + _private_int_shr_leg(q, um + 1) /* x = x mod b**(k+1), quick (no division) @@ -2062,7 +2064,7 @@ _private_int_reduce :: proc(x, m, mu: ^Int, allocator := context.allocator) -> ( */ if internal_is_negative(x) { internal_set(q, 1) or_return - internal_shl_digit(q, um + 1) or_return + _private_int_shl_leg(q, um + 1) or_return internal_add(x, x, q) or_return } @@ -3192,6 +3194,74 @@ _private_copy_digits :: proc(dest, src: ^Int, digits: int, offset := int(0)) -> return nil } + +/* + Shift left by `digits` * _DIGIT_BITS bits. +*/ +_private_int_shl_leg :: proc(quotient: ^Int, digits: int, allocator := context.allocator) -> (err: Error) { + context.allocator = allocator + + if digits <= 0 { return nil } + + /* + No need to shift a zero. + */ + if #force_inline internal_is_zero(quotient) { + return nil + } + + /* + Resize `quotient` to accomodate extra digits. + */ + #force_inline internal_grow(quotient, quotient.used + digits) or_return + + /* + Increment the used by the shift amount then copy upwards. + */ + + /* + Much like `_private_int_shr_leg`, this is implemented using a sliding window, + except the window goes the other way around. + */ + #no_bounds_check for x := quotient.used; x > 0; x -= 1 { + quotient.digit[x+digits-1] = quotient.digit[x-1] + } + + quotient.used += digits + mem.zero_slice(quotient.digit[:digits]) + return nil +} + +/* + Shift right by `digits` * _DIGIT_BITS bits. +*/ +_private_int_shr_leg :: proc(quotient: ^Int, digits: int, allocator := context.allocator) -> (err: Error) { + context.allocator = allocator + + if digits <= 0 { return nil } + + /* + If digits > used simply zero and return. + */ + if digits > quotient.used { return internal_zero(quotient) } + + /* + Much like `int_shl_digit`, this is implemented using a sliding window, + except the window goes the other way around. + + b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> + /\ | ----> + \-------------------/ ----> + */ + + #no_bounds_check for x := 0; x < (quotient.used - digits); x += 1 { + quotient.digit[x] = quotient.digit[x + digits] + } + quotient.used -= digits + internal_zero_unused(quotient) + return internal_clamp(quotient) +} + /* ======================== End of private procedures ======================= diff --git a/core/math/big/public.odin b/core/math/big/public.odin index 2673a262f..3227d7bc4 100644 --- a/core/math/big/public.odin +++ b/core/math/big/public.odin @@ -8,6 +8,8 @@ This file contains basic arithmetic operations like `add`, `sub`, `mul`, `div`, ... */ + + package math_big import "core:intrinsics" diff --git a/core/math/big/radix.odin b/core/math/big/radix.odin index 760c49d77..2b758dc35 100644 --- a/core/math/big/radix.odin +++ b/core/math/big/radix.odin @@ -12,6 +12,8 @@ - Use Barrett reduction for non-powers-of-two. - Also look at extracting and splatting several digits at once. */ + + package math_big import "core:intrinsics" diff --git a/core/math/big/rat.odin b/core/math/big/rat.odin index 121f0ab50..c3efc30aa 100644 --- a/core/math/big/rat.odin +++ b/core/math/big/rat.odin @@ -42,9 +42,9 @@ rat_set_f64 :: proc(dst: ^Rat, f: f64, allocator := context.allocator) -> (err: dst.a.sign = .Negative if f < 0 else .Zero_or_Positive if shift > 0 { - internal_int_shl_digit(&dst.b, shift) or_return + internal_int_shl(&dst.b, &dst.b, shift) or_return } else { - internal_int_shl_digit(&dst.a, -shift) or_return + internal_int_shl(&dst.a, &dst.a, -shift) or_return } return internal_rat_norm(dst) @@ -112,14 +112,14 @@ rat_set_u64 :: proc(dst: ^Rat, x: u64, allocator := context.allocator) -> (err: assert_if_nil(dst) context.allocator = allocator internal_set(&dst.a, x) or_return - internal_set(&dst.a, 1) or_return + internal_set(&dst.b, 1) or_return return } rat_set_i64 :: proc(dst: ^Rat, x: i64, allocator := context.allocator) -> (err: Error) { assert_if_nil(dst) context.allocator = allocator internal_set(&dst.a, x) or_return - internal_set(&dst.a, 1) or_return + internal_set(&dst.b, 1) or_return return } @@ -265,7 +265,7 @@ rat_mul_rat :: proc(dst, x, y: ^Rat, allocator := context.allocator) -> (err: Er return } - int_sub(&dst.a, &x.a, &y.a) or_return + int_mul(&dst.a, &x.a, &y.a) or_return internal_int_mul_denom(&dst.b, &x.b, &y.b) or_return return internal_rat_norm(dst) } @@ -389,9 +389,9 @@ internal_rat_to_float :: proc($T: typeid, z: ^Rat, allocator := context.allocato internal_int_abs(b2, b) or_return if shift := MSIZE2 - exp; shift > 0 { - internal_int_shl_digit(a2, shift) or_return - } else { - internal_int_shl_digit(b2, -shift) or_return + internal_int_shl(a2, a2, shift) or_return + } else if shift < 0 { + internal_int_shl(b2, b2, -shift) or_return } q, r := &Int{}, &Int{} diff --git a/core/math/big/tune.odin b/core/math/big/tune.odin index d67ff61b4..78a20c12b 100644 --- a/core/math/big/tune.odin +++ b/core/math/big/tune.odin @@ -1,4 +1,3 @@ -//+ignore /* Copyright 2021 Jeroen van Rijn . Made available under Odin's BSD-3 license. @@ -7,6 +6,8 @@ For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3. The code started out as an idiomatic source port of libTomMath, which is in the public domain, with thanks. */ + +//+ignore package math_big import "core:time" diff --git a/core/math/bits/bits.odin b/core/math/bits/bits.odin index bff984cc7..850e8038a 100644 --- a/core/math/bits/bits.odin +++ b/core/math/bits/bits.odin @@ -69,29 +69,29 @@ rotate_left :: proc(x: uint, k: int) -> uint { } from_be_u8 :: proc(i: u8) -> u8 { return i } -from_be_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } -from_be_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } -from_be_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } -from_be_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } +from_be_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } +from_be_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } +from_be_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } +from_be_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } from_le_u8 :: proc(i: u8) -> u8 { return i } -from_le_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } -from_le_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } -from_le_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } -from_le_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } +from_le_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } +from_le_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } +from_le_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } +from_le_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } to_be_u8 :: proc(i: u8) -> u8 { return i } -to_be_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } -to_be_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } -to_be_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } -to_be_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == "big" { return i } else { return byte_swap(i) } } +to_be_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } +to_be_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } +to_be_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } +to_be_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } to_le_u8 :: proc(i: u8) -> u8 { return i } -to_le_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } -to_le_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } -to_le_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } -to_le_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == "little" { return i } else { return byte_swap(i) } } +to_le_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } +to_le_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } +to_le_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } +to_le_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } diff --git a/core/math/ease/ease.odin b/core/math/ease/ease.odin new file mode 100644 index 000000000..5a767b5a9 --- /dev/null +++ b/core/math/ease/ease.odin @@ -0,0 +1,483 @@ +// easing procedures and flux easing used for animations +package ease + +import "core:math" +import "core:intrinsics" +import "core:time" + +@(private) PI_2 :: math.PI / 2 + +// converted to odin from https://github.com/warrenm/AHEasing +// with additional enum based call + +// Modeled after the parabola y = x^2 +quadratic_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return p * p +} + +// Modeled after the parabola y = -x^2 + 2x +quadratic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return -(p * (p - 2)) +} + +// Modeled after the piecewise quadratic +// y = (1/2)((2x)^2) ; [0, 0.5) +// y = -(1/2)((2x-1)*(2x-3) - 1) ; [0.5, 1] +quadratic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + if p < 0.5 { + return 2 * p * p + } else { + return (-2 * p * p) + (4 * p) - 1 + } +} + +// Modeled after the cubic y = x^3 +cubic_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return p * p * p +} + +// Modeled after the cubic y = (x - 1)^3 + 1 +cubic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + f := p - 1 + return f * f * f + 1 +} + +// Modeled after the piecewise cubic +// y = (1/2)((2x)^3) ; [0, 0.5) +// y = (1/2)((2x-2)^3 + 2) ; [0.5, 1] +cubic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + if p < 0.5 { + return 4 * p * p * p + } else { + f := (2 * p) - 2 + return 0.5 * f * f * f + 1 + } +} + +// Modeled after the quartic x^4 +quartic_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return p * p * p * p +} + +// Modeled after the quartic y = 1 - (x - 1)^4 +quartic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + f := p - 1 + return f * f * f * (1 - p) + 1 +} + +// Modeled after the piecewise quartic +// y = (1/2)((2x)^4) ; [0, 0.5) +// y = -(1/2)((2x-2)^4 - 2) ; [0.5, 1] +quartic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + if p < 0.5 { + return 8 * p * p * p * p + } else { + f := p - 1 + return -8 * f * f * f * f + 1 + } +} + +// Modeled after the quintic y = x^5 +quintic_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return p * p * p * p * p +} + +// Modeled after the quintic y = (x - 1)^5 + 1 +quintic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + f := p - 1 + return f * f * f * f * f + 1 +} + +// Modeled after the piecewise quintic +// y = (1/2)((2x)^5) ; [0, 0.5) +// y = (1/2)((2x-2)^5 + 2) ; [0.5, 1] +quintic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + if p < 0.5 { + return 16 * p * p * p * p * p + } else { + f := (2 * p) - 2 + return 0.5 * f * f * f * f * f + 1 + } +} + +// Modeled after quarter-cycle of sine wave +sine_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return math.sin((p - 1) * PI_2) + 1 +} + +// Modeled after quarter-cycle of sine wave (different phase) +sine_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return math.sin(p * PI_2) +} + +// Modeled after half sine wave +sine_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return 0.5 * (1 - math.cos(p * math.PI)) +} + +// Modeled after shifted quadrant IV of unit circle +circular_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return 1 - math.sqrt(1 - (p * p)) +} + +// Modeled after shifted quadrant II of unit circle +circular_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return math.sqrt((2 - p) * p) +} + +// Modeled after the piecewise circular function +// y = (1/2)(1 - sqrt(1 - 4x^2)) ; [0, 0.5) +// y = (1/2)(sqrt(-(2x - 3)*(2x - 1)) + 1) ; [0.5, 1] +circular_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + if p < 0.5 { + return 0.5 * (1 - math.sqrt(1 - 4 * (p * p))) + } else { + return 0.5 * (math.sqrt(-((2 * p) - 3) * ((2 * p) - 1)) + 1) + } +} + +// Modeled after the exponential function y = 2^(10(x - 1)) +exponential_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return p == 0.0 ? p : math.pow(2, 10 * (p - 1)) +} + +// Modeled after the exponential function y = -2^(-10x) + 1 +exponential_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return p == 1.0 ? p : 1 - math.pow(2, -10 * p) +} + +// Modeled after the piecewise exponential +// y = (1/2)2^(10(2x - 1)) ; [0,0.5) +// y = -(1/2)*2^(-10(2x - 1))) + 1 ; [0.5,1] +exponential_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + if p == 0.0 || p == 1.0 { + return p + } + + if p < 0.5 { + return 0.5 * math.pow(2, (20 * p) - 10) + } else { + return -0.5 * math.pow(2, (-20 * p) + 10) + 1 + } +} + +// Modeled after the damped sine wave y = sin(13pi/2*x)*pow(2, 10 * (x - 1)) +elastic_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return math.sin(13 * PI_2 * p) * math.pow(2, 10 * (p - 1)) +} + +// Modeled after the damped sine wave y = sin(-13pi/2*(x + 1))*pow(2, -10x) + 1 +elastic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return math.sin(-13 * PI_2 * (p + 1)) * math.pow(2, -10 * p) + 1 +} + +// Modeled after the piecewise exponentially-damped sine wave: +// y = (1/2)*sin(13pi/2*(2*x))*pow(2, 10 * ((2*x) - 1)) ; [0,0.5) +// y = (1/2)*(sin(-13pi/2*((2x-1)+1))*pow(2,-10(2*x-1)) + 2) ; [0.5, 1] +elastic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + if p < 0.5 { + return 0.5 * math.sin(13 * PI_2 * (2 * p)) * math.pow(2, 10 * ((2 * p) - 1)) + } else { + return 0.5 * (math.sin(-13 * PI_2 * ((2 * p - 1) + 1)) * math.pow(2, -10 * (2 * p - 1)) + 2) + } +} + +// Modeled after the overshooting cubic y = x^3-x*sin(x*pi) +back_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return p * p * p - p * math.sin(p * math.PI) +} + +// Modeled after overshooting cubic y = 1-((1-x)^3-(1-x)*sin((1-x)*pi)) +back_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + f := 1 - p + return 1 - (f * f * f - f * math.sin(f * math.PI)) +} + +// Modeled after the piecewise overshooting cubic function: +// y = (1/2)*((2x)^3-(2x)*sin(2*x*pi)) ; [0, 0.5) +// y = (1/2)*(1-((1-x)^3-(1-x)*sin((1-x)*pi))+1) ; [0.5, 1] +back_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + if p < 0.5 { + f := 2 * p + return 0.5 * (f * f * f - f * math.sin(f * math.PI)) + } else { + f := (1 - (2*p - 1)) + return 0.5 * (1 - (f * f * f - f * math.sin(f * math.PI))) + 0.5 + } +} + +bounce_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return 1 - bounce_out(1 - p) +} + +bounce_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + if p < 4/11.0 { + return (121 * p * p)/16.0 + } else if p < 8/11.0 { + return (363/40.0 * p * p) - (99/10.0 * p) + 17/5.0 + } else if p < 9/10.0 { + return (4356/361.0 * p * p) - (35442/1805.0 * p) + 16061/1805.0 + } else { + return (54/5.0 * p * p) - (513/25.0 * p) + 268/25.0 + } +} + +bounce_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + if p < 0.5 { + return 0.5 * bounce_in(p*2) + } else { + return 0.5 * bounce_out(p * 2 - 1) + 0.5 + } +} + +// additional enum variant + +Ease :: enum { + Linear, + + Quadratic_In, + Quadratic_Out, + Quadratic_In_Out, + + Cubic_In, + Cubic_Out, + Cubic_In_Out, + + Quartic_In, + Quartic_Out, + Quartic_In_Out, + + Quintic_In, + Quintic_Out, + Quintic_In_Out, + + Sine_In, + Sine_Out, + Sine_In_Out, + + Circular_In, + Circular_Out, + Circular_In_Out, + + Exponential_In, + Exponential_Out, + Exponential_In_Out, + + Elastic_In, + Elastic_Out, + Elastic_In_Out, + + Back_In, + Back_Out, + Back_In_Out, + + Bounce_In, + Bounce_Out, + Bounce_In_Out, +} + +ease :: proc "contextless" (type: Ease, p: $T) -> T + where intrinsics.type_is_float(T) { + switch type { + case .Linear: return p + + case .Quadratic_In: return quadratic_in(p) + case .Quadratic_Out: return quadratic_out(p) + case .Quadratic_In_Out: return quadratic_in_out(p) + + case .Cubic_In: return cubic_in(p) + case .Cubic_Out: return cubic_out(p) + case .Cubic_In_Out: return cubic_in_out(p) + + case .Quartic_In: return quartic_in(p) + case .Quartic_Out: return quartic_out(p) + case .Quartic_In_Out: return quartic_in_out(p) + + case .Quintic_In: return quintic_in(p) + case .Quintic_Out: return quintic_out(p) + case .Quintic_In_Out: return quintic_in_out(p) + + case .Sine_In: return sine_in(p) + case .Sine_Out: return sine_out(p) + case .Sine_In_Out: return sine_in_out(p) + + case .Circular_In: return circular_in(p) + case .Circular_Out: return circular_out(p) + case .Circular_In_Out: return circular_in_out(p) + + case .Exponential_In: return exponential_in(p) + case .Exponential_Out: return exponential_out(p) + case .Exponential_In_Out: return exponential_in_out(p) + + case .Elastic_In: return elastic_in(p) + case .Elastic_Out: return elastic_out(p) + case .Elastic_In_Out: return elastic_in_out(p) + + case .Back_In: return back_in(p) + case .Back_Out: return back_out(p) + case .Back_In_Out: return back_in_out(p) + + case .Bounce_In: return bounce_in(p) + case .Bounce_Out: return bounce_out(p) + case .Bounce_In_Out: return bounce_in_out(p) + } + + // in case type was invalid + return 0 +} + +Flux_Map :: struct($T: typeid) { + values: map[^T]Flux_Tween(T), +} + +Flux_Tween :: struct($T: typeid) { + value: ^T, + start: T, + diff: T, + goal: T, + + delay: f64, // in seconds + duration: time.Duration, + + progress: f64, + rate: f64, + type: Ease, + + inited: bool, + + // callbacks, data can be set, will be pushed to callback + data: rawptr, // by default gets set to value input + on_start: proc(flux: ^Flux_Map(T), data: rawptr), + on_update: proc(flux: ^Flux_Map(T), data: rawptr), + on_complete: proc(flux: ^Flux_Map(T), data: rawptr), +} + +// init flux map to a float type and a wanted cap +flux_init :: proc($T: typeid, cap := 8) -> Flux_Map(T) where intrinsics.type_is_float(T) { + return { + make(map[^T]Flux_Tween(T), cap), + } +} + +// delete map content +flux_destroy :: proc(flux: Flux_Map($T)) where intrinsics.type_is_float(T) { + delete(flux.values) +} + +// clear map content, stops all animations +flux_clear :: proc(flux: ^Flux_Map($T)) where intrinsics.type_is_float(T) { + clear(&flux.values) +} + +// append / overwrite existing tween value to parameters +// rest is initialized in flux_tween_init, inside update +// return value can be used to set callbacks +flux_to :: proc( + flux: ^Flux_Map($T), + value: ^f32, + goal: f32, + type: Ease = .Quadratic_Out, + duration: time.Duration = time.Second, + delay: f64 = 0, +) -> (tween: ^Flux_Tween(T)) where intrinsics.type_is_float(T) { + if res, ok := &flux.values[value]; ok { + tween = res + } else { + flux.values[value] = {} + tween = &flux.values[value] + } + + tween^ = { + value = value, + goal = goal, + duration = duration, + delay = delay, + type = type, + data = value, + } + + return +} + +// init internal properties +flux_tween_init :: proc(tween: ^Flux_Tween($T), duration: time.Duration) where intrinsics.type_is_float(T) { + tween.inited = true + tween.start = tween.value^ + tween.diff = tween.goal - tween.value^ + s := time.duration_seconds(duration) + tween.rate = duration > 0 ? 1.0 / s : 0 + tween.progress = duration > 0 ? 0 : 1 +} + +// update all tweens, wait for their delay if one exists +// calls callbacks in all stages, when they're filled +// deletes tween from the map after completion +flux_update :: proc(flux: ^Flux_Map($T), dt: f64) where intrinsics.type_is_float(T) { + for key, tween in &flux.values { + delay_remainder := f64(0) + + // Update delay if necessary. + if tween.delay > 0 { + tween.delay -= dt + + if tween.delay < 0 { + // We finished the delay, but in doing so consumed part of this frame's `dt` budget. + // Keep track of it so we can apply it to this tween without affecting others. + delay_remainder = tween.delay + // We're done with this delay. + tween.delay = 0 + } + } + + // We either had no delay, or the delay has been consumed. + if tween.delay <= 0 { + if !tween.inited { + flux_tween_init(&tween, tween.duration) + + if tween.on_start != nil { + tween.on_start(flux, tween.data) + } + } + + // If part of the `dt` budget was consumed this frame, then `delay_remainder` will be + // that remainder, a negative value. Adding it to `dt` applies what's left of the `dt` + // to the tween so it advances properly, instead of too much or little. + tween.progress += tween.rate * (dt + delay_remainder) + x := tween.progress >= 1 ? 1 : ease(tween.type, tween.progress) + tween.value^ = tween.start + tween.diff * T(x) + + if tween.on_update != nil { + tween.on_update(flux, tween.data) + } + + if tween.progress >= 1 { + delete_key(&flux.values, key) + + if tween.on_complete != nil { + tween.on_complete(flux, tween.data) + } + } + } + } +} + +// stop a specific key inside the map +// returns true when it successfully removed the key +flux_stop :: proc(flux: ^Flux_Map($T), key: ^T) -> bool where intrinsics.type_is_float(T) { + if key in flux.values { + delete_key(&flux.values, key) + return true + } + + return false +} + +// returns the amount of time left for the tween animation, if the key exists in the map +// returns 0 if the tween doesnt exist on the map +flux_tween_time_left :: proc(flux: Flux_Map($T), key: ^T) -> f64 { + if tween, ok := flux.values[key]; ok { + return ((1 - tween.progress) * tween.rate) + tween.delay + } else { + return 0 + } +} diff --git a/core/math/linalg/extended.odin b/core/math/linalg/extended.odin index ba64356ce..c2bf5552a 100644 --- a/core/math/linalg/extended.odin +++ b/core/math/linalg/extended.odin @@ -103,10 +103,10 @@ max :: proc{max_single, max_double, max_triple} abs :: proc(a: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) { when IS_ARRAY(T) { for i in 0.. (c: f64) { dot :: proc{scalar_dot, vector_dot, quaternion64_dot, quaternion128_dot, quaternion256_dot} inner_product :: dot -outer_product :: proc(a: $A/[$M]$E, b: $B/[$N]E) -> (out: [M][N]E) where IS_NUMERIC(E) #no_bounds_check { - for i in 0.. Q where IS_QUATERNION(Q) { return conj(q) * quaternion(1.0/dot(q, q), 0, 0, 0) @@ -163,65 +157,28 @@ identity :: proc($T: typeid/[$N][N]$E) -> (m: T) #no_bounds_check { return m } -trace :: proc(m: $T/[$N][N]$E) -> (tr: E) { - for i in 0.. (m: (T when N == M else [M][N]E)) #no_bounds_check { - for j in 0.. (c: M) +matrix_mul :: proc(a, b: $M/matrix[$N, N]$E) -> (c: M) where !IS_ARRAY(E), IS_NUMERIC(E) #no_bounds_check { - for i in 0.. (c: M) +matrix_comp_mul :: proc(a, b: $M/matrix[$I, $J]$E) -> (c: M) where !IS_ARRAY(E), IS_NUMERIC(E) #no_bounds_check { - for j in 0.. (c: [K][I]E) +matrix_mul_differ :: proc(a: $A/matrix[$I, $J]$E, b: $B/matrix[J, $K]E) -> (c: matrix[I, K]E) where !IS_ARRAY(E), IS_NUMERIC(E), I != K #no_bounds_check { - for k in 0.. (c: B) +matrix_mul_vector :: proc(a: $A/matrix[$I, $J]$E, b: $B/[J]E) -> (c: B) where !IS_ARRAY(E), IS_NUMERIC(E) #no_bounds_check { - for i in 0.. Q where IS_QUATERNION(Q) { @@ -270,8 +227,8 @@ mul :: proc{ vector_to_ptr :: proc(v: ^$V/[$N]$E) -> ^E where IS_NUMERIC(E), N > 0 #no_bounds_check { return &v[0] } -matrix_to_ptr :: proc(m: ^$A/[$I][$J]$E) -> ^E where IS_NUMERIC(E), I > 0, J > 0 #no_bounds_check { - return &m[0][0] +matrix_to_ptr :: proc(m: ^$A/matrix[$I, $J]$E) -> ^E where IS_NUMERIC(E), I > 0, J > 0 #no_bounds_check { + return &m[0, 0] } to_ptr :: proc{vector_to_ptr, matrix_to_ptr} @@ -330,10 +287,10 @@ array_cast :: proc(v: $A/[$N]$T, $Elem_Type: typeid) -> (w: [N]Elem_Type) #no_bo return } -matrix_cast :: proc(v: $A/[$M][$N]$T, $Elem_Type: typeid) -> (w: [M][N]Elem_Type) #no_bounds_check { - for i in 0.. (w: matrix[M, N]Elem_Type) #no_bounds_check { + for j in 0.. [N]uint { return array_cast(v, ui to_complex32 :: #force_inline proc(v: $A/[$N]$T) -> [N]complex32 { return array_cast(v, complex32) } to_complex64 :: #force_inline proc(v: $A/[$N]$T) -> [N]complex64 { return array_cast(v, complex64) } to_complex128 :: #force_inline proc(v: $A/[$N]$T) -> [N]complex128 { return array_cast(v, complex128) } -to_quaternion64 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion64 { return array_cast(v, quaternion64) } +to_quaternion64 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion64 { return array_cast(v, quaternion64) } to_quaternion128 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion128 { return array_cast(v, quaternion128) } to_quaternion256 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion256 { return array_cast(v, quaternion256) } diff --git a/core/math/linalg/glsl/linalg_glsl.odin b/core/math/linalg/glsl/linalg_glsl.odin index 3b4976452..74753f66f 100644 --- a/core/math/linalg/glsl/linalg_glsl.odin +++ b/core/math/linalg/glsl/linalg_glsl.odin @@ -473,6 +473,25 @@ floor_dvec3 :: proc "c" (x: dvec3) -> dvec3 { return {floor(x.x), floor(x.y), fl floor_dvec4 :: proc "c" (x: dvec4) -> dvec4 { return {floor(x.x), floor(x.y), floor(x.z), floor(x.w)} } + +round :: proc{ + round_f32, + round_f64, + round_vec2, + round_vec3, + round_vec4, + round_dvec2, + round_dvec3, + round_dvec4, +} +round_vec2 :: proc "c" (x: vec2) -> vec2 { return {round(x.x), round(x.y)} } +round_vec3 :: proc "c" (x: vec3) -> vec3 { return {round(x.x), round(x.y), round(x.z)} } +round_vec4 :: proc "c" (x: vec4) -> vec4 { return {round(x.x), round(x.y), round(x.z), round(x.w)} } +round_dvec2 :: proc "c" (x: dvec2) -> dvec2 { return {round(x.x), round(x.y)} } +round_dvec3 :: proc "c" (x: dvec3) -> dvec3 { return {round(x.x), round(x.y), round(x.z)} } +round_dvec4 :: proc "c" (x: dvec4) -> dvec4 { return {round(x.x), round(x.y), round(x.z), round(x.w)} } + + ceil :: proc{ ceil_f32, ceil_f64, @@ -693,23 +712,22 @@ saturate :: proc{ saturate_uvec3, saturate_uvec4, } -saturate_i32 :: proc "c" (x, y, z: i32) -> i32 { return builtin.clamp(x, 0, 1) } -saturate_u32 :: proc "c" (x, y, z: u32) -> u32 { return builtin.clamp(x, 0, 1) } -saturate_f32 :: proc "c" (x, y, z: f32) -> f32 { return builtin.clamp(x, 0, 1) } -saturate_f64 :: proc "c" (x, y, z: f64) -> f64 { return builtin.clamp(x, 0, 1) } -saturate_vec2 :: proc "c" (x, y, z: vec2) -> vec2 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1)} } -saturate_vec3 :: proc "c" (x, y, z: vec3) -> vec3 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1), builtin.clamp(x.z, 0, 1)} } -saturate_vec4 :: proc "c" (x, y, z: vec4) -> vec4 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1), builtin.clamp(x.z, 0, 1), builtin.clamp(x.w, 0, 1)} } -saturate_dvec2 :: proc "c" (x, y, z: dvec2) -> dvec2 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1)} } -saturate_dvec3 :: proc "c" (x, y, z: dvec3) -> dvec3 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1), builtin.clamp(x.z, 0, 1)} } -saturate_dvec4 :: proc "c" (x, y, z: dvec4) -> dvec4 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1), builtin.clamp(x.z, 0, 1), builtin.clamp(x.w, 0, 1)} } -saturate_ivec2 :: proc "c" (x, y, z: ivec2) -> ivec2 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1)} } -saturate_ivec3 :: proc "c" (x, y, z: ivec3) -> ivec3 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1), builtin.clamp(x.z, 0, 1)} } -saturate_ivec4 :: proc "c" (x, y, z: ivec4) -> ivec4 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1), builtin.clamp(x.z, 0, 1), builtin.clamp(x.w, 0, 1)} } -saturate_uvec2 :: proc "c" (x, y, z: uvec2) -> uvec2 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1)} } -saturate_uvec3 :: proc "c" (x, y, z: uvec3) -> uvec3 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1), builtin.clamp(x.z, 0, 1)} } -saturate_uvec4 :: proc "c" (x, y, z: uvec4) -> uvec4 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1), builtin.clamp(x.z, 0, 1), builtin.clamp(x.w, 0, 1)} } - +saturate_i32 :: proc "c" (v: i32) -> i32 { return builtin.clamp(v, 0, 1) } +saturate_u32 :: proc "c" (v: u32) -> u32 { return builtin.clamp(v, 0, 1) } +saturate_f32 :: proc "c" (v: f32) -> f32 { return builtin.clamp(v, 0, 1) } +saturate_f64 :: proc "c" (v: f64) -> f64 { return builtin.clamp(v, 0, 1) } +saturate_vec2 :: proc "c" (v: vec2) -> vec2 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1)} } +saturate_vec3 :: proc "c" (v: vec3) -> vec3 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1), builtin.clamp(v.z, 0, 1)} } +saturate_vec4 :: proc "c" (v: vec4) -> vec4 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1), builtin.clamp(v.z, 0, 1), builtin.clamp(v.w, 0, 1)} } +saturate_dvec2 :: proc "c" (v: dvec2) -> dvec2 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1)} } +saturate_dvec3 :: proc "c" (v: dvec3) -> dvec3 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1), builtin.clamp(v.z, 0, 1)} } +saturate_dvec4 :: proc "c" (v: dvec4) -> dvec4 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1), builtin.clamp(v.z, 0, 1), builtin.clamp(v.w, 0, 1)} } +saturate_ivec2 :: proc "c" (v: ivec2) -> ivec2 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1)} } +saturate_ivec3 :: proc "c" (v: ivec3) -> ivec3 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1), builtin.clamp(v.z, 0, 1)} } +saturate_ivec4 :: proc "c" (v: ivec4) -> ivec4 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1), builtin.clamp(v.z, 0, 1), builtin.clamp(v.w, 0, 1)} } +saturate_uvec2 :: proc "c" (v: uvec2) -> uvec2 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1)} } +saturate_uvec3 :: proc "c" (v: uvec3) -> uvec3 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1), builtin.clamp(v.z, 0, 1)} } +saturate_uvec4 :: proc "c" (v: uvec4) -> uvec4 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1), builtin.clamp(v.z, 0, 1), builtin.clamp(v.w, 0, 1)} } mix :: proc{ mix_f32, @@ -1597,7 +1615,7 @@ quatNlerp :: proc "c" (a, b: quat, t: f32) -> (c: quat) { c.y = a.y + (b.y-a.y)*t c.z = a.z + (b.z-a.z)*t c.w = a.w + (b.w-a.w)*t - return c/builtin.abs(c) + return c/quat(builtin.abs(c)) } quatSlerp :: proc "c" (x, y: quat, t: f32) -> (q: quat) { @@ -1699,7 +1717,7 @@ dquatNlerp :: proc "c" (a, b: dquat, t: f64) -> (c: dquat) { c.y = a.y + (b.y-a.y)*t c.z = a.z + (b.z-a.z)*t c.w = a.w + (b.w-a.w)*t - return c/builtin.abs(c) + return c/dquat(builtin.abs(c)) } dquatSlerp :: proc "c" (x, y: dquat, t: f64) -> (q: dquat) { diff --git a/core/math/linalg/glsl/linalg_glsl_math.odin b/core/math/linalg/glsl/linalg_glsl_math.odin index 68f43a2f7..968a3fa5e 100644 --- a/core/math/linalg/glsl/linalg_glsl_math.odin +++ b/core/math/linalg/glsl/linalg_glsl_math.odin @@ -23,6 +23,7 @@ log_f32 :: proc "c" (x: f32) -> f32 { return math.ln(x) } exp2_f32 :: proc "c" (x: f32) -> f32 { return math.pow(f32(2), x) } sign_f32 :: proc "c" (x: f32) -> f32 { return math.sign(x) } floor_f32 :: proc "c" (x: f32) -> f32 { return math.floor(x) } +round_f32 :: proc "c" (x: f32) -> f32 { return math.round(x) } ceil_f32 :: proc "c" (x: f32) -> f32 { return math.ceil(x) } mod_f32 :: proc "c" (x, y: f32) -> f32 { return math.mod(x, y) } fract_f32 :: proc "c" (x: f32) -> f32 { @@ -53,6 +54,7 @@ log_f64 :: proc "c" (x: f64) -> f64 { return math.ln(x) } exp2_f64 :: proc "c" (x: f64) -> f64 { return math.pow(f64(2), x) } sign_f64 :: proc "c" (x: f64) -> f64 { return math.sign(x) } floor_f64 :: proc "c" (x: f64) -> f64 { return math.floor(x) } +round_f64 :: proc "c" (x: f64) -> f64 { return math.round(x) } ceil_f64 :: proc "c" (x: f64) -> f64 { return math.ceil(x) } mod_f64 :: proc "c" (x, y: f64) -> f64 { return math.mod(x, y) } fract_f64 :: proc "c" (x: f64) -> f64 { diff --git a/core/math/linalg/hlsl/linalg_hlsl.odin b/core/math/linalg/hlsl/linalg_hlsl.odin index 0eb8413a9..3f73dcd1f 100644 --- a/core/math/linalg/hlsl/linalg_hlsl.odin +++ b/core/math/linalg/hlsl/linalg_hlsl.odin @@ -551,6 +551,23 @@ floor_double2 :: proc "c" (x: double2) -> double2 { return {floor(x.x), floor(x. floor_double3 :: proc "c" (x: double3) -> double3 { return {floor(x.x), floor(x.y), floor(x.z)} } floor_double4 :: proc "c" (x: double4) -> double4 { return {floor(x.x), floor(x.y), floor(x.z), floor(x.w)} } +round :: proc{ + round_float, + round_double, + round_float2, + round_float3, + round_float4, + round_double2, + round_double3, + round_double4, +} +round_float2 :: proc "c" (x: float2) -> float2 { return {round(x.x), round(x.y)} } +round_float3 :: proc "c" (x: float3) -> float3 { return {round(x.x), round(x.y), round(x.z)} } +round_float4 :: proc "c" (x: float4) -> float4 { return {round(x.x), round(x.y), round(x.z), round(x.w)} } +round_double2 :: proc "c" (x: double2) -> double2 { return {round(x.x), round(x.y)} } +round_double3 :: proc "c" (x: double3) -> double3 { return {round(x.x), round(x.y), round(x.z)} } +round_double4 :: proc "c" (x: double4) -> double4 { return {round(x.x), round(x.y), round(x.z), round(x.w)} } + ceil :: proc{ ceil_float, @@ -570,6 +587,69 @@ ceil_double3 :: proc "c" (x: double3) -> double3 { return {ceil(x.x), ceil(x.y), ceil_double4 :: proc "c" (x: double4) -> double4 { return {ceil(x.x), ceil(x.y), ceil(x.z), ceil(x.w)} } +isfinite_float :: proc "c" (x: float) -> bool { return !isinf_float(x) } +isfinite_float2 :: proc "c" (x: float2) -> bool2 { return {isfinite_float(x.x), isfinite_float(x.y)} } +isfinite_float3 :: proc "c" (x: float3) -> bool3 { return {isfinite_float(x.x), isfinite_float(x.y), isfinite_float(x.z)} } +isfinite_float4 :: proc "c" (x: float4) -> bool4 { return {isfinite_float(x.x), isfinite_float(x.y), isfinite_float(x.z), isfinite_float(x.w)} } +isfinite_double :: proc "c" (x: double) -> bool { return !isinf_double(x) } +isfinite_double2 :: proc "c" (x: double2) -> bool2 { return {isfinite_double(x.x), isfinite_double(x.y)} } +isfinite_double3 :: proc "c" (x: double3) -> bool3 { return {isfinite_double(x.x), isfinite_double(x.y), isfinite_double(x.z)} } +isfinite_double4 :: proc "c" (x: double4) -> bool4 { return {isfinite_double(x.x), isfinite_double(x.y), isfinite_double(x.z), isfinite_double(x.w)} } + +// isfinite is the opposite of isinf and returns true if the number is neither positive-infinite or negative-infinite +isfinite :: proc{ + isfinite_float, + isfinite_float2, + isfinite_float3, + isfinite_float4, + isfinite_double, + isfinite_double2, + isfinite_double3, + isfinite_double4, +} + + +isinf_float :: proc "c" (x: float) -> bool { return x * 0.5 == x } +isinf_float2 :: proc "c" (x: float2) -> bool2 { return {isinf_float(x.x), isinf_float(x.y)} } +isinf_float3 :: proc "c" (x: float3) -> bool3 { return {isinf_float(x.x), isinf_float(x.y), isinf_float(x.z)} } +isinf_float4 :: proc "c" (x: float4) -> bool4 { return {isinf_float(x.x), isinf_float(x.y), isinf_float(x.z), isinf_float(x.w)} } +isinf_double :: proc "c" (x: double) -> bool { return x * 0.5 == x } +isinf_double2 :: proc "c" (x: double2) -> bool2 { return {isinf_double(x.x), isinf_double(x.y)} } +isinf_double3 :: proc "c" (x: double3) -> bool3 { return {isinf_double(x.x), isinf_double(x.y), isinf_double(x.z)} } +isinf_double4 :: proc "c" (x: double4) -> bool4 { return {isinf_double(x.x), isinf_double(x.y), isinf_double(x.z), isinf_double(x.w)} } + +// isinf is the opposite of isfinite and returns true if the number is either positive-infinite or negative-infinite +isinf :: proc{ + isinf_float, + isinf_float2, + isinf_float3, + isinf_float4, + isinf_double, + isinf_double2, + isinf_double3, + isinf_double4, +} + + +isnan_float2 :: proc "c" (x: float2) -> bool2 { return {isnan_float(x.x), isnan_float(x.y)} } +isnan_float3 :: proc "c" (x: float3) -> bool3 { return {isnan_float(x.x), isnan_float(x.y), isnan_float(x.z)} } +isnan_float4 :: proc "c" (x: float4) -> bool4 { return {isnan_float(x.x), isnan_float(x.y), isnan_float(x.z), isnan_float(x.w)} } +isnan_double2 :: proc "c" (x: double2) -> bool2 { return {isnan_double(x.x), isnan_double(x.y)} } +isnan_double3 :: proc "c" (x: double3) -> bool3 { return {isnan_double(x.x), isnan_double(x.y), isnan_double(x.z)} } +isnan_double4 :: proc "c" (x: double4) -> bool4 { return {isnan_double(x.x), isnan_double(x.y), isnan_double(x.z), isnan_double(x.w)} } + +// isnan returns true if the input value is the special case of Not-A-Number +isnan :: proc{ + isnan_float, + isnan_float2, + isnan_float3, + isnan_float4, + isnan_double, + isnan_double2, + isnan_double3, + isnan_double4, +} + fmod :: proc{ fmod_float, fmod_double, @@ -772,22 +852,22 @@ saturate :: proc{ saturate_uint3, saturate_uint4, } -saturate_int :: proc "c" (x, y, z: int) -> int { return builtin.clamp(x, 0, 1) } -saturate_uint :: proc "c" (x, y, z: uint) -> uint { return builtin.clamp(x, 0, 1) } -saturate_float :: proc "c" (x, y, z: float) -> float { return builtin.clamp(x, 0, 1) } -saturate_double :: proc "c" (x, y, z: double) -> double { return builtin.clamp(x, 0, 1) } -saturate_float2 :: proc "c" (x, y, z: float2) -> float2 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1)} } -saturate_float3 :: proc "c" (x, y, z: float3) -> float3 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1), builtin.clamp(x.z, 0, 1)} } -saturate_float4 :: proc "c" (x, y, z: float4) -> float4 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1), builtin.clamp(x.z, 0, 1), builtin.clamp(x.w, 0, 1)} } -saturate_double2 :: proc "c" (x, y, z: double2) -> double2 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1)} } -saturate_double3 :: proc "c" (x, y, z: double3) -> double3 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1), builtin.clamp(x.z, 0, 1)} } -saturate_double4 :: proc "c" (x, y, z: double4) -> double4 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1), builtin.clamp(x.z, 0, 1), builtin.clamp(x.w, 0, 1)} } -saturate_int2 :: proc "c" (x, y, z: int2) -> int2 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1)} } -saturate_int3 :: proc "c" (x, y, z: int3) -> int3 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1), builtin.clamp(x.z, 0, 1)} } -saturate_int4 :: proc "c" (x, y, z: int4) -> int4 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1), builtin.clamp(x.z, 0, 1), builtin.clamp(x.w, 0, 1)} } -saturate_uint2 :: proc "c" (x, y, z: uint2) -> uint2 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1)} } -saturate_uint3 :: proc "c" (x, y, z: uint3) -> uint3 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1), builtin.clamp(x.z, 0, 1)} } -saturate_uint4 :: proc "c" (x, y, z: uint4) -> uint4 { return {builtin.clamp(x.x, 0, 1), builtin.clamp(x.y, 0, 1), builtin.clamp(x.z, 0, 1), builtin.clamp(x.w, 0, 1)} } +saturate_int :: proc "c" (v: int) -> int { return builtin.clamp(v, 0, 1) } +saturate_uint :: proc "c" (v: uint) -> uint { return builtin.clamp(v, 0, 1) } +saturate_float :: proc "c" (v: float) -> float { return builtin.clamp(v, 0, 1) } +saturate_double :: proc "c" (v: double) -> double { return builtin.clamp(v, 0, 1) } +saturate_float2 :: proc "c" (v: float2) -> float2 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1)} } +saturate_float3 :: proc "c" (v: float3) -> float3 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1), builtin.clamp(v.z, 0, 1)} } +saturate_float4 :: proc "c" (v: float4) -> float4 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1), builtin.clamp(v.z, 0, 1), builtin.clamp(v.w, 0, 1)} } +saturate_double2 :: proc "c" (v: double2) -> double2 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1)} } +saturate_double3 :: proc "c" (v: double3) -> double3 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1), builtin.clamp(v.z, 0, 1)} } +saturate_double4 :: proc "c" (v: double4) -> double4 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1), builtin.clamp(v.z, 0, 1), builtin.clamp(v.w, 0, 1)} } +saturate_int2 :: proc "c" (v: int2) -> int2 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1)} } +saturate_int3 :: proc "c" (v: int3) -> int3 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1), builtin.clamp(v.z, 0, 1)} } +saturate_int4 :: proc "c" (v: int4) -> int4 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1), builtin.clamp(v.z, 0, 1), builtin.clamp(v.w, 0, 1)} } +saturate_uint2 :: proc "c" (v: uint2) -> uint2 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1)} } +saturate_uint3 :: proc "c" (v: uint3) -> uint3 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1), builtin.clamp(v.z, 0, 1)} } +saturate_uint4 :: proc "c" (v: uint4) -> uint4 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1), builtin.clamp(v.z, 0, 1), builtin.clamp(v.w, 0, 1)} } lerp :: proc{ diff --git a/core/math/linalg/hlsl/linalg_hlsl_math.odin b/core/math/linalg/hlsl/linalg_hlsl_math.odin index d884c3d31..91c542b59 100644 --- a/core/math/linalg/hlsl/linalg_hlsl_math.odin +++ b/core/math/linalg/hlsl/linalg_hlsl_math.odin @@ -26,7 +26,9 @@ log10_float :: proc "c" (x: float) -> float { return math.log(x, 10) } exp2_float :: proc "c" (x: float) -> float { return math.pow(float(2), x) } sign_float :: proc "c" (x: float) -> float { return math.sign(x) } floor_float :: proc "c" (x: float) -> float { return math.floor(x) } +round_float :: proc "c" (x: float) -> float { return math.round(x) } ceil_float :: proc "c" (x: float) -> float { return math.ceil(x) } +isnan_float :: proc "c" (x: float) -> bool { return math.classify(x) == .NaN} fmod_float :: proc "c" (x, y: float) -> float { return math.mod(x, y) } frac_float :: proc "c" (x: float) -> float { if x >= 0 { @@ -35,6 +37,7 @@ frac_float :: proc "c" (x: float) -> float { return math.trunc(-x) + x } + cos_double :: proc "c" (x: double) -> double { return math.cos(x) } sin_double :: proc "c" (x: double) -> double { return math.sin(x) } tan_double :: proc "c" (x: double) -> double { return math.tan(x) } @@ -59,7 +62,9 @@ log10_double :: proc "c" (x: double) -> double { return math.log(x, 10) exp2_double :: proc "c" (x: double) -> double { return math.pow(double(2), x) } sign_double :: proc "c" (x: double) -> double { return math.sign(x) } floor_double :: proc "c" (x: double) -> double { return math.floor(x) } +round_double :: proc "c" (x: double) -> double { return math.round(x) } ceil_double :: proc "c" (x: double) -> double { return math.ceil(x) } +isnan_double :: proc "c" (x: double) -> bool { return math.classify(x) == .NaN} fmod_double :: proc "c" (x, y: double) -> double { return math.mod(x, y) } frac_double :: proc "c" (x: double) -> double { if x >= 0 { diff --git a/core/math/linalg/specific.odin b/core/math/linalg/specific.odin index 5cb68e3a8..a4aaeb012 100644 --- a/core/math/linalg/specific.odin +++ b/core/math/linalg/specific.odin @@ -1,5 +1,6 @@ package linalg +import "core:builtin" import "core:math" F16_EPSILON :: 1e-3 @@ -10,25 +11,25 @@ Vector2f16 :: distinct [2]f16 Vector3f16 :: distinct [3]f16 Vector4f16 :: distinct [4]f16 -Matrix1x1f16 :: distinct [1][1]f16 -Matrix1x2f16 :: distinct [1][2]f16 -Matrix1x3f16 :: distinct [1][3]f16 -Matrix1x4f16 :: distinct [1][4]f16 +Matrix1x1f16 :: distinct matrix[1, 1]f16 +Matrix1x2f16 :: distinct matrix[1, 2]f16 +Matrix1x3f16 :: distinct matrix[1, 3]f16 +Matrix1x4f16 :: distinct matrix[1, 4]f16 -Matrix2x1f16 :: distinct [2][1]f16 -Matrix2x2f16 :: distinct [2][2]f16 -Matrix2x3f16 :: distinct [2][3]f16 -Matrix2x4f16 :: distinct [2][4]f16 +Matrix2x1f16 :: distinct matrix[2, 1]f16 +Matrix2x2f16 :: distinct matrix[2, 2]f16 +Matrix2x3f16 :: distinct matrix[2, 3]f16 +Matrix2x4f16 :: distinct matrix[2, 4]f16 -Matrix3x1f16 :: distinct [3][1]f16 -Matrix3x2f16 :: distinct [3][2]f16 -Matrix3x3f16 :: distinct [3][3]f16 -Matrix3x4f16 :: distinct [3][4]f16 +Matrix3x1f16 :: distinct matrix[3, 1]f16 +Matrix3x2f16 :: distinct matrix[3, 2]f16 +Matrix3x3f16 :: distinct matrix[3, 3]f16 +Matrix3x4f16 :: distinct matrix[3, 4]f16 -Matrix4x1f16 :: distinct [4][1]f16 -Matrix4x2f16 :: distinct [4][2]f16 -Matrix4x3f16 :: distinct [4][3]f16 -Matrix4x4f16 :: distinct [4][4]f16 +Matrix4x1f16 :: distinct matrix[4, 1]f16 +Matrix4x2f16 :: distinct matrix[4, 2]f16 +Matrix4x3f16 :: distinct matrix[4, 3]f16 +Matrix4x4f16 :: distinct matrix[4, 4]f16 Matrix1f16 :: Matrix1x1f16 Matrix2f16 :: Matrix2x2f16 @@ -39,25 +40,25 @@ Vector2f32 :: distinct [2]f32 Vector3f32 :: distinct [3]f32 Vector4f32 :: distinct [4]f32 -Matrix1x1f32 :: distinct [1][1]f32 -Matrix1x2f32 :: distinct [1][2]f32 -Matrix1x3f32 :: distinct [1][3]f32 -Matrix1x4f32 :: distinct [1][4]f32 +Matrix1x1f32 :: distinct matrix[1, 1]f32 +Matrix1x2f32 :: distinct matrix[1, 2]f32 +Matrix1x3f32 :: distinct matrix[1, 3]f32 +Matrix1x4f32 :: distinct matrix[1, 4]f32 -Matrix2x1f32 :: distinct [2][1]f32 -Matrix2x2f32 :: distinct [2][2]f32 -Matrix2x3f32 :: distinct [2][3]f32 -Matrix2x4f32 :: distinct [2][4]f32 +Matrix2x1f32 :: distinct matrix[2, 1]f32 +Matrix2x2f32 :: distinct matrix[2, 2]f32 +Matrix2x3f32 :: distinct matrix[2, 3]f32 +Matrix2x4f32 :: distinct matrix[2, 4]f32 -Matrix3x1f32 :: distinct [3][1]f32 -Matrix3x2f32 :: distinct [3][2]f32 -Matrix3x3f32 :: distinct [3][3]f32 -Matrix3x4f32 :: distinct [3][4]f32 +Matrix3x1f32 :: distinct matrix[3, 1]f32 +Matrix3x2f32 :: distinct matrix[3, 2]f32 +Matrix3x3f32 :: distinct matrix[3, 3]f32 +Matrix3x4f32 :: distinct matrix[3, 4]f32 -Matrix4x1f32 :: distinct [4][1]f32 -Matrix4x2f32 :: distinct [4][2]f32 -Matrix4x3f32 :: distinct [4][3]f32 -Matrix4x4f32 :: distinct [4][4]f32 +Matrix4x1f32 :: distinct matrix[4, 1]f32 +Matrix4x2f32 :: distinct matrix[4, 2]f32 +Matrix4x3f32 :: distinct matrix[4, 3]f32 +Matrix4x4f32 :: distinct matrix[4, 4]f32 Matrix1f32 :: Matrix1x1f32 Matrix2f32 :: Matrix2x2f32 @@ -68,25 +69,25 @@ Vector2f64 :: distinct [2]f64 Vector3f64 :: distinct [3]f64 Vector4f64 :: distinct [4]f64 -Matrix1x1f64 :: distinct [1][1]f64 -Matrix1x2f64 :: distinct [1][2]f64 -Matrix1x3f64 :: distinct [1][3]f64 -Matrix1x4f64 :: distinct [1][4]f64 +Matrix1x1f64 :: distinct matrix[1, 1]f64 +Matrix1x2f64 :: distinct matrix[1, 2]f64 +Matrix1x3f64 :: distinct matrix[1, 3]f64 +Matrix1x4f64 :: distinct matrix[1, 4]f64 -Matrix2x1f64 :: distinct [2][1]f64 -Matrix2x2f64 :: distinct [2][2]f64 -Matrix2x3f64 :: distinct [2][3]f64 -Matrix2x4f64 :: distinct [2][4]f64 +Matrix2x1f64 :: distinct matrix[2, 1]f64 +Matrix2x2f64 :: distinct matrix[2, 2]f64 +Matrix2x3f64 :: distinct matrix[2, 3]f64 +Matrix2x4f64 :: distinct matrix[2, 4]f64 -Matrix3x1f64 :: distinct [3][1]f64 -Matrix3x2f64 :: distinct [3][2]f64 -Matrix3x3f64 :: distinct [3][3]f64 -Matrix3x4f64 :: distinct [3][4]f64 +Matrix3x1f64 :: distinct matrix[3, 1]f64 +Matrix3x2f64 :: distinct matrix[3, 2]f64 +Matrix3x3f64 :: distinct matrix[3, 3]f64 +Matrix3x4f64 :: distinct matrix[3, 4]f64 -Matrix4x1f64 :: distinct [4][1]f64 -Matrix4x2f64 :: distinct [4][2]f64 -Matrix4x3f64 :: distinct [4][3]f64 -Matrix4x4f64 :: distinct [4][4]f64 +Matrix4x1f64 :: distinct matrix[4, 1]f64 +Matrix4x2f64 :: distinct matrix[4, 2]f64 +Matrix4x3f64 :: distinct matrix[4, 3]f64 +Matrix4x4f64 :: distinct matrix[4, 4]f64 Matrix1f64 :: Matrix1x1f64 Matrix2f64 :: Matrix2x2f64 @@ -97,20 +98,20 @@ Quaternionf16 :: distinct quaternion64 Quaternionf32 :: distinct quaternion128 Quaternionf64 :: distinct quaternion256 -MATRIX1F16_IDENTITY :: Matrix1f16{{1}} -MATRIX2F16_IDENTITY :: Matrix2f16{{1, 0}, {0, 1}} -MATRIX3F16_IDENTITY :: Matrix3f16{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}} -MATRIX4F16_IDENTITY :: Matrix4f16{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}} +MATRIX1F16_IDENTITY :: Matrix1f16(1) +MATRIX2F16_IDENTITY :: Matrix2f16(1) +MATRIX3F16_IDENTITY :: Matrix3f16(1) +MATRIX4F16_IDENTITY :: Matrix4f16(1) -MATRIX1F32_IDENTITY :: Matrix1f32{{1}} -MATRIX2F32_IDENTITY :: Matrix2f32{{1, 0}, {0, 1}} -MATRIX3F32_IDENTITY :: Matrix3f32{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}} -MATRIX4F32_IDENTITY :: Matrix4f32{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}} +MATRIX1F32_IDENTITY :: Matrix1f32(1) +MATRIX2F32_IDENTITY :: Matrix2f32(1) +MATRIX3F32_IDENTITY :: Matrix3f32(1) +MATRIX4F32_IDENTITY :: Matrix4f32(1) -MATRIX1F64_IDENTITY :: Matrix1f64{{1}} -MATRIX2F64_IDENTITY :: Matrix2f64{{1, 0}, {0, 1}} -MATRIX3F64_IDENTITY :: Matrix3f64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}} -MATRIX4F64_IDENTITY :: Matrix4f64{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}} +MATRIX1F64_IDENTITY :: Matrix1f64(1) +MATRIX2F64_IDENTITY :: Matrix2f64(1) +MATRIX3F64_IDENTITY :: Matrix3f64(1) +MATRIX4F64_IDENTITY :: Matrix4f64(1) QUATERNIONF16_IDENTITY :: Quaternionf16(1) QUATERNIONF32_IDENTITY :: Quaternionf32(1) @@ -478,21 +479,21 @@ angle_from_quaternion_f16 :: proc(q: Quaternionf16) -> f16 { return math.asin(q.x*q.x + q.y*q.y + q.z*q.z) * 2 } - return math.cos(q.x) * 2 + return math.acos(q.w) * 2 } angle_from_quaternion_f32 :: proc(q: Quaternionf32) -> f32 { if abs(q.w) > math.SQRT_THREE*0.5 { return math.asin(q.x*q.x + q.y*q.y + q.z*q.z) * 2 } - return math.cos(q.x) * 2 + return math.acos(q.w) * 2 } angle_from_quaternion_f64 :: proc(q: Quaternionf64) -> f64 { if abs(q.w) > math.SQRT_THREE*0.5 { return math.asin(q.x*q.x + q.y*q.y + q.z*q.z) * 2 } - return math.cos(q.x) * 2 + return math.acos(q.w) * 2 } angle_from_quaternion :: proc{ angle_from_quaternion_f16, @@ -558,9 +559,9 @@ quaternion_from_forward_and_up_f16 :: proc(forward, up: Vector3f16) -> Quaternio s := normalize(cross(f, up)) u := cross(s, f) m := Matrix3f16{ - {+s.x, +u.x, -f.x}, - {+s.y, +u.y, -f.y}, - {+s.z, +u.z, -f.z}, + +s.x, +s.y, +s.z, + +u.x, +u.y, +u.z, + -f.x, -f.y, -f.z, } tr := trace(m) @@ -571,26 +572,26 @@ quaternion_from_forward_and_up_f16 :: proc(forward, up: Vector3f16) -> Quaternio case tr > 0: S := 2 * math.sqrt(1 + tr) q.w = 0.25 * S - q.x = (m[2][1] - m[1][2]) / S - q.y = (m[0][2] - m[2][0]) / S - q.z = (m[1][0] - m[0][1]) / S - case (m[0][0] > m[1][1]) && (m[0][0] > m[2][2]): - S := 2 * math.sqrt(1 + m[0][0] - m[1][1] - m[2][2]) - q.w = (m[2][1] - m[1][2]) / S + q.x = (m[1, 2] - m[2, 1]) / S + q.y = (m[2, 0] - m[0, 2]) / S + q.z = (m[0, 1] - m[1, 0]) / S + case (m[0, 0] > m[1, 1]) && (m[0, 0] > m[2, 2]): + S := 2 * math.sqrt(1 + m[0, 0] - m[1, 1] - m[2, 2]) + q.w = (m[1, 2] - m[2, 1]) / S q.x = 0.25 * S - q.y = (m[0][1] + m[1][0]) / S - q.z = (m[0][2] + m[2][0]) / S - case m[1][1] > m[2][2]: - S := 2 * math.sqrt(1 + m[1][1] - m[0][0] - m[2][2]) - q.w = (m[0][2] - m[2][0]) / S - q.x = (m[0][1] + m[1][0]) / S + q.y = (m[1, 0] + m[0, 1]) / S + q.z = (m[2, 0] + m[0, 2]) / S + case m[1, 1] > m[2, 2]: + S := 2 * math.sqrt(1 + m[1, 1] - m[0, 0] - m[2, 2]) + q.w = (m[2, 0] - m[0, 2]) / S + q.x = (m[1, 0] + m[0, 1]) / S q.y = 0.25 * S - q.z = (m[1][2] + m[2][1]) / S + q.z = (m[2, 1] + m[1, 2]) / S case: - S := 2 * math.sqrt(1 + m[2][2] - m[0][0] - m[1][1]) - q.w = (m[1][0] - m[0][1]) / S - q.x = (m[0][2] - m[2][0]) / S - q.y = (m[1][2] + m[2][1]) / S + S := 2 * math.sqrt(1 + m[2, 2] - m[0, 0] - m[1, 1]) + q.w = (m[0, 1] - m[1, 0]) / S + q.x = (m[2, 0] - m[0, 2]) / S + q.y = (m[2, 1] + m[1, 2]) / S q.z = 0.25 * S } @@ -601,9 +602,9 @@ quaternion_from_forward_and_up_f32 :: proc(forward, up: Vector3f32) -> Quaternio s := normalize(cross(f, up)) u := cross(s, f) m := Matrix3f32{ - {+s.x, +u.x, -f.x}, - {+s.y, +u.y, -f.y}, - {+s.z, +u.z, -f.z}, + +s.x, +s.y, +s.z, + +u.x, +u.y, +u.z, + -f.x, -f.y, -f.z, } tr := trace(m) @@ -614,26 +615,26 @@ quaternion_from_forward_and_up_f32 :: proc(forward, up: Vector3f32) -> Quaternio case tr > 0: S := 2 * math.sqrt(1 + tr) q.w = 0.25 * S - q.x = (m[2][1] - m[1][2]) / S - q.y = (m[0][2] - m[2][0]) / S - q.z = (m[1][0] - m[0][1]) / S - case (m[0][0] > m[1][1]) && (m[0][0] > m[2][2]): - S := 2 * math.sqrt(1 + m[0][0] - m[1][1] - m[2][2]) - q.w = (m[2][1] - m[1][2]) / S + q.x = (m[1, 2] - m[2, 1]) / S + q.y = (m[2, 0] - m[0, 2]) / S + q.z = (m[0, 1] - m[1, 0]) / S + case (m[0, 0] > m[1, 1]) && (m[0, 0] > m[2, 2]): + S := 2 * math.sqrt(1 + m[0, 0] - m[1, 1] - m[2, 2]) + q.w = (m[1, 2] - m[2, 1]) / S q.x = 0.25 * S - q.y = (m[0][1] + m[1][0]) / S - q.z = (m[0][2] + m[2][0]) / S - case m[1][1] > m[2][2]: - S := 2 * math.sqrt(1 + m[1][1] - m[0][0] - m[2][2]) - q.w = (m[0][2] - m[2][0]) / S - q.x = (m[0][1] + m[1][0]) / S + q.y = (m[1, 0] + m[0, 1]) / S + q.z = (m[2, 0] + m[0, 2]) / S + case m[1, 1] > m[2, 2]: + S := 2 * math.sqrt(1 + m[1, 1] - m[0, 0] - m[2, 2]) + q.w = (m[2, 0] - m[0, 2]) / S + q.x = (m[1, 0] + m[0, 1]) / S q.y = 0.25 * S - q.z = (m[1][2] + m[2][1]) / S + q.z = (m[2, 1] + m[1, 2]) / S case: - S := 2 * math.sqrt(1 + m[2][2] - m[0][0] - m[1][1]) - q.w = (m[1][0] - m[0][1]) / S - q.x = (m[0][2] - m[2][0]) / S - q.y = (m[1][2] + m[2][1]) / S + S := 2 * math.sqrt(1 + m[2, 2] - m[0, 0] - m[1, 1]) + q.w = (m[0, 1] - m[1, 0]) / S + q.x = (m[2, 0] - m[0, 2]) / S + q.y = (m[2, 1] + m[1, 2]) / S q.z = 0.25 * S } @@ -644,9 +645,9 @@ quaternion_from_forward_and_up_f64 :: proc(forward, up: Vector3f64) -> Quaternio s := normalize(cross(f, up)) u := cross(s, f) m := Matrix3f64{ - {+s.x, +u.x, -f.x}, - {+s.y, +u.y, -f.y}, - {+s.z, +u.z, -f.z}, + +s.x, +s.y, +s.z, + +u.x, +u.y, +u.z, + -f.x, -f.y, -f.z, } tr := trace(m) @@ -657,26 +658,26 @@ quaternion_from_forward_and_up_f64 :: proc(forward, up: Vector3f64) -> Quaternio case tr > 0: S := 2 * math.sqrt(1 + tr) q.w = 0.25 * S - q.x = (m[2][1] - m[1][2]) / S - q.y = (m[0][2] - m[2][0]) / S - q.z = (m[1][0] - m[0][1]) / S - case (m[0][0] > m[1][1]) && (m[0][0] > m[2][2]): - S := 2 * math.sqrt(1 + m[0][0] - m[1][1] - m[2][2]) - q.w = (m[2][1] - m[1][2]) / S + q.x = (m[1, 2] - m[2, 1]) / S + q.y = (m[2, 0] - m[0, 2]) / S + q.z = (m[0, 1] - m[1, 0]) / S + case (m[0, 0] > m[1, 1]) && (m[0, 0] > m[2, 2]): + S := 2 * math.sqrt(1 + m[0, 0] - m[1, 1] - m[2, 2]) + q.w = (m[1, 2] - m[2, 1]) / S q.x = 0.25 * S - q.y = (m[0][1] + m[1][0]) / S - q.z = (m[0][2] + m[2][0]) / S - case m[1][1] > m[2][2]: - S := 2 * math.sqrt(1 + m[1][1] - m[0][0] - m[2][2]) - q.w = (m[0][2] - m[2][0]) / S - q.x = (m[0][1] + m[1][0]) / S + q.y = (m[1, 0] + m[0, 1]) / S + q.z = (m[2, 0] + m[0, 2]) / S + case m[1, 1] > m[2, 2]: + S := 2 * math.sqrt(1 + m[1, 1] - m[0, 0] - m[2, 2]) + q.w = (m[2, 0] - m[0, 2]) / S + q.x = (m[1, 0] + m[0, 1]) / S q.y = 0.25 * S - q.z = (m[1][2] + m[2][1]) / S + q.z = (m[2, 1] + m[1, 2]) / S case: - S := 2 * math.sqrt(1 + m[2][2] - m[0][0] - m[1][1]) - q.w = (m[1][0] - m[0][1]) / S - q.x = (m[0][2] - m[2][0]) / S - q.y = (m[1][2] + m[2][1]) / S + S := 2 * math.sqrt(1 + m[2, 2] - m[0, 0] - m[1, 1]) + q.w = (m[0, 1] - m[1, 0]) / S + q.x = (m[2, 0] - m[0, 2]) / S + q.y = (m[2, 1] + m[1, 2]) / S q.z = 0.25 * S } @@ -842,23 +843,23 @@ quaternion_squad :: proc{ quaternion_from_matrix4_f16 :: proc(m: Matrix4f16) -> (q: Quaternionf16) { m3: Matrix3f16 = --- - m3[0][0], m3[0][1], m3[0][2] = m[0][0], m[0][1], m[0][2] - m3[1][0], m3[1][1], m3[1][2] = m[1][0], m[1][1], m[1][2] - m3[2][0], m3[2][1], m3[2][2] = m[2][0], m[2][1], m[2][2] + m3[0, 0], m3[1, 0], m3[2, 0] = m[0, 0], m[1, 0], m[2, 0] + m3[0, 1], m3[1, 1], m3[2, 1] = m[0, 1], m[1, 1], m[2, 1] + m3[0, 2], m3[1, 2], m3[2, 2] = m[0, 2], m[1, 2], m[2, 2] return quaternion_from_matrix3(m3) } quaternion_from_matrix4_f32 :: proc(m: Matrix4f32) -> (q: Quaternionf32) { m3: Matrix3f32 = --- - m3[0][0], m3[0][1], m3[0][2] = m[0][0], m[0][1], m[0][2] - m3[1][0], m3[1][1], m3[1][2] = m[1][0], m[1][1], m[1][2] - m3[2][0], m3[2][1], m3[2][2] = m[2][0], m[2][1], m[2][2] + m3[0, 0], m3[1, 0], m3[2, 0] = m[0, 0], m[1, 0], m[2, 0] + m3[0, 1], m3[1, 1], m3[2, 1] = m[0, 1], m[1, 1], m[2, 1] + m3[0, 2], m3[1, 2], m3[2, 2] = m[0, 2], m[1, 2], m[2, 2] return quaternion_from_matrix3(m3) } quaternion_from_matrix4_f64 :: proc(m: Matrix4f64) -> (q: Quaternionf64) { m3: Matrix3f64 = --- - m3[0][0], m3[0][1], m3[0][2] = m[0][0], m[0][1], m[0][2] - m3[1][0], m3[1][1], m3[1][2] = m[1][0], m[1][1], m[1][2] - m3[2][0], m3[2][1], m3[2][2] = m[2][0], m[2][1], m[2][2] + m3[0, 0], m3[1, 0], m3[2, 0] = m[0, 0], m[1, 0], m[2, 0] + m3[0, 1], m3[1, 1], m3[2, 1] = m[0, 1], m[1, 1], m[2, 1] + m3[0, 2], m3[1, 2], m3[2, 2] = m[0, 2], m[1, 2], m[2, 2] return quaternion_from_matrix3(m3) } quaternion_from_matrix4 :: proc{ @@ -869,10 +870,10 @@ quaternion_from_matrix4 :: proc{ quaternion_from_matrix3_f16 :: proc(m: Matrix3f16) -> (q: Quaternionf16) { - four_x_squared_minus_1 := m[0][0] - m[1][1] - m[2][2] - four_y_squared_minus_1 := m[1][1] - m[0][0] - m[2][2] - four_z_squared_minus_1 := m[2][2] - m[0][0] - m[1][1] - four_w_squared_minus_1 := m[0][0] + m[1][1] + m[2][2] + four_x_squared_minus_1 := m[0, 0] - m[1, 1] - m[2, 2] + four_y_squared_minus_1 := m[1, 1] - m[0, 0] - m[2, 2] + four_z_squared_minus_1 := m[2, 2] - m[0, 0] - m[1, 1] + four_w_squared_minus_1 := m[0, 0] + m[1, 1] + m[2, 2] biggest_index := 0 four_biggest_squared_minus_1 := four_w_squared_minus_1 @@ -896,32 +897,32 @@ quaternion_from_matrix3_f16 :: proc(m: Matrix3f16) -> (q: Quaternionf16) { switch biggest_index { case 0: q.w = biggest_val - q.x = (m[1][2] - m[2][1]) * mult - q.y = (m[2][0] - m[0][2]) * mult - q.z = (m[0][1] - m[1][0]) * mult + q.x = (m[2, 1] - m[1, 2]) * mult + q.y = (m[0, 2] - m[2, 0]) * mult + q.z = (m[1, 0] - m[0, 1]) * mult case 1: - q.w = (m[1][2] - m[2][1]) * mult + q.w = (m[2, 1] - m[1, 2]) * mult q.x = biggest_val - q.y = (m[0][1] + m[1][0]) * mult - q.z = (m[2][0] + m[0][2]) * mult + q.y = (m[1, 0] + m[0, 1]) * mult + q.z = (m[0, 2] + m[2, 0]) * mult case 2: - q.w = (m[2][0] - m[0][2]) * mult - q.x = (m[0][1] + m[1][0]) * mult + q.w = (m[0, 2] - m[2, 0]) * mult + q.x = (m[1, 0] + m[0, 1]) * mult q.y = biggest_val - q.z = (m[1][2] + m[2][1]) * mult + q.z = (m[2, 1] + m[1, 2]) * mult case 3: - q.w = (m[0][1] - m[1][0]) * mult - q.x = (m[2][0] + m[0][2]) * mult - q.y = (m[1][2] + m[2][1]) * mult + q.w = (m[1, 0] - m[0, 1]) * mult + q.x = (m[0, 2] + m[2, 0]) * mult + q.y = (m[2, 1] + m[1, 2]) * mult q.z = biggest_val } return } quaternion_from_matrix3_f32 :: proc(m: Matrix3f32) -> (q: Quaternionf32) { - four_x_squared_minus_1 := m[0][0] - m[1][1] - m[2][2] - four_y_squared_minus_1 := m[1][1] - m[0][0] - m[2][2] - four_z_squared_minus_1 := m[2][2] - m[0][0] - m[1][1] - four_w_squared_minus_1 := m[0][0] + m[1][1] + m[2][2] + four_x_squared_minus_1 := m[0, 0] - m[1, 1] - m[2, 2] + four_y_squared_minus_1 := m[1, 1] - m[0, 0] - m[2, 2] + four_z_squared_minus_1 := m[2, 2] - m[0, 0] - m[1, 1] + four_w_squared_minus_1 := m[0, 0] + m[1, 1] + m[2, 2] biggest_index := 0 four_biggest_squared_minus_1 := four_w_squared_minus_1 @@ -945,32 +946,32 @@ quaternion_from_matrix3_f32 :: proc(m: Matrix3f32) -> (q: Quaternionf32) { switch biggest_index { case 0: q.w = biggest_val - q.x = (m[1][2] - m[2][1]) * mult - q.y = (m[2][0] - m[0][2]) * mult - q.z = (m[0][1] - m[1][0]) * mult + q.x = (m[2, 1] - m[1, 2]) * mult + q.y = (m[0, 2] - m[2, 0]) * mult + q.z = (m[1, 0] - m[0, 1]) * mult case 1: - q.w = (m[1][2] - m[2][1]) * mult + q.w = (m[2, 1] - m[1, 2]) * mult q.x = biggest_val - q.y = (m[0][1] + m[1][0]) * mult - q.z = (m[2][0] + m[0][2]) * mult + q.y = (m[1, 0] + m[0, 1]) * mult + q.z = (m[0, 2] + m[2, 0]) * mult case 2: - q.w = (m[2][0] - m[0][2]) * mult - q.x = (m[0][1] + m[1][0]) * mult + q.w = (m[0, 2] - m[2, 0]) * mult + q.x = (m[1, 0] + m[0, 1]) * mult q.y = biggest_val - q.z = (m[1][2] + m[2][1]) * mult + q.z = (m[2, 1] + m[1, 2]) * mult case 3: - q.w = (m[0][1] - m[1][0]) * mult - q.x = (m[2][0] + m[0][2]) * mult - q.y = (m[1][2] + m[2][1]) * mult + q.w = (m[1, 0] - m[0, 1]) * mult + q.x = (m[0, 2] + m[2, 0]) * mult + q.y = (m[2, 1] + m[1, 2]) * mult q.z = biggest_val } return } quaternion_from_matrix3_f64 :: proc(m: Matrix3f64) -> (q: Quaternionf64) { - four_x_squared_minus_1 := m[0][0] - m[1][1] - m[2][2] - four_y_squared_minus_1 := m[1][1] - m[0][0] - m[2][2] - four_z_squared_minus_1 := m[2][2] - m[0][0] - m[1][1] - four_w_squared_minus_1 := m[0][0] + m[1][1] + m[2][2] + four_x_squared_minus_1 := m[0, 0] - m[1, 1] - m[2, 2] + four_y_squared_minus_1 := m[1, 1] - m[0, 0] - m[2, 2] + four_z_squared_minus_1 := m[2, 2] - m[0, 0] - m[1, 1] + four_w_squared_minus_1 := m[0, 0] + m[1, 1] + m[2, 2] biggest_index := 0 four_biggest_squared_minus_1 := four_w_squared_minus_1 @@ -994,23 +995,23 @@ quaternion_from_matrix3_f64 :: proc(m: Matrix3f64) -> (q: Quaternionf64) { switch biggest_index { case 0: q.w = biggest_val - q.x = (m[1][2] - m[2][1]) * mult - q.y = (m[2][0] - m[0][2]) * mult - q.z = (m[0][1] - m[1][0]) * mult + q.x = (m[2, 1] - m[1, 2]) * mult + q.y = (m[0, 2] - m[2, 0]) * mult + q.z = (m[1, 0] - m[0, 1]) * mult case 1: - q.w = (m[1][2] - m[2][1]) * mult + q.w = (m[2, 1] - m[1, 2]) * mult q.x = biggest_val - q.y = (m[0][1] + m[1][0]) * mult - q.z = (m[2][0] + m[0][2]) * mult + q.y = (m[1, 0] + m[0, 1]) * mult + q.z = (m[0, 2] + m[2, 0]) * mult case 2: - q.w = (m[2][0] - m[0][2]) * mult - q.x = (m[0][1] + m[1][0]) * mult + q.w = (m[0, 2] - m[2, 0]) * mult + q.x = (m[1, 0] + m[0, 1]) * mult q.y = biggest_val - q.z = (m[1][2] + m[2][1]) * mult + q.z = (m[2, 1] + m[1, 2]) * mult case 3: - q.w = (m[0][1] - m[1][0]) * mult - q.x = (m[2][0] + m[0][2]) * mult - q.y = (m[1][2] + m[2][1]) * mult + q.w = (m[1, 0] - m[0, 1]) * mult + q.x = (m[0, 2] + m[2, 0]) * mult + q.y = (m[2, 1] + m[1, 2]) * mult q.z = biggest_val } return @@ -1093,30 +1094,30 @@ quaternion_between_two_vector3 :: proc{ matrix2_inverse_transpose_f16 :: proc(m: Matrix2f16) -> (c: Matrix2f16) { - d := m[0][0]*m[1][1] - m[1][0]*m[0][1] + d := m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0] id := 1.0/d - c[0][0] = +m[1][1] * id - c[0][1] = -m[0][1] * id - c[1][0] = -m[1][0] * id - c[1][1] = +m[0][0] * id + c[0, 0] = +m[1, 1] * id + c[1, 0] = -m[1, 0] * id + c[0, 1] = -m[0, 1] * id + c[1, 1] = +m[0, 0] * id return c } matrix2_inverse_transpose_f32 :: proc(m: Matrix2f32) -> (c: Matrix2f32) { - d := m[0][0]*m[1][1] - m[1][0]*m[0][1] + d := m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0] id := 1.0/d - c[0][0] = +m[1][1] * id - c[0][1] = -m[0][1] * id - c[1][0] = -m[1][0] * id - c[1][1] = +m[0][0] * id + c[0, 0] = +m[1, 1] * id + c[1, 0] = -m[1, 0] * id + c[0, 1] = -m[0, 1] * id + c[1, 1] = +m[0, 0] * id return c } matrix2_inverse_transpose_f64 :: proc(m: Matrix2f64) -> (c: Matrix2f64) { - d := m[0][0]*m[1][1] - m[1][0]*m[0][1] + d := m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0] id := 1.0/d - c[0][0] = +m[1][1] * id - c[0][1] = -m[0][1] * id - c[1][0] = -m[1][0] * id - c[1][1] = +m[0][0] * id + c[0, 0] = +m[1, 1] * id + c[1, 0] = -m[1, 0] * id + c[0, 1] = -m[0, 1] * id + c[1, 1] = +m[0, 0] * id return c } matrix2_inverse_transpose :: proc{ @@ -1127,13 +1128,13 @@ matrix2_inverse_transpose :: proc{ matrix2_determinant_f16 :: proc(m: Matrix2f16) -> f16 { - return m[0][0]*m[1][1] - m[1][0]*m[0][1] + return m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0] } matrix2_determinant_f32 :: proc(m: Matrix2f32) -> f32 { - return m[0][0]*m[1][1] - m[1][0]*m[0][1] + return m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0] } matrix2_determinant_f64 :: proc(m: Matrix2f64) -> f64 { - return m[0][0]*m[1][1] - m[1][0]*m[0][1] + return m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0] } matrix2_determinant :: proc{ matrix2_determinant_f16, @@ -1143,30 +1144,30 @@ matrix2_determinant :: proc{ matrix2_inverse_f16 :: proc(m: Matrix2f16) -> (c: Matrix2f16) { - d := m[0][0]*m[1][1] - m[1][0]*m[0][1] + d := m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0] id := 1.0/d - c[0][0] = +m[1][1] * id - c[1][0] = -m[0][1] * id - c[0][1] = -m[1][0] * id - c[1][1] = +m[0][0] * id + c[0, 0] = +m[1, 1] * id + c[0, 1] = -m[1, 0] * id + c[1, 0] = -m[0, 1] * id + c[1, 1] = +m[0, 0] * id return c } matrix2_inverse_f32 :: proc(m: Matrix2f32) -> (c: Matrix2f32) { - d := m[0][0]*m[1][1] - m[1][0]*m[0][1] + d := m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0] id := 1.0/d - c[0][0] = +m[1][1] * id - c[1][0] = -m[0][1] * id - c[0][1] = -m[1][0] * id - c[1][1] = +m[0][0] * id + c[0, 0] = +m[1, 1] * id + c[0, 1] = -m[1, 0] * id + c[1, 0] = -m[0, 1] * id + c[1, 1] = +m[0, 0] * id return c } matrix2_inverse_f64 :: proc(m: Matrix2f64) -> (c: Matrix2f64) { - d := m[0][0]*m[1][1] - m[1][0]*m[0][1] + d := m[0, 0]*m[1, 1] - m[0, 1]*m[1, 0] id := 1.0/d - c[0][0] = +m[1][1] * id - c[1][0] = -m[0][1] * id - c[0][1] = -m[1][0] * id - c[1][1] = +m[0][0] * id + c[0, 0] = +m[1, 1] * id + c[0, 1] = -m[1, 0] * id + c[1, 0] = -m[0, 1] * id + c[1, 1] = +m[0, 0] * id return c } matrix2_inverse :: proc{ @@ -1177,24 +1178,24 @@ matrix2_inverse :: proc{ matrix2_adjoint_f16 :: proc(m: Matrix2f16) -> (c: Matrix2f16) { - c[0][0] = +m[1][1] - c[0][1] = -m[1][0] - c[1][0] = -m[0][1] - c[1][1] = +m[0][0] + c[0, 0] = +m[1, 1] + c[1, 0] = -m[0, 1] + c[0, 1] = -m[1, 0] + c[1, 1] = +m[0, 0] return c } matrix2_adjoint_f32 :: proc(m: Matrix2f32) -> (c: Matrix2f32) { - c[0][0] = +m[1][1] - c[0][1] = -m[1][0] - c[1][0] = -m[0][1] - c[1][1] = +m[0][0] + c[0, 0] = +m[1, 1] + c[1, 0] = -m[0, 1] + c[0, 1] = -m[1, 0] + c[1, 1] = +m[0, 0] return c } matrix2_adjoint_f64 :: proc(m: Matrix2f64) -> (c: Matrix2f64) { - c[0][0] = +m[1][1] - c[0][1] = -m[1][0] - c[1][0] = -m[0][1] - c[1][1] = +m[0][0] + c[0, 0] = +m[1, 1] + c[1, 0] = -m[0, 1] + c[0, 1] = -m[1, 0] + c[1, 1] = +m[0, 0] return c } matrix2_adjoint :: proc{ @@ -1215,17 +1216,17 @@ matrix3_from_quaternion_f16 :: proc(q: Quaternionf16) -> (m: Matrix3f16) { qwy := q.w * q.y qwz := q.w * q.z - m[0][0] = 1 - 2 * (qyy + qzz) - m[0][1] = 2 * (qxy + qwz) - m[0][2] = 2 * (qxz - qwy) + m[0, 0] = 1 - 2 * (qyy + qzz) + m[1, 0] = 2 * (qxy + qwz) + m[2, 0] = 2 * (qxz - qwy) - m[1][0] = 2 * (qxy - qwz) - m[1][1] = 1 - 2 * (qxx + qzz) - m[1][2] = 2 * (qyz + qwx) + m[0, 1] = 2 * (qxy - qwz) + m[1, 1] = 1 - 2 * (qxx + qzz) + m[2, 1] = 2 * (qyz + qwx) - m[2][0] = 2 * (qxz + qwy) - m[2][1] = 2 * (qyz - qwx) - m[2][2] = 1 - 2 * (qxx + qyy) + m[0, 2] = 2 * (qxz + qwy) + m[1, 2] = 2 * (qyz - qwx) + m[2, 2] = 1 - 2 * (qxx + qyy) return m } matrix3_from_quaternion_f32 :: proc(q: Quaternionf32) -> (m: Matrix3f32) { @@ -1239,17 +1240,17 @@ matrix3_from_quaternion_f32 :: proc(q: Quaternionf32) -> (m: Matrix3f32) { qwy := q.w * q.y qwz := q.w * q.z - m[0][0] = 1 - 2 * (qyy + qzz) - m[0][1] = 2 * (qxy + qwz) - m[0][2] = 2 * (qxz - qwy) + m[0, 0] = 1 - 2 * (qyy + qzz) + m[1, 0] = 2 * (qxy + qwz) + m[2, 0] = 2 * (qxz - qwy) - m[1][0] = 2 * (qxy - qwz) - m[1][1] = 1 - 2 * (qxx + qzz) - m[1][2] = 2 * (qyz + qwx) + m[0, 1] = 2 * (qxy - qwz) + m[1, 1] = 1 - 2 * (qxx + qzz) + m[2, 1] = 2 * (qyz + qwx) - m[2][0] = 2 * (qxz + qwy) - m[2][1] = 2 * (qyz - qwx) - m[2][2] = 1 - 2 * (qxx + qyy) + m[0, 2] = 2 * (qxz + qwy) + m[1, 2] = 2 * (qyz - qwx) + m[2, 2] = 1 - 2 * (qxx + qyy) return m } matrix3_from_quaternion_f64 :: proc(q: Quaternionf64) -> (m: Matrix3f64) { @@ -1263,17 +1264,17 @@ matrix3_from_quaternion_f64 :: proc(q: Quaternionf64) -> (m: Matrix3f64) { qwy := q.w * q.y qwz := q.w * q.z - m[0][0] = 1 - 2 * (qyy + qzz) - m[0][1] = 2 * (qxy + qwz) - m[0][2] = 2 * (qxz - qwy) + m[0, 0] = 1 - 2 * (qyy + qzz) + m[1, 0] = 2 * (qxy + qwz) + m[2, 0] = 2 * (qxz - qwy) - m[1][0] = 2 * (qxy - qwz) - m[1][1] = 1 - 2 * (qxx + qzz) - m[1][2] = 2 * (qyz + qwx) + m[0, 1] = 2 * (qxy - qwz) + m[1, 1] = 1 - 2 * (qxx + qzz) + m[2, 1] = 2 * (qyz + qwx) - m[2][0] = 2 * (qxz + qwy) - m[2][1] = 2 * (qyz - qwx) - m[2][2] = 1 - 2 * (qxx + qyy) + m[0, 2] = 2 * (qxz + qwy) + m[1, 2] = 2 * (qyz - qwx) + m[2, 2] = 1 - 2 * (qxx + qyy) return m } matrix3_from_quaternion :: proc{ @@ -1300,21 +1301,21 @@ matrix3_inverse :: proc{ matrix3_determinant_f16 :: proc(m: Matrix3f16) -> f16 { - a := +m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]) - b := -m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2]) - c := +m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]) + a := +m[0, 0] * (m[1, 1] * m[2, 2] - m[1, 2] * m[2, 1]) + b := -m[0, 1] * (m[1, 0] * m[2, 2] - m[1, 2] * m[2, 0]) + c := +m[0, 2] * (m[1, 0] * m[2, 1] - m[1, 1] * m[2, 0]) return a + b + c } matrix3_determinant_f32 :: proc(m: Matrix3f32) -> f32 { - a := +m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]) - b := -m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2]) - c := +m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]) + a := +m[0, 0] * (m[1, 1] * m[2, 2] - m[1, 2] * m[2, 1]) + b := -m[0, 1] * (m[1, 0] * m[2, 2] - m[1, 2] * m[2, 0]) + c := +m[0, 2] * (m[1, 0] * m[2, 1] - m[1, 1] * m[2, 0]) return a + b + c } matrix3_determinant_f64 :: proc(m: Matrix3f64) -> f64 { - a := +m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]) - b := -m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2]) - c := +m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]) + a := +m[0, 0] * (m[1, 1] * m[2, 2] - m[1, 2] * m[2, 1]) + b := -m[0, 1] * (m[1, 0] * m[2, 2] - m[1, 2] * m[2, 0]) + c := +m[0, 2] * (m[1, 0] * m[2, 1] - m[1, 1] * m[2, 0]) return a + b + c } matrix3_determinant :: proc{ @@ -1325,39 +1326,39 @@ matrix3_determinant :: proc{ matrix3_adjoint_f16 :: proc(m: Matrix3f16) -> (adjoint: Matrix3f16) { - adjoint[0][0] = +(m[1][1] * m[2][2] - m[1][2] * m[2][1]) - adjoint[1][0] = -(m[0][1] * m[2][2] - m[0][2] * m[2][1]) - adjoint[2][0] = +(m[0][1] * m[1][2] - m[0][2] * m[1][1]) - adjoint[0][1] = -(m[1][0] * m[2][2] - m[1][2] * m[2][0]) - adjoint[1][1] = +(m[0][0] * m[2][2] - m[0][2] * m[2][0]) - adjoint[2][1] = -(m[0][0] * m[1][2] - m[0][2] * m[1][0]) - adjoint[0][2] = +(m[1][0] * m[2][1] - m[1][1] * m[2][0]) - adjoint[1][2] = -(m[0][0] * m[2][1] - m[0][1] * m[2][0]) - adjoint[2][2] = +(m[0][0] * m[1][1] - m[0][1] * m[1][0]) + adjoint[0, 0] = +(m[1, 1] * m[2, 2] - m[2, 1] * m[1, 2]) + adjoint[0, 1] = -(m[1, 0] * m[2, 2] - m[2, 0] * m[1, 2]) + adjoint[0, 2] = +(m[1, 0] * m[2, 1] - m[2, 0] * m[1, 1]) + adjoint[1, 0] = -(m[0, 1] * m[2, 2] - m[2, 1] * m[0, 2]) + adjoint[1, 1] = +(m[0, 0] * m[2, 2] - m[2, 0] * m[0, 2]) + adjoint[1, 2] = -(m[0, 0] * m[2, 1] - m[2, 0] * m[0, 1]) + adjoint[2, 0] = +(m[0, 1] * m[1, 2] - m[1, 1] * m[0, 2]) + adjoint[2, 1] = -(m[0, 0] * m[1, 2] - m[1, 0] * m[0, 2]) + adjoint[2, 2] = +(m[0, 0] * m[1, 1] - m[1, 0] * m[0, 1]) return adjoint } matrix3_adjoint_f32 :: proc(m: Matrix3f32) -> (adjoint: Matrix3f32) { - adjoint[0][0] = +(m[1][1] * m[2][2] - m[1][2] * m[2][1]) - adjoint[1][0] = -(m[0][1] * m[2][2] - m[0][2] * m[2][1]) - adjoint[2][0] = +(m[0][1] * m[1][2] - m[0][2] * m[1][1]) - adjoint[0][1] = -(m[1][0] * m[2][2] - m[1][2] * m[2][0]) - adjoint[1][1] = +(m[0][0] * m[2][2] - m[0][2] * m[2][0]) - adjoint[2][1] = -(m[0][0] * m[1][2] - m[0][2] * m[1][0]) - adjoint[0][2] = +(m[1][0] * m[2][1] - m[1][1] * m[2][0]) - adjoint[1][2] = -(m[0][0] * m[2][1] - m[0][1] * m[2][0]) - adjoint[2][2] = +(m[0][0] * m[1][1] - m[0][1] * m[1][0]) + adjoint[0, 0] = +(m[1, 1] * m[2, 2] - m[2, 1] * m[1, 2]) + adjoint[0, 1] = -(m[1, 0] * m[2, 2] - m[2, 0] * m[1, 2]) + adjoint[0, 2] = +(m[1, 0] * m[2, 1] - m[2, 0] * m[1, 1]) + adjoint[1, 0] = -(m[0, 1] * m[2, 2] - m[2, 1] * m[0, 2]) + adjoint[1, 1] = +(m[0, 0] * m[2, 2] - m[2, 0] * m[0, 2]) + adjoint[1, 2] = -(m[0, 0] * m[2, 1] - m[2, 0] * m[0, 1]) + adjoint[2, 0] = +(m[0, 1] * m[1, 2] - m[1, 1] * m[0, 2]) + adjoint[2, 1] = -(m[0, 0] * m[1, 2] - m[1, 0] * m[0, 2]) + adjoint[2, 2] = +(m[0, 0] * m[1, 1] - m[1, 0] * m[0, 1]) return adjoint } matrix3_adjoint_f64 :: proc(m: Matrix3f64) -> (adjoint: Matrix3f64) { - adjoint[0][0] = +(m[1][1] * m[2][2] - m[1][2] * m[2][1]) - adjoint[1][0] = -(m[0][1] * m[2][2] - m[0][2] * m[2][1]) - adjoint[2][0] = +(m[0][1] * m[1][2] - m[0][2] * m[1][1]) - adjoint[0][1] = -(m[1][0] * m[2][2] - m[1][2] * m[2][0]) - adjoint[1][1] = +(m[0][0] * m[2][2] - m[0][2] * m[2][0]) - adjoint[2][1] = -(m[0][0] * m[1][2] - m[0][2] * m[1][0]) - adjoint[0][2] = +(m[1][0] * m[2][1] - m[1][1] * m[2][0]) - adjoint[1][2] = -(m[0][0] * m[2][1] - m[0][1] * m[2][0]) - adjoint[2][2] = +(m[0][0] * m[1][1] - m[0][1] * m[1][0]) + adjoint[0, 0] = +(m[1, 1] * m[2, 2] - m[2, 1] * m[1, 2]) + adjoint[0, 1] = -(m[1, 0] * m[2, 2] - m[2, 0] * m[1, 2]) + adjoint[0, 2] = +(m[1, 0] * m[2, 1] - m[2, 0] * m[1, 1]) + adjoint[1, 0] = -(m[0, 1] * m[2, 2] - m[2, 1] * m[0, 2]) + adjoint[1, 1] = +(m[0, 0] * m[2, 2] - m[2, 0] * m[0, 2]) + adjoint[1, 2] = -(m[0, 0] * m[2, 1] - m[2, 0] * m[0, 1]) + adjoint[2, 0] = +(m[0, 1] * m[1, 2] - m[1, 1] * m[0, 2]) + adjoint[2, 1] = -(m[0, 0] * m[1, 2] - m[1, 0] * m[0, 2]) + adjoint[2, 2] = +(m[0, 0] * m[1, 1] - m[1, 0] * m[0, 1]) return adjoint } matrix3_adjoint :: proc{ @@ -1369,37 +1370,13 @@ matrix3_adjoint :: proc{ matrix3_inverse_transpose_f16 :: proc(m: Matrix3f16) -> (inverse_transpose: Matrix3f16) { - adjoint := matrix3_adjoint(m) - determinant := matrix3_determinant(m) - inv_determinant := 1.0 / determinant - for i in 0..<3 { - for j in 0..<3 { - inverse_transpose[i][j] = adjoint[i][j] * inv_determinant - } - } - return + return builtin.inverse_transpose(m) } matrix3_inverse_transpose_f32 :: proc(m: Matrix3f32) -> (inverse_transpose: Matrix3f32) { - adjoint := matrix3_adjoint(m) - determinant := matrix3_determinant(m) - inv_determinant := 1.0 / determinant - for i in 0..<3 { - for j in 0..<3 { - inverse_transpose[i][j] = adjoint[i][j] * inv_determinant - } - } - return + return builtin.inverse_transpose(m) } matrix3_inverse_transpose_f64 :: proc(m: Matrix3f64) -> (inverse_transpose: Matrix3f64) { - adjoint := matrix3_adjoint(m) - determinant := matrix3_determinant(m) - inv_determinant := 1.0 / determinant - for i in 0..<3 { - for j in 0..<3 { - inverse_transpose[i][j] = adjoint[i][j] * inv_determinant - } - } - return + return builtin.inverse_transpose(m) } matrix3_inverse_transpose :: proc{ matrix3_inverse_transpose_f16, @@ -1409,21 +1386,21 @@ matrix3_inverse_transpose :: proc{ matrix3_scale_f16 :: proc(s: Vector3f16) -> (m: Matrix3f16) { - m[0][0] = s[0] - m[1][1] = s[1] - m[2][2] = s[2] + m[0, 0] = s[0] + m[1, 1] = s[1] + m[2, 2] = s[2] return m } matrix3_scale_f32 :: proc(s: Vector3f32) -> (m: Matrix3f32) { - m[0][0] = s[0] - m[1][1] = s[1] - m[2][2] = s[2] + m[0, 0] = s[0] + m[1, 1] = s[1] + m[2, 2] = s[2] return m } matrix3_scale_f64 :: proc(s: Vector3f64) -> (m: Matrix3f64) { - m[0][0] = s[0] - m[1][1] = s[1] - m[2][2] = s[2] + m[0, 0] = s[0] + m[1, 1] = s[1] + m[2, 2] = s[2] return m } matrix3_scale :: proc{ @@ -1440,17 +1417,17 @@ matrix3_rotate_f16 :: proc(angle_radians: f16, v: Vector3f16) -> (rot: Matrix3f1 a := normalize(v) t := a * (1-c) - rot[0][0] = c + t[0]*a[0] - rot[0][1] = 0 + t[0]*a[1] + s*a[2] - rot[0][2] = 0 + t[0]*a[2] - s*a[1] + rot[0, 0] = c + t[0]*a[0] + rot[1, 0] = 0 + t[0]*a[1] + s*a[2] + rot[2, 0] = 0 + t[0]*a[2] - s*a[1] - rot[1][0] = 0 + t[1]*a[0] - s*a[2] - rot[1][1] = c + t[1]*a[1] - rot[1][2] = 0 + t[1]*a[2] + s*a[0] + rot[0, 1] = 0 + t[1]*a[0] - s*a[2] + rot[1, 1] = c + t[1]*a[1] + rot[2, 1] = 0 + t[1]*a[2] + s*a[0] - rot[2][0] = 0 + t[2]*a[0] + s*a[1] - rot[2][1] = 0 + t[2]*a[1] - s*a[0] - rot[2][2] = c + t[2]*a[2] + rot[0, 2] = 0 + t[2]*a[0] + s*a[1] + rot[1, 2] = 0 + t[2]*a[1] - s*a[0] + rot[2, 2] = c + t[2]*a[2] return rot } @@ -1461,17 +1438,17 @@ matrix3_rotate_f32 :: proc(angle_radians: f32, v: Vector3f32) -> (rot: Matrix3f3 a := normalize(v) t := a * (1-c) - rot[0][0] = c + t[0]*a[0] - rot[0][1] = 0 + t[0]*a[1] + s*a[2] - rot[0][2] = 0 + t[0]*a[2] - s*a[1] + rot[0, 0] = c + t[0]*a[0] + rot[1, 0] = 0 + t[0]*a[1] + s*a[2] + rot[2, 0] = 0 + t[0]*a[2] - s*a[1] - rot[1][0] = 0 + t[1]*a[0] - s*a[2] - rot[1][1] = c + t[1]*a[1] - rot[1][2] = 0 + t[1]*a[2] + s*a[0] + rot[0, 1] = 0 + t[1]*a[0] - s*a[2] + rot[1, 1] = c + t[1]*a[1] + rot[2, 1] = 0 + t[1]*a[2] + s*a[0] - rot[2][0] = 0 + t[2]*a[0] + s*a[1] - rot[2][1] = 0 + t[2]*a[1] - s*a[0] - rot[2][2] = c + t[2]*a[2] + rot[0, 2] = 0 + t[2]*a[0] + s*a[1] + rot[1, 2] = 0 + t[2]*a[1] - s*a[0] + rot[2, 2] = c + t[2]*a[2] return rot } @@ -1482,17 +1459,17 @@ matrix3_rotate_f64 :: proc(angle_radians: f64, v: Vector3f64) -> (rot: Matrix3f6 a := normalize(v) t := a * (1-c) - rot[0][0] = c + t[0]*a[0] - rot[0][1] = 0 + t[0]*a[1] + s*a[2] - rot[0][2] = 0 + t[0]*a[2] - s*a[1] + rot[0, 0] = c + t[0]*a[0] + rot[1, 0] = 0 + t[0]*a[1] + s*a[2] + rot[2, 0] = 0 + t[0]*a[2] - s*a[1] - rot[1][0] = 0 + t[1]*a[0] - s*a[2] - rot[1][1] = c + t[1]*a[1] - rot[1][2] = 0 + t[1]*a[2] + s*a[0] + rot[0, 1] = 0 + t[1]*a[0] - s*a[2] + rot[1, 1] = c + t[1]*a[1] + rot[2, 1] = 0 + t[1]*a[2] + s*a[0] - rot[2][0] = 0 + t[2]*a[0] + s*a[1] - rot[2][1] = 0 + t[2]*a[1] - s*a[0] - rot[2][2] = c + t[2]*a[2] + rot[0, 2] = 0 + t[2]*a[0] + s*a[1] + rot[1, 2] = 0 + t[2]*a[1] - s*a[0] + rot[2, 2] = c + t[2]*a[2] return rot } @@ -1508,9 +1485,9 @@ matrix3_look_at_f16 :: proc(eye, centre, up: Vector3f16) -> Matrix3f16 { s := normalize(cross(f, up)) u := cross(s, f) return Matrix3f16{ - {+s.x, +u.x, -f.x}, - {+s.y, +u.y, -f.y}, - {+s.z, +u.z, -f.z}, + +s.x, +s.y, +s.z, + +u.x, +u.y, +u.z, + -f.x, -f.y, -f.z, } } matrix3_look_at_f32 :: proc(eye, centre, up: Vector3f32) -> Matrix3f32 { @@ -1518,9 +1495,9 @@ matrix3_look_at_f32 :: proc(eye, centre, up: Vector3f32) -> Matrix3f32 { s := normalize(cross(f, up)) u := cross(s, f) return Matrix3f32{ - {+s.x, +u.x, -f.x}, - {+s.y, +u.y, -f.y}, - {+s.z, +u.z, -f.z}, + +s.x, +s.y, +s.z, + +u.x, +u.y, +u.z, + -f.x, -f.y, -f.z, } } matrix3_look_at_f64 :: proc(eye, centre, up: Vector3f64) -> Matrix3f64 { @@ -1528,9 +1505,9 @@ matrix3_look_at_f64 :: proc(eye, centre, up: Vector3f64) -> Matrix3f64 { s := normalize(cross(f, up)) u := cross(s, f) return Matrix3f64{ - {+s.x, +u.x, -f.x}, - {+s.y, +u.y, -f.y}, - {+s.z, +u.z, -f.z}, + +s.x, +s.y, +s.z, + +u.x, +u.y, +u.z, + -f.x, -f.y, -f.z, } } matrix3_look_at :: proc{ @@ -1551,19 +1528,19 @@ matrix4_from_quaternion_f16 :: proc(q: Quaternionf16) -> (m: Matrix4f16) { qwy := q.w * q.y qwz := q.w * q.z - m[0][0] = 1 - 2 * (qyy + qzz) - m[0][1] = 2 * (qxy + qwz) - m[0][2] = 2 * (qxz - qwy) + m[0, 0] = 1 - 2 * (qyy + qzz) + m[1, 0] = 2 * (qxy + qwz) + m[2, 0] = 2 * (qxz - qwy) - m[1][0] = 2 * (qxy - qwz) - m[1][1] = 1 - 2 * (qxx + qzz) - m[1][2] = 2 * (qyz + qwx) + m[0, 1] = 2 * (qxy - qwz) + m[1, 1] = 1 - 2 * (qxx + qzz) + m[2, 1] = 2 * (qyz + qwx) - m[2][0] = 2 * (qxz + qwy) - m[2][1] = 2 * (qyz - qwx) - m[2][2] = 1 - 2 * (qxx + qyy) + m[0, 2] = 2 * (qxz + qwy) + m[1, 2] = 2 * (qyz - qwx) + m[2, 2] = 1 - 2 * (qxx + qyy) - m[3][3] = 1 + m[3, 3] = 1 return m } @@ -1578,19 +1555,19 @@ matrix4_from_quaternion_f32 :: proc(q: Quaternionf32) -> (m: Matrix4f32) { qwy := q.w * q.y qwz := q.w * q.z - m[0][0] = 1 - 2 * (qyy + qzz) - m[0][1] = 2 * (qxy + qwz) - m[0][2] = 2 * (qxz - qwy) + m[0, 0] = 1 - 2 * (qyy + qzz) + m[1, 0] = 2 * (qxy + qwz) + m[2, 0] = 2 * (qxz - qwy) - m[1][0] = 2 * (qxy - qwz) - m[1][1] = 1 - 2 * (qxx + qzz) - m[1][2] = 2 * (qyz + qwx) + m[0, 1] = 2 * (qxy - qwz) + m[1, 1] = 1 - 2 * (qxx + qzz) + m[2, 1] = 2 * (qyz + qwx) - m[2][0] = 2 * (qxz + qwy) - m[2][1] = 2 * (qyz - qwx) - m[2][2] = 1 - 2 * (qxx + qyy) + m[0, 2] = 2 * (qxz + qwy) + m[1, 2] = 2 * (qyz - qwx) + m[2, 2] = 1 - 2 * (qxx + qyy) - m[3][3] = 1 + m[3, 3] = 1 return m } @@ -1605,19 +1582,19 @@ matrix4_from_quaternion_f64 :: proc(q: Quaternionf64) -> (m: Matrix4f64) { qwy := q.w * q.y qwz := q.w * q.z - m[0][0] = 1 - 2 * (qyy + qzz) - m[0][1] = 2 * (qxy + qwz) - m[0][2] = 2 * (qxz - qwy) + m[0, 0] = 1 - 2 * (qyy + qzz) + m[1, 0] = 2 * (qxy + qwz) + m[2, 0] = 2 * (qxz - qwy) - m[1][0] = 2 * (qxy - qwz) - m[1][1] = 1 - 2 * (qxx + qzz) - m[1][2] = 2 * (qyz + qwx) + m[0, 1] = 2 * (qxy - qwz) + m[1, 1] = 1 - 2 * (qxx + qzz) + m[2, 1] = 2 * (qyz + qwx) - m[2][0] = 2 * (qxz + qwy) - m[2][1] = 2 * (qyz - qwx) - m[2][2] = 1 - 2 * (qxx + qyy) + m[0, 2] = 2 * (qxz + qwy) + m[1, 2] = 2 * (qyz - qwx) + m[2, 2] = 1 - 2 * (qxx + qyy) - m[3][3] = 1 + m[3, 3] = 1 return m } @@ -1992,10 +1969,10 @@ matrix4_look_at_f16 :: proc(eye, centre, up: Vector3f16, flip_z_axis := true) -> fe := dot(f, eye) return { - {+s.x, +u.x, -f.x, 0}, - {+s.y, +u.y, -f.y, 0}, - {+s.z, +u.z, -f.z, 0}, - {-dot(s, eye), -dot(u, eye), +fe if flip_z_axis else -fe, 1}, + +s.x, +s.y, +s.z, -dot(s, eye), + +u.x, +u.y, +u.z, -dot(u, eye), + -f.x, -f.y, -f.z, +fe if flip_z_axis else -fe, + 0, 0, 0, 1, } } matrix4_look_at_f32 :: proc(eye, centre, up: Vector3f32, flip_z_axis := true) -> (m: Matrix4f32) { @@ -2006,10 +1983,10 @@ matrix4_look_at_f32 :: proc(eye, centre, up: Vector3f32, flip_z_axis := true) -> fe := dot(f, eye) return { - {+s.x, +u.x, -f.x, 0}, - {+s.y, +u.y, -f.y, 0}, - {+s.z, +u.z, -f.z, 0}, - {-dot(s, eye), -dot(u, eye), +fe if flip_z_axis else -fe, 1}, + +s.x, +s.y, +s.z, -dot(s, eye), + +u.x, +u.y, +u.z, -dot(u, eye), + -f.x, -f.y, -f.z, +fe if flip_z_axis else -fe, + 0, 0, 0, 1, } } matrix4_look_at_f64 :: proc(eye, centre, up: Vector3f64, flip_z_axis := true) -> (m: Matrix4f64) { @@ -2020,10 +1997,10 @@ matrix4_look_at_f64 :: proc(eye, centre, up: Vector3f64, flip_z_axis := true) -> fe := dot(f, eye) return { - {+s.x, +u.x, -f.x, 0}, - {+s.y, +u.y, -f.y, 0}, - {+s.z, +u.z, -f.z, 0}, - {-dot(s, eye), -dot(u, eye), +fe if flip_z_axis else -fe, 1}, + +s.x, +s.y, +s.z, -dot(s, eye), + +u.x, +u.y, +u.z, -dot(u, eye), + -f.x, -f.y, -f.z, +fe if flip_z_axis else -fe, + 0, 0, 0, 1, } } matrix4_look_at :: proc{ @@ -2041,10 +2018,10 @@ matrix4_look_at_from_fru_f16 :: proc(eye, f, r, u: Vector3f16, flip_z_axis := tr fe := dot(f, eye) return { - {+s.x, +u.x, -f.x, 0}, - {+s.y, +u.y, -f.y, 0}, - {+s.z, +u.z, -f.z, 0}, - {-dot(s, eye), -dot(u, eye), +fe if flip_z_axis else -fe, 1}, + +s.x, +s.y, +s.z, -dot(s, eye), + +u.x, +u.y, +u.z, -dot(u, eye), + -f.x, -f.y, -f.z, +fe if flip_z_axis else -fe, + 0, 0, 0, 1, } } matrix4_look_at_from_fru_f32 :: proc(eye, f, r, u: Vector3f32, flip_z_axis := true) -> (m: Matrix4f32) { @@ -2055,10 +2032,10 @@ matrix4_look_at_from_fru_f32 :: proc(eye, f, r, u: Vector3f32, flip_z_axis := tr fe := dot(f, eye) return { - {+s.x, +u.x, -f.x, 0}, - {+s.y, +u.y, -f.y, 0}, - {+s.z, +u.z, -f.z, 0}, - {-dot(s, eye), -dot(u, eye), +fe if flip_z_axis else -fe, 1}, + +s.x, +s.y, +s.z, -dot(s, eye), + +u.x, +u.y, +u.z, -dot(u, eye), + -f.x, -f.y, -f.z, +fe if flip_z_axis else -fe, + 0, 0, 0, 1, } } matrix4_look_at_from_fru_f64 :: proc(eye, f, r, u: Vector3f64, flip_z_axis := true) -> (m: Matrix4f64) { @@ -2069,10 +2046,10 @@ matrix4_look_at_from_fru_f64 :: proc(eye, f, r, u: Vector3f64, flip_z_axis := tr fe := dot(f, eye) return { - {+s.x, +u.x, -f.x, 0}, - {+s.y, +u.y, -f.y, 0}, - {+s.z, +u.z, -f.z, 0}, - {-dot(s, eye), -dot(u, eye), +fe if flip_z_axis else -fe, 1}, + +s.x, +s.y, +s.z, -dot(s, eye), + +u.x, +u.y, +u.z, -dot(u, eye), + -f.x, -f.y, -f.z, +fe if flip_z_axis else -fe, + 0, 0, 0, 1, } } matrix4_look_at_from_fru :: proc{ @@ -2084,11 +2061,11 @@ matrix4_look_at_from_fru :: proc{ matrix4_perspective_f16 :: proc(fovy, aspect, near, far: f16, flip_z_axis := true) -> (m: Matrix4f16) { tan_half_fovy := math.tan(0.5 * fovy) - m[0][0] = 1 / (aspect*tan_half_fovy) - m[1][1] = 1 / (tan_half_fovy) - m[2][2] = +(far + near) / (far - near) - m[2][3] = +1 - m[3][2] = -2*far*near / (far - near) + m[0, 0] = 1 / (aspect*tan_half_fovy) + m[1, 1] = 1 / (tan_half_fovy) + m[2, 2] = +(far + near) / (far - near) + m[3, 2] = +1 + m[2, 3] = -2*far*near / (far - near) if flip_z_axis { m[2] = -m[2] @@ -2098,11 +2075,11 @@ matrix4_perspective_f16 :: proc(fovy, aspect, near, far: f16, flip_z_axis := tru } matrix4_perspective_f32 :: proc(fovy, aspect, near, far: f32, flip_z_axis := true) -> (m: Matrix4f32) { tan_half_fovy := math.tan(0.5 * fovy) - m[0][0] = 1 / (aspect*tan_half_fovy) - m[1][1] = 1 / (tan_half_fovy) - m[2][2] = +(far + near) / (far - near) - m[2][3] = +1 - m[3][2] = -2*far*near / (far - near) + m[0, 0] = 1 / (aspect*tan_half_fovy) + m[1, 1] = 1 / (tan_half_fovy) + m[2, 2] = +(far + near) / (far - near) + m[3, 2] = +1 + m[2, 3] = -2*far*near / (far - near) if flip_z_axis { m[2] = -m[2] @@ -2112,11 +2089,11 @@ matrix4_perspective_f32 :: proc(fovy, aspect, near, far: f32, flip_z_axis := tru } matrix4_perspective_f64 :: proc(fovy, aspect, near, far: f64, flip_z_axis := true) -> (m: Matrix4f64) { tan_half_fovy := math.tan(0.5 * fovy) - m[0][0] = 1 / (aspect*tan_half_fovy) - m[1][1] = 1 / (tan_half_fovy) - m[2][2] = +(far + near) / (far - near) - m[2][3] = +1 - m[3][2] = -2*far*near / (far - near) + m[0, 0] = 1 / (aspect*tan_half_fovy) + m[1, 1] = 1 / (tan_half_fovy) + m[2, 2] = +(far + near) / (far - near) + m[3, 2] = +1 + m[2, 3] = -2*far*near / (far - near) if flip_z_axis { m[2] = -m[2] @@ -2133,13 +2110,13 @@ matrix4_perspective :: proc{ matrix_ortho3d_f16 :: proc(left, right, bottom, top, near, far: f16, flip_z_axis := true) -> (m: Matrix4f16) { - m[0][0] = +2 / (right - left) - m[1][1] = +2 / (top - bottom) - m[2][2] = +2 / (far - near) - m[3][0] = -(right + left) / (right - left) - m[3][1] = -(top + bottom) / (top - bottom) - m[3][2] = -(far + near) / (far- near) - m[3][3] = 1 + m[0, 0] = +2 / (right - left) + m[1, 1] = +2 / (top - bottom) + m[2, 2] = +2 / (far - near) + m[0, 3] = -(right + left) / (right - left) + m[1, 3] = -(top + bottom) / (top - bottom) + m[2, 3] = -(far + near) / (far- near) + m[3, 3] = 1 if flip_z_axis { m[2] = -m[2] @@ -2148,13 +2125,13 @@ matrix_ortho3d_f16 :: proc(left, right, bottom, top, near, far: f16, flip_z_axis return } matrix_ortho3d_f32 :: proc(left, right, bottom, top, near, far: f32, flip_z_axis := true) -> (m: Matrix4f32) { - m[0][0] = +2 / (right - left) - m[1][1] = +2 / (top - bottom) - m[2][2] = +2 / (far - near) - m[3][0] = -(right + left) / (right - left) - m[3][1] = -(top + bottom) / (top - bottom) - m[3][2] = -(far + near) / (far- near) - m[3][3] = 1 + m[0, 0] = +2 / (right - left) + m[1, 1] = +2 / (top - bottom) + m[2, 2] = +2 / (far - near) + m[0, 3] = -(right + left) / (right - left) + m[1, 3] = -(top + bottom) / (top - bottom) + m[2, 3] = -(far + near) / (far- near) + m[3, 3] = 1 if flip_z_axis { m[2] = -m[2] @@ -2163,13 +2140,13 @@ matrix_ortho3d_f32 :: proc(left, right, bottom, top, near, far: f32, flip_z_axis return } matrix_ortho3d_f64 :: proc(left, right, bottom, top, near, far: f64, flip_z_axis := true) -> (m: Matrix4f64) { - m[0][0] = +2 / (right - left) - m[1][1] = +2 / (top - bottom) - m[2][2] = +2 / (far - near) - m[3][0] = -(right + left) / (right - left) - m[3][1] = -(top + bottom) / (top - bottom) - m[3][2] = -(far + near) / (far- near) - m[3][3] = 1 + m[0, 0] = +2 / (right - left) + m[1, 1] = +2 / (top - bottom) + m[2, 2] = +2 / (far - near) + m[0, 3] = -(right + left) / (right - left) + m[1, 3] = -(top + bottom) / (top - bottom) + m[2, 3] = -(far + near) / (far- near) + m[3, 3] = 1 if flip_z_axis { m[2] = -m[2] @@ -2187,11 +2164,11 @@ matrix_ortho3d :: proc{ matrix4_infinite_perspective_f16 :: proc(fovy, aspect, near: f16, flip_z_axis := true) -> (m: Matrix4f16) { tan_half_fovy := math.tan(0.5 * fovy) - m[0][0] = 1 / (aspect*tan_half_fovy) - m[1][1] = 1 / (tan_half_fovy) - m[2][2] = +1 - m[2][3] = +1 - m[3][2] = -2*near + m[0, 0] = 1 / (aspect*tan_half_fovy) + m[1, 1] = 1 / (tan_half_fovy) + m[2, 2] = +1 + m[3, 2] = +1 + m[2, 3] = -2*near if flip_z_axis { m[2] = -m[2] @@ -2201,11 +2178,11 @@ matrix4_infinite_perspective_f16 :: proc(fovy, aspect, near: f16, flip_z_axis := } matrix4_infinite_perspective_f32 :: proc(fovy, aspect, near: f32, flip_z_axis := true) -> (m: Matrix4f32) { tan_half_fovy := math.tan(0.5 * fovy) - m[0][0] = 1 / (aspect*tan_half_fovy) - m[1][1] = 1 / (tan_half_fovy) - m[2][2] = +1 - m[2][3] = +1 - m[3][2] = -2*near + m[0, 0] = 1 / (aspect*tan_half_fovy) + m[1, 1] = 1 / (tan_half_fovy) + m[2, 2] = +1 + m[3, 2] = +1 + m[2, 3] = -2*near if flip_z_axis { m[2] = -m[2] @@ -2215,11 +2192,11 @@ matrix4_infinite_perspective_f32 :: proc(fovy, aspect, near: f32, flip_z_axis := } matrix4_infinite_perspective_f64 :: proc(fovy, aspect, near: f64, flip_z_axis := true) -> (m: Matrix4f64) { tan_half_fovy := math.tan(0.5 * fovy) - m[0][0] = 1 / (aspect*tan_half_fovy) - m[1][1] = 1 / (tan_half_fovy) - m[2][2] = +1 - m[2][3] = +1 - m[3][2] = -2*near + m[0, 0] = 1 / (aspect*tan_half_fovy) + m[1, 1] = 1 / (tan_half_fovy) + m[2, 2] = +1 + m[3, 2] = +1 + m[2, 3] = -2*near if flip_z_axis { m[2] = -m[2] @@ -2236,18 +2213,18 @@ matrix4_infinite_perspective :: proc{ matrix2_from_scalar_f16 :: proc(f: f16) -> (m: Matrix2f16) { - m[0][0], m[0][1] = f, 0 - m[1][0], m[1][1] = 0, f + m[0, 0], m[1, 0] = f, 0 + m[0, 1], m[1, 1] = 0, f return } matrix2_from_scalar_f32 :: proc(f: f32) -> (m: Matrix2f32) { - m[0][0], m[0][1] = f, 0 - m[1][0], m[1][1] = 0, f + m[0, 0], m[1, 0] = f, 0 + m[0, 1], m[1, 1] = 0, f return } matrix2_from_scalar_f64 :: proc(f: f64) -> (m: Matrix2f64) { - m[0][0], m[0][1] = f, 0 - m[1][0], m[1][1] = 0, f + m[0, 0], m[1, 0] = f, 0 + m[0, 1], m[1, 1] = 0, f return } matrix2_from_scalar :: proc{ @@ -2258,21 +2235,21 @@ matrix2_from_scalar :: proc{ matrix3_from_scalar_f16 :: proc(f: f16) -> (m: Matrix3f16) { - m[0][0], m[0][1], m[0][2] = f, 0, 0 - m[1][0], m[1][1], m[1][2] = 0, f, 0 - m[2][0], m[2][1], m[2][2] = 0, 0, f + m[0, 0], m[1, 0], m[2, 0] = f, 0, 0 + m[0, 1], m[1, 1], m[2, 1] = 0, f, 0 + m[0, 2], m[1, 2], m[2, 2] = 0, 0, f return } matrix3_from_scalar_f32 :: proc(f: f32) -> (m: Matrix3f32) { - m[0][0], m[0][1], m[0][2] = f, 0, 0 - m[1][0], m[1][1], m[1][2] = 0, f, 0 - m[2][0], m[2][1], m[2][2] = 0, 0, f + m[0, 0], m[1, 0], m[2, 0] = f, 0, 0 + m[0, 1], m[1, 1], m[2, 1] = 0, f, 0 + m[0, 2], m[1, 2], m[2, 2] = 0, 0, f return } matrix3_from_scalar_f64 :: proc(f: f64) -> (m: Matrix3f64) { - m[0][0], m[0][1], m[0][2] = f, 0, 0 - m[1][0], m[1][1], m[1][2] = 0, f, 0 - m[2][0], m[2][1], m[2][2] = 0, 0, f + m[0, 0], m[1, 0], m[2, 0] = f, 0, 0 + m[0, 1], m[1, 1], m[2, 1] = 0, f, 0 + m[0, 2], m[1, 2], m[2, 2] = 0, 0, f return } matrix3_from_scalar :: proc{ @@ -2283,24 +2260,24 @@ matrix3_from_scalar :: proc{ matrix4_from_scalar_f16 :: proc(f: f16) -> (m: Matrix4f16) { - m[0][0], m[0][1], m[0][2], m[0][3] = f, 0, 0, 0 - m[1][0], m[1][1], m[1][2], m[1][3] = 0, f, 0, 0 - m[2][0], m[2][1], m[2][2], m[2][3] = 0, 0, f, 0 - m[3][0], m[3][1], m[3][2], m[3][3] = 0, 0, 0, f + m[0, 0], m[1, 0], m[2, 0], m[3, 0] = f, 0, 0, 0 + m[0, 1], m[1, 1], m[2, 1], m[3, 1] = 0, f, 0, 0 + m[0, 2], m[1, 2], m[2, 2], m[3, 2] = 0, 0, f, 0 + m[0, 3], m[1, 3], m[2, 3], m[3, 3] = 0, 0, 0, f return } matrix4_from_scalar_f32 :: proc(f: f32) -> (m: Matrix4f32) { - m[0][0], m[0][1], m[0][2], m[0][3] = f, 0, 0, 0 - m[1][0], m[1][1], m[1][2], m[1][3] = 0, f, 0, 0 - m[2][0], m[2][1], m[2][2], m[2][3] = 0, 0, f, 0 - m[3][0], m[3][1], m[3][2], m[3][3] = 0, 0, 0, f + m[0, 0], m[1, 0], m[2, 0], m[3, 0] = f, 0, 0, 0 + m[0, 1], m[1, 1], m[2, 1], m[3, 1] = 0, f, 0, 0 + m[0, 2], m[1, 2], m[2, 2], m[3, 2] = 0, 0, f, 0 + m[0, 3], m[1, 3], m[2, 3], m[3, 3] = 0, 0, 0, f return } matrix4_from_scalar_f64 :: proc(f: f64) -> (m: Matrix4f64) { - m[0][0], m[0][1], m[0][2], m[0][3] = f, 0, 0, 0 - m[1][0], m[1][1], m[1][2], m[1][3] = 0, f, 0, 0 - m[2][0], m[2][1], m[2][2], m[2][3] = 0, 0, f, 0 - m[3][0], m[3][1], m[3][2], m[3][3] = 0, 0, 0, f + m[0, 0], m[1, 0], m[2, 0], m[3, 0] = f, 0, 0, 0 + m[0, 1], m[1, 1], m[2, 1], m[3, 1] = 0, f, 0, 0 + m[0, 2], m[1, 2], m[2, 2], m[3, 2] = 0, 0, f, 0 + m[0, 3], m[1, 3], m[2, 3], m[3, 3] = 0, 0, 0, f return } matrix4_from_scalar :: proc{ @@ -2311,18 +2288,18 @@ matrix4_from_scalar :: proc{ matrix2_from_matrix3_f16 :: proc(m: Matrix3f16) -> (r: Matrix2f16) { - r[0][0], r[0][1] = m[0][0], m[0][1] - r[1][0], r[1][1] = m[1][0], m[1][1] + r[0, 0], r[1, 0] = m[0, 0], m[1, 0] + r[0, 1], r[1, 1] = m[0, 1], m[1, 1] return } matrix2_from_matrix3_f32 :: proc(m: Matrix3f32) -> (r: Matrix2f32) { - r[0][0], r[0][1] = m[0][0], m[0][1] - r[1][0], r[1][1] = m[1][0], m[1][1] + r[0, 0], r[1, 0] = m[0, 0], m[1, 0] + r[0, 1], r[1, 1] = m[0, 1], m[1, 1] return } matrix2_from_matrix3_f64 :: proc(m: Matrix3f64) -> (r: Matrix2f64) { - r[0][0], r[0][1] = m[0][0], m[0][1] - r[1][0], r[1][1] = m[1][0], m[1][1] + r[0, 0], r[1, 0] = m[0, 0], m[1, 0] + r[0, 1], r[1, 1] = m[0, 1], m[1, 1] return } matrix2_from_matrix3 :: proc{ @@ -2333,18 +2310,18 @@ matrix2_from_matrix3 :: proc{ matrix2_from_matrix4_f16 :: proc(m: Matrix4f16) -> (r: Matrix2f16) { - r[0][0], r[0][1] = m[0][0], m[0][1] - r[1][0], r[1][1] = m[1][0], m[1][1] + r[0, 0], r[1, 0] = m[0, 0], m[1, 0] + r[0, 1], r[1, 1] = m[0, 1], m[1, 1] return } matrix2_from_matrix4_f32 :: proc(m: Matrix4f32) -> (r: Matrix2f32) { - r[0][0], r[0][1] = m[0][0], m[0][1] - r[1][0], r[1][1] = m[1][0], m[1][1] + r[0, 0], r[1, 0] = m[0, 0], m[1, 0] + r[0, 1], r[1, 1] = m[0, 1], m[1, 1] return } matrix2_from_matrix4_f64 :: proc(m: Matrix4f64) -> (r: Matrix2f64) { - r[0][0], r[0][1] = m[0][0], m[0][1] - r[1][0], r[1][1] = m[1][0], m[1][1] + r[0, 0], r[1, 0] = m[0, 0], m[1, 0] + r[0, 1], r[1, 1] = m[0, 1], m[1, 1] return } matrix2_from_matrix4 :: proc{ @@ -2355,21 +2332,21 @@ matrix2_from_matrix4 :: proc{ matrix3_from_matrix2_f16 :: proc(m: Matrix2f16) -> (r: Matrix3f16) { - r[0][0], r[0][1], r[0][2] = m[0][0], m[0][1], 0 - r[1][0], r[1][1], r[1][2] = m[1][0], m[1][1], 0 - r[2][0], r[2][1], r[2][2] = 0, 0, 1 + r[0, 0], r[1, 0], r[2, 0] = m[0, 0], m[1, 0], 0 + r[0, 1], r[1, 1], r[2, 1] = m[0, 1], m[1, 1], 0 + r[0, 2], r[1, 2], r[2, 2] = 0, 0, 1 return } matrix3_from_matrix2_f32 :: proc(m: Matrix2f32) -> (r: Matrix3f32) { - r[0][0], r[0][1], r[0][2] = m[0][0], m[0][1], 0 - r[1][0], r[1][1], r[1][2] = m[1][0], m[1][1], 0 - r[2][0], r[2][1], r[2][2] = 0, 0, 1 + r[0, 0], r[1, 0], r[2, 0] = m[0, 0], m[1, 0], 0 + r[0, 1], r[1, 1], r[2, 1] = m[0, 1], m[1, 1], 0 + r[0, 2], r[1, 2], r[2, 2] = 0, 0, 1 return } matrix3_from_matrix2_f64 :: proc(m: Matrix2f64) -> (r: Matrix3f64) { - r[0][0], r[0][1], r[0][2] = m[0][0], m[0][1], 0 - r[1][0], r[1][1], r[1][2] = m[1][0], m[1][1], 0 - r[2][0], r[2][1], r[2][2] = 0, 0, 1 + r[0, 0], r[1, 0], r[2, 0] = m[0, 0], m[1, 0], 0 + r[0, 1], r[1, 1], r[2, 1] = m[0, 1], m[1, 1], 0 + r[0, 2], r[1, 2], r[2, 2] = 0, 0, 1 return } matrix3_from_matrix2 :: proc{ @@ -2380,21 +2357,21 @@ matrix3_from_matrix2 :: proc{ matrix3_from_matrix4_f16 :: proc(m: Matrix4f16) -> (r: Matrix3f16) { - r[0][0], r[0][1], r[0][2] = m[0][0], m[0][1], m[0][2] - r[1][0], r[1][1], r[1][2] = m[1][0], m[1][1], m[1][2] - r[2][0], r[2][1], r[2][2] = m[2][0], m[2][1], m[2][2] + r[0, 0], r[1, 0], r[2, 0] = m[0, 0], m[1, 0], m[2, 0] + r[0, 1], r[1, 1], r[2, 1] = m[0, 1], m[1, 1], m[2, 1] + r[0, 2], r[1, 2], r[2, 2] = m[0, 2], m[1, 2], m[2, 2] return } matrix3_from_matrix4_f32 :: proc(m: Matrix4f32) -> (r: Matrix3f32) { - r[0][0], r[0][1], r[0][2] = m[0][0], m[0][1], m[0][2] - r[1][0], r[1][1], r[1][2] = m[1][0], m[1][1], m[1][2] - r[2][0], r[2][1], r[2][2] = m[2][0], m[2][1], m[2][2] + r[0, 0], r[1, 0], r[2, 0] = m[0, 0], m[1, 0], m[2, 0] + r[0, 1], r[1, 1], r[2, 1] = m[0, 1], m[1, 1], m[2, 1] + r[0, 2], r[1, 2], r[2, 2] = m[0, 2], m[1, 2], m[2, 2] return } matrix3_from_matrix4_f64 :: proc(m: Matrix4f64) -> (r: Matrix3f64) { - r[0][0], r[0][1], r[0][2] = m[0][0], m[0][1], m[0][2] - r[1][0], r[1][1], r[1][2] = m[1][0], m[1][1], m[1][2] - r[2][0], r[2][1], r[2][2] = m[2][0], m[2][1], m[2][2] + r[0, 0], r[1, 0], r[2, 0] = m[0, 0], m[1, 0], m[2, 0] + r[0, 1], r[1, 1], r[2, 1] = m[0, 1], m[1, 1], m[2, 1] + r[0, 2], r[1, 2], r[2, 2] = m[0, 2], m[1, 2], m[2, 2] return } matrix3_from_matrix4 :: proc{ @@ -2405,24 +2382,24 @@ matrix3_from_matrix4 :: proc{ matrix4_from_matrix2_f16 :: proc(m: Matrix2f16) -> (r: Matrix4f16) { - r[0][0], r[0][1], r[0][2], r[0][3] = m[0][0], m[0][1], 0, 0 - r[1][0], r[1][1], r[1][2], r[1][3] = m[1][0], m[1][1], 0, 0 - r[2][0], r[2][1], r[2][2], r[2][3] = 0, 0, 1, 0 - r[3][0], r[3][1], r[3][2], r[3][3] = 0, 0, 0, 1 + r[0, 0], r[1, 0], r[2, 0], r[3, 0] = m[0, 0], m[1, 0], 0, 0 + r[0, 1], r[1, 1], r[2, 1], r[3, 1] = m[0, 1], m[1, 1], 0, 0 + r[0, 2], r[1, 2], r[2, 2], r[3, 2] = 0, 0, 1, 0 + r[0, 3], r[1, 3], r[2, 3], r[3, 3] = 0, 0, 0, 1 return } matrix4_from_matrix2_f32 :: proc(m: Matrix2f32) -> (r: Matrix4f32) { - r[0][0], r[0][1], r[0][2], r[0][3] = m[0][0], m[0][1], 0, 0 - r[1][0], r[1][1], r[1][2], r[1][3] = m[1][0], m[1][1], 0, 0 - r[2][0], r[2][1], r[2][2], r[2][3] = 0, 0, 1, 0 - r[3][0], r[3][1], r[3][2], r[3][3] = 0, 0, 0, 1 + r[0, 0], r[1, 0], r[2, 0], r[3, 0] = m[0, 0], m[1, 0], 0, 0 + r[0, 1], r[1, 1], r[2, 1], r[3, 1] = m[0, 1], m[1, 1], 0, 0 + r[0, 2], r[1, 2], r[2, 2], r[3, 2] = 0, 0, 1, 0 + r[0, 3], r[1, 3], r[2, 3], r[3, 3] = 0, 0, 0, 1 return } matrix4_from_matrix2_f64 :: proc(m: Matrix2f64) -> (r: Matrix4f64) { - r[0][0], r[0][1], r[0][2], r[0][3] = m[0][0], m[0][1], 0, 0 - r[1][0], r[1][1], r[1][2], r[1][3] = m[1][0], m[1][1], 0, 0 - r[2][0], r[2][1], r[2][2], r[2][3] = 0, 0, 1, 0 - r[3][0], r[3][1], r[3][2], r[3][3] = 0, 0, 0, 1 + r[0, 0], r[1, 0], r[2, 0], r[3, 0] = m[0, 0], m[1, 0], 0, 0 + r[0, 1], r[1, 1], r[2, 1], r[3, 1] = m[0, 1], m[1, 1], 0, 0 + r[0, 2], r[1, 2], r[2, 2], r[3, 2] = 0, 0, 1, 0 + r[0, 3], r[1, 3], r[2, 3], r[3, 3] = 0, 0, 0, 1 return } matrix4_from_matrix2 :: proc{ @@ -2433,24 +2410,24 @@ matrix4_from_matrix2 :: proc{ matrix4_from_matrix3_f16 :: proc(m: Matrix3f16) -> (r: Matrix4f16) { - r[0][0], r[0][1], r[0][2], r[0][3] = m[0][0], m[0][1], m[0][2], 0 - r[1][0], r[1][1], r[1][2], r[1][3] = m[1][0], m[1][1], m[1][2], 0 - r[2][0], r[2][1], r[2][2], r[2][3] = m[2][0], m[2][1], m[2][2], 0 - r[3][0], r[3][1], r[3][2], r[3][3] = 0, 0, 0, 1 + r[0, 0], r[1, 0], r[2, 0], r[3, 0] = m[0, 0], m[1, 0], m[2, 0], 0 + r[0, 1], r[1, 1], r[2, 1], r[3, 1] = m[0, 1], m[1, 1], m[2, 1], 0 + r[0, 2], r[1, 2], r[2, 2], r[3, 2] = m[0, 2], m[1, 2], m[2, 2], 0 + r[0, 3], r[1, 3], r[2, 3], r[3, 3] = 0, 0, 0, 1 return } matrix4_from_matrix3_f32 :: proc(m: Matrix3f32) -> (r: Matrix4f32) { - r[0][0], r[0][1], r[0][2], r[0][3] = m[0][0], m[0][1], m[0][2], 0 - r[1][0], r[1][1], r[1][2], r[1][3] = m[1][0], m[1][1], m[1][2], 0 - r[2][0], r[2][1], r[2][2], r[2][3] = m[2][0], m[2][1], m[2][2], 0 - r[3][0], r[3][1], r[3][2], r[3][3] = 0, 0, 0, 1 + r[0, 0], r[1, 0], r[2, 0], r[3, 0] = m[0, 0], m[1, 0], m[2, 0], 0 + r[0, 1], r[1, 1], r[2, 1], r[3, 1] = m[0, 1], m[1, 1], m[2, 1], 0 + r[0, 2], r[1, 2], r[2, 2], r[3, 2] = m[0, 2], m[1, 2], m[2, 2], 0 + r[0, 3], r[1, 3], r[2, 3], r[3, 3] = 0, 0, 0, 1 return } matrix4_from_matrix3_f64 :: proc(m: Matrix3f64) -> (r: Matrix4f64) { - r[0][0], r[0][1], r[0][2], r[0][3] = m[0][0], m[0][1], m[0][2], 0 - r[1][0], r[1][1], r[1][2], r[1][3] = m[1][0], m[1][1], m[1][2], 0 - r[2][0], r[2][1], r[2][2], r[2][3] = m[2][0], m[2][1], m[2][2], 0 - r[3][0], r[3][1], r[3][2], r[3][3] = 0, 0, 0, 1 + r[0, 0], r[1, 0], r[2, 0], r[3, 0] = m[0, 0], m[1, 0], m[2, 0], 0 + r[0, 1], r[1, 1], r[2, 1], r[3, 1] = m[0, 1], m[1, 1], m[2, 1], 0 + r[0, 2], r[1, 2], r[2, 2], r[3, 2] = m[0, 2], m[1, 2], m[2, 2], 0 + r[0, 3], r[1, 3], r[2, 3], r[3, 3] = 0, 0, 0, 1 return } matrix4_from_matrix3 :: proc{ diff --git a/core/math/linalg/specific_euler_angles_f16.odin b/core/math/linalg/specific_euler_angles_f16.odin index d0fb1beb3..9e21c7f97 100644 --- a/core/math/linalg/specific_euler_angles_f16.odin +++ b/core/math/linalg/specific_euler_angles_f16.odin @@ -212,29 +212,29 @@ euler_angles_zxy_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f matrix3_from_euler_angle_x_f16 :: proc(angle_x: f16) -> (m: Matrix3f16) { cos_x, sin_x := math.cos(angle_x), math.sin(angle_x) - m[0][0] = 1 - m[1][1] = +cos_x - m[2][1] = +sin_x - m[1][2] = -sin_x - m[2][2] = +cos_x + m[0, 0] = 1 + m[1, 1] = +cos_x + m[1, 2] = +sin_x + m[2, 1] = -sin_x + m[2, 2] = +cos_x return } matrix3_from_euler_angle_y_f16 :: proc(angle_y: f16) -> (m: Matrix3f16) { cos_y, sin_y := math.cos(angle_y), math.sin(angle_y) - m[0][0] = +cos_y - m[2][0] = -sin_y - m[1][1] = 1 - m[0][2] = +sin_y - m[2][2] = +cos_y + m[0, 0] = +cos_y + m[0, 2] = -sin_y + m[1, 1] = 1 + m[2, 0] = +sin_y + m[2, 2] = +cos_y return } matrix3_from_euler_angle_z_f16 :: proc(angle_z: f16) -> (m: Matrix3f16) { cos_z, sin_z := math.cos(angle_z), math.sin(angle_z) - m[0][0] = +cos_z - m[1][0] = +sin_z - m[1][1] = +cos_z - m[0][1] = -sin_z - m[2][2] = 1 + m[0, 0] = +cos_z + m[0, 1] = +sin_z + m[1, 1] = +cos_z + m[1, 0] = -sin_z + m[2, 2] = 1 return } @@ -242,31 +242,31 @@ matrix3_from_euler_angle_z_f16 :: proc(angle_z: f16) -> (m: Matrix3f16) { matrix3_from_derived_euler_angle_x_f16 :: proc(angle_x: f16, angular_velocity_x: f16) -> (m: Matrix3f16) { cos_x := math.cos(angle_x) * angular_velocity_x sin_x := math.sin(angle_x) * angular_velocity_x - m[0][0] = 1 - m[1][1] = +cos_x - m[2][1] = +sin_x - m[1][2] = -sin_x - m[2][2] = +cos_x + m[0, 0] = 1 + m[1, 1] = +cos_x + m[1, 2] = +sin_x + m[2, 1] = -sin_x + m[2, 2] = +cos_x return } matrix3_from_derived_euler_angle_y_f16 :: proc(angle_y: f16, angular_velocity_y: f16) -> (m: Matrix3f16) { cos_y := math.cos(angle_y) * angular_velocity_y sin_y := math.sin(angle_y) * angular_velocity_y - m[0][0] = +cos_y - m[2][0] = -sin_y - m[1][1] = 1 - m[0][2] = +sin_y - m[2][2] = +cos_y + m[0, 0] = +cos_y + m[0, 2] = -sin_y + m[1, 1] = 1 + m[2, 0] = +sin_y + m[2, 2] = +cos_y return } matrix3_from_derived_euler_angle_z_f16 :: proc(angle_z: f16, angular_velocity_z: f16) -> (m: Matrix3f16) { cos_z := math.cos(angle_z) * angular_velocity_z sin_z := math.sin(angle_z) * angular_velocity_z - m[0][0] = +cos_z - m[1][0] = +sin_z - m[1][1] = +cos_z - m[0][1] = -sin_z - m[2][2] = 1 + m[0, 0] = +cos_z + m[0, 1] = +sin_z + m[1, 1] = +cos_z + m[1, 0] = -sin_z + m[2, 2] = 1 return } @@ -274,14 +274,14 @@ matrix3_from_derived_euler_angle_z_f16 :: proc(angle_z: f16, angular_velocity_z: matrix3_from_euler_angles_xy_f16 :: proc(angle_x, angle_y: f16) -> (m: Matrix3f16) { cos_x, sin_x := math.cos(angle_x), math.sin(angle_x) cos_y, sin_y := math.cos(angle_y), math.sin(angle_y) - m[0][0] = cos_y - m[1][0] = -sin_x * - sin_y - m[2][0] = -cos_x * - sin_y - m[1][1] = cos_x - m[2][1] = sin_x - m[0][2] = sin_y - m[1][2] = -sin_x * cos_y - m[2][2] = cos_x * cos_y + m[0, 0] = cos_y + m[0, 1] = -sin_x * - sin_y + m[0, 2] = -cos_x * - sin_y + m[1, 1] = cos_x + m[1, 2] = sin_x + m[2, 0] = sin_y + m[2, 1] = -sin_x * cos_y + m[2, 2] = cos_x * cos_y return } @@ -289,14 +289,14 @@ matrix3_from_euler_angles_xy_f16 :: proc(angle_x, angle_y: f16) -> (m: Matrix3f1 matrix3_from_euler_angles_yx_f16 :: proc(angle_y, angle_x: f16) -> (m: Matrix3f16) { cos_x, sin_x := math.cos(angle_x), math.sin(angle_x) cos_y, sin_y := math.cos(angle_y), math.sin(angle_y) - m[0][0] = cos_y - m[2][0] = -sin_y - m[0][1] = sin_y*sin_x - m[1][1] = cos_x - m[2][1] = cos_y*sin_x - m[0][2] = sin_y*cos_x - m[1][2] = -sin_x - m[2][2] = cos_y*cos_x + m[0, 0] = cos_y + m[0, 2] = -sin_y + m[1, 0] = sin_y*sin_x + m[1, 1] = cos_x + m[1, 2] = cos_y*sin_x + m[2, 0] = sin_y*cos_x + m[2, 1] = -sin_x + m[2, 2] = cos_y*cos_x return } @@ -322,15 +322,15 @@ matrix3_from_euler_angles_xyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) { s2 := math.sin(-t2) s3 := math.sin(-t3) - m[0][0] = c2 * c3 - m[0][1] =-c1 * s3 + s1 * s2 * c3 - m[0][2] = s1 * s3 + c1 * s2 * c3 - m[1][0] = c2 * s3 - m[1][1] = c1 * c3 + s1 * s2 * s3 - m[1][2] =-s1 * c3 + c1 * s2 * s3 - m[2][0] =-s2 - m[2][1] = s1 * c2 - m[2][2] = c1 * c2 + m[0, 0] = c2 * c3 + m[1, 0] =-c1 * s3 + s1 * s2 * c3 + m[2, 0] = s1 * s3 + c1 * s2 * c3 + m[0, 1] = c2 * s3 + m[1, 1] = c1 * c3 + s1 * s2 * s3 + m[2, 1] =-s1 * c3 + c1 * s2 * s3 + m[0, 2] =-s2 + m[1, 2] = s1 * c2 + m[2, 2] = c1 * c2 return } @@ -342,15 +342,15 @@ matrix3_from_euler_angles_yxz_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix3f cb := math.cos(roll) sb := math.sin(roll) - m[0][0] = ch * cb + sh * sp * sb - m[0][1] = sb * cp - m[0][2] = -sh * cb + ch * sp * sb - m[1][0] = -ch * sb + sh * sp * cb - m[1][1] = cb * cp - m[1][2] = sb * sh + ch * sp * cb - m[2][0] = sh * cp - m[2][1] = -sp - m[2][2] = ch * cp + m[0, 0] = ch * cb + sh * sp * sb + m[1, 0] = sb * cp + m[2, 0] = -sh * cb + ch * sp * sb + m[0, 1] = -ch * sb + sh * sp * cb + m[1, 1] = cb * cp + m[2, 1] = sb * sh + ch * sp * cb + m[0, 2] = sh * cp + m[1, 2] = -sp + m[2, 2] = ch * cp return } @@ -362,15 +362,15 @@ matrix3_from_euler_angles_xzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c2 - m[0][1] = c1 * s2 - m[0][2] = s1 * s2 - m[1][0] =-c3 * s2 - m[1][1] = c1 * c2 * c3 - s1 * s3 - m[1][2] = c1 * s3 + c2 * c3 * s1 - m[2][0] = s2 * s3 - m[2][1] =-c3 * s1 - c1 * c2 * s3 - m[2][2] = c1 * c3 - c2 * s1 * s3 + m[0, 0] = c2 + m[1, 0] = c1 * s2 + m[2, 0] = s1 * s2 + m[0, 1] =-c3 * s2 + m[1, 1] = c1 * c2 * c3 - s1 * s3 + m[2, 1] = c1 * s3 + c2 * c3 * s1 + m[0, 2] = s2 * s3 + m[1, 2] =-c3 * s1 - c1 * c2 * s3 + m[2, 2] = c1 * c3 - c2 * s1 * s3 return } @@ -382,15 +382,15 @@ matrix3_from_euler_angles_xyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c2 - m[0][1] = s1 * s2 - m[0][2] =-c1 * s2 - m[1][0] = s2 * s3 - m[1][1] = c1 * c3 - c2 * s1 * s3 - m[1][2] = c3 * s1 + c1 * c2 * s3 - m[2][0] = c3 * s2 - m[2][1] =-c1 * s3 - c2 * c3 * s1 - m[2][2] = c1 * c2 * c3 - s1 * s3 + m[0, 0] = c2 + m[1, 0] = s1 * s2 + m[2, 0] =-c1 * s2 + m[0, 1] = s2 * s3 + m[1, 1] = c1 * c3 - c2 * s1 * s3 + m[2, 1] = c3 * s1 + c1 * c2 * s3 + m[0, 2] = c3 * s2 + m[1, 2] =-c1 * s3 - c2 * c3 * s1 + m[2, 2] = c1 * c2 * c3 - s1 * s3 return } @@ -402,15 +402,15 @@ matrix3_from_euler_angles_yxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c3 - c2 * s1 * s3 - m[0][1] = s2* s3 - m[0][2] =-c3 * s1 - c1 * c2 * s3 - m[1][0] = s1 * s2 - m[1][1] = c2 - m[1][2] = c1 * s2 - m[2][0] = c1 * s3 + c2 * c3 * s1 - m[2][1] =-c3 * s2 - m[2][2] = c1 * c2 * c3 - s1 * s3 + m[0, 0] = c1 * c3 - c2 * s1 * s3 + m[1, 0] = s2* s3 + m[2, 0] =-c3 * s1 - c1 * c2 * s3 + m[0, 1] = s1 * s2 + m[1, 1] = c2 + m[2, 1] = c1 * s2 + m[0, 2] = c1 * s3 + c2 * c3 * s1 + m[1, 2] =-c3 * s2 + m[2, 2] = c1 * c2 * c3 - s1 * s3 return } @@ -422,15 +422,15 @@ matrix3_from_euler_angles_yzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 * c3 - s1 * s3 - m[0][1] = c3 * s2 - m[0][2] =-c1 * s3 - c2 * c3 * s1 - m[1][0] =-c1 * s2 - m[1][1] = c2 - m[1][2] = s1 * s2 - m[2][0] = c3 * s1 + c1 * c2 * s3 - m[2][1] = s2 * s3 - m[2][2] = c1 * c3 - c2 * s1 * s3 + m[0, 0] = c1 * c2 * c3 - s1 * s3 + m[1, 0] = c3 * s2 + m[2, 0] =-c1 * s3 - c2 * c3 * s1 + m[0, 1] =-c1 * s2 + m[1, 1] = c2 + m[2, 1] = s1 * s2 + m[0, 2] = c3 * s1 + c1 * c2 * s3 + m[1, 2] = s2 * s3 + m[2, 2] = c1 * c3 - c2 * s1 * s3 return } @@ -442,15 +442,15 @@ matrix3_from_euler_angles_zyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 * c3 - s1 * s3 - m[0][1] = c1 * s3 + c2 * c3 * s1 - m[0][2] =-c3 * s2 - m[1][0] =-c3 * s1 - c1 * c2 * s3 - m[1][1] = c1 * c3 - c2 * s1 * s3 - m[1][2] = s2 * s3 - m[2][0] = c1 * s2 - m[2][1] = s1 * s2 - m[2][2] = c2 + m[0, 0] = c1 * c2 * c3 - s1 * s3 + m[1, 0] = c1 * s3 + c2 * c3 * s1 + m[2, 0] =-c3 * s2 + m[0, 1] =-c3 * s1 - c1 * c2 * s3 + m[1, 1] = c1 * c3 - c2 * s1 * s3 + m[2, 1] = s2 * s3 + m[0, 2] = c1 * s2 + m[1, 2] = s1 * s2 + m[2, 2] = c2 return } @@ -462,15 +462,15 @@ matrix3_from_euler_angles_zxz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c3 - c2 * s1 * s3 - m[0][1] = c3 * s1 + c1 * c2 * s3 - m[0][2] = s2 *s3 - m[1][0] =-c1 * s3 - c2 * c3 * s1 - m[1][1] = c1 * c2 * c3 - s1 * s3 - m[1][2] = c3 * s2 - m[2][0] = s1 * s2 - m[2][1] =-c1 * s2 - m[2][2] = c2 + m[0, 0] = c1 * c3 - c2 * s1 * s3 + m[1, 0] = c3 * s1 + c1 * c2 * s3 + m[2, 0] = s2 *s3 + m[0, 1] =-c1 * s3 - c2 * c3 * s1 + m[1, 1] = c1 * c2 * c3 - s1 * s3 + m[2, 1] = c3 * s2 + m[0, 2] = s1 * s2 + m[1, 2] =-c1 * s2 + m[2, 2] = c2 return } @@ -483,15 +483,15 @@ matrix3_from_euler_angles_xzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c2 * c3 - m[0][1] = s1 * s3 + c1 * c3 * s2 - m[0][2] = c3 * s1 * s2 - c1 * s3 - m[1][0] =-s2 - m[1][1] = c1 * c2 - m[1][2] = c2 * s1 - m[2][0] = c2 * s3 - m[2][1] = c1 * s2 * s3 - c3 * s1 - m[2][2] = c1 * c3 + s1 * s2 *s3 + m[0, 0] = c2 * c3 + m[1, 0] = s1 * s3 + c1 * c3 * s2 + m[2, 0] = c3 * s1 * s2 - c1 * s3 + m[0, 1] =-s2 + m[1, 1] = c1 * c2 + m[2, 1] = c2 * s1 + m[0, 2] = c2 * s3 + m[1, 2] = c1 * s2 * s3 - c3 * s1 + m[2, 2] = c1 * c3 + s1 * s2 *s3 return } @@ -503,15 +503,15 @@ matrix3_from_euler_angles_yzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 - m[0][1] = s2 - m[0][2] =-c2 * s1 - m[1][0] = s1 * s3 - c1 * c3 * s2 - m[1][1] = c2 * c3 - m[1][2] = c1 * s3 + c3 * s1 * s2 - m[2][0] = c3 * s1 + c1 * s2 * s3 - m[2][1] =-c2 * s3 - m[2][2] = c1 * c3 - s1 * s2 * s3 + m[0, 0] = c1 * c2 + m[1, 0] = s2 + m[2, 0] =-c2 * s1 + m[0, 1] = s1 * s3 - c1 * c3 * s2 + m[1, 1] = c2 * c3 + m[2, 1] = c1 * s3 + c3 * s1 * s2 + m[0, 2] = c3 * s1 + c1 * s2 * s3 + m[1, 2] =-c2 * s3 + m[2, 2] = c1 * c3 - s1 * s2 * s3 return } @@ -523,15 +523,15 @@ matrix3_from_euler_angles_zyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 - m[0][1] = c2 * s1 - m[0][2] =-s2 - m[1][0] = c1 * s2 * s3 - c3 * s1 - m[1][1] = c1 * c3 + s1 * s2 * s3 - m[1][2] = c2 * s3 - m[2][0] = s1 * s3 + c1 * c3 * s2 - m[2][1] = c3 * s1 * s2 - c1 * s3 - m[2][2] = c2 * c3 + m[0, 0] = c1 * c2 + m[1, 0] = c2 * s1 + m[2, 0] =-s2 + m[0, 1] = c1 * s2 * s3 - c3 * s1 + m[1, 1] = c1 * c3 + s1 * s2 * s3 + m[2, 1] = c2 * s3 + m[0, 2] = s1 * s3 + c1 * c3 * s2 + m[1, 2] = c3 * s1 * s2 - c1 * s3 + m[2, 2] = c2 * c3 return } @@ -543,15 +543,15 @@ matrix3_from_euler_angles_zxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c3 - s1 * s2 * s3 - m[0][1] = c3 * s1 + c1 * s2 * s3 - m[0][2] =-c2 * s3 - m[1][0] =-c2 * s1 - m[1][1] = c1 * c2 - m[1][2] = s2 - m[2][0] = c1 * s3 + c3 * s1 * s2 - m[2][1] = s1 * s3 - c1 * c3 * s2 - m[2][2] = c2 * c3 + m[0, 0] = c1 * c3 - s1 * s2 * s3 + m[1, 0] = c3 * s1 + c1 * s2 * s3 + m[2, 0] =-c2 * s3 + m[0, 1] =-c2 * s1 + m[1, 1] = c1 * c2 + m[2, 1] = s2 + m[0, 2] = c1 * s3 + c3 * s1 * s2 + m[1, 2] = s1 * s3 - c1 * c3 * s2 + m[2, 2] = c2 * c3 return } @@ -564,25 +564,25 @@ matrix3_from_yaw_pitch_roll_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix3f16 cb := math.cos(roll) sb := math.sin(roll) - m[0][0] = ch * cb + sh * sp * sb - m[0][1] = sb * cp - m[0][2] = -sh * cb + ch * sp * sb - m[1][0] = -ch * sb + sh * sp * cb - m[1][1] = cb * cp - m[1][2] = sb * sh + ch * sp * cb - m[2][0] = sh * cp - m[2][1] = -sp - m[2][2] = ch * cp + m[0, 0] = ch * cb + sh * sp * sb + m[1, 0] = sb * cp + m[2, 0] = -sh * cb + ch * sp * sb + m[0, 1] = -ch * sb + sh * sp * cb + m[1, 1] = cb * cp + m[2, 1] = sb * sh + ch * sp * cb + m[0, 2] = sh * cp + m[1, 2] = -sp + m[2, 2] = ch * cp return m } euler_angles_xyz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(m[2][1], m[2][2]) - C2 := math.sqrt(m[0][0]*m[0][0] + m[1][0]*m[1][0]) - T2 := math.atan2(-m[2][0], C2) + T1 := math.atan2(m[1, 2], m[2, 2]) + C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 1]*m[0, 1]) + T2 := math.atan2(-m[0, 2], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[0][2] - C1*m[0][1], C1*m[1][1] - S1*m[1][2]) + T3 := math.atan2(S1*m[2, 0] - C1*m[1, 0], C1*m[1, 1] - S1*m[2, 1]) t1 = -T1 t2 = -T2 t3 = -T3 @@ -590,12 +590,12 @@ euler_angles_xyz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { } euler_angles_yxz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(m[2][0], m[2][2]) - C2 := math.sqrt(m[0][1]*m[0][1] + m[1][1]*m[1][1]) - T2 := math.atan2(-m[2][1], C2) + T1 := math.atan2(m[0, 2], m[2, 2]) + C2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 1]*m[1, 1]) + T2 := math.atan2(-m[1, 2], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[1][2] - C1*m[1][0], C1*m[0][0] - S1*m[0][2]) + T3 := math.atan2(S1*m[2, 1] - C1*m[0, 1], C1*m[0, 0] - S1*m[2, 0]) t1 = T1 t2 = T2 t3 = T3 @@ -603,12 +603,12 @@ euler_angles_yxz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { } euler_angles_xzx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(m[0][2], m[0][1]) - S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]) - T2 := math.atan2(S2, m[0][0]) + T1 := math.atan2(m[2, 0], m[1, 0]) + S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2]) + T2 := math.atan2(S2, m[0, 0]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[1][2] - S1*m[1][1], C1*m[2][2] - S1*m[2][1]) + T3 := math.atan2(C1*m[2, 1] - S1*m[1, 1], C1*m[2, 2] - S1*m[1, 2]) t1 = T1 t2 = T2 t3 = T3 @@ -616,12 +616,12 @@ euler_angles_xzx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { } euler_angles_xyx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(m[0][1], -m[0][2]) - S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]) - T2 := math.atan2(S2, m[0][0]) + T1 := math.atan2(m[1, 0], -m[2, 0]) + S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2]) + T2 := math.atan2(S2, m[0, 0]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(-C1*m[2][1] - S1*m[2][2], C1*m[1][1] + S1*m[1][2]) + T3 := math.atan2(-C1*m[1, 2] - S1*m[2, 2], C1*m[1, 1] + S1*m[2, 1]) t1 = T1 t2 = T2 t3 = T3 @@ -629,12 +629,12 @@ euler_angles_xyx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { } euler_angles_yxy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(m[1][0], m[1][2]) - S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]) - T2 := math.atan2(S2, m[1][1]) + T1 := math.atan2(m[0, 1], m[2, 1]) + S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2]) + T2 := math.atan2(S2, m[1, 1]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[2][0] - S1*m[2][2], C1*m[0][0] - S1*m[0][2]) + T3 := math.atan2(C1*m[0, 2] - S1*m[2, 2], C1*m[0, 0] - S1*m[2, 0]) t1 = T1 t2 = T2 t3 = T3 @@ -642,24 +642,24 @@ euler_angles_yxy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { } euler_angles_yzy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(m[1][2], -m[1][0]) - S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]) - T2 := math.atan2(S2, m[1][1]) + T1 := math.atan2(m[2, 1], -m[0, 1]) + S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2]) + T2 := math.atan2(S2, m[1, 1]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(-S1*m[0][0] - C1*m[0][2], S1*m[2][0] + C1*m[2][2]) + T3 := math.atan2(-S1*m[0, 0] - C1*m[2, 0], S1*m[0, 2] + C1*m[2, 2]) t1 = T1 t2 = T2 t3 = T3 return } euler_angles_zyz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(m[2][1], m[2][0]) - S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]) - T2 := math.atan2(S2, m[2][2]) + T1 := math.atan2(m[1, 2], m[0, 2]) + S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1]) + T2 := math.atan2(S2, m[2, 2]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[0][1] - S1*m[0][0], C1*m[1][1] - S1*m[1][0]) + T3 := math.atan2(C1*m[1, 0] - S1*m[0, 0], C1*m[1, 1] - S1*m[0, 1]) t1 = T1 t2 = T2 t3 = T3 @@ -667,12 +667,12 @@ euler_angles_zyz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { } euler_angles_zxz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(m[2][0], -m[2][1]) - S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]) - T2 := math.atan2(S2, m[2][2]) + T1 := math.atan2(m[0, 2], -m[1, 2]) + S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1]) + T2 := math.atan2(S2, m[2, 2]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(-C1*m[1][0] - S1*m[1][1], C1*m[0][0] + S1*m[0][1]) + T3 := math.atan2(-C1*m[0, 1] - S1*m[1, 1], C1*m[0, 0] + S1*m[1, 0]) t1 = T1 t2 = T2 t3 = T3 @@ -680,12 +680,12 @@ euler_angles_zxz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { } euler_angles_xzy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(m[1][2], m[1][1]) - C2 := math.sqrt(m[0][0]*m[0][0] + m[2][0]*m[2][0]) - T2 := math.atan2(-m[1][0], C2) + T1 := math.atan2(m[2, 1], m[1, 1]) + C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 2]*m[0, 2]) + T2 := math.atan2(-m[0, 1], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[0][1] - C1*m[0][2], C1*m[2][2] - S1*m[2][1]) + T3 := math.atan2(S1*m[1, 0] - C1*m[2, 0], C1*m[2, 2] - S1*m[1, 2]) t1 = T1 t2 = T2 t3 = T3 @@ -693,12 +693,12 @@ euler_angles_xzy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { } euler_angles_yzx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(-m[0][2], m[0][0]) - C2 := math.sqrt(m[1][1]*m[1][1] + m[2][1]*m[2][1]) - T2 := math.atan2(m[0][1], C2) + T1 := math.atan2(-m[2, 0], m[0, 0]) + C2 := math.sqrt(m[1, 1]*m[1, 1] + m[1, 2]*m[1, 2]) + T2 := math.atan2(m[1, 0], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[1][0] + C1*m[1][2], S1*m[2][0] + C1*m[2][2]) + T3 := math.atan2(S1*m[0, 1] + C1*m[2, 1], S1*m[0, 2] + C1*m[2, 2]) t1 = T1 t2 = T2 t3 = T3 @@ -706,12 +706,12 @@ euler_angles_yzx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { } euler_angles_zyx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(m[0][1], m[0][0]) - C2 := math.sqrt(m[1][2]*m[1][2] + m[2][2]*m[2][2]) - T2 := math.atan2(-m[0][2], C2) + T1 := math.atan2(m[1, 0], m[0, 0]) + C2 := math.sqrt(m[2, 1]*m[2, 1] + m[2, 2]*m[2, 2]) + T2 := math.atan2(-m[2, 0], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[2][0] - C1*m[2][1], C1*m[1][1] - S1*m[1][0]) + T3 := math.atan2(S1*m[0, 2] - C1*m[1, 2], C1*m[1, 1] - S1*m[0, 1]) t1 = T1 t2 = T2 t3 = T3 @@ -719,12 +719,12 @@ euler_angles_zyx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { } euler_angles_zxy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(-m[1][0], m[1][1]) - C2 := math.sqrt(m[0][2]*m[0][2] + m[2][2]*m[2][2]) - T2 := math.atan2(m[1][2], C2) + T1 := math.atan2(-m[0, 1], m[1, 1]) + C2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 2]*m[2, 2]) + T2 := math.atan2(m[2, 1], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[2][0] + S1*m[2][1], C1*m[0][0] + S1*m[0][1]) + T3 := math.atan2(C1*m[0, 2] + S1*m[1, 2], C1*m[0, 0] + S1*m[1, 0]) t1 = T1 t2 = T2 t3 = T3 @@ -737,32 +737,32 @@ euler_angles_zxy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) { matrix4_from_euler_angle_x_f16 :: proc(angle_x: f16) -> (m: Matrix4f16) { cos_x, sin_x := math.cos(angle_x), math.sin(angle_x) - m[0][0] = 1 - m[1][1] = +cos_x - m[2][1] = +sin_x - m[1][2] = -sin_x - m[2][2] = +cos_x - m[3][3] = 1 + m[0, 0] = 1 + m[1, 1] = +cos_x + m[1, 2] = +sin_x + m[2, 1] = -sin_x + m[2, 2] = +cos_x + m[3, 3] = 1 return } matrix4_from_euler_angle_y_f16 :: proc(angle_y: f16) -> (m: Matrix4f16) { cos_y, sin_y := math.cos(angle_y), math.sin(angle_y) - m[0][0] = +cos_y - m[2][0] = -sin_y - m[1][1] = 1 - m[0][2] = +sin_y - m[2][2] = +cos_y - m[3][3] = 1 + m[0, 0] = +cos_y + m[0, 2] = -sin_y + m[1, 1] = 1 + m[2, 0] = +sin_y + m[2, 2] = +cos_y + m[3, 3] = 1 return } matrix4_from_euler_angle_z_f16 :: proc(angle_z: f16) -> (m: Matrix4f16) { cos_z, sin_z := math.cos(angle_z), math.sin(angle_z) - m[0][0] = +cos_z - m[1][0] = +sin_z - m[1][1] = +cos_z - m[0][1] = -sin_z - m[2][2] = 1 - m[3][3] = 1 + m[0, 0] = +cos_z + m[0, 1] = +sin_z + m[1, 1] = +cos_z + m[1, 0] = -sin_z + m[2, 2] = 1 + m[3, 3] = 1 return } @@ -770,34 +770,34 @@ matrix4_from_euler_angle_z_f16 :: proc(angle_z: f16) -> (m: Matrix4f16) { matrix4_from_derived_euler_angle_x_f16 :: proc(angle_x: f16, angular_velocity_x: f16) -> (m: Matrix4f16) { cos_x := math.cos(angle_x) * angular_velocity_x sin_x := math.sin(angle_x) * angular_velocity_x - m[0][0] = 1 - m[1][1] = +cos_x - m[2][1] = +sin_x - m[1][2] = -sin_x - m[2][2] = +cos_x - m[3][3] = 1 + m[0, 0] = 1 + m[1, 1] = +cos_x + m[1, 2] = +sin_x + m[2, 1] = -sin_x + m[2, 2] = +cos_x + m[3, 3] = 1 return } matrix4_from_derived_euler_angle_y_f16 :: proc(angle_y: f16, angular_velocity_y: f16) -> (m: Matrix4f16) { cos_y := math.cos(angle_y) * angular_velocity_y sin_y := math.sin(angle_y) * angular_velocity_y - m[0][0] = +cos_y - m[2][0] = -sin_y - m[1][1] = 1 - m[0][2] = +sin_y - m[2][2] = +cos_y - m[3][3] = 1 + m[0, 0] = +cos_y + m[0, 2] = -sin_y + m[1, 1] = 1 + m[2, 0] = +sin_y + m[2, 2] = +cos_y + m[3, 3] = 1 return } matrix4_from_derived_euler_angle_z_f16 :: proc(angle_z: f16, angular_velocity_z: f16) -> (m: Matrix4f16) { cos_z := math.cos(angle_z) * angular_velocity_z sin_z := math.sin(angle_z) * angular_velocity_z - m[0][0] = +cos_z - m[1][0] = +sin_z - m[1][1] = +cos_z - m[0][1] = -sin_z - m[2][2] = 1 - m[3][3] = 1 + m[0, 0] = +cos_z + m[0, 1] = +sin_z + m[1, 1] = +cos_z + m[1, 0] = -sin_z + m[2, 2] = 1 + m[3, 3] = 1 return } @@ -805,15 +805,15 @@ matrix4_from_derived_euler_angle_z_f16 :: proc(angle_z: f16, angular_velocity_z: matrix4_from_euler_angles_xy_f16 :: proc(angle_x, angle_y: f16) -> (m: Matrix4f16) { cos_x, sin_x := math.cos(angle_x), math.sin(angle_x) cos_y, sin_y := math.cos(angle_y), math.sin(angle_y) - m[0][0] = cos_y - m[1][0] = -sin_x * - sin_y - m[2][0] = -cos_x * - sin_y - m[1][1] = cos_x - m[2][1] = sin_x - m[0][2] = sin_y - m[1][2] = -sin_x * cos_y - m[2][2] = cos_x * cos_y - m[3][3] = 1 + m[0, 0] = cos_y + m[0, 1] = -sin_x * - sin_y + m[0, 2] = -cos_x * - sin_y + m[1, 1] = cos_x + m[1, 2] = sin_x + m[2, 0] = sin_y + m[2, 1] = -sin_x * cos_y + m[2, 2] = cos_x * cos_y + m[3, 3] = 1 return } @@ -821,15 +821,15 @@ matrix4_from_euler_angles_xy_f16 :: proc(angle_x, angle_y: f16) -> (m: Matrix4f1 matrix4_from_euler_angles_yx_f16 :: proc(angle_y, angle_x: f16) -> (m: Matrix4f16) { cos_x, sin_x := math.cos(angle_x), math.sin(angle_x) cos_y, sin_y := math.cos(angle_y), math.sin(angle_y) - m[0][0] = cos_y - m[2][0] = -sin_y - m[0][1] = sin_y*sin_x - m[1][1] = cos_x - m[2][1] = cos_y*sin_x - m[0][2] = sin_y*cos_x - m[1][2] = -sin_x - m[2][2] = cos_y*cos_x - m[3][3] = 1 + m[0, 0] = cos_y + m[0, 2] = -sin_y + m[1, 0] = sin_y*sin_x + m[1, 1] = cos_x + m[1, 2] = cos_y*sin_x + m[2, 0] = sin_y*cos_x + m[2, 1] = -sin_x + m[2, 2] = cos_y*cos_x + m[3, 3] = 1 return } @@ -855,22 +855,22 @@ matrix4_from_euler_angles_xyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) { s2 := math.sin(-t2) s3 := math.sin(-t3) - m[0][0] = c2 * c3 - m[0][1] =-c1 * s3 + s1 * s2 * c3 - m[0][2] = s1 * s3 + c1 * s2 * c3 - m[0][3] = 0 - m[1][0] = c2 * s3 - m[1][1] = c1 * c3 + s1 * s2 * s3 - m[1][2] =-s1 * c3 + c1 * s2 * s3 - m[1][3] = 0 - m[2][0] =-s2 - m[2][1] = s1 * c2 - m[2][2] = c1 * c2 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c2 * c3 + m[1, 0] =-c1 * s3 + s1 * s2 * c3 + m[2, 0] = s1 * s3 + c1 * s2 * c3 + m[3, 0] = 0 + m[0, 1] = c2 * s3 + m[1, 1] = c1 * c3 + s1 * s2 * s3 + m[2, 1] =-s1 * c3 + c1 * s2 * s3 + m[3, 1] = 0 + m[0, 2] =-s2 + m[1, 2] = s1 * c2 + m[2, 2] = c1 * c2 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -882,22 +882,22 @@ matrix4_from_euler_angles_yxz_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix4f cb := math.cos(roll) sb := math.sin(roll) - m[0][0] = ch * cb + sh * sp * sb - m[0][1] = sb * cp - m[0][2] = -sh * cb + ch * sp * sb - m[0][3] = 0 - m[1][0] = -ch * sb + sh * sp * cb - m[1][1] = cb * cp - m[1][2] = sb * sh + ch * sp * cb - m[1][3] = 0 - m[2][0] = sh * cp - m[2][1] = -sp - m[2][2] = ch * cp - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = ch * cb + sh * sp * sb + m[1, 0] = sb * cp + m[2, 0] = -sh * cb + ch * sp * sb + m[3, 0] = 0 + m[0, 1] = -ch * sb + sh * sp * cb + m[1, 1] = cb * cp + m[2, 1] = sb * sh + ch * sp * cb + m[3, 1] = 0 + m[0, 2] = sh * cp + m[1, 2] = -sp + m[2, 2] = ch * cp + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -909,22 +909,22 @@ matrix4_from_euler_angles_xzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c2 - m[0][1] = c1 * s2 - m[0][2] = s1 * s2 - m[0][3] = 0 - m[1][0] =-c3 * s2 - m[1][1] = c1 * c2 * c3 - s1 * s3 - m[1][2] = c1 * s3 + c2 * c3 * s1 - m[1][3] = 0 - m[2][0] = s2 * s3 - m[2][1] =-c3 * s1 - c1 * c2 * s3 - m[2][2] = c1 * c3 - c2 * s1 * s3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c2 + m[1, 0] = c1 * s2 + m[2, 0] = s1 * s2 + m[3, 0] = 0 + m[0, 1] =-c3 * s2 + m[1, 1] = c1 * c2 * c3 - s1 * s3 + m[2, 1] = c1 * s3 + c2 * c3 * s1 + m[3, 1] = 0 + m[0, 2] = s2 * s3 + m[1, 2] =-c3 * s1 - c1 * c2 * s3 + m[2, 2] = c1 * c3 - c2 * s1 * s3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -936,22 +936,22 @@ matrix4_from_euler_angles_xyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c2 - m[0][1] = s1 * s2 - m[0][2] =-c1 * s2 - m[0][3] = 0 - m[1][0] = s2 * s3 - m[1][1] = c1 * c3 - c2 * s1 * s3 - m[1][2] = c3 * s1 + c1 * c2 * s3 - m[1][3] = 0 - m[2][0] = c3 * s2 - m[2][1] =-c1 * s3 - c2 * c3 * s1 - m[2][2] = c1 * c2 * c3 - s1 * s3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c2 + m[1, 0] = s1 * s2 + m[2, 0] =-c1 * s2 + m[3, 0] = 0 + m[0, 1] = s2 * s3 + m[1, 1] = c1 * c3 - c2 * s1 * s3 + m[2, 1] = c3 * s1 + c1 * c2 * s3 + m[3, 1] = 0 + m[0, 2] = c3 * s2 + m[1, 2] =-c1 * s3 - c2 * c3 * s1 + m[2, 2] = c1 * c2 * c3 - s1 * s3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -963,22 +963,22 @@ matrix4_from_euler_angles_yxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c3 - c2 * s1 * s3 - m[0][1] = s2* s3 - m[0][2] =-c3 * s1 - c1 * c2 * s3 - m[0][3] = 0 - m[1][0] = s1 * s2 - m[1][1] = c2 - m[1][2] = c1 * s2 - m[1][3] = 0 - m[2][0] = c1 * s3 + c2 * c3 * s1 - m[2][1] =-c3 * s2 - m[2][2] = c1 * c2 * c3 - s1 * s3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c1 * c3 - c2 * s1 * s3 + m[1, 0] = s2* s3 + m[2, 0] =-c3 * s1 - c1 * c2 * s3 + m[3, 0] = 0 + m[0, 1] = s1 * s2 + m[1, 1] = c2 + m[2, 1] = c1 * s2 + m[3, 1] = 0 + m[0, 2] = c1 * s3 + c2 * c3 * s1 + m[1, 2] =-c3 * s2 + m[2, 2] = c1 * c2 * c3 - s1 * s3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -990,22 +990,22 @@ matrix4_from_euler_angles_yzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 * c3 - s1 * s3 - m[0][1] = c3 * s2 - m[0][2] =-c1 * s3 - c2 * c3 * s1 - m[0][3] = 0 - m[1][0] =-c1 * s2 - m[1][1] = c2 - m[1][2] = s1 * s2 - m[1][3] = 0 - m[2][0] = c3 * s1 + c1 * c2 * s3 - m[2][1] = s2 * s3 - m[2][2] = c1 * c3 - c2 * s1 * s3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c1 * c2 * c3 - s1 * s3 + m[1, 0] = c3 * s2 + m[2, 0] =-c1 * s3 - c2 * c3 * s1 + m[3, 0] = 0 + m[0, 1] =-c1 * s2 + m[1, 1] = c2 + m[2, 1] = s1 * s2 + m[3, 1] = 0 + m[0, 2] = c3 * s1 + c1 * c2 * s3 + m[1, 2] = s2 * s3 + m[2, 2] = c1 * c3 - c2 * s1 * s3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -1017,22 +1017,22 @@ matrix4_from_euler_angles_zyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 * c3 - s1 * s3 - m[0][1] = c1 * s3 + c2 * c3 * s1 - m[0][2] =-c3 * s2 - m[0][3] = 0 - m[1][0] =-c3 * s1 - c1 * c2 * s3 - m[1][1] = c1 * c3 - c2 * s1 * s3 - m[1][2] = s2 * s3 - m[1][3] = 0 - m[2][0] = c1 * s2 - m[2][1] = s1 * s2 - m[2][2] = c2 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c1 * c2 * c3 - s1 * s3 + m[1, 0] = c1 * s3 + c2 * c3 * s1 + m[2, 0] =-c3 * s2 + m[3, 0] = 0 + m[0, 1] =-c3 * s1 - c1 * c2 * s3 + m[1, 1] = c1 * c3 - c2 * s1 * s3 + m[2, 1] = s2 * s3 + m[3, 1] = 0 + m[0, 2] = c1 * s2 + m[1, 2] = s1 * s2 + m[2, 2] = c2 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -1044,22 +1044,22 @@ matrix4_from_euler_angles_zxz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c3 - c2 * s1 * s3 - m[0][1] = c3 * s1 + c1 * c2 * s3 - m[0][2] = s2 *s3 - m[0][3] = 0 - m[1][0] =-c1 * s3 - c2 * c3 * s1 - m[1][1] = c1 * c2 * c3 - s1 * s3 - m[1][2] = c3 * s2 - m[1][3] = 0 - m[2][0] = s1 * s2 - m[2][1] =-c1 * s2 - m[2][2] = c2 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c1 * c3 - c2 * s1 * s3 + m[1, 0] = c3 * s1 + c1 * c2 * s3 + m[2, 0] = s2 *s3 + m[3, 0] = 0 + m[0, 1] =-c1 * s3 - c2 * c3 * s1 + m[1, 1] = c1 * c2 * c3 - s1 * s3 + m[2, 1] = c3 * s2 + m[3, 1] = 0 + m[0, 2] = s1 * s2 + m[1, 2] =-c1 * s2 + m[2, 2] = c2 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -1072,22 +1072,22 @@ matrix4_from_euler_angles_xzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c2 * c3 - m[0][1] = s1 * s3 + c1 * c3 * s2 - m[0][2] = c3 * s1 * s2 - c1 * s3 - m[0][3] = 0 - m[1][0] =-s2 - m[1][1] = c1 * c2 - m[1][2] = c2 * s1 - m[1][3] = 0 - m[2][0] = c2 * s3 - m[2][1] = c1 * s2 * s3 - c3 * s1 - m[2][2] = c1 * c3 + s1 * s2 *s3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c2 * c3 + m[1, 0] = s1 * s3 + c1 * c3 * s2 + m[2, 0] = c3 * s1 * s2 - c1 * s3 + m[3, 0] = 0 + m[0, 1] =-s2 + m[1, 1] = c1 * c2 + m[2, 1] = c2 * s1 + m[3, 1] = 0 + m[0, 2] = c2 * s3 + m[1, 2] = c1 * s2 * s3 - c3 * s1 + m[2, 2] = c1 * c3 + s1 * s2 *s3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -1099,22 +1099,22 @@ matrix4_from_euler_angles_yzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 - m[0][1] = s2 - m[0][2] =-c2 * s1 - m[0][3] = 0 - m[1][0] = s1 * s3 - c1 * c3 * s2 - m[1][1] = c2 * c3 - m[1][2] = c1 * s3 + c3 * s1 * s2 - m[1][3] = 0 - m[2][0] = c3 * s1 + c1 * s2 * s3 - m[2][1] =-c2 * s3 - m[2][2] = c1 * c3 - s1 * s2 * s3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c1 * c2 + m[1, 0] = s2 + m[2, 0] =-c2 * s1 + m[3, 0] = 0 + m[0, 1] = s1 * s3 - c1 * c3 * s2 + m[1, 1] = c2 * c3 + m[2, 1] = c1 * s3 + c3 * s1 * s2 + m[3, 1] = 0 + m[0, 2] = c3 * s1 + c1 * s2 * s3 + m[1, 2] =-c2 * s3 + m[2, 2] = c1 * c3 - s1 * s2 * s3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -1126,22 +1126,22 @@ matrix4_from_euler_angles_zyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 - m[0][1] = c2 * s1 - m[0][2] =-s2 - m[0][3] = 0 - m[1][0] = c1 * s2 * s3 - c3 * s1 - m[1][1] = c1 * c3 + s1 * s2 * s3 - m[1][2] = c2 * s3 - m[1][3] = 0 - m[2][0] = s1 * s3 + c1 * c3 * s2 - m[2][1] = c3 * s1 * s2 - c1 * s3 - m[2][2] = c2 * c3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c1 * c2 + m[1, 0] = c2 * s1 + m[2, 0] =-s2 + m[3, 0] = 0 + m[0, 1] = c1 * s2 * s3 - c3 * s1 + m[1, 1] = c1 * c3 + s1 * s2 * s3 + m[2, 1] = c2 * s3 + m[3, 1] = 0 + m[0, 2] = s1 * s3 + c1 * c3 * s2 + m[1, 2] = c3 * s1 * s2 - c1 * s3 + m[2, 2] = c2 * c3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -1153,22 +1153,22 @@ matrix4_from_euler_angles_zxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c3 - s1 * s2 * s3 - m[0][1] = c3 * s1 + c1 * s2 * s3 - m[0][2] =-c2 * s3 - m[0][3] = 0 - m[1][0] =-c2 * s1 - m[1][1] = c1 * c2 - m[1][2] = s2 - m[1][3] = 0 - m[2][0] = c1 * s3 + c3 * s1 * s2 - m[2][1] = s1 * s3 - c1 * c3 * s2 - m[2][2] = c2 * c3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c1 * c3 - s1 * s2 * s3 + m[1, 0] = c3 * s1 + c1 * s2 * s3 + m[2, 0] =-c2 * s3 + m[3, 0] = 0 + m[0, 1] =-c2 * s1 + m[1, 1] = c1 * c2 + m[2, 1] = s2 + m[3, 1] = 0 + m[0, 2] = c1 * s3 + c3 * s1 * s2 + m[1, 2] = s1 * s3 - c1 * c3 * s2 + m[2, 2] = c2 * c3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -1181,32 +1181,32 @@ matrix4_from_yaw_pitch_roll_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix4f16 cb := math.cos(roll) sb := math.sin(roll) - m[0][0] = ch * cb + sh * sp * sb - m[0][1] = sb * cp - m[0][2] = -sh * cb + ch * sp * sb - m[0][3] = 0 - m[1][0] = -ch * sb + sh * sp * cb - m[1][1] = cb * cp - m[1][2] = sb * sh + ch * sp * cb - m[1][3] = 0 - m[2][0] = sh * cp - m[2][1] = -sp - m[2][2] = ch * cp - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = ch * cb + sh * sp * sb + m[1, 0] = sb * cp + m[2, 0] = -sh * cb + ch * sp * sb + m[3, 0] = 0 + m[0, 1] = -ch * sb + sh * sp * cb + m[1, 1] = cb * cp + m[2, 1] = sb * sh + ch * sp * cb + m[3, 1] = 0 + m[0, 2] = sh * cp + m[1, 2] = -sp + m[2, 2] = ch * cp + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return m } euler_angles_xyz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(m[2][1], m[2][2]) - C2 := math.sqrt(m[0][0]*m[0][0] + m[1][0]*m[1][0]) - T2 := math.atan2(-m[2][0], C2) + T1 := math.atan2(m[1, 2], m[2, 2]) + C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 1]*m[0, 1]) + T2 := math.atan2(-m[0, 2], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[0][2] - C1*m[0][1], C1*m[1][1] - S1*m[1][2]) + T3 := math.atan2(S1*m[2, 0] - C1*m[1, 0], C1*m[1, 1] - S1*m[2, 1]) t1 = -T1 t2 = -T2 t3 = -T3 @@ -1214,12 +1214,12 @@ euler_angles_xyz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { } euler_angles_yxz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(m[2][0], m[2][2]) - C2 := math.sqrt(m[0][1]*m[0][1] + m[1][1]*m[1][1]) - T2 := math.atan2(-m[2][1], C2) + T1 := math.atan2(m[0, 2], m[2, 2]) + C2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 1]*m[1, 1]) + T2 := math.atan2(-m[1, 2], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[1][2] - C1*m[1][0], C1*m[0][0] - S1*m[0][2]) + T3 := math.atan2(S1*m[2, 1] - C1*m[0, 1], C1*m[0, 0] - S1*m[2, 0]) t1 = T1 t2 = T2 t3 = T3 @@ -1227,12 +1227,12 @@ euler_angles_yxz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { } euler_angles_xzx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(m[0][2], m[0][1]) - S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]) - T2 := math.atan2(S2, m[0][0]) + T1 := math.atan2(m[2, 0], m[1, 0]) + S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2]) + T2 := math.atan2(S2, m[0, 0]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[1][2] - S1*m[1][1], C1*m[2][2] - S1*m[2][1]) + T3 := math.atan2(C1*m[2, 1] - S1*m[1, 1], C1*m[2, 2] - S1*m[1, 2]) t1 = T1 t2 = T2 t3 = T3 @@ -1240,12 +1240,12 @@ euler_angles_xzx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { } euler_angles_xyx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(m[0][1], -m[0][2]) - S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]) - T2 := math.atan2(S2, m[0][0]) + T1 := math.atan2(m[1, 0], -m[2, 0]) + S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2]) + T2 := math.atan2(S2, m[0, 0]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(-C1*m[2][1] - S1*m[2][2], C1*m[1][1] + S1*m[1][2]) + T3 := math.atan2(-C1*m[1, 2] - S1*m[2, 2], C1*m[1, 1] + S1*m[2, 1]) t1 = T1 t2 = T2 t3 = T3 @@ -1253,12 +1253,12 @@ euler_angles_xyx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { } euler_angles_yxy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(m[1][0], m[1][2]) - S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]) - T2 := math.atan2(S2, m[1][1]) + T1 := math.atan2(m[0, 1], m[2, 1]) + S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2]) + T2 := math.atan2(S2, m[1, 1]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[2][0] - S1*m[2][2], C1*m[0][0] - S1*m[0][2]) + T3 := math.atan2(C1*m[0, 2] - S1*m[2, 2], C1*m[0, 0] - S1*m[2, 0]) t1 = T1 t2 = T2 t3 = T3 @@ -1266,24 +1266,24 @@ euler_angles_yxy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { } euler_angles_yzy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(m[1][2], -m[1][0]) - S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]) - T2 := math.atan2(S2, m[1][1]) + T1 := math.atan2(m[2, 1], -m[0, 1]) + S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2]) + T2 := math.atan2(S2, m[1, 1]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(-S1*m[0][0] - C1*m[0][2], S1*m[2][0] + C1*m[2][2]) + T3 := math.atan2(-S1*m[0, 0] - C1*m[2, 0], S1*m[0, 2] + C1*m[2, 2]) t1 = T1 t2 = T2 t3 = T3 return } euler_angles_zyz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(m[2][1], m[2][0]) - S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]) - T2 := math.atan2(S2, m[2][2]) + T1 := math.atan2(m[1, 2], m[0, 2]) + S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1]) + T2 := math.atan2(S2, m[2, 2]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[0][1] - S1*m[0][0], C1*m[1][1] - S1*m[1][0]) + T3 := math.atan2(C1*m[1, 0] - S1*m[0, 0], C1*m[1, 1] - S1*m[0, 1]) t1 = T1 t2 = T2 t3 = T3 @@ -1291,12 +1291,12 @@ euler_angles_zyz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { } euler_angles_zxz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(m[2][0], -m[2][1]) - S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]) - T2 := math.atan2(S2, m[2][2]) + T1 := math.atan2(m[0, 2], -m[1, 2]) + S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1]) + T2 := math.atan2(S2, m[2, 2]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(-C1*m[1][0] - S1*m[1][1], C1*m[0][0] + S1*m[0][1]) + T3 := math.atan2(-C1*m[0, 1] - S1*m[1, 1], C1*m[0, 0] + S1*m[1, 0]) t1 = T1 t2 = T2 t3 = T3 @@ -1304,12 +1304,12 @@ euler_angles_zxz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { } euler_angles_xzy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(m[1][2], m[1][1]) - C2 := math.sqrt(m[0][0]*m[0][0] + m[2][0]*m[2][0]) - T2 := math.atan2(-m[1][0], C2) + T1 := math.atan2(m[2, 1], m[1, 1]) + C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 2]*m[0, 2]) + T2 := math.atan2(-m[0, 1], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[0][1] - C1*m[0][2], C1*m[2][2] - S1*m[2][1]) + T3 := math.atan2(S1*m[1, 0] - C1*m[2, 0], C1*m[2, 2] - S1*m[1, 2]) t1 = T1 t2 = T2 t3 = T3 @@ -1317,12 +1317,12 @@ euler_angles_xzy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { } euler_angles_yzx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(-m[0][2], m[0][0]) - C2 := math.sqrt(m[1][1]*m[1][1] + m[2][1]*m[2][1]) - T2 := math.atan2(m[0][1], C2) + T1 := math.atan2(-m[2, 0], m[0, 0]) + C2 := math.sqrt(m[1, 1]*m[1, 1] + m[1, 2]*m[1, 2]) + T2 := math.atan2(m[1, 0], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[1][0] + C1*m[1][2], S1*m[2][0] + C1*m[2][2]) + T3 := math.atan2(S1*m[0, 1] + C1*m[2, 1], S1*m[0, 2] + C1*m[2, 2]) t1 = T1 t2 = T2 t3 = T3 @@ -1330,12 +1330,12 @@ euler_angles_yzx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { } euler_angles_zyx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(m[0][1], m[0][0]) - C2 := math.sqrt(m[1][2]*m[1][2] + m[2][2]*m[2][2]) - T2 := math.atan2(-m[0][2], C2) + T1 := math.atan2(m[1, 0], m[0, 0]) + C2 := math.sqrt(m[2, 1]*m[2, 1] + m[2, 2]*m[2, 2]) + T2 := math.atan2(-m[2, 0], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[2][0] - C1*m[2][1], C1*m[1][1] - S1*m[1][0]) + T3 := math.atan2(S1*m[0, 2] - C1*m[1, 2], C1*m[1, 1] - S1*m[0, 1]) t1 = T1 t2 = T2 t3 = T3 @@ -1343,12 +1343,12 @@ euler_angles_zyx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { } euler_angles_zxy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) { - T1 := math.atan2(-m[1][0], m[1][1]) - C2 := math.sqrt(m[0][2]*m[0][2] + m[2][2]*m[2][2]) - T2 := math.atan2(m[1][2], C2) + T1 := math.atan2(-m[0, 1], m[1, 1]) + C2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 2]*m[2, 2]) + T2 := math.atan2(m[2, 1], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[2][0] + S1*m[2][1], C1*m[0][0] + S1*m[0][1]) + T3 := math.atan2(C1*m[0, 2] + S1*m[1, 2], C1*m[0, 0] + S1*m[1, 0]) t1 = T1 t2 = T2 t3 = T3 diff --git a/core/math/linalg/specific_euler_angles_f32.odin b/core/math/linalg/specific_euler_angles_f32.odin index 6ae1b0fa0..80e19ce85 100644 --- a/core/math/linalg/specific_euler_angles_f32.odin +++ b/core/math/linalg/specific_euler_angles_f32.odin @@ -212,29 +212,29 @@ euler_angles_zxy_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f matrix3_from_euler_angle_x_f32 :: proc(angle_x: f32) -> (m: Matrix3f32) { cos_x, sin_x := math.cos(angle_x), math.sin(angle_x) - m[0][0] = 1 - m[1][1] = +cos_x - m[2][1] = +sin_x - m[1][2] = -sin_x - m[2][2] = +cos_x + m[0, 0] = 1 + m[1, 1] = +cos_x + m[1, 2] = +sin_x + m[2, 1] = -sin_x + m[2, 2] = +cos_x return } matrix3_from_euler_angle_y_f32 :: proc(angle_y: f32) -> (m: Matrix3f32) { cos_y, sin_y := math.cos(angle_y), math.sin(angle_y) - m[0][0] = +cos_y - m[2][0] = -sin_y - m[1][1] = 1 - m[0][2] = +sin_y - m[2][2] = +cos_y + m[0, 0] = +cos_y + m[0, 2] = -sin_y + m[1, 1] = 1 + m[2, 0] = +sin_y + m[2, 2] = +cos_y return } matrix3_from_euler_angle_z_f32 :: proc(angle_z: f32) -> (m: Matrix3f32) { cos_z, sin_z := math.cos(angle_z), math.sin(angle_z) - m[0][0] = +cos_z - m[1][0] = +sin_z - m[1][1] = +cos_z - m[0][1] = -sin_z - m[2][2] = 1 + m[0, 0] = +cos_z + m[0, 1] = +sin_z + m[1, 1] = +cos_z + m[1, 0] = -sin_z + m[2, 2] = 1 return } @@ -242,31 +242,31 @@ matrix3_from_euler_angle_z_f32 :: proc(angle_z: f32) -> (m: Matrix3f32) { matrix3_from_derived_euler_angle_x_f32 :: proc(angle_x: f32, angular_velocity_x: f32) -> (m: Matrix3f32) { cos_x := math.cos(angle_x) * angular_velocity_x sin_x := math.sin(angle_x) * angular_velocity_x - m[0][0] = 1 - m[1][1] = +cos_x - m[2][1] = +sin_x - m[1][2] = -sin_x - m[2][2] = +cos_x + m[0, 0] = 1 + m[1, 1] = +cos_x + m[1, 2] = +sin_x + m[2, 1] = -sin_x + m[2, 2] = +cos_x return } matrix3_from_derived_euler_angle_y_f32 :: proc(angle_y: f32, angular_velocity_y: f32) -> (m: Matrix3f32) { cos_y := math.cos(angle_y) * angular_velocity_y sin_y := math.sin(angle_y) * angular_velocity_y - m[0][0] = +cos_y - m[2][0] = -sin_y - m[1][1] = 1 - m[0][2] = +sin_y - m[2][2] = +cos_y + m[0, 0] = +cos_y + m[0, 2] = -sin_y + m[1, 1] = 1 + m[2, 0] = +sin_y + m[2, 2] = +cos_y return } matrix3_from_derived_euler_angle_z_f32 :: proc(angle_z: f32, angular_velocity_z: f32) -> (m: Matrix3f32) { cos_z := math.cos(angle_z) * angular_velocity_z sin_z := math.sin(angle_z) * angular_velocity_z - m[0][0] = +cos_z - m[1][0] = +sin_z - m[1][1] = +cos_z - m[0][1] = -sin_z - m[2][2] = 1 + m[0, 0] = +cos_z + m[0, 1] = +sin_z + m[1, 1] = +cos_z + m[1, 0] = -sin_z + m[2, 2] = 1 return } @@ -274,14 +274,14 @@ matrix3_from_derived_euler_angle_z_f32 :: proc(angle_z: f32, angular_velocity_z: matrix3_from_euler_angles_xy_f32 :: proc(angle_x, angle_y: f32) -> (m: Matrix3f32) { cos_x, sin_x := math.cos(angle_x), math.sin(angle_x) cos_y, sin_y := math.cos(angle_y), math.sin(angle_y) - m[0][0] = cos_y - m[1][0] = -sin_x * - sin_y - m[2][0] = -cos_x * - sin_y - m[1][1] = cos_x - m[2][1] = sin_x - m[0][2] = sin_y - m[1][2] = -sin_x * cos_y - m[2][2] = cos_x * cos_y + m[0, 0] = cos_y + m[0, 1] = -sin_x * - sin_y + m[0, 2] = -cos_x * - sin_y + m[1, 1] = cos_x + m[1, 2] = sin_x + m[2, 0] = sin_y + m[2, 1] = -sin_x * cos_y + m[2, 2] = cos_x * cos_y return } @@ -289,14 +289,14 @@ matrix3_from_euler_angles_xy_f32 :: proc(angle_x, angle_y: f32) -> (m: Matrix3f3 matrix3_from_euler_angles_yx_f32 :: proc(angle_y, angle_x: f32) -> (m: Matrix3f32) { cos_x, sin_x := math.cos(angle_x), math.sin(angle_x) cos_y, sin_y := math.cos(angle_y), math.sin(angle_y) - m[0][0] = cos_y - m[2][0] = -sin_y - m[0][1] = sin_y*sin_x - m[1][1] = cos_x - m[2][1] = cos_y*sin_x - m[0][2] = sin_y*cos_x - m[1][2] = -sin_x - m[2][2] = cos_y*cos_x + m[0, 0] = cos_y + m[0, 2] = -sin_y + m[1, 0] = sin_y*sin_x + m[1, 1] = cos_x + m[1, 2] = cos_y*sin_x + m[2, 0] = sin_y*cos_x + m[2, 1] = -sin_x + m[2, 2] = cos_y*cos_x return } @@ -322,15 +322,15 @@ matrix3_from_euler_angles_xyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) { s2 := math.sin(-t2) s3 := math.sin(-t3) - m[0][0] = c2 * c3 - m[0][1] =-c1 * s3 + s1 * s2 * c3 - m[0][2] = s1 * s3 + c1 * s2 * c3 - m[1][0] = c2 * s3 - m[1][1] = c1 * c3 + s1 * s2 * s3 - m[1][2] =-s1 * c3 + c1 * s2 * s3 - m[2][0] =-s2 - m[2][1] = s1 * c2 - m[2][2] = c1 * c2 + m[0, 0] = c2 * c3 + m[1, 0] =-c1 * s3 + s1 * s2 * c3 + m[2, 0] = s1 * s3 + c1 * s2 * c3 + m[0, 1] = c2 * s3 + m[1, 1] = c1 * c3 + s1 * s2 * s3 + m[2, 1] =-s1 * c3 + c1 * s2 * s3 + m[0, 2] =-s2 + m[1, 2] = s1 * c2 + m[2, 2] = c1 * c2 return } @@ -342,15 +342,15 @@ matrix3_from_euler_angles_yxz_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix3f cb := math.cos(roll) sb := math.sin(roll) - m[0][0] = ch * cb + sh * sp * sb - m[0][1] = sb * cp - m[0][2] = -sh * cb + ch * sp * sb - m[1][0] = -ch * sb + sh * sp * cb - m[1][1] = cb * cp - m[1][2] = sb * sh + ch * sp * cb - m[2][0] = sh * cp - m[2][1] = -sp - m[2][2] = ch * cp + m[0, 0] = ch * cb + sh * sp * sb + m[1, 0] = sb * cp + m[2, 0] = -sh * cb + ch * sp * sb + m[0, 1] = -ch * sb + sh * sp * cb + m[1, 1] = cb * cp + m[2, 1] = sb * sh + ch * sp * cb + m[0, 2] = sh * cp + m[1, 2] = -sp + m[2, 2] = ch * cp return } @@ -362,15 +362,15 @@ matrix3_from_euler_angles_xzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c2 - m[0][1] = c1 * s2 - m[0][2] = s1 * s2 - m[1][0] =-c3 * s2 - m[1][1] = c1 * c2 * c3 - s1 * s3 - m[1][2] = c1 * s3 + c2 * c3 * s1 - m[2][0] = s2 * s3 - m[2][1] =-c3 * s1 - c1 * c2 * s3 - m[2][2] = c1 * c3 - c2 * s1 * s3 + m[0, 0] = c2 + m[1, 0] = c1 * s2 + m[2, 0] = s1 * s2 + m[0, 1] =-c3 * s2 + m[1, 1] = c1 * c2 * c3 - s1 * s3 + m[2, 1] = c1 * s3 + c2 * c3 * s1 + m[0, 2] = s2 * s3 + m[1, 2] =-c3 * s1 - c1 * c2 * s3 + m[2, 2] = c1 * c3 - c2 * s1 * s3 return } @@ -382,15 +382,15 @@ matrix3_from_euler_angles_xyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c2 - m[0][1] = s1 * s2 - m[0][2] =-c1 * s2 - m[1][0] = s2 * s3 - m[1][1] = c1 * c3 - c2 * s1 * s3 - m[1][2] = c3 * s1 + c1 * c2 * s3 - m[2][0] = c3 * s2 - m[2][1] =-c1 * s3 - c2 * c3 * s1 - m[2][2] = c1 * c2 * c3 - s1 * s3 + m[0, 0] = c2 + m[1, 0] = s1 * s2 + m[2, 0] =-c1 * s2 + m[0, 1] = s2 * s3 + m[1, 1] = c1 * c3 - c2 * s1 * s3 + m[2, 1] = c3 * s1 + c1 * c2 * s3 + m[0, 2] = c3 * s2 + m[1, 2] =-c1 * s3 - c2 * c3 * s1 + m[2, 2] = c1 * c2 * c3 - s1 * s3 return } @@ -402,15 +402,15 @@ matrix3_from_euler_angles_yxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c3 - c2 * s1 * s3 - m[0][1] = s2* s3 - m[0][2] =-c3 * s1 - c1 * c2 * s3 - m[1][0] = s1 * s2 - m[1][1] = c2 - m[1][2] = c1 * s2 - m[2][0] = c1 * s3 + c2 * c3 * s1 - m[2][1] =-c3 * s2 - m[2][2] = c1 * c2 * c3 - s1 * s3 + m[0, 0] = c1 * c3 - c2 * s1 * s3 + m[1, 0] = s2* s3 + m[2, 0] =-c3 * s1 - c1 * c2 * s3 + m[0, 1] = s1 * s2 + m[1, 1] = c2 + m[2, 1] = c1 * s2 + m[0, 2] = c1 * s3 + c2 * c3 * s1 + m[1, 2] =-c3 * s2 + m[2, 2] = c1 * c2 * c3 - s1 * s3 return } @@ -422,15 +422,15 @@ matrix3_from_euler_angles_yzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 * c3 - s1 * s3 - m[0][1] = c3 * s2 - m[0][2] =-c1 * s3 - c2 * c3 * s1 - m[1][0] =-c1 * s2 - m[1][1] = c2 - m[1][2] = s1 * s2 - m[2][0] = c3 * s1 + c1 * c2 * s3 - m[2][1] = s2 * s3 - m[2][2] = c1 * c3 - c2 * s1 * s3 + m[0, 0] = c1 * c2 * c3 - s1 * s3 + m[1, 0] = c3 * s2 + m[2, 0] =-c1 * s3 - c2 * c3 * s1 + m[0, 1] =-c1 * s2 + m[1, 1] = c2 + m[2, 1] = s1 * s2 + m[0, 2] = c3 * s1 + c1 * c2 * s3 + m[1, 2] = s2 * s3 + m[2, 2] = c1 * c3 - c2 * s1 * s3 return } @@ -442,15 +442,15 @@ matrix3_from_euler_angles_zyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 * c3 - s1 * s3 - m[0][1] = c1 * s3 + c2 * c3 * s1 - m[0][2] =-c3 * s2 - m[1][0] =-c3 * s1 - c1 * c2 * s3 - m[1][1] = c1 * c3 - c2 * s1 * s3 - m[1][2] = s2 * s3 - m[2][0] = c1 * s2 - m[2][1] = s1 * s2 - m[2][2] = c2 + m[0, 0] = c1 * c2 * c3 - s1 * s3 + m[1, 0] = c1 * s3 + c2 * c3 * s1 + m[2, 0] =-c3 * s2 + m[0, 1] =-c3 * s1 - c1 * c2 * s3 + m[1, 1] = c1 * c3 - c2 * s1 * s3 + m[2, 1] = s2 * s3 + m[0, 2] = c1 * s2 + m[1, 2] = s1 * s2 + m[2, 2] = c2 return } @@ -462,15 +462,15 @@ matrix3_from_euler_angles_zxz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c3 - c2 * s1 * s3 - m[0][1] = c3 * s1 + c1 * c2 * s3 - m[0][2] = s2 *s3 - m[1][0] =-c1 * s3 - c2 * c3 * s1 - m[1][1] = c1 * c2 * c3 - s1 * s3 - m[1][2] = c3 * s2 - m[2][0] = s1 * s2 - m[2][1] =-c1 * s2 - m[2][2] = c2 + m[0, 0] = c1 * c3 - c2 * s1 * s3 + m[1, 0] = c3 * s1 + c1 * c2 * s3 + m[2, 0] = s2 *s3 + m[0, 1] =-c1 * s3 - c2 * c3 * s1 + m[1, 1] = c1 * c2 * c3 - s1 * s3 + m[2, 1] = c3 * s2 + m[0, 2] = s1 * s2 + m[1, 2] =-c1 * s2 + m[2, 2] = c2 return } @@ -483,15 +483,15 @@ matrix3_from_euler_angles_xzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c2 * c3 - m[0][1] = s1 * s3 + c1 * c3 * s2 - m[0][2] = c3 * s1 * s2 - c1 * s3 - m[1][0] =-s2 - m[1][1] = c1 * c2 - m[1][2] = c2 * s1 - m[2][0] = c2 * s3 - m[2][1] = c1 * s2 * s3 - c3 * s1 - m[2][2] = c1 * c3 + s1 * s2 *s3 + m[0, 0] = c2 * c3 + m[1, 0] = s1 * s3 + c1 * c3 * s2 + m[2, 0] = c3 * s1 * s2 - c1 * s3 + m[0, 1] =-s2 + m[1, 1] = c1 * c2 + m[2, 1] = c2 * s1 + m[0, 2] = c2 * s3 + m[1, 2] = c1 * s2 * s3 - c3 * s1 + m[2, 2] = c1 * c3 + s1 * s2 *s3 return } @@ -503,15 +503,15 @@ matrix3_from_euler_angles_yzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 - m[0][1] = s2 - m[0][2] =-c2 * s1 - m[1][0] = s1 * s3 - c1 * c3 * s2 - m[1][1] = c2 * c3 - m[1][2] = c1 * s3 + c3 * s1 * s2 - m[2][0] = c3 * s1 + c1 * s2 * s3 - m[2][1] =-c2 * s3 - m[2][2] = c1 * c3 - s1 * s2 * s3 + m[0, 0] = c1 * c2 + m[1, 0] = s2 + m[2, 0] =-c2 * s1 + m[0, 1] = s1 * s3 - c1 * c3 * s2 + m[1, 1] = c2 * c3 + m[2, 1] = c1 * s3 + c3 * s1 * s2 + m[0, 2] = c3 * s1 + c1 * s2 * s3 + m[1, 2] =-c2 * s3 + m[2, 2] = c1 * c3 - s1 * s2 * s3 return } @@ -523,15 +523,15 @@ matrix3_from_euler_angles_zyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 - m[0][1] = c2 * s1 - m[0][2] =-s2 - m[1][0] = c1 * s2 * s3 - c3 * s1 - m[1][1] = c1 * c3 + s1 * s2 * s3 - m[1][2] = c2 * s3 - m[2][0] = s1 * s3 + c1 * c3 * s2 - m[2][1] = c3 * s1 * s2 - c1 * s3 - m[2][2] = c2 * c3 + m[0, 0] = c1 * c2 + m[1, 0] = c2 * s1 + m[2, 0] =-s2 + m[0, 1] = c1 * s2 * s3 - c3 * s1 + m[1, 1] = c1 * c3 + s1 * s2 * s3 + m[2, 1] = c2 * s3 + m[0, 2] = s1 * s3 + c1 * c3 * s2 + m[1, 2] = c3 * s1 * s2 - c1 * s3 + m[2, 2] = c2 * c3 return } @@ -543,15 +543,15 @@ matrix3_from_euler_angles_zxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c3 - s1 * s2 * s3 - m[0][1] = c3 * s1 + c1 * s2 * s3 - m[0][2] =-c2 * s3 - m[1][0] =-c2 * s1 - m[1][1] = c1 * c2 - m[1][2] = s2 - m[2][0] = c1 * s3 + c3 * s1 * s2 - m[2][1] = s1 * s3 - c1 * c3 * s2 - m[2][2] = c2 * c3 + m[0, 0] = c1 * c3 - s1 * s2 * s3 + m[1, 0] = c3 * s1 + c1 * s2 * s3 + m[2, 0] =-c2 * s3 + m[0, 1] =-c2 * s1 + m[1, 1] = c1 * c2 + m[2, 1] = s2 + m[0, 2] = c1 * s3 + c3 * s1 * s2 + m[1, 2] = s1 * s3 - c1 * c3 * s2 + m[2, 2] = c2 * c3 return } @@ -564,25 +564,25 @@ matrix3_from_yaw_pitch_roll_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix3f32 cb := math.cos(roll) sb := math.sin(roll) - m[0][0] = ch * cb + sh * sp * sb - m[0][1] = sb * cp - m[0][2] = -sh * cb + ch * sp * sb - m[1][0] = -ch * sb + sh * sp * cb - m[1][1] = cb * cp - m[1][2] = sb * sh + ch * sp * cb - m[2][0] = sh * cp - m[2][1] = -sp - m[2][2] = ch * cp + m[0, 0] = ch * cb + sh * sp * sb + m[1, 0] = sb * cp + m[2, 0] = -sh * cb + ch * sp * sb + m[0, 1] = -ch * sb + sh * sp * cb + m[1, 1] = cb * cp + m[2, 1] = sb * sh + ch * sp * cb + m[0, 2] = sh * cp + m[1, 2] = -sp + m[2, 2] = ch * cp return m } euler_angles_xyz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(m[2][1], m[2][2]) - C2 := math.sqrt(m[0][0]*m[0][0] + m[1][0]*m[1][0]) - T2 := math.atan2(-m[2][0], C2) + T1 := math.atan2(m[1, 2], m[2, 2]) + C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 1]*m[0, 1]) + T2 := math.atan2(-m[0, 2], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[0][2] - C1*m[0][1], C1*m[1][1] - S1*m[1][2]) + T3 := math.atan2(S1*m[2, 0] - C1*m[1, 0], C1*m[1, 1] - S1*m[2, 1]) t1 = -T1 t2 = -T2 t3 = -T3 @@ -590,12 +590,12 @@ euler_angles_xyz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { } euler_angles_yxz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(m[2][0], m[2][2]) - C2 := math.sqrt(m[0][1]*m[0][1] + m[1][1]*m[1][1]) - T2 := math.atan2(-m[2][1], C2) + T1 := math.atan2(m[0, 2], m[2, 2]) + C2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 1]*m[1, 1]) + T2 := math.atan2(-m[1, 2], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[1][2] - C1*m[1][0], C1*m[0][0] - S1*m[0][2]) + T3 := math.atan2(S1*m[2, 1] - C1*m[0, 1], C1*m[0, 0] - S1*m[2, 0]) t1 = T1 t2 = T2 t3 = T3 @@ -603,12 +603,12 @@ euler_angles_yxz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { } euler_angles_xzx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(m[0][2], m[0][1]) - S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]) - T2 := math.atan2(S2, m[0][0]) + T1 := math.atan2(m[2, 0], m[1, 0]) + S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2]) + T2 := math.atan2(S2, m[0, 0]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[1][2] - S1*m[1][1], C1*m[2][2] - S1*m[2][1]) + T3 := math.atan2(C1*m[2, 1] - S1*m[1, 1], C1*m[2, 2] - S1*m[1, 2]) t1 = T1 t2 = T2 t3 = T3 @@ -616,12 +616,12 @@ euler_angles_xzx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { } euler_angles_xyx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(m[0][1], -m[0][2]) - S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]) - T2 := math.atan2(S2, m[0][0]) + T1 := math.atan2(m[1, 0], -m[2, 0]) + S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2]) + T2 := math.atan2(S2, m[0, 0]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(-C1*m[2][1] - S1*m[2][2], C1*m[1][1] + S1*m[1][2]) + T3 := math.atan2(-C1*m[1, 2] - S1*m[2, 2], C1*m[1, 1] + S1*m[2, 1]) t1 = T1 t2 = T2 t3 = T3 @@ -629,12 +629,12 @@ euler_angles_xyx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { } euler_angles_yxy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(m[1][0], m[1][2]) - S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]) - T2 := math.atan2(S2, m[1][1]) + T1 := math.atan2(m[0, 1], m[2, 1]) + S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2]) + T2 := math.atan2(S2, m[1, 1]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[2][0] - S1*m[2][2], C1*m[0][0] - S1*m[0][2]) + T3 := math.atan2(C1*m[0, 2] - S1*m[2, 2], C1*m[0, 0] - S1*m[2, 0]) t1 = T1 t2 = T2 t3 = T3 @@ -642,24 +642,24 @@ euler_angles_yxy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { } euler_angles_yzy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(m[1][2], -m[1][0]) - S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]) - T2 := math.atan2(S2, m[1][1]) + T1 := math.atan2(m[2, 1], -m[0, 1]) + S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2]) + T2 := math.atan2(S2, m[1, 1]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(-S1*m[0][0] - C1*m[0][2], S1*m[2][0] + C1*m[2][2]) + T3 := math.atan2(-S1*m[0, 0] - C1*m[2, 0], S1*m[0, 2] + C1*m[2, 2]) t1 = T1 t2 = T2 t3 = T3 return } euler_angles_zyz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(m[2][1], m[2][0]) - S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]) - T2 := math.atan2(S2, m[2][2]) + T1 := math.atan2(m[1, 2], m[0, 2]) + S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1]) + T2 := math.atan2(S2, m[2, 2]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[0][1] - S1*m[0][0], C1*m[1][1] - S1*m[1][0]) + T3 := math.atan2(C1*m[1, 0] - S1*m[0, 0], C1*m[1, 1] - S1*m[0, 1]) t1 = T1 t2 = T2 t3 = T3 @@ -667,12 +667,12 @@ euler_angles_zyz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { } euler_angles_zxz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(m[2][0], -m[2][1]) - S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]) - T2 := math.atan2(S2, m[2][2]) + T1 := math.atan2(m[0, 2], -m[1, 2]) + S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1]) + T2 := math.atan2(S2, m[2, 2]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(-C1*m[1][0] - S1*m[1][1], C1*m[0][0] + S1*m[0][1]) + T3 := math.atan2(-C1*m[0, 1] - S1*m[1, 1], C1*m[0, 0] + S1*m[1, 0]) t1 = T1 t2 = T2 t3 = T3 @@ -680,12 +680,12 @@ euler_angles_zxz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { } euler_angles_xzy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(m[1][2], m[1][1]) - C2 := math.sqrt(m[0][0]*m[0][0] + m[2][0]*m[2][0]) - T2 := math.atan2(-m[1][0], C2) + T1 := math.atan2(m[2, 1], m[1, 1]) + C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 2]*m[0, 2]) + T2 := math.atan2(-m[0, 1], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[0][1] - C1*m[0][2], C1*m[2][2] - S1*m[2][1]) + T3 := math.atan2(S1*m[1, 0] - C1*m[2, 0], C1*m[2, 2] - S1*m[1, 2]) t1 = T1 t2 = T2 t3 = T3 @@ -693,12 +693,12 @@ euler_angles_xzy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { } euler_angles_yzx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(-m[0][2], m[0][0]) - C2 := math.sqrt(m[1][1]*m[1][1] + m[2][1]*m[2][1]) - T2 := math.atan2(m[0][1], C2) + T1 := math.atan2(-m[2, 0], m[0, 0]) + C2 := math.sqrt(m[1, 1]*m[1, 1] + m[1, 2]*m[1, 2]) + T2 := math.atan2(m[1, 0], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[1][0] + C1*m[1][2], S1*m[2][0] + C1*m[2][2]) + T3 := math.atan2(S1*m[0, 1] + C1*m[2, 1], S1*m[0, 2] + C1*m[2, 2]) t1 = T1 t2 = T2 t3 = T3 @@ -706,12 +706,12 @@ euler_angles_yzx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { } euler_angles_zyx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(m[0][1], m[0][0]) - C2 := math.sqrt(m[1][2]*m[1][2] + m[2][2]*m[2][2]) - T2 := math.atan2(-m[0][2], C2) + T1 := math.atan2(m[1, 0], m[0, 0]) + C2 := math.sqrt(m[2, 1]*m[2, 1] + m[2, 2]*m[2, 2]) + T2 := math.atan2(-m[2, 0], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[2][0] - C1*m[2][1], C1*m[1][1] - S1*m[1][0]) + T3 := math.atan2(S1*m[0, 2] - C1*m[1, 2], C1*m[1, 1] - S1*m[0, 1]) t1 = T1 t2 = T2 t3 = T3 @@ -719,12 +719,12 @@ euler_angles_zyx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { } euler_angles_zxy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(-m[1][0], m[1][1]) - C2 := math.sqrt(m[0][2]*m[0][2] + m[2][2]*m[2][2]) - T2 := math.atan2(m[1][2], C2) + T1 := math.atan2(-m[0, 1], m[1, 1]) + C2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 2]*m[2, 2]) + T2 := math.atan2(m[2, 1], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[2][0] + S1*m[2][1], C1*m[0][0] + S1*m[0][1]) + T3 := math.atan2(C1*m[0, 2] + S1*m[1, 2], C1*m[0, 0] + S1*m[1, 0]) t1 = T1 t2 = T2 t3 = T3 @@ -737,32 +737,32 @@ euler_angles_zxy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) { matrix4_from_euler_angle_x_f32 :: proc(angle_x: f32) -> (m: Matrix4f32) { cos_x, sin_x := math.cos(angle_x), math.sin(angle_x) - m[0][0] = 1 - m[1][1] = +cos_x - m[2][1] = +sin_x - m[1][2] = -sin_x - m[2][2] = +cos_x - m[3][3] = 1 + m[0, 0] = 1 + m[1, 1] = +cos_x + m[1, 2] = +sin_x + m[2, 1] = -sin_x + m[2, 2] = +cos_x + m[3, 3] = 1 return } matrix4_from_euler_angle_y_f32 :: proc(angle_y: f32) -> (m: Matrix4f32) { cos_y, sin_y := math.cos(angle_y), math.sin(angle_y) - m[0][0] = +cos_y - m[2][0] = -sin_y - m[1][1] = 1 - m[0][2] = +sin_y - m[2][2] = +cos_y - m[3][3] = 1 + m[0, 0] = +cos_y + m[0, 2] = -sin_y + m[1, 1] = 1 + m[2, 0] = +sin_y + m[2, 2] = +cos_y + m[3, 3] = 1 return } matrix4_from_euler_angle_z_f32 :: proc(angle_z: f32) -> (m: Matrix4f32) { cos_z, sin_z := math.cos(angle_z), math.sin(angle_z) - m[0][0] = +cos_z - m[1][0] = +sin_z - m[1][1] = +cos_z - m[0][1] = -sin_z - m[2][2] = 1 - m[3][3] = 1 + m[0, 0] = +cos_z + m[0, 1] = +sin_z + m[1, 1] = +cos_z + m[1, 0] = -sin_z + m[2, 2] = 1 + m[3, 3] = 1 return } @@ -770,34 +770,34 @@ matrix4_from_euler_angle_z_f32 :: proc(angle_z: f32) -> (m: Matrix4f32) { matrix4_from_derived_euler_angle_x_f32 :: proc(angle_x: f32, angular_velocity_x: f32) -> (m: Matrix4f32) { cos_x := math.cos(angle_x) * angular_velocity_x sin_x := math.sin(angle_x) * angular_velocity_x - m[0][0] = 1 - m[1][1] = +cos_x - m[2][1] = +sin_x - m[1][2] = -sin_x - m[2][2] = +cos_x - m[3][3] = 1 + m[0, 0] = 1 + m[1, 1] = +cos_x + m[1, 2] = +sin_x + m[2, 1] = -sin_x + m[2, 2] = +cos_x + m[3, 3] = 1 return } matrix4_from_derived_euler_angle_y_f32 :: proc(angle_y: f32, angular_velocity_y: f32) -> (m: Matrix4f32) { cos_y := math.cos(angle_y) * angular_velocity_y sin_y := math.sin(angle_y) * angular_velocity_y - m[0][0] = +cos_y - m[2][0] = -sin_y - m[1][1] = 1 - m[0][2] = +sin_y - m[2][2] = +cos_y - m[3][3] = 1 + m[0, 0] = +cos_y + m[0, 2] = -sin_y + m[1, 1] = 1 + m[2, 0] = +sin_y + m[2, 2] = +cos_y + m[3, 3] = 1 return } matrix4_from_derived_euler_angle_z_f32 :: proc(angle_z: f32, angular_velocity_z: f32) -> (m: Matrix4f32) { cos_z := math.cos(angle_z) * angular_velocity_z sin_z := math.sin(angle_z) * angular_velocity_z - m[0][0] = +cos_z - m[1][0] = +sin_z - m[1][1] = +cos_z - m[0][1] = -sin_z - m[2][2] = 1 - m[3][3] = 1 + m[0, 0] = +cos_z + m[0, 1] = +sin_z + m[1, 1] = +cos_z + m[1, 0] = -sin_z + m[2, 2] = 1 + m[3, 3] = 1 return } @@ -805,15 +805,15 @@ matrix4_from_derived_euler_angle_z_f32 :: proc(angle_z: f32, angular_velocity_z: matrix4_from_euler_angles_xy_f32 :: proc(angle_x, angle_y: f32) -> (m: Matrix4f32) { cos_x, sin_x := math.cos(angle_x), math.sin(angle_x) cos_y, sin_y := math.cos(angle_y), math.sin(angle_y) - m[0][0] = cos_y - m[1][0] = -sin_x * - sin_y - m[2][0] = -cos_x * - sin_y - m[1][1] = cos_x - m[2][1] = sin_x - m[0][2] = sin_y - m[1][2] = -sin_x * cos_y - m[2][2] = cos_x * cos_y - m[3][3] = 1 + m[0, 0] = cos_y + m[0, 1] = -sin_x * - sin_y + m[0, 2] = -cos_x * - sin_y + m[1, 1] = cos_x + m[1, 2] = sin_x + m[2, 0] = sin_y + m[2, 1] = -sin_x * cos_y + m[2, 2] = cos_x * cos_y + m[3, 3] = 1 return } @@ -821,15 +821,15 @@ matrix4_from_euler_angles_xy_f32 :: proc(angle_x, angle_y: f32) -> (m: Matrix4f3 matrix4_from_euler_angles_yx_f32 :: proc(angle_y, angle_x: f32) -> (m: Matrix4f32) { cos_x, sin_x := math.cos(angle_x), math.sin(angle_x) cos_y, sin_y := math.cos(angle_y), math.sin(angle_y) - m[0][0] = cos_y - m[2][0] = -sin_y - m[0][1] = sin_y*sin_x - m[1][1] = cos_x - m[2][1] = cos_y*sin_x - m[0][2] = sin_y*cos_x - m[1][2] = -sin_x - m[2][2] = cos_y*cos_x - m[3][3] = 1 + m[0, 0] = cos_y + m[0, 2] = -sin_y + m[1, 0] = sin_y*sin_x + m[1, 1] = cos_x + m[1, 2] = cos_y*sin_x + m[2, 0] = sin_y*cos_x + m[2, 1] = -sin_x + m[2, 2] = cos_y*cos_x + m[3, 3] = 1 return } @@ -855,22 +855,22 @@ matrix4_from_euler_angles_xyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) { s2 := math.sin(-t2) s3 := math.sin(-t3) - m[0][0] = c2 * c3 - m[0][1] =-c1 * s3 + s1 * s2 * c3 - m[0][2] = s1 * s3 + c1 * s2 * c3 - m[0][3] = 0 - m[1][0] = c2 * s3 - m[1][1] = c1 * c3 + s1 * s2 * s3 - m[1][2] =-s1 * c3 + c1 * s2 * s3 - m[1][3] = 0 - m[2][0] =-s2 - m[2][1] = s1 * c2 - m[2][2] = c1 * c2 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c2 * c3 + m[1, 0] =-c1 * s3 + s1 * s2 * c3 + m[2, 0] = s1 * s3 + c1 * s2 * c3 + m[3, 0] = 0 + m[0, 1] = c2 * s3 + m[1, 1] = c1 * c3 + s1 * s2 * s3 + m[2, 1] =-s1 * c3 + c1 * s2 * s3 + m[3, 1] = 0 + m[0, 2] =-s2 + m[1, 2] = s1 * c2 + m[2, 2] = c1 * c2 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -882,22 +882,22 @@ matrix4_from_euler_angles_yxz_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix4f cb := math.cos(roll) sb := math.sin(roll) - m[0][0] = ch * cb + sh * sp * sb - m[0][1] = sb * cp - m[0][2] = -sh * cb + ch * sp * sb - m[0][3] = 0 - m[1][0] = -ch * sb + sh * sp * cb - m[1][1] = cb * cp - m[1][2] = sb * sh + ch * sp * cb - m[1][3] = 0 - m[2][0] = sh * cp - m[2][1] = -sp - m[2][2] = ch * cp - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = ch * cb + sh * sp * sb + m[1, 0] = sb * cp + m[2, 0] = -sh * cb + ch * sp * sb + m[3, 0] = 0 + m[0, 1] = -ch * sb + sh * sp * cb + m[1, 1] = cb * cp + m[2, 1] = sb * sh + ch * sp * cb + m[3, 1] = 0 + m[0, 2] = sh * cp + m[1, 2] = -sp + m[2, 2] = ch * cp + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -909,22 +909,22 @@ matrix4_from_euler_angles_xzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c2 - m[0][1] = c1 * s2 - m[0][2] = s1 * s2 - m[0][3] = 0 - m[1][0] =-c3 * s2 - m[1][1] = c1 * c2 * c3 - s1 * s3 - m[1][2] = c1 * s3 + c2 * c3 * s1 - m[1][3] = 0 - m[2][0] = s2 * s3 - m[2][1] =-c3 * s1 - c1 * c2 * s3 - m[2][2] = c1 * c3 - c2 * s1 * s3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c2 + m[1, 0] = c1 * s2 + m[2, 0] = s1 * s2 + m[3, 0] = 0 + m[0, 1] =-c3 * s2 + m[1, 1] = c1 * c2 * c3 - s1 * s3 + m[2, 1] = c1 * s3 + c2 * c3 * s1 + m[3, 1] = 0 + m[0, 2] = s2 * s3 + m[1, 2] =-c3 * s1 - c1 * c2 * s3 + m[2, 2] = c1 * c3 - c2 * s1 * s3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -936,22 +936,22 @@ matrix4_from_euler_angles_xyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c2 - m[0][1] = s1 * s2 - m[0][2] =-c1 * s2 - m[0][3] = 0 - m[1][0] = s2 * s3 - m[1][1] = c1 * c3 - c2 * s1 * s3 - m[1][2] = c3 * s1 + c1 * c2 * s3 - m[1][3] = 0 - m[2][0] = c3 * s2 - m[2][1] =-c1 * s3 - c2 * c3 * s1 - m[2][2] = c1 * c2 * c3 - s1 * s3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c2 + m[1, 0] = s1 * s2 + m[2, 0] =-c1 * s2 + m[3, 0] = 0 + m[0, 1] = s2 * s3 + m[1, 1] = c1 * c3 - c2 * s1 * s3 + m[2, 1] = c3 * s1 + c1 * c2 * s3 + m[3, 1] = 0 + m[0, 2] = c3 * s2 + m[1, 2] =-c1 * s3 - c2 * c3 * s1 + m[2, 2] = c1 * c2 * c3 - s1 * s3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -963,22 +963,22 @@ matrix4_from_euler_angles_yxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c3 - c2 * s1 * s3 - m[0][1] = s2* s3 - m[0][2] =-c3 * s1 - c1 * c2 * s3 - m[0][3] = 0 - m[1][0] = s1 * s2 - m[1][1] = c2 - m[1][2] = c1 * s2 - m[1][3] = 0 - m[2][0] = c1 * s3 + c2 * c3 * s1 - m[2][1] =-c3 * s2 - m[2][2] = c1 * c2 * c3 - s1 * s3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c1 * c3 - c2 * s1 * s3 + m[1, 0] = s2* s3 + m[2, 0] =-c3 * s1 - c1 * c2 * s3 + m[3, 0] = 0 + m[0, 1] = s1 * s2 + m[1, 1] = c2 + m[2, 1] = c1 * s2 + m[3, 1] = 0 + m[0, 2] = c1 * s3 + c2 * c3 * s1 + m[1, 2] =-c3 * s2 + m[2, 2] = c1 * c2 * c3 - s1 * s3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -990,22 +990,22 @@ matrix4_from_euler_angles_yzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 * c3 - s1 * s3 - m[0][1] = c3 * s2 - m[0][2] =-c1 * s3 - c2 * c3 * s1 - m[0][3] = 0 - m[1][0] =-c1 * s2 - m[1][1] = c2 - m[1][2] = s1 * s2 - m[1][3] = 0 - m[2][0] = c3 * s1 + c1 * c2 * s3 - m[2][1] = s2 * s3 - m[2][2] = c1 * c3 - c2 * s1 * s3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c1 * c2 * c3 - s1 * s3 + m[1, 0] = c3 * s2 + m[2, 0] =-c1 * s3 - c2 * c3 * s1 + m[3, 0] = 0 + m[0, 1] =-c1 * s2 + m[1, 1] = c2 + m[2, 1] = s1 * s2 + m[3, 1] = 0 + m[0, 2] = c3 * s1 + c1 * c2 * s3 + m[1, 2] = s2 * s3 + m[2, 2] = c1 * c3 - c2 * s1 * s3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -1017,22 +1017,22 @@ matrix4_from_euler_angles_zyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 * c3 - s1 * s3 - m[0][1] = c1 * s3 + c2 * c3 * s1 - m[0][2] =-c3 * s2 - m[0][3] = 0 - m[1][0] =-c3 * s1 - c1 * c2 * s3 - m[1][1] = c1 * c3 - c2 * s1 * s3 - m[1][2] = s2 * s3 - m[1][3] = 0 - m[2][0] = c1 * s2 - m[2][1] = s1 * s2 - m[2][2] = c2 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c1 * c2 * c3 - s1 * s3 + m[1, 0] = c1 * s3 + c2 * c3 * s1 + m[2, 0] =-c3 * s2 + m[3, 0] = 0 + m[0, 1] =-c3 * s1 - c1 * c2 * s3 + m[1, 1] = c1 * c3 - c2 * s1 * s3 + m[2, 1] = s2 * s3 + m[3, 1] = 0 + m[0, 2] = c1 * s2 + m[1, 2] = s1 * s2 + m[2, 2] = c2 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -1044,22 +1044,22 @@ matrix4_from_euler_angles_zxz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c3 - c2 * s1 * s3 - m[0][1] = c3 * s1 + c1 * c2 * s3 - m[0][2] = s2 *s3 - m[0][3] = 0 - m[1][0] =-c1 * s3 - c2 * c3 * s1 - m[1][1] = c1 * c2 * c3 - s1 * s3 - m[1][2] = c3 * s2 - m[1][3] = 0 - m[2][0] = s1 * s2 - m[2][1] =-c1 * s2 - m[2][2] = c2 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c1 * c3 - c2 * s1 * s3 + m[1, 0] = c3 * s1 + c1 * c2 * s3 + m[2, 0] = s2 *s3 + m[3, 0] = 0 + m[0, 1] =-c1 * s3 - c2 * c3 * s1 + m[1, 1] = c1 * c2 * c3 - s1 * s3 + m[2, 1] = c3 * s2 + m[3, 1] = 0 + m[0, 2] = s1 * s2 + m[1, 2] =-c1 * s2 + m[2, 2] = c2 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -1072,22 +1072,22 @@ matrix4_from_euler_angles_xzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c2 * c3 - m[0][1] = s1 * s3 + c1 * c3 * s2 - m[0][2] = c3 * s1 * s2 - c1 * s3 - m[0][3] = 0 - m[1][0] =-s2 - m[1][1] = c1 * c2 - m[1][2] = c2 * s1 - m[1][3] = 0 - m[2][0] = c2 * s3 - m[2][1] = c1 * s2 * s3 - c3 * s1 - m[2][2] = c1 * c3 + s1 * s2 *s3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c2 * c3 + m[1, 0] = s1 * s3 + c1 * c3 * s2 + m[2, 0] = c3 * s1 * s2 - c1 * s3 + m[3, 0] = 0 + m[0, 1] =-s2 + m[1, 1] = c1 * c2 + m[2, 1] = c2 * s1 + m[3, 1] = 0 + m[0, 2] = c2 * s3 + m[1, 2] = c1 * s2 * s3 - c3 * s1 + m[2, 2] = c1 * c3 + s1 * s2 *s3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -1099,22 +1099,22 @@ matrix4_from_euler_angles_yzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 - m[0][1] = s2 - m[0][2] =-c2 * s1 - m[0][3] = 0 - m[1][0] = s1 * s3 - c1 * c3 * s2 - m[1][1] = c2 * c3 - m[1][2] = c1 * s3 + c3 * s1 * s2 - m[1][3] = 0 - m[2][0] = c3 * s1 + c1 * s2 * s3 - m[2][1] =-c2 * s3 - m[2][2] = c1 * c3 - s1 * s2 * s3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c1 * c2 + m[1, 0] = s2 + m[2, 0] =-c2 * s1 + m[3, 0] = 0 + m[0, 1] = s1 * s3 - c1 * c3 * s2 + m[1, 1] = c2 * c3 + m[2, 1] = c1 * s3 + c3 * s1 * s2 + m[3, 1] = 0 + m[0, 2] = c3 * s1 + c1 * s2 * s3 + m[1, 2] =-c2 * s3 + m[2, 2] = c1 * c3 - s1 * s2 * s3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -1126,22 +1126,22 @@ matrix4_from_euler_angles_zyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 - m[0][1] = c2 * s1 - m[0][2] =-s2 - m[0][3] = 0 - m[1][0] = c1 * s2 * s3 - c3 * s1 - m[1][1] = c1 * c3 + s1 * s2 * s3 - m[1][2] = c2 * s3 - m[1][3] = 0 - m[2][0] = s1 * s3 + c1 * c3 * s2 - m[2][1] = c3 * s1 * s2 - c1 * s3 - m[2][2] = c2 * c3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c1 * c2 + m[1, 0] = c2 * s1 + m[2, 0] =-s2 + m[3, 0] = 0 + m[0, 1] = c1 * s2 * s3 - c3 * s1 + m[1, 1] = c1 * c3 + s1 * s2 * s3 + m[2, 1] = c2 * s3 + m[3, 1] = 0 + m[0, 2] = s1 * s3 + c1 * c3 * s2 + m[1, 2] = c3 * s1 * s2 - c1 * s3 + m[2, 2] = c2 * c3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -1153,22 +1153,22 @@ matrix4_from_euler_angles_zxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c3 - s1 * s2 * s3 - m[0][1] = c3 * s1 + c1 * s2 * s3 - m[0][2] =-c2 * s3 - m[0][3] = 0 - m[1][0] =-c2 * s1 - m[1][1] = c1 * c2 - m[1][2] = s2 - m[1][3] = 0 - m[2][0] = c1 * s3 + c3 * s1 * s2 - m[2][1] = s1 * s3 - c1 * c3 * s2 - m[2][2] = c2 * c3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c1 * c3 - s1 * s2 * s3 + m[1, 0] = c3 * s1 + c1 * s2 * s3 + m[2, 0] =-c2 * s3 + m[3, 0] = 0 + m[0, 1] =-c2 * s1 + m[1, 1] = c1 * c2 + m[2, 1] = s2 + m[3, 1] = 0 + m[0, 2] = c1 * s3 + c3 * s1 * s2 + m[1, 2] = s1 * s3 - c1 * c3 * s2 + m[2, 2] = c2 * c3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -1181,32 +1181,32 @@ matrix4_from_yaw_pitch_roll_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix4f32 cb := math.cos(roll) sb := math.sin(roll) - m[0][0] = ch * cb + sh * sp * sb - m[0][1] = sb * cp - m[0][2] = -sh * cb + ch * sp * sb - m[0][3] = 0 - m[1][0] = -ch * sb + sh * sp * cb - m[1][1] = cb * cp - m[1][2] = sb * sh + ch * sp * cb - m[1][3] = 0 - m[2][0] = sh * cp - m[2][1] = -sp - m[2][2] = ch * cp - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = ch * cb + sh * sp * sb + m[1, 0] = sb * cp + m[2, 0] = -sh * cb + ch * sp * sb + m[3, 0] = 0 + m[0, 1] = -ch * sb + sh * sp * cb + m[1, 1] = cb * cp + m[2, 1] = sb * sh + ch * sp * cb + m[3, 1] = 0 + m[0, 2] = sh * cp + m[1, 2] = -sp + m[2, 2] = ch * cp + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return m } euler_angles_xyz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(m[2][1], m[2][2]) - C2 := math.sqrt(m[0][0]*m[0][0] + m[1][0]*m[1][0]) - T2 := math.atan2(-m[2][0], C2) + T1 := math.atan2(m[1, 2], m[2, 2]) + C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 1]*m[0, 1]) + T2 := math.atan2(-m[0, 2], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[0][2] - C1*m[0][1], C1*m[1][1] - S1*m[1][2]) + T3 := math.atan2(S1*m[2, 0] - C1*m[1, 0], C1*m[1, 1] - S1*m[2, 1]) t1 = -T1 t2 = -T2 t3 = -T3 @@ -1214,12 +1214,12 @@ euler_angles_xyz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { } euler_angles_yxz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(m[2][0], m[2][2]) - C2 := math.sqrt(m[0][1]*m[0][1] + m[1][1]*m[1][1]) - T2 := math.atan2(-m[2][1], C2) + T1 := math.atan2(m[0, 2], m[2, 2]) + C2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 1]*m[1, 1]) + T2 := math.atan2(-m[1, 2], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[1][2] - C1*m[1][0], C1*m[0][0] - S1*m[0][2]) + T3 := math.atan2(S1*m[2, 1] - C1*m[0, 1], C1*m[0, 0] - S1*m[2, 0]) t1 = T1 t2 = T2 t3 = T3 @@ -1227,12 +1227,12 @@ euler_angles_yxz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { } euler_angles_xzx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(m[0][2], m[0][1]) - S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]) - T2 := math.atan2(S2, m[0][0]) + T1 := math.atan2(m[2, 0], m[1, 0]) + S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2]) + T2 := math.atan2(S2, m[0, 0]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[1][2] - S1*m[1][1], C1*m[2][2] - S1*m[2][1]) + T3 := math.atan2(C1*m[2, 1] - S1*m[1, 1], C1*m[2, 2] - S1*m[1, 2]) t1 = T1 t2 = T2 t3 = T3 @@ -1240,12 +1240,12 @@ euler_angles_xzx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { } euler_angles_xyx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(m[0][1], -m[0][2]) - S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]) - T2 := math.atan2(S2, m[0][0]) + T1 := math.atan2(m[1, 0], -m[2, 0]) + S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2]) + T2 := math.atan2(S2, m[0, 0]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(-C1*m[2][1] - S1*m[2][2], C1*m[1][1] + S1*m[1][2]) + T3 := math.atan2(-C1*m[1, 2] - S1*m[2, 2], C1*m[1, 1] + S1*m[2, 1]) t1 = T1 t2 = T2 t3 = T3 @@ -1253,12 +1253,12 @@ euler_angles_xyx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { } euler_angles_yxy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(m[1][0], m[1][2]) - S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]) - T2 := math.atan2(S2, m[1][1]) + T1 := math.atan2(m[0, 1], m[2, 1]) + S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2]) + T2 := math.atan2(S2, m[1, 1]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[2][0] - S1*m[2][2], C1*m[0][0] - S1*m[0][2]) + T3 := math.atan2(C1*m[0, 2] - S1*m[2, 2], C1*m[0, 0] - S1*m[2, 0]) t1 = T1 t2 = T2 t3 = T3 @@ -1266,24 +1266,24 @@ euler_angles_yxy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { } euler_angles_yzy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(m[1][2], -m[1][0]) - S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]) - T2 := math.atan2(S2, m[1][1]) + T1 := math.atan2(m[2, 1], -m[0, 1]) + S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2]) + T2 := math.atan2(S2, m[1, 1]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(-S1*m[0][0] - C1*m[0][2], S1*m[2][0] + C1*m[2][2]) + T3 := math.atan2(-S1*m[0, 0] - C1*m[2, 0], S1*m[0, 2] + C1*m[2, 2]) t1 = T1 t2 = T2 t3 = T3 return } euler_angles_zyz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(m[2][1], m[2][0]) - S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]) - T2 := math.atan2(S2, m[2][2]) + T1 := math.atan2(m[1, 2], m[0, 2]) + S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1]) + T2 := math.atan2(S2, m[2, 2]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[0][1] - S1*m[0][0], C1*m[1][1] - S1*m[1][0]) + T3 := math.atan2(C1*m[1, 0] - S1*m[0, 0], C1*m[1, 1] - S1*m[0, 1]) t1 = T1 t2 = T2 t3 = T3 @@ -1291,12 +1291,12 @@ euler_angles_zyz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { } euler_angles_zxz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(m[2][0], -m[2][1]) - S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]) - T2 := math.atan2(S2, m[2][2]) + T1 := math.atan2(m[0, 2], -m[1, 2]) + S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1]) + T2 := math.atan2(S2, m[2, 2]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(-C1*m[1][0] - S1*m[1][1], C1*m[0][0] + S1*m[0][1]) + T3 := math.atan2(-C1*m[0, 1] - S1*m[1, 1], C1*m[0, 0] + S1*m[1, 0]) t1 = T1 t2 = T2 t3 = T3 @@ -1304,12 +1304,12 @@ euler_angles_zxz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { } euler_angles_xzy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(m[1][2], m[1][1]) - C2 := math.sqrt(m[0][0]*m[0][0] + m[2][0]*m[2][0]) - T2 := math.atan2(-m[1][0], C2) + T1 := math.atan2(m[2, 1], m[1, 1]) + C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 2]*m[0, 2]) + T2 := math.atan2(-m[0, 1], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[0][1] - C1*m[0][2], C1*m[2][2] - S1*m[2][1]) + T3 := math.atan2(S1*m[1, 0] - C1*m[2, 0], C1*m[2, 2] - S1*m[1, 2]) t1 = T1 t2 = T2 t3 = T3 @@ -1317,12 +1317,12 @@ euler_angles_xzy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { } euler_angles_yzx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(-m[0][2], m[0][0]) - C2 := math.sqrt(m[1][1]*m[1][1] + m[2][1]*m[2][1]) - T2 := math.atan2(m[0][1], C2) + T1 := math.atan2(-m[2, 0], m[0, 0]) + C2 := math.sqrt(m[1, 1]*m[1, 1] + m[1, 2]*m[1, 2]) + T2 := math.atan2(m[1, 0], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[1][0] + C1*m[1][2], S1*m[2][0] + C1*m[2][2]) + T3 := math.atan2(S1*m[0, 1] + C1*m[2, 1], S1*m[0, 2] + C1*m[2, 2]) t1 = T1 t2 = T2 t3 = T3 @@ -1330,12 +1330,12 @@ euler_angles_yzx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { } euler_angles_zyx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(m[0][1], m[0][0]) - C2 := math.sqrt(m[1][2]*m[1][2] + m[2][2]*m[2][2]) - T2 := math.atan2(-m[0][2], C2) + T1 := math.atan2(m[1, 0], m[0, 0]) + C2 := math.sqrt(m[2, 1]*m[2, 1] + m[2, 2]*m[2, 2]) + T2 := math.atan2(-m[2, 0], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[2][0] - C1*m[2][1], C1*m[1][1] - S1*m[1][0]) + T3 := math.atan2(S1*m[0, 2] - C1*m[1, 2], C1*m[1, 1] - S1*m[0, 1]) t1 = T1 t2 = T2 t3 = T3 @@ -1343,12 +1343,12 @@ euler_angles_zyx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { } euler_angles_zxy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) { - T1 := math.atan2(-m[1][0], m[1][1]) - C2 := math.sqrt(m[0][2]*m[0][2] + m[2][2]*m[2][2]) - T2 := math.atan2(m[1][2], C2) + T1 := math.atan2(-m[0, 1], m[1, 1]) + C2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 2]*m[2, 2]) + T2 := math.atan2(m[2, 1], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[2][0] + S1*m[2][1], C1*m[0][0] + S1*m[0][1]) + T3 := math.atan2(C1*m[0, 2] + S1*m[1, 2], C1*m[0, 0] + S1*m[1, 0]) t1 = T1 t2 = T2 t3 = T3 diff --git a/core/math/linalg/specific_euler_angles_f64.odin b/core/math/linalg/specific_euler_angles_f64.odin index efaddd651..2f8f758b0 100644 --- a/core/math/linalg/specific_euler_angles_f64.odin +++ b/core/math/linalg/specific_euler_angles_f64.odin @@ -212,29 +212,29 @@ euler_angles_zxy_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f matrix3_from_euler_angle_x_f64 :: proc(angle_x: f64) -> (m: Matrix3f64) { cos_x, sin_x := math.cos(angle_x), math.sin(angle_x) - m[0][0] = 1 - m[1][1] = +cos_x - m[2][1] = +sin_x - m[1][2] = -sin_x - m[2][2] = +cos_x + m[0, 0] = 1 + m[1, 1] = +cos_x + m[1, 2] = +sin_x + m[2, 1] = -sin_x + m[2, 2] = +cos_x return } matrix3_from_euler_angle_y_f64 :: proc(angle_y: f64) -> (m: Matrix3f64) { cos_y, sin_y := math.cos(angle_y), math.sin(angle_y) - m[0][0] = +cos_y - m[2][0] = -sin_y - m[1][1] = 1 - m[0][2] = +sin_y - m[2][2] = +cos_y + m[0, 0] = +cos_y + m[0, 2] = -sin_y + m[1, 1] = 1 + m[2, 0] = +sin_y + m[2, 2] = +cos_y return } matrix3_from_euler_angle_z_f64 :: proc(angle_z: f64) -> (m: Matrix3f64) { cos_z, sin_z := math.cos(angle_z), math.sin(angle_z) - m[0][0] = +cos_z - m[1][0] = +sin_z - m[1][1] = +cos_z - m[0][1] = -sin_z - m[2][2] = 1 + m[0, 0] = +cos_z + m[0, 1] = +sin_z + m[1, 1] = +cos_z + m[1, 0] = -sin_z + m[2, 2] = 1 return } @@ -242,31 +242,31 @@ matrix3_from_euler_angle_z_f64 :: proc(angle_z: f64) -> (m: Matrix3f64) { matrix3_from_derived_euler_angle_x_f64 :: proc(angle_x: f64, angular_velocity_x: f64) -> (m: Matrix3f64) { cos_x := math.cos(angle_x) * angular_velocity_x sin_x := math.sin(angle_x) * angular_velocity_x - m[0][0] = 1 - m[1][1] = +cos_x - m[2][1] = +sin_x - m[1][2] = -sin_x - m[2][2] = +cos_x + m[0, 0] = 1 + m[1, 1] = +cos_x + m[1, 2] = +sin_x + m[2, 1] = -sin_x + m[2, 2] = +cos_x return } matrix3_from_derived_euler_angle_y_f64 :: proc(angle_y: f64, angular_velocity_y: f64) -> (m: Matrix3f64) { cos_y := math.cos(angle_y) * angular_velocity_y sin_y := math.sin(angle_y) * angular_velocity_y - m[0][0] = +cos_y - m[2][0] = -sin_y - m[1][1] = 1 - m[0][2] = +sin_y - m[2][2] = +cos_y + m[0, 0] = +cos_y + m[0, 2] = -sin_y + m[1, 1] = 1 + m[2, 0] = +sin_y + m[2, 2] = +cos_y return } matrix3_from_derived_euler_angle_z_f64 :: proc(angle_z: f64, angular_velocity_z: f64) -> (m: Matrix3f64) { cos_z := math.cos(angle_z) * angular_velocity_z sin_z := math.sin(angle_z) * angular_velocity_z - m[0][0] = +cos_z - m[1][0] = +sin_z - m[1][1] = +cos_z - m[0][1] = -sin_z - m[2][2] = 1 + m[0, 0] = +cos_z + m[0, 1] = +sin_z + m[1, 1] = +cos_z + m[1, 0] = -sin_z + m[2, 2] = 1 return } @@ -274,14 +274,14 @@ matrix3_from_derived_euler_angle_z_f64 :: proc(angle_z: f64, angular_velocity_z: matrix3_from_euler_angles_xy_f64 :: proc(angle_x, angle_y: f64) -> (m: Matrix3f64) { cos_x, sin_x := math.cos(angle_x), math.sin(angle_x) cos_y, sin_y := math.cos(angle_y), math.sin(angle_y) - m[0][0] = cos_y - m[1][0] = -sin_x * - sin_y - m[2][0] = -cos_x * - sin_y - m[1][1] = cos_x - m[2][1] = sin_x - m[0][2] = sin_y - m[1][2] = -sin_x * cos_y - m[2][2] = cos_x * cos_y + m[0, 0] = cos_y + m[0, 1] = -sin_x * - sin_y + m[0, 2] = -cos_x * - sin_y + m[1, 1] = cos_x + m[1, 2] = sin_x + m[2, 0] = sin_y + m[2, 1] = -sin_x * cos_y + m[2, 2] = cos_x * cos_y return } @@ -289,14 +289,14 @@ matrix3_from_euler_angles_xy_f64 :: proc(angle_x, angle_y: f64) -> (m: Matrix3f6 matrix3_from_euler_angles_yx_f64 :: proc(angle_y, angle_x: f64) -> (m: Matrix3f64) { cos_x, sin_x := math.cos(angle_x), math.sin(angle_x) cos_y, sin_y := math.cos(angle_y), math.sin(angle_y) - m[0][0] = cos_y - m[2][0] = -sin_y - m[0][1] = sin_y*sin_x - m[1][1] = cos_x - m[2][1] = cos_y*sin_x - m[0][2] = sin_y*cos_x - m[1][2] = -sin_x - m[2][2] = cos_y*cos_x + m[0, 0] = cos_y + m[0, 2] = -sin_y + m[1, 0] = sin_y*sin_x + m[1, 1] = cos_x + m[1, 2] = cos_y*sin_x + m[2, 0] = sin_y*cos_x + m[2, 1] = -sin_x + m[2, 2] = cos_y*cos_x return } @@ -322,15 +322,15 @@ matrix3_from_euler_angles_xyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) { s2 := math.sin(-t2) s3 := math.sin(-t3) - m[0][0] = c2 * c3 - m[0][1] =-c1 * s3 + s1 * s2 * c3 - m[0][2] = s1 * s3 + c1 * s2 * c3 - m[1][0] = c2 * s3 - m[1][1] = c1 * c3 + s1 * s2 * s3 - m[1][2] =-s1 * c3 + c1 * s2 * s3 - m[2][0] =-s2 - m[2][1] = s1 * c2 - m[2][2] = c1 * c2 + m[0, 0] = c2 * c3 + m[1, 0] =-c1 * s3 + s1 * s2 * c3 + m[2, 0] = s1 * s3 + c1 * s2 * c3 + m[0, 1] = c2 * s3 + m[1, 1] = c1 * c3 + s1 * s2 * s3 + m[2, 1] =-s1 * c3 + c1 * s2 * s3 + m[0, 2] =-s2 + m[1, 2] = s1 * c2 + m[2, 2] = c1 * c2 return } @@ -342,15 +342,15 @@ matrix3_from_euler_angles_yxz_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix3f cb := math.cos(roll) sb := math.sin(roll) - m[0][0] = ch * cb + sh * sp * sb - m[0][1] = sb * cp - m[0][2] = -sh * cb + ch * sp * sb - m[1][0] = -ch * sb + sh * sp * cb - m[1][1] = cb * cp - m[1][2] = sb * sh + ch * sp * cb - m[2][0] = sh * cp - m[2][1] = -sp - m[2][2] = ch * cp + m[0, 0] = ch * cb + sh * sp * sb + m[1, 0] = sb * cp + m[2, 0] = -sh * cb + ch * sp * sb + m[0, 1] = -ch * sb + sh * sp * cb + m[1, 1] = cb * cp + m[2, 1] = sb * sh + ch * sp * cb + m[0, 2] = sh * cp + m[1, 2] = -sp + m[2, 2] = ch * cp return } @@ -362,15 +362,15 @@ matrix3_from_euler_angles_xzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c2 - m[0][1] = c1 * s2 - m[0][2] = s1 * s2 - m[1][0] =-c3 * s2 - m[1][1] = c1 * c2 * c3 - s1 * s3 - m[1][2] = c1 * s3 + c2 * c3 * s1 - m[2][0] = s2 * s3 - m[2][1] =-c3 * s1 - c1 * c2 * s3 - m[2][2] = c1 * c3 - c2 * s1 * s3 + m[0, 0] = c2 + m[1, 0] = c1 * s2 + m[2, 0] = s1 * s2 + m[0, 1] =-c3 * s2 + m[1, 1] = c1 * c2 * c3 - s1 * s3 + m[2, 1] = c1 * s3 + c2 * c3 * s1 + m[0, 2] = s2 * s3 + m[1, 2] =-c3 * s1 - c1 * c2 * s3 + m[2, 2] = c1 * c3 - c2 * s1 * s3 return } @@ -382,15 +382,15 @@ matrix3_from_euler_angles_xyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c2 - m[0][1] = s1 * s2 - m[0][2] =-c1 * s2 - m[1][0] = s2 * s3 - m[1][1] = c1 * c3 - c2 * s1 * s3 - m[1][2] = c3 * s1 + c1 * c2 * s3 - m[2][0] = c3 * s2 - m[2][1] =-c1 * s3 - c2 * c3 * s1 - m[2][2] = c1 * c2 * c3 - s1 * s3 + m[0, 0] = c2 + m[1, 0] = s1 * s2 + m[2, 0] =-c1 * s2 + m[0, 1] = s2 * s3 + m[1, 1] = c1 * c3 - c2 * s1 * s3 + m[2, 1] = c3 * s1 + c1 * c2 * s3 + m[0, 2] = c3 * s2 + m[1, 2] =-c1 * s3 - c2 * c3 * s1 + m[2, 2] = c1 * c2 * c3 - s1 * s3 return } @@ -402,15 +402,15 @@ matrix3_from_euler_angles_yxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c3 - c2 * s1 * s3 - m[0][1] = s2* s3 - m[0][2] =-c3 * s1 - c1 * c2 * s3 - m[1][0] = s1 * s2 - m[1][1] = c2 - m[1][2] = c1 * s2 - m[2][0] = c1 * s3 + c2 * c3 * s1 - m[2][1] =-c3 * s2 - m[2][2] = c1 * c2 * c3 - s1 * s3 + m[0, 0] = c1 * c3 - c2 * s1 * s3 + m[1, 0] = s2* s3 + m[2, 0] =-c3 * s1 - c1 * c2 * s3 + m[0, 1] = s1 * s2 + m[1, 1] = c2 + m[2, 1] = c1 * s2 + m[0, 2] = c1 * s3 + c2 * c3 * s1 + m[1, 2] =-c3 * s2 + m[2, 2] = c1 * c2 * c3 - s1 * s3 return } @@ -422,15 +422,15 @@ matrix3_from_euler_angles_yzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 * c3 - s1 * s3 - m[0][1] = c3 * s2 - m[0][2] =-c1 * s3 - c2 * c3 * s1 - m[1][0] =-c1 * s2 - m[1][1] = c2 - m[1][2] = s1 * s2 - m[2][0] = c3 * s1 + c1 * c2 * s3 - m[2][1] = s2 * s3 - m[2][2] = c1 * c3 - c2 * s1 * s3 + m[0, 0] = c1 * c2 * c3 - s1 * s3 + m[1, 0] = c3 * s2 + m[2, 0] =-c1 * s3 - c2 * c3 * s1 + m[0, 1] =-c1 * s2 + m[1, 1] = c2 + m[2, 1] = s1 * s2 + m[0, 2] = c3 * s1 + c1 * c2 * s3 + m[1, 2] = s2 * s3 + m[2, 2] = c1 * c3 - c2 * s1 * s3 return } @@ -442,15 +442,15 @@ matrix3_from_euler_angles_zyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 * c3 - s1 * s3 - m[0][1] = c1 * s3 + c2 * c3 * s1 - m[0][2] =-c3 * s2 - m[1][0] =-c3 * s1 - c1 * c2 * s3 - m[1][1] = c1 * c3 - c2 * s1 * s3 - m[1][2] = s2 * s3 - m[2][0] = c1 * s2 - m[2][1] = s1 * s2 - m[2][2] = c2 + m[0, 0] = c1 * c2 * c3 - s1 * s3 + m[1, 0] = c1 * s3 + c2 * c3 * s1 + m[2, 0] =-c3 * s2 + m[0, 1] =-c3 * s1 - c1 * c2 * s3 + m[1, 1] = c1 * c3 - c2 * s1 * s3 + m[2, 1] = s2 * s3 + m[0, 2] = c1 * s2 + m[1, 2] = s1 * s2 + m[2, 2] = c2 return } @@ -462,15 +462,15 @@ matrix3_from_euler_angles_zxz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c3 - c2 * s1 * s3 - m[0][1] = c3 * s1 + c1 * c2 * s3 - m[0][2] = s2 *s3 - m[1][0] =-c1 * s3 - c2 * c3 * s1 - m[1][1] = c1 * c2 * c3 - s1 * s3 - m[1][2] = c3 * s2 - m[2][0] = s1 * s2 - m[2][1] =-c1 * s2 - m[2][2] = c2 + m[0, 0] = c1 * c3 - c2 * s1 * s3 + m[1, 0] = c3 * s1 + c1 * c2 * s3 + m[2, 0] = s2 *s3 + m[0, 1] =-c1 * s3 - c2 * c3 * s1 + m[1, 1] = c1 * c2 * c3 - s1 * s3 + m[2, 1] = c3 * s2 + m[0, 2] = s1 * s2 + m[1, 2] =-c1 * s2 + m[2, 2] = c2 return } @@ -483,15 +483,15 @@ matrix3_from_euler_angles_xzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c2 * c3 - m[0][1] = s1 * s3 + c1 * c3 * s2 - m[0][2] = c3 * s1 * s2 - c1 * s3 - m[1][0] =-s2 - m[1][1] = c1 * c2 - m[1][2] = c2 * s1 - m[2][0] = c2 * s3 - m[2][1] = c1 * s2 * s3 - c3 * s1 - m[2][2] = c1 * c3 + s1 * s2 *s3 + m[0, 0] = c2 * c3 + m[1, 0] = s1 * s3 + c1 * c3 * s2 + m[2, 0] = c3 * s1 * s2 - c1 * s3 + m[0, 1] =-s2 + m[1, 1] = c1 * c2 + m[2, 1] = c2 * s1 + m[0, 2] = c2 * s3 + m[1, 2] = c1 * s2 * s3 - c3 * s1 + m[2, 2] = c1 * c3 + s1 * s2 *s3 return } @@ -503,15 +503,15 @@ matrix3_from_euler_angles_yzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 - m[0][1] = s2 - m[0][2] =-c2 * s1 - m[1][0] = s1 * s3 - c1 * c3 * s2 - m[1][1] = c2 * c3 - m[1][2] = c1 * s3 + c3 * s1 * s2 - m[2][0] = c3 * s1 + c1 * s2 * s3 - m[2][1] =-c2 * s3 - m[2][2] = c1 * c3 - s1 * s2 * s3 + m[0, 0] = c1 * c2 + m[1, 0] = s2 + m[2, 0] =-c2 * s1 + m[0, 1] = s1 * s3 - c1 * c3 * s2 + m[1, 1] = c2 * c3 + m[2, 1] = c1 * s3 + c3 * s1 * s2 + m[0, 2] = c3 * s1 + c1 * s2 * s3 + m[1, 2] =-c2 * s3 + m[2, 2] = c1 * c3 - s1 * s2 * s3 return } @@ -523,15 +523,15 @@ matrix3_from_euler_angles_zyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 - m[0][1] = c2 * s1 - m[0][2] =-s2 - m[1][0] = c1 * s2 * s3 - c3 * s1 - m[1][1] = c1 * c3 + s1 * s2 * s3 - m[1][2] = c2 * s3 - m[2][0] = s1 * s3 + c1 * c3 * s2 - m[2][1] = c3 * s1 * s2 - c1 * s3 - m[2][2] = c2 * c3 + m[0, 0] = c1 * c2 + m[1, 0] = c2 * s1 + m[2, 0] =-s2 + m[0, 1] = c1 * s2 * s3 - c3 * s1 + m[1, 1] = c1 * c3 + s1 * s2 * s3 + m[2, 1] = c2 * s3 + m[0, 2] = s1 * s3 + c1 * c3 * s2 + m[1, 2] = c3 * s1 * s2 - c1 * s3 + m[2, 2] = c2 * c3 return } @@ -543,15 +543,15 @@ matrix3_from_euler_angles_zxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c3 - s1 * s2 * s3 - m[0][1] = c3 * s1 + c1 * s2 * s3 - m[0][2] =-c2 * s3 - m[1][0] =-c2 * s1 - m[1][1] = c1 * c2 - m[1][2] = s2 - m[2][0] = c1 * s3 + c3 * s1 * s2 - m[2][1] = s1 * s3 - c1 * c3 * s2 - m[2][2] = c2 * c3 + m[0, 0] = c1 * c3 - s1 * s2 * s3 + m[1, 0] = c3 * s1 + c1 * s2 * s3 + m[2, 0] =-c2 * s3 + m[0, 1] =-c2 * s1 + m[1, 1] = c1 * c2 + m[2, 1] = s2 + m[0, 2] = c1 * s3 + c3 * s1 * s2 + m[1, 2] = s1 * s3 - c1 * c3 * s2 + m[2, 2] = c2 * c3 return } @@ -564,25 +564,25 @@ matrix3_from_yaw_pitch_roll_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix3f64 cb := math.cos(roll) sb := math.sin(roll) - m[0][0] = ch * cb + sh * sp * sb - m[0][1] = sb * cp - m[0][2] = -sh * cb + ch * sp * sb - m[1][0] = -ch * sb + sh * sp * cb - m[1][1] = cb * cp - m[1][2] = sb * sh + ch * sp * cb - m[2][0] = sh * cp - m[2][1] = -sp - m[2][2] = ch * cp + m[0, 0] = ch * cb + sh * sp * sb + m[1, 0] = sb * cp + m[2, 0] = -sh * cb + ch * sp * sb + m[0, 1] = -ch * sb + sh * sp * cb + m[1, 1] = cb * cp + m[2, 1] = sb * sh + ch * sp * cb + m[0, 2] = sh * cp + m[1, 2] = -sp + m[2, 2] = ch * cp return m } euler_angles_xyz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(m[2][1], m[2][2]) - C2 := math.sqrt(m[0][0]*m[0][0] + m[1][0]*m[1][0]) - T2 := math.atan2(-m[2][0], C2) + T1 := math.atan2(m[1, 2], m[2, 2]) + C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 1]*m[0, 1]) + T2 := math.atan2(-m[0, 2], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[0][2] - C1*m[0][1], C1*m[1][1] - S1*m[1][2]) + T3 := math.atan2(S1*m[2, 0] - C1*m[1, 0], C1*m[1, 1] - S1*m[2, 1]) t1 = -T1 t2 = -T2 t3 = -T3 @@ -590,12 +590,12 @@ euler_angles_xyz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { } euler_angles_yxz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(m[2][0], m[2][2]) - C2 := math.sqrt(m[0][1]*m[0][1] + m[1][1]*m[1][1]) - T2 := math.atan2(-m[2][1], C2) + T1 := math.atan2(m[0, 2], m[2, 2]) + C2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 1]*m[1, 1]) + T2 := math.atan2(-m[1, 2], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[1][2] - C1*m[1][0], C1*m[0][0] - S1*m[0][2]) + T3 := math.atan2(S1*m[2, 1] - C1*m[0, 1], C1*m[0, 0] - S1*m[2, 0]) t1 = T1 t2 = T2 t3 = T3 @@ -603,12 +603,12 @@ euler_angles_yxz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { } euler_angles_xzx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(m[0][2], m[0][1]) - S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]) - T2 := math.atan2(S2, m[0][0]) + T1 := math.atan2(m[2, 0], m[1, 0]) + S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2]) + T2 := math.atan2(S2, m[0, 0]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[1][2] - S1*m[1][1], C1*m[2][2] - S1*m[2][1]) + T3 := math.atan2(C1*m[2, 1] - S1*m[1, 1], C1*m[2, 2] - S1*m[1, 2]) t1 = T1 t2 = T2 t3 = T3 @@ -616,12 +616,12 @@ euler_angles_xzx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { } euler_angles_xyx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(m[0][1], -m[0][2]) - S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]) - T2 := math.atan2(S2, m[0][0]) + T1 := math.atan2(m[1, 0], -m[2, 0]) + S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2]) + T2 := math.atan2(S2, m[0, 0]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(-C1*m[2][1] - S1*m[2][2], C1*m[1][1] + S1*m[1][2]) + T3 := math.atan2(-C1*m[1, 2] - S1*m[2, 2], C1*m[1, 1] + S1*m[2, 1]) t1 = T1 t2 = T2 t3 = T3 @@ -629,12 +629,12 @@ euler_angles_xyx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { } euler_angles_yxy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(m[1][0], m[1][2]) - S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]) - T2 := math.atan2(S2, m[1][1]) + T1 := math.atan2(m[0, 1], m[2, 1]) + S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2]) + T2 := math.atan2(S2, m[1, 1]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[2][0] - S1*m[2][2], C1*m[0][0] - S1*m[0][2]) + T3 := math.atan2(C1*m[0, 2] - S1*m[2, 2], C1*m[0, 0] - S1*m[2, 0]) t1 = T1 t2 = T2 t3 = T3 @@ -642,24 +642,24 @@ euler_angles_yxy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { } euler_angles_yzy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(m[1][2], -m[1][0]) - S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]) - T2 := math.atan2(S2, m[1][1]) + T1 := math.atan2(m[2, 1], -m[0, 1]) + S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2]) + T2 := math.atan2(S2, m[1, 1]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(-S1*m[0][0] - C1*m[0][2], S1*m[2][0] + C1*m[2][2]) + T3 := math.atan2(-S1*m[0, 0] - C1*m[2, 0], S1*m[0, 2] + C1*m[2, 2]) t1 = T1 t2 = T2 t3 = T3 return } euler_angles_zyz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(m[2][1], m[2][0]) - S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]) - T2 := math.atan2(S2, m[2][2]) + T1 := math.atan2(m[1, 2], m[0, 2]) + S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1]) + T2 := math.atan2(S2, m[2, 2]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[0][1] - S1*m[0][0], C1*m[1][1] - S1*m[1][0]) + T3 := math.atan2(C1*m[1, 0] - S1*m[0, 0], C1*m[1, 1] - S1*m[0, 1]) t1 = T1 t2 = T2 t3 = T3 @@ -667,12 +667,12 @@ euler_angles_zyz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { } euler_angles_zxz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(m[2][0], -m[2][1]) - S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]) - T2 := math.atan2(S2, m[2][2]) + T1 := math.atan2(m[0, 2], -m[1, 2]) + S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1]) + T2 := math.atan2(S2, m[2, 2]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(-C1*m[1][0] - S1*m[1][1], C1*m[0][0] + S1*m[0][1]) + T3 := math.atan2(-C1*m[0, 1] - S1*m[1, 1], C1*m[0, 0] + S1*m[1, 0]) t1 = T1 t2 = T2 t3 = T3 @@ -680,12 +680,12 @@ euler_angles_zxz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { } euler_angles_xzy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(m[1][2], m[1][1]) - C2 := math.sqrt(m[0][0]*m[0][0] + m[2][0]*m[2][0]) - T2 := math.atan2(-m[1][0], C2) + T1 := math.atan2(m[2, 1], m[1, 1]) + C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 2]*m[0, 2]) + T2 := math.atan2(-m[0, 1], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[0][1] - C1*m[0][2], C1*m[2][2] - S1*m[2][1]) + T3 := math.atan2(S1*m[1, 0] - C1*m[2, 0], C1*m[2, 2] - S1*m[1, 2]) t1 = T1 t2 = T2 t3 = T3 @@ -693,12 +693,12 @@ euler_angles_xzy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { } euler_angles_yzx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(-m[0][2], m[0][0]) - C2 := math.sqrt(m[1][1]*m[1][1] + m[2][1]*m[2][1]) - T2 := math.atan2(m[0][1], C2) + T1 := math.atan2(-m[2, 0], m[0, 0]) + C2 := math.sqrt(m[1, 1]*m[1, 1] + m[1, 2]*m[1, 2]) + T2 := math.atan2(m[1, 0], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[1][0] + C1*m[1][2], S1*m[2][0] + C1*m[2][2]) + T3 := math.atan2(S1*m[0, 1] + C1*m[2, 1], S1*m[0, 2] + C1*m[2, 2]) t1 = T1 t2 = T2 t3 = T3 @@ -706,12 +706,12 @@ euler_angles_yzx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { } euler_angles_zyx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(m[0][1], m[0][0]) - C2 := math.sqrt(m[1][2]*m[1][2] + m[2][2]*m[2][2]) - T2 := math.atan2(-m[0][2], C2) + T1 := math.atan2(m[1, 0], m[0, 0]) + C2 := math.sqrt(m[2, 1]*m[2, 1] + m[2, 2]*m[2, 2]) + T2 := math.atan2(-m[2, 0], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[2][0] - C1*m[2][1], C1*m[1][1] - S1*m[1][0]) + T3 := math.atan2(S1*m[0, 2] - C1*m[1, 2], C1*m[1, 1] - S1*m[0, 1]) t1 = T1 t2 = T2 t3 = T3 @@ -719,12 +719,12 @@ euler_angles_zyx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { } euler_angles_zxy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(-m[1][0], m[1][1]) - C2 := math.sqrt(m[0][2]*m[0][2] + m[2][2]*m[2][2]) - T2 := math.atan2(m[1][2], C2) + T1 := math.atan2(-m[0, 1], m[1, 1]) + C2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 2]*m[2, 2]) + T2 := math.atan2(m[2, 1], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[2][0] + S1*m[2][1], C1*m[0][0] + S1*m[0][1]) + T3 := math.atan2(C1*m[0, 2] + S1*m[1, 2], C1*m[0, 0] + S1*m[1, 0]) t1 = T1 t2 = T2 t3 = T3 @@ -737,32 +737,32 @@ euler_angles_zxy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) { matrix4_from_euler_angle_x_f64 :: proc(angle_x: f64) -> (m: Matrix4f64) { cos_x, sin_x := math.cos(angle_x), math.sin(angle_x) - m[0][0] = 1 - m[1][1] = +cos_x - m[2][1] = +sin_x - m[1][2] = -sin_x - m[2][2] = +cos_x - m[3][3] = 1 + m[0, 0] = 1 + m[1, 1] = +cos_x + m[1, 2] = +sin_x + m[2, 1] = -sin_x + m[2, 2] = +cos_x + m[3, 3] = 1 return } matrix4_from_euler_angle_y_f64 :: proc(angle_y: f64) -> (m: Matrix4f64) { cos_y, sin_y := math.cos(angle_y), math.sin(angle_y) - m[0][0] = +cos_y - m[2][0] = -sin_y - m[1][1] = 1 - m[0][2] = +sin_y - m[2][2] = +cos_y - m[3][3] = 1 + m[0, 0] = +cos_y + m[0, 2] = -sin_y + m[1, 1] = 1 + m[2, 0] = +sin_y + m[2, 2] = +cos_y + m[3, 3] = 1 return } matrix4_from_euler_angle_z_f64 :: proc(angle_z: f64) -> (m: Matrix4f64) { cos_z, sin_z := math.cos(angle_z), math.sin(angle_z) - m[0][0] = +cos_z - m[1][0] = +sin_z - m[1][1] = +cos_z - m[0][1] = -sin_z - m[2][2] = 1 - m[3][3] = 1 + m[0, 0] = +cos_z + m[0, 1] = +sin_z + m[1, 1] = +cos_z + m[1, 0] = -sin_z + m[2, 2] = 1 + m[3, 3] = 1 return } @@ -770,34 +770,34 @@ matrix4_from_euler_angle_z_f64 :: proc(angle_z: f64) -> (m: Matrix4f64) { matrix4_from_derived_euler_angle_x_f64 :: proc(angle_x: f64, angular_velocity_x: f64) -> (m: Matrix4f64) { cos_x := math.cos(angle_x) * angular_velocity_x sin_x := math.sin(angle_x) * angular_velocity_x - m[0][0] = 1 - m[1][1] = +cos_x - m[2][1] = +sin_x - m[1][2] = -sin_x - m[2][2] = +cos_x - m[3][3] = 1 + m[0, 0] = 1 + m[1, 1] = +cos_x + m[1, 2] = +sin_x + m[2, 1] = -sin_x + m[2, 2] = +cos_x + m[3, 3] = 1 return } matrix4_from_derived_euler_angle_y_f64 :: proc(angle_y: f64, angular_velocity_y: f64) -> (m: Matrix4f64) { cos_y := math.cos(angle_y) * angular_velocity_y sin_y := math.sin(angle_y) * angular_velocity_y - m[0][0] = +cos_y - m[2][0] = -sin_y - m[1][1] = 1 - m[0][2] = +sin_y - m[2][2] = +cos_y - m[3][3] = 1 + m[0, 0] = +cos_y + m[0, 2] = -sin_y + m[1, 1] = 1 + m[2, 0] = +sin_y + m[2, 2] = +cos_y + m[3, 3] = 1 return } matrix4_from_derived_euler_angle_z_f64 :: proc(angle_z: f64, angular_velocity_z: f64) -> (m: Matrix4f64) { cos_z := math.cos(angle_z) * angular_velocity_z sin_z := math.sin(angle_z) * angular_velocity_z - m[0][0] = +cos_z - m[1][0] = +sin_z - m[1][1] = +cos_z - m[0][1] = -sin_z - m[2][2] = 1 - m[3][3] = 1 + m[0, 0] = +cos_z + m[0, 1] = +sin_z + m[1, 1] = +cos_z + m[1, 0] = -sin_z + m[2, 2] = 1 + m[3, 3] = 1 return } @@ -805,15 +805,15 @@ matrix4_from_derived_euler_angle_z_f64 :: proc(angle_z: f64, angular_velocity_z: matrix4_from_euler_angles_xy_f64 :: proc(angle_x, angle_y: f64) -> (m: Matrix4f64) { cos_x, sin_x := math.cos(angle_x), math.sin(angle_x) cos_y, sin_y := math.cos(angle_y), math.sin(angle_y) - m[0][0] = cos_y - m[1][0] = -sin_x * - sin_y - m[2][0] = -cos_x * - sin_y - m[1][1] = cos_x - m[2][1] = sin_x - m[0][2] = sin_y - m[1][2] = -sin_x * cos_y - m[2][2] = cos_x * cos_y - m[3][3] = 1 + m[0, 0] = cos_y + m[0, 1] = -sin_x * - sin_y + m[0, 2] = -cos_x * - sin_y + m[1, 1] = cos_x + m[1, 2] = sin_x + m[2, 0] = sin_y + m[2, 1] = -sin_x * cos_y + m[2, 2] = cos_x * cos_y + m[3, 3] = 1 return } @@ -821,15 +821,15 @@ matrix4_from_euler_angles_xy_f64 :: proc(angle_x, angle_y: f64) -> (m: Matrix4f6 matrix4_from_euler_angles_yx_f64 :: proc(angle_y, angle_x: f64) -> (m: Matrix4f64) { cos_x, sin_x := math.cos(angle_x), math.sin(angle_x) cos_y, sin_y := math.cos(angle_y), math.sin(angle_y) - m[0][0] = cos_y - m[2][0] = -sin_y - m[0][1] = sin_y*sin_x - m[1][1] = cos_x - m[2][1] = cos_y*sin_x - m[0][2] = sin_y*cos_x - m[1][2] = -sin_x - m[2][2] = cos_y*cos_x - m[3][3] = 1 + m[0, 0] = cos_y + m[0, 2] = -sin_y + m[1, 0] = sin_y*sin_x + m[1, 1] = cos_x + m[1, 2] = cos_y*sin_x + m[2, 0] = sin_y*cos_x + m[2, 1] = -sin_x + m[2, 2] = cos_y*cos_x + m[3, 3] = 1 return } @@ -855,22 +855,22 @@ matrix4_from_euler_angles_xyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) { s2 := math.sin(-t2) s3 := math.sin(-t3) - m[0][0] = c2 * c3 - m[0][1] =-c1 * s3 + s1 * s2 * c3 - m[0][2] = s1 * s3 + c1 * s2 * c3 - m[0][3] = 0 - m[1][0] = c2 * s3 - m[1][1] = c1 * c3 + s1 * s2 * s3 - m[1][2] =-s1 * c3 + c1 * s2 * s3 - m[1][3] = 0 - m[2][0] =-s2 - m[2][1] = s1 * c2 - m[2][2] = c1 * c2 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c2 * c3 + m[1, 0] =-c1 * s3 + s1 * s2 * c3 + m[2, 0] = s1 * s3 + c1 * s2 * c3 + m[3, 0] = 0 + m[0, 1] = c2 * s3 + m[1, 1] = c1 * c3 + s1 * s2 * s3 + m[2, 1] =-s1 * c3 + c1 * s2 * s3 + m[3, 1] = 0 + m[0, 2] =-s2 + m[1, 2] = s1 * c2 + m[2, 2] = c1 * c2 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -882,22 +882,22 @@ matrix4_from_euler_angles_yxz_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix4f cb := math.cos(roll) sb := math.sin(roll) - m[0][0] = ch * cb + sh * sp * sb - m[0][1] = sb * cp - m[0][2] = -sh * cb + ch * sp * sb - m[0][3] = 0 - m[1][0] = -ch * sb + sh * sp * cb - m[1][1] = cb * cp - m[1][2] = sb * sh + ch * sp * cb - m[1][3] = 0 - m[2][0] = sh * cp - m[2][1] = -sp - m[2][2] = ch * cp - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = ch * cb + sh * sp * sb + m[1, 0] = sb * cp + m[2, 0] = -sh * cb + ch * sp * sb + m[3, 0] = 0 + m[0, 1] = -ch * sb + sh * sp * cb + m[1, 1] = cb * cp + m[2, 1] = sb * sh + ch * sp * cb + m[3, 1] = 0 + m[0, 2] = sh * cp + m[1, 2] = -sp + m[2, 2] = ch * cp + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -909,22 +909,22 @@ matrix4_from_euler_angles_xzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c2 - m[0][1] = c1 * s2 - m[0][2] = s1 * s2 - m[0][3] = 0 - m[1][0] =-c3 * s2 - m[1][1] = c1 * c2 * c3 - s1 * s3 - m[1][2] = c1 * s3 + c2 * c3 * s1 - m[1][3] = 0 - m[2][0] = s2 * s3 - m[2][1] =-c3 * s1 - c1 * c2 * s3 - m[2][2] = c1 * c3 - c2 * s1 * s3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c2 + m[1, 0] = c1 * s2 + m[2, 0] = s1 * s2 + m[3, 0] = 0 + m[0, 1] =-c3 * s2 + m[1, 1] = c1 * c2 * c3 - s1 * s3 + m[2, 1] = c1 * s3 + c2 * c3 * s1 + m[3, 1] = 0 + m[0, 2] = s2 * s3 + m[1, 2] =-c3 * s1 - c1 * c2 * s3 + m[2, 2] = c1 * c3 - c2 * s1 * s3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -936,22 +936,22 @@ matrix4_from_euler_angles_xyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c2 - m[0][1] = s1 * s2 - m[0][2] =-c1 * s2 - m[0][3] = 0 - m[1][0] = s2 * s3 - m[1][1] = c1 * c3 - c2 * s1 * s3 - m[1][2] = c3 * s1 + c1 * c2 * s3 - m[1][3] = 0 - m[2][0] = c3 * s2 - m[2][1] =-c1 * s3 - c2 * c3 * s1 - m[2][2] = c1 * c2 * c3 - s1 * s3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c2 + m[1, 0] = s1 * s2 + m[2, 0] =-c1 * s2 + m[3, 0] = 0 + m[0, 1] = s2 * s3 + m[1, 1] = c1 * c3 - c2 * s1 * s3 + m[2, 1] = c3 * s1 + c1 * c2 * s3 + m[3, 1] = 0 + m[0, 2] = c3 * s2 + m[1, 2] =-c1 * s3 - c2 * c3 * s1 + m[2, 2] = c1 * c2 * c3 - s1 * s3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -963,22 +963,22 @@ matrix4_from_euler_angles_yxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c3 - c2 * s1 * s3 - m[0][1] = s2* s3 - m[0][2] =-c3 * s1 - c1 * c2 * s3 - m[0][3] = 0 - m[1][0] = s1 * s2 - m[1][1] = c2 - m[1][2] = c1 * s2 - m[1][3] = 0 - m[2][0] = c1 * s3 + c2 * c3 * s1 - m[2][1] =-c3 * s2 - m[2][2] = c1 * c2 * c3 - s1 * s3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c1 * c3 - c2 * s1 * s3 + m[1, 0] = s2* s3 + m[2, 0] =-c3 * s1 - c1 * c2 * s3 + m[3, 0] = 0 + m[0, 1] = s1 * s2 + m[1, 1] = c2 + m[2, 1] = c1 * s2 + m[3, 1] = 0 + m[0, 2] = c1 * s3 + c2 * c3 * s1 + m[1, 2] =-c3 * s2 + m[2, 2] = c1 * c2 * c3 - s1 * s3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -990,22 +990,22 @@ matrix4_from_euler_angles_yzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 * c3 - s1 * s3 - m[0][1] = c3 * s2 - m[0][2] =-c1 * s3 - c2 * c3 * s1 - m[0][3] = 0 - m[1][0] =-c1 * s2 - m[1][1] = c2 - m[1][2] = s1 * s2 - m[1][3] = 0 - m[2][0] = c3 * s1 + c1 * c2 * s3 - m[2][1] = s2 * s3 - m[2][2] = c1 * c3 - c2 * s1 * s3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c1 * c2 * c3 - s1 * s3 + m[1, 0] = c3 * s2 + m[2, 0] =-c1 * s3 - c2 * c3 * s1 + m[3, 0] = 0 + m[0, 1] =-c1 * s2 + m[1, 1] = c2 + m[2, 1] = s1 * s2 + m[3, 1] = 0 + m[0, 2] = c3 * s1 + c1 * c2 * s3 + m[1, 2] = s2 * s3 + m[2, 2] = c1 * c3 - c2 * s1 * s3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -1017,22 +1017,22 @@ matrix4_from_euler_angles_zyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 * c3 - s1 * s3 - m[0][1] = c1 * s3 + c2 * c3 * s1 - m[0][2] =-c3 * s2 - m[0][3] = 0 - m[1][0] =-c3 * s1 - c1 * c2 * s3 - m[1][1] = c1 * c3 - c2 * s1 * s3 - m[1][2] = s2 * s3 - m[1][3] = 0 - m[2][0] = c1 * s2 - m[2][1] = s1 * s2 - m[2][2] = c2 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c1 * c2 * c3 - s1 * s3 + m[1, 0] = c1 * s3 + c2 * c3 * s1 + m[2, 0] =-c3 * s2 + m[3, 0] = 0 + m[0, 1] =-c3 * s1 - c1 * c2 * s3 + m[1, 1] = c1 * c3 - c2 * s1 * s3 + m[2, 1] = s2 * s3 + m[3, 1] = 0 + m[0, 2] = c1 * s2 + m[1, 2] = s1 * s2 + m[2, 2] = c2 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -1044,22 +1044,22 @@ matrix4_from_euler_angles_zxz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c3 - c2 * s1 * s3 - m[0][1] = c3 * s1 + c1 * c2 * s3 - m[0][2] = s2 *s3 - m[0][3] = 0 - m[1][0] =-c1 * s3 - c2 * c3 * s1 - m[1][1] = c1 * c2 * c3 - s1 * s3 - m[1][2] = c3 * s2 - m[1][3] = 0 - m[2][0] = s1 * s2 - m[2][1] =-c1 * s2 - m[2][2] = c2 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c1 * c3 - c2 * s1 * s3 + m[1, 0] = c3 * s1 + c1 * c2 * s3 + m[2, 0] = s2 *s3 + m[3, 0] = 0 + m[0, 1] =-c1 * s3 - c2 * c3 * s1 + m[1, 1] = c1 * c2 * c3 - s1 * s3 + m[2, 1] = c3 * s2 + m[3, 1] = 0 + m[0, 2] = s1 * s2 + m[1, 2] =-c1 * s2 + m[2, 2] = c2 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -1072,22 +1072,22 @@ matrix4_from_euler_angles_xzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c2 * c3 - m[0][1] = s1 * s3 + c1 * c3 * s2 - m[0][2] = c3 * s1 * s2 - c1 * s3 - m[0][3] = 0 - m[1][0] =-s2 - m[1][1] = c1 * c2 - m[1][2] = c2 * s1 - m[1][3] = 0 - m[2][0] = c2 * s3 - m[2][1] = c1 * s2 * s3 - c3 * s1 - m[2][2] = c1 * c3 + s1 * s2 *s3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c2 * c3 + m[1, 0] = s1 * s3 + c1 * c3 * s2 + m[2, 0] = c3 * s1 * s2 - c1 * s3 + m[3, 0] = 0 + m[0, 1] =-s2 + m[1, 1] = c1 * c2 + m[2, 1] = c2 * s1 + m[3, 1] = 0 + m[0, 2] = c2 * s3 + m[1, 2] = c1 * s2 * s3 - c3 * s1 + m[2, 2] = c1 * c3 + s1 * s2 *s3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -1099,22 +1099,22 @@ matrix4_from_euler_angles_yzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 - m[0][1] = s2 - m[0][2] =-c2 * s1 - m[0][3] = 0 - m[1][0] = s1 * s3 - c1 * c3 * s2 - m[1][1] = c2 * c3 - m[1][2] = c1 * s3 + c3 * s1 * s2 - m[1][3] = 0 - m[2][0] = c3 * s1 + c1 * s2 * s3 - m[2][1] =-c2 * s3 - m[2][2] = c1 * c3 - s1 * s2 * s3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c1 * c2 + m[1, 0] = s2 + m[2, 0] =-c2 * s1 + m[3, 0] = 0 + m[0, 1] = s1 * s3 - c1 * c3 * s2 + m[1, 1] = c2 * c3 + m[2, 1] = c1 * s3 + c3 * s1 * s2 + m[3, 1] = 0 + m[0, 2] = c3 * s1 + c1 * s2 * s3 + m[1, 2] =-c2 * s3 + m[2, 2] = c1 * c3 - s1 * s2 * s3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -1126,22 +1126,22 @@ matrix4_from_euler_angles_zyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c2 - m[0][1] = c2 * s1 - m[0][2] =-s2 - m[0][3] = 0 - m[1][0] = c1 * s2 * s3 - c3 * s1 - m[1][1] = c1 * c3 + s1 * s2 * s3 - m[1][2] = c2 * s3 - m[1][3] = 0 - m[2][0] = s1 * s3 + c1 * c3 * s2 - m[2][1] = c3 * s1 * s2 - c1 * s3 - m[2][2] = c2 * c3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c1 * c2 + m[1, 0] = c2 * s1 + m[2, 0] =-s2 + m[3, 0] = 0 + m[0, 1] = c1 * s2 * s3 - c3 * s1 + m[1, 1] = c1 * c3 + s1 * s2 * s3 + m[2, 1] = c2 * s3 + m[3, 1] = 0 + m[0, 2] = s1 * s3 + c1 * c3 * s2 + m[1, 2] = c3 * s1 * s2 - c1 * s3 + m[2, 2] = c2 * c3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -1153,22 +1153,22 @@ matrix4_from_euler_angles_zxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) { c3 := math.cos(t3) s3 := math.sin(t3) - m[0][0] = c1 * c3 - s1 * s2 * s3 - m[0][1] = c3 * s1 + c1 * s2 * s3 - m[0][2] =-c2 * s3 - m[0][3] = 0 - m[1][0] =-c2 * s1 - m[1][1] = c1 * c2 - m[1][2] = s2 - m[1][3] = 0 - m[2][0] = c1 * s3 + c3 * s1 * s2 - m[2][1] = s1 * s3 - c1 * c3 * s2 - m[2][2] = c2 * c3 - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = c1 * c3 - s1 * s2 * s3 + m[1, 0] = c3 * s1 + c1 * s2 * s3 + m[2, 0] =-c2 * s3 + m[3, 0] = 0 + m[0, 1] =-c2 * s1 + m[1, 1] = c1 * c2 + m[2, 1] = s2 + m[3, 1] = 0 + m[0, 2] = c1 * s3 + c3 * s1 * s2 + m[1, 2] = s1 * s3 - c1 * c3 * s2 + m[2, 2] = c2 * c3 + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return } @@ -1181,32 +1181,32 @@ matrix4_from_yaw_pitch_roll_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix4f64 cb := math.cos(roll) sb := math.sin(roll) - m[0][0] = ch * cb + sh * sp * sb - m[0][1] = sb * cp - m[0][2] = -sh * cb + ch * sp * sb - m[0][3] = 0 - m[1][0] = -ch * sb + sh * sp * cb - m[1][1] = cb * cp - m[1][2] = sb * sh + ch * sp * cb - m[1][3] = 0 - m[2][0] = sh * cp - m[2][1] = -sp - m[2][2] = ch * cp - m[2][3] = 0 - m[3][0] = 0 - m[3][1] = 0 - m[3][2] = 0 - m[3][3] = 1 + m[0, 0] = ch * cb + sh * sp * sb + m[1, 0] = sb * cp + m[2, 0] = -sh * cb + ch * sp * sb + m[3, 0] = 0 + m[0, 1] = -ch * sb + sh * sp * cb + m[1, 1] = cb * cp + m[2, 1] = sb * sh + ch * sp * cb + m[3, 1] = 0 + m[0, 2] = sh * cp + m[1, 2] = -sp + m[2, 2] = ch * cp + m[3, 2] = 0 + m[0, 3] = 0 + m[1, 3] = 0 + m[2, 3] = 0 + m[3, 3] = 1 return m } euler_angles_xyz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(m[2][1], m[2][2]) - C2 := math.sqrt(m[0][0]*m[0][0] + m[1][0]*m[1][0]) - T2 := math.atan2(-m[2][0], C2) + T1 := math.atan2(m[1, 2], m[2, 2]) + C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 1]*m[0, 1]) + T2 := math.atan2(-m[0, 2], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[0][2] - C1*m[0][1], C1*m[1][1] - S1*m[1][2]) + T3 := math.atan2(S1*m[2, 0] - C1*m[1, 0], C1*m[1, 1] - S1*m[2, 1]) t1 = -T1 t2 = -T2 t3 = -T3 @@ -1214,12 +1214,12 @@ euler_angles_xyz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { } euler_angles_yxz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(m[2][0], m[2][2]) - C2 := math.sqrt(m[0][1]*m[0][1] + m[1][1]*m[1][1]) - T2 := math.atan2(-m[2][1], C2) + T1 := math.atan2(m[0, 2], m[2, 2]) + C2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 1]*m[1, 1]) + T2 := math.atan2(-m[1, 2], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[1][2] - C1*m[1][0], C1*m[0][0] - S1*m[0][2]) + T3 := math.atan2(S1*m[2, 1] - C1*m[0, 1], C1*m[0, 0] - S1*m[2, 0]) t1 = T1 t2 = T2 t3 = T3 @@ -1227,12 +1227,12 @@ euler_angles_yxz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { } euler_angles_xzx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(m[0][2], m[0][1]) - S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]) - T2 := math.atan2(S2, m[0][0]) + T1 := math.atan2(m[2, 0], m[1, 0]) + S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2]) + T2 := math.atan2(S2, m[0, 0]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[1][2] - S1*m[1][1], C1*m[2][2] - S1*m[2][1]) + T3 := math.atan2(C1*m[2, 1] - S1*m[1, 1], C1*m[2, 2] - S1*m[1, 2]) t1 = T1 t2 = T2 t3 = T3 @@ -1240,12 +1240,12 @@ euler_angles_xzx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { } euler_angles_xyx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(m[0][1], -m[0][2]) - S2 := math.sqrt(m[1][0]*m[1][0] + m[2][0]*m[2][0]) - T2 := math.atan2(S2, m[0][0]) + T1 := math.atan2(m[1, 0], -m[2, 0]) + S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2]) + T2 := math.atan2(S2, m[0, 0]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(-C1*m[2][1] - S1*m[2][2], C1*m[1][1] + S1*m[1][2]) + T3 := math.atan2(-C1*m[1, 2] - S1*m[2, 2], C1*m[1, 1] + S1*m[2, 1]) t1 = T1 t2 = T2 t3 = T3 @@ -1253,12 +1253,12 @@ euler_angles_xyx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { } euler_angles_yxy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(m[1][0], m[1][2]) - S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]) - T2 := math.atan2(S2, m[1][1]) + T1 := math.atan2(m[0, 1], m[2, 1]) + S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2]) + T2 := math.atan2(S2, m[1, 1]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[2][0] - S1*m[2][2], C1*m[0][0] - S1*m[0][2]) + T3 := math.atan2(C1*m[0, 2] - S1*m[2, 2], C1*m[0, 0] - S1*m[2, 0]) t1 = T1 t2 = T2 t3 = T3 @@ -1266,24 +1266,24 @@ euler_angles_yxy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { } euler_angles_yzy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(m[1][2], -m[1][0]) - S2 := math.sqrt(m[0][1]*m[0][1] + m[2][1]*m[2][1]) - T2 := math.atan2(S2, m[1][1]) + T1 := math.atan2(m[2, 1], -m[0, 1]) + S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2]) + T2 := math.atan2(S2, m[1, 1]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(-S1*m[0][0] - C1*m[0][2], S1*m[2][0] + C1*m[2][2]) + T3 := math.atan2(-S1*m[0, 0] - C1*m[2, 0], S1*m[0, 2] + C1*m[2, 2]) t1 = T1 t2 = T2 t3 = T3 return } euler_angles_zyz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(m[2][1], m[2][0]) - S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]) - T2 := math.atan2(S2, m[2][2]) + T1 := math.atan2(m[1, 2], m[0, 2]) + S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1]) + T2 := math.atan2(S2, m[2, 2]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[0][1] - S1*m[0][0], C1*m[1][1] - S1*m[1][0]) + T3 := math.atan2(C1*m[1, 0] - S1*m[0, 0], C1*m[1, 1] - S1*m[0, 1]) t1 = T1 t2 = T2 t3 = T3 @@ -1291,12 +1291,12 @@ euler_angles_zyz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { } euler_angles_zxz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(m[2][0], -m[2][1]) - S2 := math.sqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2]) - T2 := math.atan2(S2, m[2][2]) + T1 := math.atan2(m[0, 2], -m[1, 2]) + S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1]) + T2 := math.atan2(S2, m[2, 2]) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(-C1*m[1][0] - S1*m[1][1], C1*m[0][0] + S1*m[0][1]) + T3 := math.atan2(-C1*m[0, 1] - S1*m[1, 1], C1*m[0, 0] + S1*m[1, 0]) t1 = T1 t2 = T2 t3 = T3 @@ -1304,12 +1304,12 @@ euler_angles_zxz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { } euler_angles_xzy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(m[1][2], m[1][1]) - C2 := math.sqrt(m[0][0]*m[0][0] + m[2][0]*m[2][0]) - T2 := math.atan2(-m[1][0], C2) + T1 := math.atan2(m[2, 1], m[1, 1]) + C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 2]*m[0, 2]) + T2 := math.atan2(-m[0, 1], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[0][1] - C1*m[0][2], C1*m[2][2] - S1*m[2][1]) + T3 := math.atan2(S1*m[1, 0] - C1*m[2, 0], C1*m[2, 2] - S1*m[1, 2]) t1 = T1 t2 = T2 t3 = T3 @@ -1317,12 +1317,12 @@ euler_angles_xzy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { } euler_angles_yzx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(-m[0][2], m[0][0]) - C2 := math.sqrt(m[1][1]*m[1][1] + m[2][1]*m[2][1]) - T2 := math.atan2(m[0][1], C2) + T1 := math.atan2(-m[2, 0], m[0, 0]) + C2 := math.sqrt(m[1, 1]*m[1, 1] + m[1, 2]*m[1, 2]) + T2 := math.atan2(m[1, 0], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[1][0] + C1*m[1][2], S1*m[2][0] + C1*m[2][2]) + T3 := math.atan2(S1*m[0, 1] + C1*m[2, 1], S1*m[0, 2] + C1*m[2, 2]) t1 = T1 t2 = T2 t3 = T3 @@ -1330,12 +1330,12 @@ euler_angles_yzx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { } euler_angles_zyx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(m[0][1], m[0][0]) - C2 := math.sqrt(m[1][2]*m[1][2] + m[2][2]*m[2][2]) - T2 := math.atan2(-m[0][2], C2) + T1 := math.atan2(m[1, 0], m[0, 0]) + C2 := math.sqrt(m[2, 1]*m[2, 1] + m[2, 2]*m[2, 2]) + T2 := math.atan2(-m[2, 0], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(S1*m[2][0] - C1*m[2][1], C1*m[1][1] - S1*m[1][0]) + T3 := math.atan2(S1*m[0, 2] - C1*m[1, 2], C1*m[1, 1] - S1*m[0, 1]) t1 = T1 t2 = T2 t3 = T3 @@ -1343,12 +1343,12 @@ euler_angles_zyx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { } euler_angles_zxy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) { - T1 := math.atan2(-m[1][0], m[1][1]) - C2 := math.sqrt(m[0][2]*m[0][2] + m[2][2]*m[2][2]) - T2 := math.atan2(m[1][2], C2) + T1 := math.atan2(-m[0, 1], m[1, 1]) + C2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 2]*m[2, 2]) + T2 := math.atan2(m[2, 1], C2) S1 := math.sin(T1) C1 := math.cos(T1) - T3 := math.atan2(C1*m[2][0] + S1*m[2][1], C1*m[0][0] + S1*m[0][1]) + T3 := math.atan2(C1*m[0, 2] + S1*m[1, 2], C1*m[0, 0] + S1*m[1, 0]) t1 = T1 t2 = T2 t3 = T3 diff --git a/core/math/linalg/swizzle.odin b/core/math/linalg/swizzle.odin index f035a5276..ada4aebcf 100644 --- a/core/math/linalg/swizzle.odin +++ b/core/math/linalg/swizzle.odin @@ -1,5 +1,10 @@ package linalg +/* + These procedures are to allow for swizzling with non-compile (runtime) known components +*/ + + Scalar_Components :: enum u8 { x = 0, r = 0, diff --git a/core/math/math.odin b/core/math/math.odin index caaa6f51b..b711c160f 100644 --- a/core/math/math.odin +++ b/core/math/math.odin @@ -396,7 +396,7 @@ trunc_f16 :: proc "contextless" (x: f16) -> f16 { e := (x >> shift) & mask - bias if e < shift { - x &= ~(1 << (shift-e)) - 1 + x &~= 1 << (shift-e) - 1 } return transmute(f16)x } @@ -428,7 +428,7 @@ trunc_f32 :: proc "contextless" (x: f32) -> f32 { e := (x >> shift) & mask - bias if e < shift { - x &= ~(1 << (shift-e)) - 1 + x &~= 1 << (shift-e) - 1 } return transmute(f32)x } @@ -460,7 +460,7 @@ trunc_f64 :: proc "contextless" (x: f64) -> f64 { e := (x >> shift) & mask - bias if e < shift { - x &= ~(1 << (shift-e)) - 1 + x &~= 1 << (shift-e) - 1 } return transmute(f64)x } @@ -473,6 +473,7 @@ trunc_f64 :: proc "contextless" (x: f64) -> f64 { } trunc_f64le :: proc "contextless" (x: f64le) -> f64le { return #force_inline f64le(trunc_f64(f64(x))) } trunc_f64be :: proc "contextless" (x: f64be) -> f64be { return #force_inline f64be(trunc_f64(f64(x))) } +// Removes the fractional part of the value, i.e. rounds towards zero. trunc :: proc{ trunc_f16, trunc_f16le, trunc_f16be, trunc_f32, trunc_f32le, trunc_f32be, @@ -958,7 +959,7 @@ classify_f16 :: proc "contextless" (x: f16) -> Float_Class { return .Neg_Zero } return .Zero - case x*0.5 == x: + case x*0.25 == x: if x < 0 { return .Neg_Inf } @@ -1027,6 +1028,8 @@ classify_f64 :: proc "contextless" (x: f64) -> Float_Class { } classify_f64le :: proc "contextless" (x: f64le) -> Float_Class { return #force_inline classify_f64(f64(x)) } classify_f64be :: proc "contextless" (x: f64be) -> Float_Class { return #force_inline classify_f64(f64(x)) } +// Returns the `Float_Class` of the value, i.e. whether normal, subnormal, zero, negative zero, NaN, infinity or +// negative infinity. classify :: proc{ classify_f16, classify_f16le, classify_f16be, classify_f32, classify_f32le, classify_f32be, @@ -1196,13 +1199,14 @@ sum :: proc "contextless" (x: $T/[]$E) -> (res: E) prod :: proc "contextless" (x: $T/[]$E) -> (res: E) where intrinsics.type_is_numeric(E) { + res = 1 for i in x { res *= i } return } -cumsum_inplace :: proc "contextless" (x: $T/[]$E) -> T +cumsum_inplace :: proc "contextless" (x: $T/[]$E) where intrinsics.type_is_numeric(E) { for i in 1.. (value: f32) { + // Get base points and offsets. + base := [2]i64{fast_floor(coord.x), fast_floor(coord.y)} + i := [2]f32{f32(coord.x - f64(base.x)), f32(coord.y - f64(base.y))} + + // Prime pre-multiplication for hash. + bp := base * [2]i64{PRIME_X, PRIME_Y} + + // Unskew. + t := f32(i.x + i.y) * f32(UNSKEW_2D) + d0 := i + [2]f32{t, t} + + // First vertex. + a0 := RSQUARED_2D - d0.x * d0.x - d0.y * d0.y + if a0 > 0 { + value = (a0 * a0) * (a0 * a0) * grad(seed, [2]i64{bp.x, bp.y}, d0) + } + + // Second vertex. + a1 := f32(2 * (1 + 2 * UNSKEW_2D) * (1 / UNSKEW_2D + 2)) * t + f32(-2 * (1 + 2 * UNSKEW_2D) * (1 + 2 * UNSKEW_2D)) + a0 + if a1 > 0 { + d1 := d0 - [2]f32{f32(1 + 2 * UNSKEW_2D), f32(1 + 2 * UNSKEW_2D)} + value += (a1 * a1) * (a1 * a1) * grad(seed, [2]i64{bp.x + PRIME_X, bp.y + PRIME_Y}, d1) + } + + // Third vertex. + if d0.y > d0.x { + d2 := d0 - [2]f32{f32(UNSKEW_2D), f32(UNSKEW_2D + 1)} + a2 := RSQUARED_2D - d2.x * d2.x - d2.y * d2.y + if(a2 > 0) { + value += (a2 * a2) * (a2 * a2) * grad(seed, [2]i64{bp.x, bp.y + PRIME_Y}, d2) + } + } else { + d2 := d0 - [2]f32{f32(UNSKEW_2D + 1), f32(UNSKEW_2D)} + a2 := RSQUARED_2D - d2.x * d2.x - d2.y * d2.y + if(a2 > 0) { + value += (a2 * a2) * (a2 * a2) * grad(seed, [2]i64{bp.x + PRIME_X, bp.y}, d2) + } + } + + return +} + + +/* + Generate overlapping cubic lattices for 3D OpenSimplex2 noise. +*/ +_internal_noise_3d_unrotated_base :: proc(seed: i64, coord: Vec3) -> (value: f32) { + seed := seed + // Get base points and offsets. + // xr, yr, zr := coord.x, coord.y, coord.z + + rb := [3]i64{fast_round(coord.x), fast_round(coord.y), fast_round(coord.z)} + ri := [3]f32{f32(coord.x - f64(rb.x)), f32(coord.y - f64(rb.y)), f32(coord.z - f64(rb.z))} + + // -1 if positive, 1 if negative. + i_sign := [3]i64{i64(-1.0 - ri.x) | 1, i64(-1.0 - ri.y) | 1, i64(-1.0 - ri.z) | 1} + f_sign := [3]f32{f32(i_sign.x), f32(i_sign.y), f32(i_sign.z)} + + // Compute absolute values, using the above as a shortcut. This was faster in my tests for some reason. + a0 := f_sign * -ri + + // Prime pre-multiplication for hash. + rbp := rb * [3]i64{PRIME_X, PRIME_Y, PRIME_Z} + + // Loop: Pick an edge on each lattice copy. + a := (RSQUARED_3D - ri.x * ri.x) - (ri.y * ri.y + ri.z * ri.z) + + l := 0 + for { + defer l += 1 + + // Closest point on cube. + if a > 0 { + a2 := a * a; a4 := a2 * a2 + value += a4 * grad(seed, rbp, ri) + } + + // Second-closest point. + if a0.x >= a0.y && a0.x >= a0.z { + b := a + a0.x + a0.x + if b > 1 { + b -= 1 + b2 := b * b; b4 := b2 * b2 + value += b4 * grad(seed, [3]i64{rbp.x - i_sign.x * PRIME_X, rbp.y, rbp.z}, [3]f32{ri.x + f_sign.x, ri.y, ri.z}) + } + } else if a0.y > a0.x && a0.y >= a0.z { + b := a + a0.y + a0.y + if b > 1 { + b -= 1 + b2 := b * b; b4 := b2 * b2 + value += b4 * grad(seed, [3]i64{rbp.x, rbp.y - i_sign.y * PRIME_Y, rbp.z}, [3]f32{ri.x, ri.y + f_sign.y, ri.z}) + } + } else { + b := a + a0.z + a0.z + if b > 1 { + b -= 1 + b2 := b * b; b4 := b2 * b2 + value += b4 * grad(seed, [3]i64{rbp.x, rbp.y, rbp.z - i_sign.z * PRIME_Z}, [3]f32{ri.x, ri.y, ri.z + f_sign.z}) + } + } + + // Break from loop if we're done, skipping updates below. + if l == 1 { + break + } + + // Update absolute value. + a0 = 0.5 - a0 + + // Update relative coordinate. + ri = a0 * f_sign + + // Update falloff. + a += (0.75 - a0.x) - (a0.y + a0.z) + + // Update prime for hash. + rbp += [3]i64{i_sign.x >> 1, i_sign.y >> 1, i_sign.z >> 1} & {PRIME_X, PRIME_Y, PRIME_Z} + + // Update the reverse sign indicators. + i_sign = -i_sign + f_sign = -f_sign + + // And finally update the seed for the other lattice copy. + seed ~= SEED_FLIP_3D + } + + return value +} + +/* + 4D OpenSimplex2 noise base. +*/ +_internal_noise_4d_unskewed_base :: proc(seed: i64, coord: Vec4) -> (value: f32) { + seed := seed + + // Get base points and offsets + base := [4]i64{fast_floor(coord.x), fast_floor(coord.y), fast_floor(coord.z), fast_floor(coord.w)} + si := [4]f32{f32(coord.x - f64(base.x)), f32(coord.y - f64(base.y)), f32(coord.z - f64(base.z)), f32(coord.w - f64(base.w))} + + // Determine which lattice we can be confident has a contributing point its corresponding cell's base simplex. + // We only look at the spaces between the diagonal planes. This proved effective in all of my tests. + si_sum := (si.x + si.y) + (si.z + si.w) + starting_lattice := i64(si_sum * 1.25) + + // Offset for seed based on first lattice copy. + seed += starting_lattice * SEED_OFFSET_4D + + // Offset for lattice point relative positions (skewed) + starting_lattice_offset := f32(starting_lattice) * -LATTICE_STEP_4D + si += starting_lattice_offset + + // Prep for vertex contributions. + ssi := (si_sum + starting_lattice_offset * 4) * UNSKEW_4D + + // Prime pre-multiplication for hash. + svp := base * [4]i64{PRIME_X, PRIME_Y, PRIME_Z, PRIME_W} + + // Five points to add, total, from five copies of the A4 lattice. + for i : i64 = 0; ; i += 1 { + + // Next point is the closest vertex on the 4-simplex whose base vertex is the aforementioned vertex. + score := 1.0 + ssi * (-1.0 / UNSKEW_4D) // Seems slightly faster than 1.0-xsi-ysi-zsi-wsi + if si.x >= si.x && si.x >= si.z && si.x >= si.w && si.x >= score { + svp.x += PRIME_X + si.x -= 1 + ssi -= UNSKEW_4D + } + else if si.y > si.x && si.y >= si.z && si.y >= si.w && si.y >= score { + svp.y += PRIME_Y + si.y -= 1 + ssi -= UNSKEW_4D + } + else if si.z > si.x && si.z > si.y && si.z >= si.w && si.z >= score { + svp.z += PRIME_Z + si.z -= 1 + ssi -= UNSKEW_4D + } + else if si.w > si.x && si.w > si.y && si.w > si.z && si.w >= score { + svp.w += PRIME_W + si.w -= 1 + ssi -= UNSKEW_4D + } + + // gradient contribution with falloff. + d := si + ssi + a := (d.x * d.x + d.y * d.y) + (d.z * d.z + d.w * d.w) + + if a < RSQUARED_4D { + a -= RSQUARED_4D + a *= a; a4 := a * a + value += a4 * grad(seed, svp, d) + } + + // Break from loop if we're done, skipping updates below. + if i == 4 { + break + } + + // Update for next lattice copy shifted down by <-0.2, -0.2, -0.2, -0.2>. + si += LATTICE_STEP_4D + ssi += LATTICE_STEP_4D * 4 * UNSKEW_4D + seed -= SEED_OFFSET_4D + + // Because we don't always start on the same lattice copy, there's a special reset case. + if i == starting_lattice { + svp -= {PRIME_X, PRIME_Y, PRIME_Z, PRIME_W} + seed += SEED_OFFSET_4D * 5 + } + } + return +} + +/* + Utility functions +*/ +@(optimization_mode="speed") +grad_2d :: proc(seed: i64, svp: [2]i64, delta: [2]f32) -> (value: f32) { + hash := seed ~ svp.x ~ svp.y + hash *= HASH_MULTIPLIER + hash ~= hash >> (64 - N_GRADS_2D_EXPONENT + 1) + + gi := hash & ((N_GRADS_2D - 1) << 1) + return GRADIENTS_2D[gi] * delta.x + GRADIENTS_2D[gi | 1] * delta.y +} + +@(optimization_mode="speed") +grad_3d :: proc(seed: i64, rvp: [3]i64, delta: [3]f32) -> (value: f32) { + hash := (seed ~ rvp.x) ~ (rvp.y ~ rvp.z) + hash *= HASH_MULTIPLIER + hash ~= hash >> (64 - N_GRADS_3D_EXPONENT + 2) + + gi := hash & ((N_GRADS_3D - 1) << 2) + return GRADIENTS_3D[gi] * delta.x + GRADIENTS_3D[gi | 1] * delta.y + GRADIENTS_3D[gi | 2] * delta.z +} + +@(optimization_mode="speed") +grad_4d :: proc(seed: i64, svp: [4]i64, delta: [4]f32) -> (value: f32) { + hash := seed ~ (svp.x ~ svp.y) ~ (svp.z ~ svp.w) + hash *= HASH_MULTIPLIER + hash ~= hash >> (64 - N_GRADS_4D_EXPONENT + 2) + + gi := hash & ((N_GRADS_4D - 1) << 2) + return (GRADIENTS_4D[gi] * delta.x + GRADIENTS_4D[gi | 1] * delta.y) + (GRADIENTS_4D[gi | 2] * delta.z + GRADIENTS_4D[gi | 3] * delta.w) +} + +grad :: proc {grad_2d, grad_3d, grad_4d} + +@(optimization_mode="speed") +fast_floor :: proc(x: f64) -> (floored: i64) { + xi := i64(x) + return x < f64(xi) ? xi - 1 : xi +} + +@(optimization_mode="speed") +fast_round :: proc(x: f64) -> (rounded: i64) { + return x < 0 ? i64(x - 0.5) : i64(x + 0.5) +} \ No newline at end of file diff --git a/core/math/noise/opensimplex2.odin b/core/math/noise/opensimplex2.odin new file mode 100644 index 000000000..d90dafdf5 --- /dev/null +++ b/core/math/noise/opensimplex2.odin @@ -0,0 +1,171 @@ +/* + OpenSimplex2 noise implementation. + + Ported from https://github.com/KdotJPG/OpenSimplex2. + Copyright 2022 Yuki2 (https://github.com/NoahR02) +*/ +package math_noise + +/* + Input coordinate vectors +*/ +Vec2 :: [2]f64 +Vec3 :: [3]f64 +Vec4 :: [4]f64 + +/* + Noise Evaluators +*/ + +/* + 2D Simplex noise, standard lattice orientation. +*/ +noise_2d :: proc(seed: i64, coord: Vec2) -> (value: f32) { + // Get points for A2* lattice + skew := SKEW_2D * (coord.x + coord.y) + skewed := coord + skew + + return _internal_noise_2d_unskewed_base(seed, skewed) +} + +/* + 2D Simplex noise, with Y pointing down the main diagonal. + Might be better for a 2D sandbox style game, where Y is vertical. + Probably slightly less optimal for heightmaps or continent maps, + unless your map is centered around an equator. It's a subtle + difference, but the option is here to make it an easy choice. +*/ +noise_2d_improve_x :: proc(seed: i64, coord: Vec2) -> (value: f32) { + // Skew transform and rotation baked into one. + xx := coord.x * ROOT_2_OVER_2 + yy := coord.y * (ROOT_2_OVER_2 * (1 + 2 * SKEW_2D)) + return _internal_noise_2d_unskewed_base(seed, Vec2{yy + xx, yy - xx}) +} + + +/* + 3D OpenSimplex2 noise, with better visual isotropy in (X, Y). + Recommended for 3D terrain and time-varied animations. + The Z coordinate should always be the "different" coordinate in whatever your use case is. + If Y is vertical in world coordinates, call `noise_3d_improve_xz(x, z, Y)` or use `noise_3d_xz_before_y`. + If Z is vertical in world coordinates, call `noise_3d_improve_xz(x, y, Z)`. + For a time varied animation, call `noise_3d_improve_xz(x, y, T)`. +*/ +noise_3d_improve_xy :: proc(seed: i64, coord: Vec3) -> (value: f32) { + /* + Re-orient the cubic lattices without skewing, so Z points up the main lattice diagonal, + and the planes formed by XY are moved far out of alignment with the cube faces. + Orthonormal rotation. Not a skew transform. + */ + xy := coord.x + coord.y + s2 := xy * ROTATE_3D_ORTHOGONALIZER + zz := coord.z * ROOT_3_OVER_3 + + r := Vec3{coord.x + s2 + zz, coord.y + s2 + zz, xy * -ROOT_3_OVER_3 + zz} + + // Evaluate both lattices to form a BCC lattice. + return _internal_noise_3d_unrotated_base(seed, r) +} + +/* + 3D OpenSimplex2 noise, with better visual isotropy in (X, Z). + Recommended for 3D terrain and time-varied animations. + The Y coordinate should always be the "different" coordinate in whatever your use case is. + If Y is vertical in world coordinates, call `noise_3d_improve_xz(x, Y, z)`. + If Z is vertical in world coordinates, call `noise_3d_improve_xz(x, Z, y)` or use `noise_3d_improve_xy`. + For a time varied animation, call `noise_3d_improve_xz(x, T, y)` or use `noise_3d_improve_xy`. +*/ +noise_3d_improve_xz :: proc(seed: i64, coord: Vec3) -> (value: f32) { + /* + Re-orient the cubic lattices without skewing, so Y points up the main lattice diagonal, + and the planes formed by XZ are moved far out of alignment with the cube faces. + Orthonormal rotation. Not a skew transform. + */ + xz := coord.x + coord.z + s2 := xz * ROTATE_3D_ORTHOGONALIZER + yy := coord.y * ROOT_3_OVER_3 + + r := Vec3{coord.x + s2 + yy, xz * -ROOT_3_OVER_3 + yy, coord.z + s2 + yy} + + // Evaluate both lattices to form a BCC lattice. + return _internal_noise_3d_unrotated_base(seed, r) +} + +/* + 3D OpenSimplex2 noise, fallback rotation option + Use `noise_3d_improve_xy` or `noise_3d_improve_xz` instead, wherever appropriate. + They have less diagonal bias. This function's best use is as a fallback. +*/ +noise_3d_fallback :: proc(seed: i64, coord: Vec3) -> (value: f32) { + /* + Re-orient the cubic lattices via rotation, to produce a familiar look. + Orthonormal rotation. Not a skew transform. + */ + bias := FALLBACK_ROTATE_3D * (coord.x + coord.y + coord.z) + biased := bias - coord + // Evaluate both lattices to form a BCC lattice. + return _internal_noise_3d_unrotated_base(seed, biased) +} + + +/* + 4D OpenSimplex2 noise, with XYZ oriented like `noise_3d_improve_xy` + and W for an extra degree of freedom. W repeats eventually. + Recommended for time-varied animations which texture a 3D object (W=time) + in a space where Z is vertical. +*/ +noise_4d_improve_xyz_improve_xy :: proc(seed: i64, coord: Vec4) -> (value: f32) { + xy := coord.x + coord.y + s2 := xy * -0.21132486540518699998 + zz := coord.z * 0.28867513459481294226 + ww := coord.w * 0.2236067977499788 + + xr, yr : f64 = coord.x + (zz + ww + s2), coord.y + (zz + ww + s2) + zr : f64 = xy * -0.57735026918962599998 + (zz + ww) + wr : f64 = coord.z * -0.866025403784439 + ww + + return _internal_noise_4d_unskewed_base(seed, Vec4{xr, yr, zr, wr}) +} + +/* + 4D OpenSimplex2 noise, with XYZ oriented like `noise_3d_improve_xz` + and W for an extra degree of freedom. W repeats eventually. + Recommended for time-varied animations which texture a 3D object (W=time) + in a space where Y is vertical. +*/ +noise_4d_improve_xyz_improve_xz :: proc(seed: i64, coord: Vec4) -> (value: f32) { + xz := coord.x + coord.z + s2 := xz * -0.21132486540518699998 + yy := coord.y * 0.28867513459481294226 + ww := coord.w * 0.2236067977499788 + + xr, zr : f64 = coord.x + (yy + ww + s2), coord.z + (yy + ww + s2) + yr := xz * -0.57735026918962599998 + (yy + ww) + wr := coord.y * -0.866025403784439 + ww + + return _internal_noise_4d_unskewed_base(seed, Vec4{xr, yr, zr, wr}) +} + +/* + 4D OpenSimplex2 noise, with XYZ oriented like `noise_3d_fallback` + and W for an extra degree of freedom. W repeats eventually. + Recommended for time-varied animations which texture a 3D object (W=time) + where there isn't a clear distinction between horizontal and vertical +*/ +noise_4d_improve_xyz :: proc(seed: i64, coord: Vec4) -> (value: f32) { + xyz := coord.x + coord.y + coord.z + ww := coord.w * 0.2236067977499788 + s2 := xyz * -0.16666666666666666 + ww + + skewed := Vec4{coord.x + s2, coord.y + s2, coord.z + s2, -0.5 * xyz + ww} + return _internal_noise_4d_unskewed_base(seed, skewed) +} + +/* + 4D OpenSimplex2 noise, fallback lattice orientation. +*/ +noise_4d_fallback :: proc(seed: i64, coord: Vec4) -> (value: f32) { + // Get points for A4 lattice + skew := f64(SKEW_4D) * (coord.x + coord.y + coord.z + coord.w) + return _internal_noise_4d_unskewed_base(seed, coord + skew) +} \ No newline at end of file diff --git a/core/math/rand/exp.odin b/core/math/rand/exp.odin new file mode 100644 index 000000000..c0f92e99c --- /dev/null +++ b/core/math/rand/exp.odin @@ -0,0 +1,214 @@ +package rand + +import "core:math" + +// exp_float64 returns a exponential distribution in the range (0, max(f64)], +// with an exponential distribution who rate parameter is 1 (lambda) and whose mean +// is 1 (1/lambda). +// +// To produce a distribution with a differetn rate parameter, divide the result by +// the desired rate parameter +// +// "The Ziggurat Method for Generating Random Variables" +// Authors: George Marsaglia, Wai Wan Tsang +// Submitted: 2000-04-15. Published: 2000-10-02. +// https://www.jstatsoft.org/index.php/jss/article/view/v005i08/ziggurat.pdf [pdf] +// https://www.jstatsoft.org/article/view/v005i08 [web page] +// +exp_float64 :: proc(r: ^Rand = nil) -> f64 { + re :: 7.69711747013104972 + + @(static) + ke := [256]u32{ + 0xe290a139, 0x0, 0x9beadebc, 0xc377ac71, 0xd4ddb990, + 0xde893fb8, 0xe4a8e87c, 0xe8dff16a, 0xebf2deab, 0xee49a6e8, + 0xf0204efd, 0xf19bdb8e, 0xf2d458bb, 0xf3da104b, 0xf4b86d78, + 0xf577ad8a, 0xf61de83d, 0xf6afb784, 0xf730a573, 0xf7a37651, + 0xf80a5bb6, 0xf867189d, 0xf8bb1b4f, 0xf9079062, 0xf94d70ca, + 0xf98d8c7d, 0xf9c8928a, 0xf9ff175b, 0xfa319996, 0xfa6085f8, + 0xfa8c3a62, 0xfab5084e, 0xfadb36c8, 0xfaff0410, 0xfb20a6ea, + 0xfb404fb4, 0xfb5e2951, 0xfb7a59e9, 0xfb95038c, 0xfbae44ba, + 0xfbc638d8, 0xfbdcf892, 0xfbf29a30, 0xfc0731df, 0xfc1ad1ed, + 0xfc2d8b02, 0xfc3f6c4d, 0xfc5083ac, 0xfc60ddd1, 0xfc708662, + 0xfc7f8810, 0xfc8decb4, 0xfc9bbd62, 0xfca9027c, 0xfcb5c3c3, + 0xfcc20864, 0xfccdd70a, 0xfcd935e3, 0xfce42ab0, 0xfceebace, + 0xfcf8eb3b, 0xfd02c0a0, 0xfd0c3f59, 0xfd156b7b, 0xfd1e48d6, + 0xfd26daff, 0xfd2f2552, 0xfd372af7, 0xfd3eeee5, 0xfd4673e7, + 0xfd4dbc9e, 0xfd54cb85, 0xfd5ba2f2, 0xfd62451b, 0xfd68b415, + 0xfd6ef1da, 0xfd750047, 0xfd7ae120, 0xfd809612, 0xfd8620b4, + 0xfd8b8285, 0xfd90bcf5, 0xfd95d15e, 0xfd9ac10b, 0xfd9f8d36, + 0xfda43708, 0xfda8bf9e, 0xfdad2806, 0xfdb17141, 0xfdb59c46, + 0xfdb9a9fd, 0xfdbd9b46, 0xfdc170f6, 0xfdc52bd8, 0xfdc8ccac, + 0xfdcc542d, 0xfdcfc30b, 0xfdd319ef, 0xfdd6597a, 0xfdd98245, + 0xfddc94e5, 0xfddf91e6, 0xfde279ce, 0xfde54d1f, 0xfde80c52, + 0xfdeab7de, 0xfded5034, 0xfdefd5be, 0xfdf248e3, 0xfdf4aa06, + 0xfdf6f984, 0xfdf937b6, 0xfdfb64f4, 0xfdfd818d, 0xfdff8dd0, + 0xfe018a08, 0xfe03767a, 0xfe05536c, 0xfe07211c, 0xfe08dfc9, + 0xfe0a8fab, 0xfe0c30fb, 0xfe0dc3ec, 0xfe0f48b1, 0xfe10bf76, + 0xfe122869, 0xfe1383b4, 0xfe14d17c, 0xfe1611e7, 0xfe174516, + 0xfe186b2a, 0xfe19843e, 0xfe1a9070, 0xfe1b8fd6, 0xfe1c8289, + 0xfe1d689b, 0xfe1e4220, 0xfe1f0f26, 0xfe1fcfbc, 0xfe2083ed, + 0xfe212bc3, 0xfe21c745, 0xfe225678, 0xfe22d95f, 0xfe234ffb, + 0xfe23ba4a, 0xfe241849, 0xfe2469f2, 0xfe24af3c, 0xfe24e81e, + 0xfe25148b, 0xfe253474, 0xfe2547c7, 0xfe254e70, 0xfe25485a, + 0xfe25356a, 0xfe251586, 0xfe24e88f, 0xfe24ae64, 0xfe2466e1, + 0xfe2411df, 0xfe23af34, 0xfe233eb4, 0xfe22c02c, 0xfe22336b, + 0xfe219838, 0xfe20ee58, 0xfe20358c, 0xfe1f6d92, 0xfe1e9621, + 0xfe1daef0, 0xfe1cb7ac, 0xfe1bb002, 0xfe1a9798, 0xfe196e0d, + 0xfe1832fd, 0xfe16e5fe, 0xfe15869d, 0xfe141464, 0xfe128ed3, + 0xfe10f565, 0xfe0f478c, 0xfe0d84b1, 0xfe0bac36, 0xfe09bd73, + 0xfe07b7b5, 0xfe059a40, 0xfe03644c, 0xfe011504, 0xfdfeab88, + 0xfdfc26e9, 0xfdf98629, 0xfdf6c83b, 0xfdf3ec01, 0xfdf0f04a, + 0xfdedd3d1, 0xfdea953d, 0xfde7331e, 0xfde3abe9, 0xfddffdfb, + 0xfddc2791, 0xfdd826cd, 0xfdd3f9a8, 0xfdcf9dfc, 0xfdcb1176, + 0xfdc65198, 0xfdc15bb3, 0xfdbc2ce2, 0xfdb6c206, 0xfdb117be, + 0xfdab2a63, 0xfda4f5fd, 0xfd9e7640, 0xfd97a67a, 0xfd908192, + 0xfd8901f2, 0xfd812182, 0xfd78d98e, 0xfd7022bb, 0xfd66f4ed, + 0xfd5d4732, 0xfd530f9c, 0xfd48432b, 0xfd3cd59a, 0xfd30b936, + 0xfd23dea4, 0xfd16349e, 0xfd07a7a3, 0xfcf8219b, 0xfce7895b, + 0xfcd5c220, 0xfcc2aadb, 0xfcae1d5e, 0xfc97ed4e, 0xfc7fe6d4, + 0xfc65ccf3, 0xfc495762, 0xfc2a2fc8, 0xfc07ee19, 0xfbe213c1, + 0xfbb8051a, 0xfb890078, 0xfb5411a5, 0xfb180005, 0xfad33482, + 0xfa839276, 0xfa263b32, 0xf9b72d1c, 0xf930a1a2, 0xf889f023, + 0xf7b577d2, 0xf69c650c, 0xf51530f0, 0xf2cb0e3c, 0xeeefb15d, + 0xe6da6ecf, + } + @(static) + we := [256]f32{ + 2.0249555e-09, 1.486674e-11, 2.4409617e-11, 3.1968806e-11, + 3.844677e-11, 4.4228204e-11, 4.9516443e-11, 5.443359e-11, + 5.905944e-11, 6.344942e-11, 6.7643814e-11, 7.1672945e-11, + 7.556032e-11, 7.932458e-11, 8.298079e-11, 8.654132e-11, + 9.0016515e-11, 9.3415074e-11, 9.674443e-11, 1.0001099e-10, + 1.03220314e-10, 1.06377254e-10, 1.09486115e-10, 1.1255068e-10, + 1.1557435e-10, 1.1856015e-10, 1.2151083e-10, 1.2442886e-10, + 1.2731648e-10, 1.3017575e-10, 1.3300853e-10, 1.3581657e-10, + 1.3860142e-10, 1.4136457e-10, 1.4410738e-10, 1.4683108e-10, + 1.4953687e-10, 1.5222583e-10, 1.54899e-10, 1.5755733e-10, + 1.6020171e-10, 1.6283301e-10, 1.6545203e-10, 1.6805951e-10, + 1.7065617e-10, 1.732427e-10, 1.7581973e-10, 1.7838787e-10, + 1.8094774e-10, 1.8349985e-10, 1.8604476e-10, 1.8858298e-10, + 1.9111498e-10, 1.9364126e-10, 1.9616223e-10, 1.9867835e-10, + 2.0119004e-10, 2.0369768e-10, 2.0620168e-10, 2.087024e-10, + 2.1120022e-10, 2.136955e-10, 2.1618855e-10, 2.1867974e-10, + 2.2116936e-10, 2.2365775e-10, 2.261452e-10, 2.2863202e-10, + 2.311185e-10, 2.3360494e-10, 2.360916e-10, 2.3857874e-10, + 2.4106667e-10, 2.4355562e-10, 2.4604588e-10, 2.485377e-10, + 2.5103128e-10, 2.5352695e-10, 2.560249e-10, 2.585254e-10, + 2.6102867e-10, 2.6353494e-10, 2.6604446e-10, 2.6855745e-10, + 2.7107416e-10, 2.7359479e-10, 2.761196e-10, 2.7864877e-10, + 2.8118255e-10, 2.8372119e-10, 2.8626485e-10, 2.888138e-10, + 2.9136826e-10, 2.939284e-10, 2.9649452e-10, 2.9906677e-10, + 3.016454e-10, 3.0423064e-10, 3.0682268e-10, 3.0942177e-10, + 3.1202813e-10, 3.1464195e-10, 3.1726352e-10, 3.19893e-10, + 3.2253064e-10, 3.251767e-10, 3.2783135e-10, 3.3049485e-10, + 3.3316744e-10, 3.3584938e-10, 3.3854083e-10, 3.4124212e-10, + 3.4395342e-10, 3.46675e-10, 3.4940711e-10, 3.5215003e-10, + 3.5490397e-10, 3.5766917e-10, 3.6044595e-10, 3.6323455e-10, + 3.660352e-10, 3.6884823e-10, 3.7167386e-10, 3.745124e-10, + 3.773641e-10, 3.802293e-10, 3.8310827e-10, 3.860013e-10, + 3.8890866e-10, 3.918307e-10, 3.9476775e-10, 3.9772008e-10, + 4.0068804e-10, 4.0367196e-10, 4.0667217e-10, 4.09689e-10, + 4.1272286e-10, 4.1577405e-10, 4.1884296e-10, 4.2192994e-10, + 4.250354e-10, 4.281597e-10, 4.313033e-10, 4.3446652e-10, + 4.3764986e-10, 4.408537e-10, 4.4407847e-10, 4.4732465e-10, + 4.5059267e-10, 4.5388301e-10, 4.571962e-10, 4.6053267e-10, + 4.6389292e-10, 4.6727755e-10, 4.70687e-10, 4.741219e-10, + 4.7758275e-10, 4.810702e-10, 4.845848e-10, 4.8812715e-10, + 4.9169796e-10, 4.9529775e-10, 4.989273e-10, 5.0258725e-10, + 5.0627835e-10, 5.100013e-10, 5.1375687e-10, 5.1754584e-10, + 5.21369e-10, 5.2522725e-10, 5.2912136e-10, 5.330522e-10, + 5.370208e-10, 5.4102806e-10, 5.45075e-10, 5.491625e-10, + 5.532918e-10, 5.5746385e-10, 5.616799e-10, 5.6594107e-10, + 5.7024857e-10, 5.746037e-10, 5.7900773e-10, 5.834621e-10, + 5.8796823e-10, 5.925276e-10, 5.971417e-10, 6.018122e-10, + 6.065408e-10, 6.113292e-10, 6.1617933e-10, 6.2109295e-10, + 6.260722e-10, 6.3111916e-10, 6.3623595e-10, 6.4142497e-10, + 6.4668854e-10, 6.5202926e-10, 6.5744976e-10, 6.6295286e-10, + 6.6854156e-10, 6.742188e-10, 6.79988e-10, 6.858526e-10, + 6.9181616e-10, 6.978826e-10, 7.04056e-10, 7.103407e-10, + 7.167412e-10, 7.2326256e-10, 7.2990985e-10, 7.366886e-10, + 7.4360473e-10, 7.5066453e-10, 7.5787476e-10, 7.6524265e-10, + 7.7277595e-10, 7.80483e-10, 7.883728e-10, 7.9645507e-10, + 8.047402e-10, 8.1323964e-10, 8.219657e-10, 8.309319e-10, + 8.401528e-10, 8.496445e-10, 8.594247e-10, 8.6951274e-10, + 8.799301e-10, 8.9070046e-10, 9.018503e-10, 9.134092e-10, + 9.254101e-10, 9.378904e-10, 9.508923e-10, 9.644638e-10, + 9.786603e-10, 9.935448e-10, 1.0091913e-09, 1.025686e-09, + 1.0431306e-09, 1.0616465e-09, 1.08138e-09, 1.1025096e-09, + 1.1252564e-09, 1.1498986e-09, 1.1767932e-09, 1.206409e-09, + 1.2393786e-09, 1.276585e-09, 1.3193139e-09, 1.3695435e-09, + 1.4305498e-09, 1.508365e-09, 1.6160854e-09, 1.7921248e-09, + } + @(static) + fe := [256]f32{ + 1, 0.9381437, 0.90046996, 0.87170434, 0.8477855, 0.8269933, + 0.8084217, 0.7915276, 0.77595687, 0.7614634, 0.7478686, + 0.7350381, 0.72286767, 0.71127474, 0.70019263, 0.6895665, + 0.67935055, 0.6695063, 0.66000086, 0.65080583, 0.6418967, + 0.63325197, 0.6248527, 0.6166822, 0.60872537, 0.60096896, + 0.5934009, 0.58601034, 0.5787874, 0.57172304, 0.5648092, + 0.5580383, 0.5514034, 0.5448982, 0.5385169, 0.53225386, + 0.5261042, 0.52006316, 0.5141264, 0.50828975, 0.5025495, + 0.496902, 0.49134386, 0.485872, 0.48048335, 0.4751752, + 0.46994483, 0.46478975, 0.45970762, 0.45469615, 0.44975325, + 0.44487688, 0.44006512, 0.43531612, 0.43062815, 0.42599955, + 0.42142874, 0.4169142, 0.41245446, 0.40804818, 0.403694, + 0.3993907, 0.39513698, 0.39093173, 0.38677382, 0.38266218, + 0.37859577, 0.37457356, 0.37059465, 0.3666581, 0.362763, + 0.35890847, 0.35509375, 0.351318, 0.3475805, 0.34388044, + 0.34021714, 0.3365899, 0.33299807, 0.32944095, 0.32591796, + 0.3224285, 0.3189719, 0.31554767, 0.31215525, 0.30879408, + 0.3054636, 0.3021634, 0.29889292, 0.2956517, 0.29243928, + 0.28925523, 0.28609908, 0.28297043, 0.27986884, 0.27679393, + 0.2737453, 0.2707226, 0.2677254, 0.26475343, 0.26180625, + 0.25888354, 0.25598502, 0.2531103, 0.25025907, 0.24743107, + 0.24462597, 0.24184346, 0.23908329, 0.23634516, 0.23362878, + 0.23093392, 0.2282603, 0.22560766, 0.22297576, 0.22036438, + 0.21777324, 0.21520215, 0.21265087, 0.21011916, 0.20760682, + 0.20511365, 0.20263945, 0.20018397, 0.19774707, 0.19532852, + 0.19292815, 0.19054577, 0.1881812, 0.18583426, 0.18350479, + 0.1811926, 0.17889754, 0.17661946, 0.17435817, 0.17211354, + 0.1698854, 0.16767362, 0.16547804, 0.16329853, 0.16113494, + 0.15898713, 0.15685499, 0.15473837, 0.15263714, 0.15055119, + 0.14848037, 0.14642459, 0.14438373, 0.14235765, 0.14034624, + 0.13834943, 0.13636707, 0.13439907, 0.13244532, 0.13050574, + 0.1285802, 0.12666863, 0.12477092, 0.12288698, 0.12101672, + 0.119160056, 0.1173169, 0.115487166, 0.11367077, 0.11186763, + 0.11007768, 0.10830083, 0.10653701, 0.10478614, 0.10304816, + 0.101323, 0.09961058, 0.09791085, 0.09622374, 0.09454919, + 0.09288713, 0.091237515, 0.08960028, 0.087975375, 0.08636274, + 0.08476233, 0.083174095, 0.081597984, 0.08003395, 0.07848195, + 0.076941945, 0.07541389, 0.07389775, 0.072393484, 0.07090106, + 0.069420435, 0.06795159, 0.066494495, 0.06504912, 0.063615434, + 0.062193416, 0.060783047, 0.059384305, 0.057997175, + 0.05662164, 0.05525769, 0.053905312, 0.052564494, 0.051235236, + 0.049917534, 0.048611384, 0.047316793, 0.046033762, 0.0447623, + 0.043502413, 0.042254124, 0.041017443, 0.039792392, + 0.038578995, 0.037377283, 0.036187284, 0.035009038, + 0.033842582, 0.032687962, 0.031545233, 0.030414443, 0.02929566, + 0.02818895, 0.027094385, 0.026012046, 0.024942026, 0.023884421, + 0.022839336, 0.021806888, 0.020787204, 0.019780423, 0.0187867, + 0.0178062, 0.016839107, 0.015885621, 0.014945968, 0.014020392, + 0.013109165, 0.012212592, 0.011331013, 0.01046481, 0.009614414, + 0.008780315, 0.007963077, 0.0071633533, 0.006381906, + 0.0056196423, 0.0048776558, 0.004157295, 0.0034602648, + 0.0027887989, 0.0021459677, 0.0015362998, 0.0009672693, + 0.00045413437, + } + + for { + j := uint32(r) + i := j & 0xFF + x := f64(j) * f64(we[i]) + if j < ke[i] { + return x + } + if i == 0 { + return re - math.ln(float64(r)) + } + if fe[i]+f32(float64(r))*(fe[i-1]-fe[i]) < f32(math.exp(-x)) { + return x + } + } +} \ No newline at end of file diff --git a/core/math/rand/normal.odin b/core/math/rand/normal.odin index 4a77543ba..a9edd0f19 100644 --- a/core/math/rand/normal.odin +++ b/core/math/rand/normal.odin @@ -2,6 +2,12 @@ package rand import "core:math" + +// norm_float64 returns a normally distributed f64 in the range -max(f64) through +max(f64) inclusive, +// with a standard normal distribution with a mean of 0 and standard deviation of 1. +// +// sample = norm_float64() * std_dev + mean +// // // Normal distribution // @@ -11,12 +17,6 @@ import "core:math" // https://www.jstatsoft.org/index.php/jss/article/view/v005i08/ziggurat.pdf [pdf] // https://www.jstatsoft.org/article/view/v005i08 [web page] // - -// norm_float64 returns a normally distributed f64 in the range -max(f64) through +max(f64) inclusive, -// with a standard normal distribution with a mean of 0 and standard deviation of 1. -// -// sample = norm_float64() * std_dev + mean -// norm_float64 :: proc(r: ^Rand = nil) -> f64 { rn :: 3.442619855899 @@ -49,7 +49,6 @@ norm_float64 :: proc(r: ^Rand = nil) -> f64 { 0x7da61a1e, 0x7d72a0fb, 0x7d30e097, 0x7cd9b4ab, 0x7c600f1a, 0x7ba90bdc, 0x7a722176, 0x77d664e5, } - @(static) wn := [128]f32{ 1.7290405e-09, 1.2680929e-10, 1.6897518e-10, 1.9862688e-10, @@ -85,7 +84,6 @@ norm_float64 :: proc(r: ^Rand = nil) -> f64 { 1.2601323e-09, 1.2857697e-09, 1.3146202e-09, 1.347784e-09, 1.3870636e-09, 1.4357403e-09, 1.5008659e-09, 1.6030948e-09, } - @(static) fn := [128]f32{ 1.00000000, 0.9635997, 0.9362827, 0.9130436, 0.89228165, diff --git a/core/math/rand/rand.odin b/core/math/rand/rand.odin index 9bd30c216..19e475835 100644 --- a/core/math/rand/rand.odin +++ b/core/math/rand/rand.odin @@ -1,5 +1,7 @@ package rand +import "core:intrinsics" + Rand :: struct { state: u64, inc: u64, @@ -7,9 +9,7 @@ Rand :: struct { @(private) -_GLOBAL_SEED_DATA := 1234567890 -@(private) -global_rand := create(u64(uintptr(&_GLOBAL_SEED_DATA))) +global_rand := create(u64(intrinsics.read_cycle_counter())) set_global_seed :: proc(seed: u64) { init(&global_rand, seed) @@ -70,7 +70,7 @@ int31_max :: proc(n: i32, r: ^Rand = nil) -> i32 { if n&(n-1) == 0 { return int31(r) & (n-1) } - max := i32((1<<31) - 1 - (1<<31)&u32(n)) + max := i32((1<<31) - 1 - (1<<31)%u32(n)) v := int31(r) for v > max { v = int31(r) @@ -85,7 +85,7 @@ int63_max :: proc(n: i64, r: ^Rand = nil) -> i64 { if n&(n-1) == 0 { return int63(r) & (n-1) } - max := i64((1<<63) - 1 - (1<<63)&u64(n)) + max := i64((1<<63) - 1 - (1<<63)%u64(n)) v := int63(r) for v > max { v = int63(r) @@ -100,7 +100,7 @@ int127_max :: proc(n: i128, r: ^Rand = nil) -> i128 { if n&(n-1) == 0 { return int127(r) & (n-1) } - max := i128((1<<63) - 1 - (1<<63)&u128(n)) + max := i128((1<<127) - 1 - (1<<127)%u128(n)) v := int127(r) for v > max { v = int127(r) @@ -142,8 +142,8 @@ read :: proc(p: []byte, r: ^Rand = nil) -> (n: int) { } // perm returns a slice of n ints in a pseudo-random permutation of integers in the range [0, n) -perm :: proc(n: int, r: ^Rand = nil) -> []int { - m := make([]int, n) +perm :: proc(n: int, r: ^Rand = nil, allocator := context.allocator) -> []int { + m := make([]int, n, allocator) for i := 0; i < n; i += 1 { j := int_max(i+1, r) m[i] = m[j] diff --git a/core/mem/doc.odin b/core/mem/doc.odin new file mode 100644 index 000000000..fe53dee83 --- /dev/null +++ b/core/mem/doc.odin @@ -0,0 +1,34 @@ +/* +package mem implements various types of allocators. + + +An example of how to use the `Tracking_Allocator` to track subsequent allocations +in your program and report leaks and bad frees: + +```odin +package foo + +import "core:mem" +import "core:fmt" + +_main :: proc() { + do stuff +} + +main :: proc() { + track: mem.Tracking_Allocator + mem.tracking_allocator_init(&track, context.allocator) + context.allocator = mem.tracking_allocator(&track) + + _main() + + for _, leak in track.allocation_map { + fmt.printf("%v leaked %v bytes\n", leak.location, leak.size) + } + for bad_free in track.bad_free_array { + fmt.printf("%v allocation %p was freed badly\n", bad_free.location, bad_free.memory) + } +} +``` +*/ +package mem \ No newline at end of file diff --git a/core/mem/mem.odin b/core/mem/mem.odin index 8eb877e75..b33f8ba13 100644 --- a/core/mem/mem.odin +++ b/core/mem/mem.odin @@ -3,6 +3,12 @@ package mem import "core:runtime" import "core:intrinsics" +Byte :: 1 +Kilobyte :: 1024 * Byte +Megabyte :: 1024 * Kilobyte +Gigabyte :: 1024 * Megabyte +Terabyte :: 1024 * Gigabyte + set :: proc "contextless" (data: rawptr, value: byte, len: int) -> rawptr { return runtime.memset(data, i32(value), len) } @@ -16,7 +22,7 @@ zero_explicit :: proc "contextless" (data: rawptr, len: int) -> rawptr { // equivalent semantics to those provided by the C11 Annex K 3.7.4.1 // memset_s call. intrinsics.mem_zero_volatile(data, len) // Use the volatile mem_zero - intrinsics.atomic_fence() // Prevent reordering + intrinsics.atomic_thread_fence(.Seq_Cst) // Prevent reordering return data } zero_item :: proc "contextless" (item: $P/^$T) { @@ -166,7 +172,7 @@ slice_data_cast :: proc "contextless" ($T: typeid/[]$A, slice: $S/[]$B) -> T { slice_to_components :: proc "contextless" (slice: $E/[]$T) -> (data: ^T, len: int) { s := transmute(Raw_Slice)slice - return s.data, s.len + return (^T)(s.data), s.len } buffer_from_slice :: proc "contextless" (backing: $T/[]$E) -> [dynamic]E { @@ -192,11 +198,6 @@ any_to_bytes :: proc "contextless" (val: any) -> []byte { } -kilobytes :: proc "contextless" (x: int) -> int { return (x) * 1024 } -megabytes :: proc "contextless" (x: int) -> int { return kilobytes(x) * 1024 } -gigabytes :: proc "contextless" (x: int) -> int { return megabytes(x) * 1024 } -terabytes :: proc "contextless" (x: int) -> int { return gigabytes(x) * 1024 } - is_power_of_two :: proc "contextless" (x: uintptr) -> bool { if x <= 0 { return false diff --git a/core/mem/virtual/virtual.odin b/core/mem/virtual/virtual.odin index 38c654254..21ab5ef21 100644 --- a/core/mem/virtual/virtual.odin +++ b/core/mem/virtual/virtual.odin @@ -6,25 +6,25 @@ DEFAULT_PAGE_SIZE := uint(4096) Allocator_Error :: mem.Allocator_Error -reserve :: proc(size: uint) -> (data: []byte, err: Allocator_Error) { +reserve :: proc "contextless" (size: uint) -> (data: []byte, err: Allocator_Error) { return _reserve(size) } -commit :: proc(data: rawptr, size: uint) -> Allocator_Error { +commit :: proc "contextless" (data: rawptr, size: uint) -> Allocator_Error { return _commit(data, size) } -reserve_and_commit :: proc(size: uint) -> (data: []byte, err: Allocator_Error) { +reserve_and_commit :: proc "contextless" (size: uint) -> (data: []byte, err: Allocator_Error) { data = reserve(size) or_return commit(raw_data(data), size) or_return return } -decommit :: proc(data: rawptr, size: uint) { +decommit :: proc "contextless" (data: rawptr, size: uint) { _decommit(data, size) } -release :: proc(data: rawptr, size: uint) { +release :: proc "contextless" (data: rawptr, size: uint) { _release(data, size) } @@ -36,7 +36,7 @@ Protect_Flag :: enum u32 { Protect_Flags :: distinct bit_set[Protect_Flag; u32] Protect_No_Access :: Protect_Flags{} -protect :: proc(data: rawptr, size: uint, flags: Protect_Flags) -> bool { +protect :: proc "contextless" (data: rawptr, size: uint, flags: Protect_Flags) -> bool { return _protect(data, size, flags) } @@ -82,11 +82,13 @@ memory_block_alloc :: proc(committed, reserved: uint, flags: Memory_Block_Flags) pmblock := platform_memory_alloc(0, total_size) or_return pmblock.block.base = ([^]byte)(uintptr(pmblock) + base_offset) - commit(pmblock.block.base, committed) or_return + commit_err := platform_memory_commit(pmblock, uint(base_offset) + committed) + assert(commit_err == nil) + // Should be zeroed assert(pmblock.block.used == 0) assert(pmblock.block.prev == nil) - if (do_protection) { + if do_protection { protect(rawptr(uintptr(pmblock) + protect_offset), page_size, Protect_No_Access) } @@ -105,7 +107,7 @@ memory_block_alloc :: proc(committed, reserved: uint, flags: Memory_Block_Flags) } alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: int) -> (data: []byte, err: Allocator_Error) { - calc_alignment_offset :: proc(block: ^Memory_Block, alignment: uintptr) -> uint { + calc_alignment_offset :: proc "contextless" (block: ^Memory_Block, alignment: uintptr) -> uint { alignment_offset := uint(0) ptr := uintptr(block.base[block.used:]) mask := alignment-1 @@ -115,23 +117,37 @@ alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: int) return alignment_offset } - + do_commit_if_necessary :: proc(block: ^Memory_Block, size: uint) -> (err: Allocator_Error) { + if block.committed - block.used < size { + pmblock := (^Platform_Memory_Block)(block) + base_offset := uint(uintptr(pmblock.block.base) - uintptr(pmblock)) + platform_total_commit := base_offset + block.used + size + + assert(pmblock.committed <= pmblock.reserved) + assert(pmblock.committed < platform_total_commit) + + platform_memory_commit(pmblock, platform_total_commit) or_return + + pmblock.committed = platform_total_commit + block.committed = pmblock.committed - base_offset + } + return nil + } + + alignment_offset := calc_alignment_offset(block, uintptr(alignment)) - size := uint(min_size) + alignment_offset - + if block.used + size > block.reserved { err = .Out_Of_Memory return } - - ptr := block.base[block.used:] - ptr = ptr[alignment_offset:] - + assert(block.committed <= block.reserved) + do_commit_if_necessary(block, size) or_return + + data = block.base[block.used+alignment_offset:][:min_size] block.used += size - assert(block.used <= block.reserved) - - return ptr[:min_size], nil + return } diff --git a/core/mem/virtual/virtual_linux.odin b/core/mem/virtual/virtual_linux.odin index 71a56e499..6ae926e47 100644 --- a/core/mem/virtual/virtual_linux.odin +++ b/core/mem/virtual/virtual_linux.odin @@ -58,7 +58,7 @@ madvise :: proc "contextless" (addr: rawptr, length: uint, advice: c.int) -> c.i } -_reserve :: proc(size: uint) -> (data: []byte, err: Allocator_Error) { +_reserve :: proc "contextless" (size: uint) -> (data: []byte, err: Allocator_Error) { MAP_FAILED := rawptr(~uintptr(0)) result := mmap(nil, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) if result == MAP_FAILED { @@ -67,7 +67,7 @@ _reserve :: proc(size: uint) -> (data: []byte, err: Allocator_Error) { return ([^]byte)(result)[:size], nil } -_commit :: proc(data: rawptr, size: uint) -> Allocator_Error { +_commit :: proc "contextless" (data: rawptr, size: uint) -> Allocator_Error { result := mprotect(data, size, PROT_READ|PROT_WRITE) if result != 0 { // TODO(bill): Handle error value correctly @@ -75,14 +75,14 @@ _commit :: proc(data: rawptr, size: uint) -> Allocator_Error { } return nil } -_decommit :: proc(data: rawptr, size: uint) { +_decommit :: proc "contextless" (data: rawptr, size: uint) { mprotect(data, size, PROT_NONE) madvise(data, size, MADV_FREE) } -_release :: proc(data: rawptr, size: uint) { +_release :: proc "contextless" (data: rawptr, size: uint) { munmap(data, size) } -_protect :: proc(data: rawptr, size: uint, flags: Protect_Flags) -> bool { +_protect :: proc "contextless" (data: rawptr, size: uint, flags: Protect_Flags) -> bool { pflags: c.int pflags = PROT_NONE if .Read in flags { pflags |= PROT_READ } diff --git a/core/mem/virtual/virtual_platform.odin b/core/mem/virtual/virtual_platform.odin index c4211ba5e..367346f63 100644 --- a/core/mem/virtual/virtual_platform.odin +++ b/core/mem/virtual/virtual_platform.odin @@ -1,15 +1,16 @@ //+private package mem_virtual -import sync "core:sync/sync2" +import "core:sync" Platform_Memory_Block :: struct { - block: Memory_Block, - reserved: uint, + block: Memory_Block, + committed: uint, + reserved: uint, prev, next: ^Platform_Memory_Block, } -platform_memory_alloc :: proc(to_commit, to_reserve: uint) -> (block: ^Platform_Memory_Block, err: Allocator_Error) { +platform_memory_alloc :: proc "contextless" (to_commit, to_reserve: uint) -> (block: ^Platform_Memory_Block, err: Allocator_Error) { to_commit, to_reserve := to_commit, to_reserve to_reserve = max(to_commit, to_reserve) @@ -20,12 +21,13 @@ platform_memory_alloc :: proc(to_commit, to_reserve: uint) -> (block: ^Platform_ commit(raw_data(data), to_commit) block = (^Platform_Memory_Block)(raw_data(data)) - block.reserved = to_reserve + block.committed = to_commit + block.reserved = to_reserve return } -platform_memory_free :: proc(block: ^Platform_Memory_Block) { +platform_memory_free :: proc "contextless" (block: ^Platform_Memory_Block) { if block != nil { release(block, block.reserved) } @@ -52,3 +54,17 @@ platform_memory_init :: proc() { global_platform_memory_block_sentinel_set = true } } + +platform_memory_commit :: proc "contextless" (block: ^Platform_Memory_Block, to_commit: uint) -> (err: Allocator_Error) { + if to_commit < block.committed { + return nil + } + if to_commit > block.reserved { + return .Out_Of_Memory + } + + + commit(block, to_commit) or_return + block.committed = to_commit + return nil +} diff --git a/core/mem/virtual/virtual_windows.odin b/core/mem/virtual/virtual_windows.odin index 623e8d469..ef0bf6f1a 100644 --- a/core/mem/virtual/virtual_windows.odin +++ b/core/mem/virtual/virtual_windows.odin @@ -62,7 +62,7 @@ foreign Kernel32 { } -_reserve :: proc(size: uint) -> (data: []byte, err: Allocator_Error) { +_reserve :: proc "contextless" (size: uint) -> (data: []byte, err: Allocator_Error) { result := VirtualAlloc(nil, size, MEM_RESERVE, PAGE_READWRITE) if result == nil { err = .Out_Of_Memory @@ -72,7 +72,7 @@ _reserve :: proc(size: uint) -> (data: []byte, err: Allocator_Error) { return } -_commit :: proc(data: rawptr, size: uint) -> Allocator_Error { +_commit :: proc "contextless" (data: rawptr, size: uint) -> Allocator_Error { result := VirtualAlloc(data, size, MEM_COMMIT, PAGE_READWRITE) if result == nil { switch err := GetLastError(); err { @@ -85,13 +85,13 @@ _commit :: proc(data: rawptr, size: uint) -> Allocator_Error { } return nil } -_decommit :: proc(data: rawptr, size: uint) { +_decommit :: proc "contextless" (data: rawptr, size: uint) { VirtualFree(data, size, MEM_DECOMMIT) } -_release :: proc(data: rawptr, size: uint) { +_release :: proc "contextless" (data: rawptr, size: uint) { VirtualFree(data, 0, MEM_RELEASE) } -_protect :: proc(data: rawptr, size: uint, flags: Protect_Flags) -> bool { +_protect :: proc "contextless" (data: rawptr, size: uint, flags: Protect_Flags) -> bool { pflags: u32 pflags = PAGE_NOACCESS switch flags { diff --git a/core/odin/ast/ast.odin b/core/odin/ast/ast.odin index 260979d89..f4aa67446 100644 --- a/core/odin/ast/ast.odin +++ b/core/odin/ast/ast.odin @@ -34,7 +34,7 @@ Node :: struct { pos: tokenizer.Pos, end: tokenizer.Pos, state_flags: Node_State_Flags, - derived: any, + derived: Any_Node, } Comment_Group :: struct { @@ -88,9 +88,11 @@ File :: struct { Expr :: struct { using expr_base: Node, + derived_expr: Any_Expr, } Stmt :: struct { using stmt_base: Node, + derived_stmt: Any_Stmt, } Decl :: struct { using decl_base: Stmt, @@ -151,6 +153,7 @@ Comp_Lit :: struct { open: tokenizer.Pos, elems: []^Expr, close: tokenizer.Pos, + tag: ^Expr, } @@ -540,7 +543,7 @@ unparen_expr :: proc(expr: ^Expr) -> (val: ^Expr) { return } for { - e, ok := val.derived.(Paren_Expr) + e, ok := val.derived.(^Paren_Expr) if !ok || e.expr == nil { break } @@ -705,12 +708,19 @@ Struct_Type :: struct { name_count: int, } +Union_Type_Kind :: enum u8 { + Normal, + maybe, + no_nil, + shared_nil, +} + Union_Type :: struct { using node: Expr, tok_pos: tokenizer.Pos, poly_params: ^Field_List, align: ^Expr, - is_maybe: bool, + kind: Union_Type_Kind, where_token: tokenizer.Token, where_clauses: []^Expr, variants: []^Expr, @@ -756,4 +766,173 @@ Matrix_Type :: struct { row_count: ^Expr, column_count: ^Expr, elem: ^Expr, -} \ No newline at end of file +} + + +Any_Node :: union { + ^Package, + ^File, + ^Comment_Group, + + ^Bad_Expr, + ^Ident, + ^Implicit, + ^Undef, + ^Basic_Lit, + ^Basic_Directive, + ^Ellipsis, + ^Proc_Lit, + ^Comp_Lit, + ^Tag_Expr, + ^Unary_Expr, + ^Binary_Expr, + ^Paren_Expr, + ^Selector_Expr, + ^Implicit_Selector_Expr, + ^Selector_Call_Expr, + ^Index_Expr, + ^Deref_Expr, + ^Slice_Expr, + ^Matrix_Index_Expr, + ^Call_Expr, + ^Field_Value, + ^Ternary_If_Expr, + ^Ternary_When_Expr, + ^Or_Else_Expr, + ^Or_Return_Expr, + ^Type_Assertion, + ^Type_Cast, + ^Auto_Cast, + ^Inline_Asm_Expr, + + ^Proc_Group, + + ^Typeid_Type, + ^Helper_Type, + ^Distinct_Type, + ^Poly_Type, + ^Proc_Type, + ^Pointer_Type, + ^Multi_Pointer_Type, + ^Array_Type, + ^Dynamic_Array_Type, + ^Struct_Type, + ^Union_Type, + ^Enum_Type, + ^Bit_Set_Type, + ^Map_Type, + ^Relative_Type, + ^Matrix_Type, + + ^Bad_Stmt, + ^Empty_Stmt, + ^Expr_Stmt, + ^Tag_Stmt, + ^Assign_Stmt, + ^Block_Stmt, + ^If_Stmt, + ^When_Stmt, + ^Return_Stmt, + ^Defer_Stmt, + ^For_Stmt, + ^Range_Stmt, + ^Inline_Range_Stmt, + ^Case_Clause, + ^Switch_Stmt, + ^Type_Switch_Stmt, + ^Branch_Stmt, + ^Using_Stmt, + + ^Bad_Decl, + ^Value_Decl, + ^Package_Decl, + ^Import_Decl, + ^Foreign_Block_Decl, + ^Foreign_Import_Decl, + + ^Attribute, + ^Field, + ^Field_List, +} + + +Any_Expr :: union { + ^Bad_Expr, + ^Ident, + ^Implicit, + ^Undef, + ^Basic_Lit, + ^Basic_Directive, + ^Ellipsis, + ^Proc_Lit, + ^Comp_Lit, + ^Tag_Expr, + ^Unary_Expr, + ^Binary_Expr, + ^Paren_Expr, + ^Selector_Expr, + ^Implicit_Selector_Expr, + ^Selector_Call_Expr, + ^Index_Expr, + ^Deref_Expr, + ^Slice_Expr, + ^Matrix_Index_Expr, + ^Call_Expr, + ^Field_Value, + ^Ternary_If_Expr, + ^Ternary_When_Expr, + ^Or_Else_Expr, + ^Or_Return_Expr, + ^Type_Assertion, + ^Type_Cast, + ^Auto_Cast, + ^Inline_Asm_Expr, + + ^Proc_Group, + + ^Typeid_Type, + ^Helper_Type, + ^Distinct_Type, + ^Poly_Type, + ^Proc_Type, + ^Pointer_Type, + ^Multi_Pointer_Type, + ^Array_Type, + ^Dynamic_Array_Type, + ^Struct_Type, + ^Union_Type, + ^Enum_Type, + ^Bit_Set_Type, + ^Map_Type, + ^Relative_Type, + ^Matrix_Type, +} + + +Any_Stmt :: union { + ^Bad_Stmt, + ^Empty_Stmt, + ^Expr_Stmt, + ^Tag_Stmt, + ^Assign_Stmt, + ^Block_Stmt, + ^If_Stmt, + ^When_Stmt, + ^Return_Stmt, + ^Defer_Stmt, + ^For_Stmt, + ^Range_Stmt, + ^Inline_Range_Stmt, + ^Case_Clause, + ^Switch_Stmt, + ^Type_Switch_Stmt, + ^Branch_Stmt, + ^Using_Stmt, + + ^Bad_Decl, + ^Value_Decl, + ^Package_Decl, + ^Import_Decl, + ^Foreign_Block_Decl, + ^Foreign_Import_Decl, +} diff --git a/core/odin/ast/clone.odin b/core/odin/ast/clone.odin index 1e3058678..400c064f5 100644 --- a/core/odin/ast/clone.odin +++ b/core/odin/ast/clone.odin @@ -1,16 +1,25 @@ package odin_ast +import "core:intrinsics" import "core:mem" import "core:fmt" +import "core:reflect" import "core:odin/tokenizer" +_ :: intrinsics new :: proc($T: typeid, pos, end: tokenizer.Pos) -> ^T { n, _ := mem.new(T) n.pos = pos n.end = end - n.derived = n^ + n.derived = n base: ^Node = n // dummy check _ = base // "Use" type to make -vet happy + when intrinsics.type_has_field(T, "derived_expr") { + n.derived_expr = n + } + when intrinsics.type_has_field(T, "derived_stmt") { + n.derived_stmt = n + } return n } @@ -59,232 +68,257 @@ clone_node :: proc(node: ^Node) -> ^Node { return nil } - size := size_of(Node) + size := size_of(Node) align := align_of(Node) - ti := type_info_of(node.derived.id) + ti := reflect.union_variant_type_info(node.derived) if ti != nil { - size = ti.size - align = ti.align + elem := ti.variant.(reflect.Type_Info_Pointer).elem + size = elem.size + align = elem.align } - switch in node.derived { - case Package, File: + #partial switch in node.derived { + case ^Package, ^File: panic("Cannot clone this node type") } res := cast(^Node)mem.alloc(size, align) src: rawptr = node if node.derived != nil { - src = node.derived.data + src = (^rawptr)(&node.derived)^ } mem.copy(res, src, size) - res.derived.data = rawptr(res) - res.derived.id = node.derived.id + res_ptr_any: any + res_ptr_any.data = &res + res_ptr_any.id = ti.id - switch r in &res.derived { - case Bad_Expr: - case Ident: - case Implicit: - case Undef: - case Basic_Lit: + reflect.set_union_value(res.derived, res_ptr_any) - case Ellipsis: + res_ptr := reflect.deref(res_ptr_any) + + if de := reflect.struct_field_value_by_name(res_ptr, "derived_expr", true); de != nil { + reflect.set_union_value(de, res_ptr_any) + } + if ds := reflect.struct_field_value_by_name(res_ptr, "derived_stmt", true); ds != nil { + reflect.set_union_value(ds, res_ptr_any) + } + + if res.derived != nil do switch r in res.derived { + case ^Package, ^File: + case ^Bad_Expr: + case ^Ident: + case ^Implicit: + case ^Undef: + case ^Basic_Lit: + case ^Basic_Directive: + case ^Comment_Group: + + case ^Ellipsis: r.expr = clone(r.expr) - case Proc_Lit: + case ^Proc_Lit: r.type = auto_cast clone(r.type) r.body = clone(r.body) - case Comp_Lit: + case ^Comp_Lit: r.type = clone(r.type) r.elems = clone(r.elems) - case Tag_Expr: + case ^Tag_Expr: r.expr = clone(r.expr) - case Unary_Expr: + case ^Unary_Expr: r.expr = clone(r.expr) - case Binary_Expr: + case ^Binary_Expr: r.left = clone(r.left) r.right = clone(r.right) - case Paren_Expr: + case ^Paren_Expr: r.expr = clone(r.expr) - case Selector_Expr: + case ^Selector_Expr: r.expr = clone(r.expr) r.field = auto_cast clone(r.field) - case Implicit_Selector_Expr: + case ^Implicit_Selector_Expr: r.field = auto_cast clone(r.field) - case Selector_Call_Expr: + case ^Selector_Call_Expr: r.expr = clone(r.expr) r.call = auto_cast clone(r.call) - case Index_Expr: + case ^Index_Expr: r.expr = clone(r.expr) r.index = clone(r.index) - case Matrix_Index_Expr: + case ^Matrix_Index_Expr: r.expr = clone(r.expr) r.row_index = clone(r.row_index) r.column_index = clone(r.column_index) - case Deref_Expr: + case ^Deref_Expr: r.expr = clone(r.expr) - case Slice_Expr: + case ^Slice_Expr: r.expr = clone(r.expr) r.low = clone(r.low) r.high = clone(r.high) - case Call_Expr: + case ^Call_Expr: r.expr = clone(r.expr) r.args = clone(r.args) - case Field_Value: + case ^Field_Value: r.field = clone(r.field) r.value = clone(r.value) - case Ternary_If_Expr: + case ^Ternary_If_Expr: r.x = clone(r.x) r.cond = clone(r.cond) r.y = clone(r.y) - case Ternary_When_Expr: + case ^Ternary_When_Expr: r.x = clone(r.x) r.cond = clone(r.cond) r.y = clone(r.y) - case Or_Else_Expr: + case ^Or_Else_Expr: r.x = clone(r.x) r.y = clone(r.y) - case Or_Return_Expr: + case ^Or_Return_Expr: r.expr = clone(r.expr) - case Type_Assertion: + case ^Type_Assertion: r.expr = clone(r.expr) r.type = clone(r.type) - case Type_Cast: + case ^Type_Cast: r.type = clone(r.type) r.expr = clone(r.expr) - case Auto_Cast: + case ^Auto_Cast: r.expr = clone(r.expr) - case Inline_Asm_Expr: + case ^Inline_Asm_Expr: r.param_types = clone(r.param_types) r.return_type = clone(r.return_type) r.constraints_string = clone(r.constraints_string) r.asm_string = clone(r.asm_string) - case Bad_Stmt: + case ^Bad_Stmt: // empty - case Empty_Stmt: + case ^Empty_Stmt: // empty - case Expr_Stmt: + case ^Expr_Stmt: r.expr = clone(r.expr) - case Tag_Stmt: + case ^Tag_Stmt: r.stmt = clone(r.stmt) - case Assign_Stmt: + case ^Assign_Stmt: r.lhs = clone(r.lhs) r.rhs = clone(r.rhs) - case Block_Stmt: + case ^Block_Stmt: r.label = clone(r.label) r.stmts = clone(r.stmts) - case If_Stmt: + case ^If_Stmt: r.label = clone(r.label) r.init = clone(r.init) r.cond = clone(r.cond) r.body = clone(r.body) r.else_stmt = clone(r.else_stmt) - case When_Stmt: + case ^When_Stmt: r.cond = clone(r.cond) r.body = clone(r.body) r.else_stmt = clone(r.else_stmt) - case Return_Stmt: + case ^Return_Stmt: r.results = clone(r.results) - case Defer_Stmt: + case ^Defer_Stmt: r.stmt = clone(r.stmt) - case For_Stmt: + case ^For_Stmt: r.label = clone(r.label) r.init = clone(r.init) r.cond = clone(r.cond) r.post = clone(r.post) r.body = clone(r.body) - case Range_Stmt: + case ^Range_Stmt: r.label = clone(r.label) r.vals = clone(r.vals) r.expr = clone(r.expr) r.body = clone(r.body) - case Case_Clause: + case ^Inline_Range_Stmt: + r.label = clone(r.label) + r.val0 = clone(r.val0) + r.val1 = clone(r.val1) + r.expr = clone(r.expr) + r.body = clone(r.body) + case ^Case_Clause: r.list = clone(r.list) r.body = clone(r.body) - case Switch_Stmt: + case ^Switch_Stmt: r.label = clone(r.label) r.init = clone(r.init) r.cond = clone(r.cond) r.body = clone(r.body) - case Type_Switch_Stmt: + case ^Type_Switch_Stmt: r.label = clone(r.label) r.tag = clone(r.tag) r.expr = clone(r.expr) r.body = clone(r.body) - case Branch_Stmt: + case ^Branch_Stmt: r.label = auto_cast clone(r.label) - case Using_Stmt: + case ^Using_Stmt: r.list = clone(r.list) - case Bad_Decl: - case Value_Decl: + case ^Bad_Decl: + case ^Value_Decl: r.attributes = clone(r.attributes) r.names = clone(r.names) r.type = clone(r.type) r.values = clone(r.values) - case Package_Decl: - case Import_Decl: - case Foreign_Block_Decl: + case ^Package_Decl: + case ^Import_Decl: + case ^Foreign_Block_Decl: r.attributes = clone(r.attributes) r.foreign_library = clone(r.foreign_library) r.body = clone(r.body) - case Foreign_Import_Decl: + case ^Foreign_Import_Decl: r.name = auto_cast clone(r.name) - case Proc_Group: + case ^Proc_Group: r.args = clone(r.args) - case Attribute: + case ^Attribute: r.elems = clone(r.elems) - case Field: + case ^Field: r.names = clone(r.names) r.type = clone(r.type) r.default_value = clone(r.default_value) - case Field_List: + case ^Field_List: r.list = clone(r.list) - case Typeid_Type: + case ^Typeid_Type: r.specialization = clone(r.specialization) - case Helper_Type: + case ^Helper_Type: r.type = clone(r.type) - case Distinct_Type: + case ^Distinct_Type: r.type = clone(r.type) - case Poly_Type: + case ^Poly_Type: r.type = auto_cast clone(r.type) r.specialization = clone(r.specialization) - case Proc_Type: + case ^Proc_Type: r.params = auto_cast clone(r.params) r.results = auto_cast clone(r.results) - case Pointer_Type: + case ^Pointer_Type: r.elem = clone(r.elem) - case Multi_Pointer_Type: + case ^Multi_Pointer_Type: r.elem = clone(r.elem) - case Array_Type: + case ^Array_Type: r.len = clone(r.len) r.elem = clone(r.elem) - case Dynamic_Array_Type: + case ^Dynamic_Array_Type: r.elem = clone(r.elem) - case Struct_Type: + case ^Struct_Type: r.poly_params = auto_cast clone(r.poly_params) r.align = clone(r.align) r.fields = auto_cast clone(r.fields) - case Union_Type: + case ^Union_Type: r.poly_params = auto_cast clone(r.poly_params) r.align = clone(r.align) r.variants = clone(r.variants) - case Enum_Type: + case ^Enum_Type: r.base_type = clone(r.base_type) r.fields = clone(r.fields) - case Bit_Set_Type: + case ^Bit_Set_Type: r.elem = clone(r.elem) r.underlying = clone(r.underlying) - case Map_Type: + case ^Map_Type: r.key = clone(r.key) r.value = clone(r.value) - case Matrix_Type: + case ^Matrix_Type: r.row_count = clone(r.row_count) r.column_count = clone(r.column_count) r.elem = clone(r.elem) + case ^Relative_Type: + r.tag = clone(r.tag) + r.type = clone(r.type) case: - fmt.panicf("Unhandled node kind: %T", r) + fmt.panicf("Unhandled node kind: %v", r) } return res diff --git a/core/odin/ast/walk.odin b/core/odin/ast/walk.odin index d0d17cc9e..b4eaf8140 100644 --- a/core/odin/ast/walk.odin +++ b/core/odin/ast/walk.odin @@ -52,71 +52,74 @@ walk :: proc(v: ^Visitor, node: ^Node) { } } - v := v + if v == nil || node == nil { + return + } + if v = v->visit(node); v == nil { return } switch n in &node.derived { - case File: + case ^File: if n.docs != nil { walk(v, n.docs) } walk_stmt_list(v, n.decls[:]) - case Package: + case ^Package: for _, f in n.files { walk(v, f) } - case Comment_Group: + case ^Comment_Group: // empty - case Bad_Expr: - case Ident: - case Implicit: - case Undef: - case Basic_Lit: - case Basic_Directive: - case Ellipsis: + case ^Bad_Expr: + case ^Ident: + case ^Implicit: + case ^Undef: + case ^Basic_Lit: + case ^Basic_Directive: + case ^Ellipsis: if n.expr != nil { walk(v, n.expr) } - case Proc_Lit: + case ^Proc_Lit: walk(v, n.type) walk(v, n.body) walk_expr_list(v, n.where_clauses) - case Comp_Lit: + case ^Comp_Lit: if n.type != nil { walk(v, n.type) } walk_expr_list(v, n.elems) - case Tag_Expr: + case ^Tag_Expr: walk(v, n.expr) - case Unary_Expr: + case ^Unary_Expr: walk(v, n.expr) - case Binary_Expr: + case ^Binary_Expr: walk(v, n.left) walk(v, n.right) - case Paren_Expr: + case ^Paren_Expr: walk(v, n.expr) - case Selector_Expr: + case ^Selector_Expr: walk(v, n.expr) walk(v, n.field) - case Implicit_Selector_Expr: + case ^Implicit_Selector_Expr: walk(v, n.field) - case Selector_Call_Expr: + case ^Selector_Call_Expr: walk(v, n.expr) walk(v, n.call) - case Index_Expr: + case ^Index_Expr: walk(v, n.expr) walk(v, n.index) - case Matrix_Index_Expr: + case ^Matrix_Index_Expr: walk(v, n.expr) walk(v, n.row_index) walk(v, n.column_index) - case Deref_Expr: + case ^Deref_Expr: walk(v, n.expr) - case Slice_Expr: + case ^Slice_Expr: walk(v, n.expr) if n.low != nil { walk(v, n.low) @@ -124,57 +127,57 @@ walk :: proc(v: ^Visitor, node: ^Node) { if n.high != nil { walk(v, n.high) } - case Call_Expr: + case ^Call_Expr: walk(v, n.expr) walk_expr_list(v, n.args) - case Field_Value: + case ^Field_Value: walk(v, n.field) walk(v, n.value) - case Ternary_If_Expr: + case ^Ternary_If_Expr: walk(v, n.x) walk(v, n.cond) walk(v, n.y) - case Ternary_When_Expr: + case ^Ternary_When_Expr: walk(v, n.x) walk(v, n.cond) walk(v, n.y) - case Or_Else_Expr: + case ^Or_Else_Expr: walk(v, n.x) walk(v, n.y) - case Or_Return_Expr: + case ^Or_Return_Expr: walk(v, n.expr) - case Type_Assertion: + case ^Type_Assertion: walk(v, n.expr) if n.type != nil { walk(v, n.type) } - case Type_Cast: + case ^Type_Cast: walk(v, n.type) walk(v, n.expr) - case Auto_Cast: + case ^Auto_Cast: walk(v, n.expr) - case Inline_Asm_Expr: + case ^Inline_Asm_Expr: walk_expr_list(v, n.param_types) walk(v, n.return_type) walk(v, n.constraints_string) walk(v, n.asm_string) - case Bad_Stmt: - case Empty_Stmt: - case Expr_Stmt: + case ^Bad_Stmt: + case ^Empty_Stmt: + case ^Expr_Stmt: walk(v, n.expr) - case Tag_Stmt: + case ^Tag_Stmt: walk(v, n.stmt) - case Assign_Stmt: + case ^Assign_Stmt: walk_expr_list(v, n.lhs) walk_expr_list(v, n.rhs) - case Block_Stmt: + case ^Block_Stmt: if n.label != nil { walk(v, n.label) } walk_stmt_list(v, n.stmts) - case If_Stmt: + case ^If_Stmt: if n.label != nil { walk(v, n.label) } @@ -186,17 +189,17 @@ walk :: proc(v: ^Visitor, node: ^Node) { if n.else_stmt != nil { walk(v, n.else_stmt) } - case When_Stmt: + case ^When_Stmt: walk(v, n.cond) walk(v, n.body) if n.else_stmt != nil { walk(v, n.else_stmt) } - case Return_Stmt: + case ^Return_Stmt: walk_expr_list(v, n.results) - case Defer_Stmt: + case ^Defer_Stmt: walk(v, n.stmt) - case For_Stmt: + case ^For_Stmt: if n.label != nil { walk(v, n.label) } @@ -210,7 +213,7 @@ walk :: proc(v: ^Visitor, node: ^Node) { walk(v, n.post) } walk(v, n.body) - case Range_Stmt: + case ^Range_Stmt: if n.label != nil { walk(v, n.label) } @@ -221,7 +224,7 @@ walk :: proc(v: ^Visitor, node: ^Node) { } walk(v, n.expr) walk(v, n.body) - case Inline_Range_Stmt: + case ^Inline_Range_Stmt: if n.label != nil { walk(v, n.label) } @@ -233,10 +236,10 @@ walk :: proc(v: ^Visitor, node: ^Node) { } walk(v, n.expr) walk(v, n.body) - case Case_Clause: + case ^Case_Clause: walk_expr_list(v, n.list) walk_stmt_list(v, n.body) - case Switch_Stmt: + case ^Switch_Stmt: if n.label != nil { walk(v, n.label) } @@ -247,7 +250,7 @@ walk :: proc(v: ^Visitor, node: ^Node) { walk(v, n.cond) } walk(v, n.body) - case Type_Switch_Stmt: + case ^Type_Switch_Stmt: if n.label != nil { walk(v, n.label) } @@ -258,16 +261,16 @@ walk :: proc(v: ^Visitor, node: ^Node) { walk(v, n.expr) } walk(v, n.body) - case Branch_Stmt: + case ^Branch_Stmt: if n.label != nil { walk(v, n.label) } - case Using_Stmt: + case ^Using_Stmt: walk_expr_list(v, n.list) - case Bad_Decl: - case Value_Decl: + case ^Bad_Decl: + case ^Value_Decl: if n.docs != nil { walk(v, n.docs) } @@ -280,21 +283,21 @@ walk :: proc(v: ^Visitor, node: ^Node) { if n.comment != nil { walk(v, n.comment) } - case Package_Decl: + case ^Package_Decl: if n.docs != nil { walk(v, n.docs) } if n.comment != nil { walk(v, n.comment) } - case Import_Decl: + case ^Import_Decl: if n.docs != nil { walk(v, n.docs) } if n.comment != nil { walk(v, n.comment) } - case Foreign_Block_Decl: + case ^Foreign_Block_Decl: if n.docs != nil { walk(v, n.docs) } @@ -303,7 +306,7 @@ walk :: proc(v: ^Visitor, node: ^Node) { walk(v, n.foreign_library) } walk(v, n.body) - case Foreign_Import_Decl: + case ^Foreign_Import_Decl: if n.docs != nil { walk(v, n.docs) } @@ -313,11 +316,11 @@ walk :: proc(v: ^Visitor, node: ^Node) { walk(v, n.comment) } - case Proc_Group: + case ^Proc_Group: walk_expr_list(v, n.args) - case Attribute: + case ^Attribute: walk_expr_list(v, n.elems) - case Field: + case ^Field: if n.docs != nil { walk(v, n.docs) } @@ -331,31 +334,31 @@ walk :: proc(v: ^Visitor, node: ^Node) { if n.comment != nil { walk(v, n.comment) } - case Field_List: + case ^Field_List: for x in n.list { walk(v, x) } - case Typeid_Type: + case ^Typeid_Type: if n.specialization != nil { walk(v, n.specialization) } - case Helper_Type: + case ^Helper_Type: walk(v, n.type) - case Distinct_Type: + case ^Distinct_Type: walk(v, n.type) - case Poly_Type: + case ^Poly_Type: walk(v, n.type) if n.specialization != nil { walk(v, n.specialization) } - case Proc_Type: + case ^Proc_Type: walk(v, n.params) walk(v, n.results) - case Pointer_Type: + case ^Pointer_Type: walk(v, n.elem) - case Multi_Pointer_Type: + case ^Multi_Pointer_Type: walk(v, n.elem) - case Array_Type: + case ^Array_Type: if n.tag != nil { walk(v, n.tag) } @@ -363,12 +366,12 @@ walk :: proc(v: ^Visitor, node: ^Node) { walk(v, n.len) } walk(v, n.elem) - case Dynamic_Array_Type: + case ^Dynamic_Array_Type: if n.tag != nil { walk(v, n.tag) } walk(v, n.elem) - case Struct_Type: + case ^Struct_Type: if n.poly_params != nil { walk(v, n.poly_params) } @@ -377,7 +380,7 @@ walk :: proc(v: ^Visitor, node: ^Node) { } walk_expr_list(v, n.where_clauses) walk(v, n.fields) - case Union_Type: + case ^Union_Type: if n.poly_params != nil { walk(v, n.poly_params) } @@ -386,23 +389,23 @@ walk :: proc(v: ^Visitor, node: ^Node) { } walk_expr_list(v, n.where_clauses) walk_expr_list(v, n.variants) - case Enum_Type: + case ^Enum_Type: if n.base_type != nil { walk(v, n.base_type) } walk_expr_list(v, n.fields) - case Bit_Set_Type: + case ^Bit_Set_Type: walk(v, n.elem) if n.underlying != nil { walk(v, n.underlying) } - case Map_Type: + case ^Map_Type: walk(v, n.key) walk(v, n.value) - case Relative_Type: + case ^Relative_Type: walk(v, n.tag) walk(v, n.type) - case Matrix_Type: + case ^Matrix_Type: walk(v, n.row_count) walk(v, n.column_count) walk(v, n.elem) diff --git a/core/odin/doc-format/doc_format.odin b/core/odin/doc-format/doc_format.odin index c80be2489..62682004d 100644 --- a/core/odin/doc-format/doc_format.odin +++ b/core/odin/doc-format/doc_format.odin @@ -11,7 +11,7 @@ String :: distinct Array(byte) Version_Type_Major :: 0 Version_Type_Minor :: 2 -Version_Type_Patch :: 1 +Version_Type_Patch :: 4 Version_Type :: struct { major, minor, patch: u8, @@ -77,9 +77,15 @@ Pkg :: struct { flags: Pkg_Flags, docs: String, files: Array(File_Index), - entities: Array(Entity_Index), + entries: Array(Scope_Entry), } +Scope_Entry :: struct { + name: String, + entity: Entity_Index, +} + + Entity_Kind :: enum u32le { Invalid = 0, Constant = 1, @@ -89,6 +95,7 @@ Entity_Kind :: enum u32le { Proc_Group = 5, Import_Name = 6, Library_Name = 7, + Builtin = 8, } Entity_Flag :: enum u32le { @@ -105,8 +112,13 @@ Entity_Flag :: enum u32le { Type_Alias = 20, + Builtin_Pkg_Builtin = 30, + Builtin_Pkg_Intrinsics = 31, + Var_Thread_Local = 40, Var_Static = 41, + + Private = 50, } Entity_Flags :: distinct bit_set[Entity_Flag; u64le] @@ -122,6 +134,10 @@ Entity :: struct { _: u32le, // reserved for init comment: String, docs: String, + // May be used by (Struct fields and procedure fields): + // .Variable + // .Constant + field_group_index: i32le, // May used by: // .Variable @@ -242,6 +258,8 @@ Type :: struct { polymorphic_params: Type_Index, // Used By: .Struct, .Union where_clauses: Array(String), + // Used By: .Struct + tags: Array(String), } Type_Flags_Basic :: distinct bit_set[Type_Flag_Basic; u32le] diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index 52d4b5e5a..25eda6bed 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -195,10 +195,10 @@ parse_file :: proc(p: ^Parser, file: ^ast.File) -> bool { for p.curr_tok.kind != .EOF { stmt := parse_stmt(p) if stmt != nil { - if _, ok := stmt.derived.(ast.Empty_Stmt); !ok { + if _, ok := stmt.derived.(^ast.Empty_Stmt); !ok { append(&p.file.decls, stmt) - if es, es_ok := stmt.derived.(ast.Expr_Stmt); es_ok && es.expr != nil { - if _, pl_ok := es.expr.derived.(ast.Proc_Lit); pl_ok { + if es, es_ok := stmt.derived.(^ast.Expr_Stmt); es_ok && es.expr != nil { + if _, pl_ok := es.expr.derived.(^ast.Proc_Lit); pl_ok { error(p, stmt.pos, "procedure literal evaluated but not used") } } @@ -428,9 +428,21 @@ expect_closing_brace_of_field_list :: proc(p: ^Parser) -> tokenizer.Token { str := tokenizer.token_to_string(token) error(p, end_of_line_pos(p, p.prev_tok), "expected a comma, got %s", str) } - return expect_token(p, .Close_Brace) + expect_brace := expect_token(p, .Close_Brace) + + if expect_brace.kind != .Close_Brace { + for p.curr_tok.kind != .Close_Brace && p.curr_tok.kind != .EOF && !is_non_inserted_semicolon(p.curr_tok) { + advance_token(p) + } + return p.curr_tok + } + + return expect_brace } +is_non_inserted_semicolon :: proc(tok: tokenizer.Token) -> bool { + return tok.kind == .Semicolon && tok.text != "\n" +} is_blank_ident :: proc{ is_blank_ident_string, @@ -447,7 +459,7 @@ is_blank_ident_token :: proc(tok: tokenizer.Token) -> bool { return false } is_blank_ident_node :: proc(node: ^ast.Node) -> bool { - if ident, ok := node.derived.(ast.Ident); ok { + if ident, ok := node.derived.(^ast.Ident); ok { return is_blank_ident(ident.name) } return true @@ -490,34 +502,34 @@ is_semicolon_optional_for_node :: proc(p: ^Parser, node: ^ast.Node) -> bool { return true } - switch n in node.derived { - case ast.Empty_Stmt, ast.Block_Stmt: + #partial switch n in node.derived { + case ^ast.Empty_Stmt, ^ast.Block_Stmt: return true - case ast.If_Stmt, ast.When_Stmt, - ast.For_Stmt, ast.Range_Stmt, ast.Inline_Range_Stmt, - ast.Switch_Stmt, ast.Type_Switch_Stmt: + case ^ast.If_Stmt, ^ast.When_Stmt, + ^ast.For_Stmt, ^ast.Range_Stmt, ^ast.Inline_Range_Stmt, + ^ast.Switch_Stmt, ^ast.Type_Switch_Stmt: return true - case ast.Helper_Type: + case ^ast.Helper_Type: return is_semicolon_optional_for_node(p, n.type) - case ast.Distinct_Type: + case ^ast.Distinct_Type: return is_semicolon_optional_for_node(p, n.type) - case ast.Pointer_Type: + case ^ast.Pointer_Type: return is_semicolon_optional_for_node(p, n.elem) - case ast.Struct_Type, ast.Union_Type, ast.Enum_Type: + case ^ast.Struct_Type, ^ast.Union_Type, ^ast.Enum_Type: // Require semicolon within a procedure body return p.curr_proc == nil - case ast.Proc_Lit: + case ^ast.Proc_Lit: return true - case ast.Package_Decl, ast.Import_Decl, ast.Foreign_Import_Decl: + case ^ast.Package_Decl, ^ast.Import_Decl, ^ast.Foreign_Import_Decl: return true - case ast.Foreign_Block_Decl: + case ^ast.Foreign_Block_Decl: return is_semicolon_optional_for_node(p, n.body) - case ast.Value_Decl: + case ^ast.Value_Decl: if n.is_mutable { return false } @@ -629,10 +641,10 @@ parse_stmt_list :: proc(p: ^Parser) -> []^ast.Stmt { p.curr_tok.kind != .EOF { stmt := parse_stmt(p) if stmt != nil { - if _, ok := stmt.derived.(ast.Empty_Stmt); !ok { + if _, ok := stmt.derived.(^ast.Empty_Stmt); !ok { append(&list, stmt) - if es, es_ok := stmt.derived.(ast.Expr_Stmt); es_ok && es.expr != nil { - if _, pl_ok := es.expr.derived.(ast.Proc_Lit); pl_ok { + if es, es_ok := stmt.derived.(^ast.Expr_Stmt); es_ok && es.expr != nil { + if _, pl_ok := es.expr.derived.(^ast.Proc_Lit); pl_ok { error(p, stmt.pos, "procedure literal evaluated but not used") } } @@ -710,7 +722,7 @@ convert_stmt_to_expr :: proc(p: ^Parser, stmt: ^ast.Stmt, kind: string) -> ^ast. if stmt == nil { return nil } - if es, ok := stmt.derived.(ast.Expr_Stmt); ok { + if es, ok := stmt.derived.(^ast.Expr_Stmt); ok { return es.expr } error(p, stmt.pos, "expected %s, found a simple statement", kind) @@ -852,7 +864,7 @@ parse_for_stmt :: proc(p: ^Parser) -> ^ast.Stmt { if p.curr_tok.kind != .Semicolon { cond = parse_simple_stmt(p, {Stmt_Allow_Flag.In}) - if as, ok := cond.derived.(ast.Assign_Stmt); ok && as.op.kind == .In { + if as, ok := cond.derived.(^ast.Assign_Stmt); ok && as.op.kind == .In { is_range = true } } @@ -888,12 +900,13 @@ parse_for_stmt :: proc(p: ^Parser) -> ^ast.Stmt { error(p, body.pos, "the body of a 'do' must be on the same line as the 'for' token") } } else { + allow_token(p, .Semicolon) body = parse_body(p) } if is_range { - assign_stmt := cond.derived.(ast.Assign_Stmt) + assign_stmt := cond.derived.(^ast.Assign_Stmt) vals := assign_stmt.lhs[:] rhs: ^ast.Expr @@ -974,7 +987,7 @@ parse_switch_stmt :: proc(p: ^Parser) -> ^ast.Stmt { tag = as } else { tag = parse_simple_stmt(p, {Stmt_Allow_Flag.In}) - if as, ok := tag.derived.(ast.Assign_Stmt); ok && as.op.kind == .In { + if as, ok := tag.derived.(^ast.Assign_Stmt); ok && as.op.kind == .In { is_type_switch = true } else if parse_control_statement_semicolon_separator(p) { init = tag @@ -1061,14 +1074,14 @@ parse_attribute :: proc(p: ^Parser, tok: tokenizer.Token, open_kind, close_kind: skip_possible_newline(p) decl := parse_stmt(p) - switch d in &decl.derived { - case ast.Value_Decl: + #partial switch d in decl.derived_stmt { + case ^ast.Value_Decl: if d.docs == nil { d.docs = docs } append(&d.attributes, attribute) - case ast.Foreign_Block_Decl: + case ^ast.Foreign_Block_Decl: if d.docs == nil { d.docs = docs } append(&d.attributes, attribute) - case ast.Foreign_Import_Decl: + case ^ast.Foreign_Import_Decl: if d.docs == nil { d.docs = docs } append(&d.attributes, attribute) case: @@ -1082,11 +1095,11 @@ parse_attribute :: proc(p: ^Parser, tok: tokenizer.Token, open_kind, close_kind: parse_foreign_block_decl :: proc(p: ^Parser) -> ^ast.Stmt { decl := parse_stmt(p) - switch in decl.derived { - case ast.Empty_Stmt, ast.Bad_Stmt, ast.Bad_Decl: + #partial switch in decl.derived_stmt { + case ^ast.Empty_Stmt, ^ast.Bad_Stmt, ^ast.Bad_Decl: // Ignore return nil - case ast.When_Stmt, ast.Value_Decl: + case ^ast.When_Stmt, ^ast.Value_Decl: return decl } @@ -1290,13 +1303,13 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt { case .Defer: tok := advance_token(p) stmt := parse_stmt(p) - switch s in stmt.derived { - case ast.Empty_Stmt: + #partial switch s in stmt.derived_stmt { + case ^ast.Empty_Stmt: error(p, s.pos, "empty statement after defer (e.g. ';')") - case ast.Defer_Stmt: + case ^ast.Defer_Stmt: error(p, s.pos, "you cannot defer a defer statement") stmt = s.stmt - case ast.Return_Stmt: + case ^ast.Return_Stmt: error(p, s.pos, "you cannot defer a return statement") } ds := ast.new(ast.Defer_Stmt, tok.pos, stmt.end) @@ -1311,7 +1324,7 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt { } results: [dynamic]^ast.Expr - for p.curr_tok.kind != .Semicolon { + for p.curr_tok.kind != .Semicolon && p.curr_tok.kind != .Close_Brace { result := parse_expr(p, false) append(&results, result) if p.curr_tok.kind != .Comma || @@ -1368,8 +1381,8 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt { expect_token_after(p, .Colon, "identifier list") decl := parse_value_decl(p, list, docs) if decl != nil { - switch d in &decl.derived { - case ast.Value_Decl: + #partial switch d in decl.derived_stmt { + case ^ast.Value_Decl: d.is_using = true return decl } @@ -1400,9 +1413,9 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt { return stmt case "partial": stmt := parse_stmt(p) - switch s in &stmt.derived { - case ast.Switch_Stmt: s.partial = true - case ast.Type_Switch_Stmt: s.partial = true + #partial switch s in stmt.derived_stmt { + case ^ast.Switch_Stmt: s.partial = true + case ^ast.Type_Switch_Stmt: s.partial = true case: error(p, stmt.pos, "#partial can only be applied to a switch statement") } return stmt @@ -1547,11 +1560,11 @@ parse_body :: proc(p: ^Parser) -> ^ast.Block_Stmt { } convert_stmt_to_body :: proc(p: ^Parser, stmt: ^ast.Stmt) -> ^ast.Stmt { - switch s in stmt.derived { - case ast.Block_Stmt: + #partial switch s in stmt.derived_stmt { + case ^ast.Block_Stmt: error(p, stmt.pos, "expected a normal statement rather than a block statement") return stmt - case ast.Empty_Stmt: + case ^ast.Empty_Stmt: error(p, stmt.pos, "expected a non-empty statement") } @@ -1628,10 +1641,10 @@ convert_to_ident_list :: proc(p: ^Parser, list: []Expr_And_Flags, ignore_flags, id: ^ast.Expr = ident.expr - switch n in ident.expr.derived { - case ast.Ident: - case ast.Bad_Expr: - case ast.Poly_Type: + #partial switch n in ident.expr.derived_expr { + case ^ast.Ident: + case ^ast.Bad_Expr: + case ^ast.Poly_Type: if allow_poly_names { if n.specialization == nil { break @@ -1793,21 +1806,21 @@ check_procedure_name_list :: proc(p: ^Parser, names: []^ast.Expr) -> bool { return false } - _, first_is_polymorphic := names[0].derived.(ast.Poly_Type) + _, first_is_polymorphic := names[0].derived.(^ast.Poly_Type) any_polymorphic_names := first_is_polymorphic for i := 1; i < len(names); i += 1 { name := names[i] if first_is_polymorphic { - if _, ok := name.derived.(ast.Poly_Type); ok { + if _, ok := name.derived.(^ast.Poly_Type); ok { any_polymorphic_names = true } else { error(p, name.pos, "mixture of polymorphic and non-polymorphic identifiers") return any_polymorphic_names } } else { - if _, ok := name.derived.(ast.Poly_Type); ok { + if _, ok := name.derived.(^ast.Poly_Type); ok { any_polymorphic_names = true error(p, name.pos, "mixture of polymorphic and non-polymorphic identifiers") return any_polymorphic_names @@ -1872,7 +1885,7 @@ parse_field_list :: proc(p: ^Parser, follow: tokenizer.Token_Kind, allowed_flags if type == nil { return false } - _, ok := type.derived.(ast.Ellipsis) + _, ok := type.derived.(^ast.Ellipsis) return ok } @@ -1890,7 +1903,7 @@ parse_field_list :: proc(p: ^Parser, follow: tokenizer.Token_Kind, allowed_flags type = parse_var_type(p, allowed_flags) tt := ast.unparen_expr(type) if is_signature && !any_polymorphic_names { - if ti, ok := tt.derived.(ast.Typeid_Type); ok && ti.specialization != nil { + if ti, ok := tt.derived.(^ast.Typeid_Type); ok && ti.specialization != nil { error(p, tt.pos, "specialization of typeid is not allowed without polymorphic names") } } @@ -1966,7 +1979,7 @@ parse_field_list :: proc(p: ^Parser, follow: tokenizer.Token_Kind, allowed_flags p.curr_tok.kind != .EOF { prefix_flags := parse_field_prefixes(p) param := parse_var_type(p, allowed_flags & {.Typeid_Token, .Ellipsis}) - if _, ok := param.derived.(ast.Ellipsis); ok { + if _, ok := param.derived.(^ast.Ellipsis); ok { if seen_ellipsis { error(p, param.pos, "extra variadic parameter after ellipsis") } @@ -1993,8 +2006,8 @@ parse_field_list :: proc(p: ^Parser, follow: tokenizer.Token_Kind, allowed_flags names := make([]^ast.Expr, 1) names[0] = ast.new(ast.Ident, tok.pos, end_pos(tok)) - switch ident in &names[0].derived { - case ast.Ident: + #partial switch ident in names[0].derived_expr { + case ^ast.Ident: ident.name = tok.text case: unreachable() @@ -2124,12 +2137,12 @@ parse_proc_type :: proc(p: ^Parser, tok: tokenizer.Token) -> ^ast.Proc_Type { loop: for param in params.list { if param.type != nil { - if _, ok := param.type.derived.(ast.Poly_Type); ok { + if _, ok := param.type.derived.(^ast.Poly_Type); ok { is_generic = true break loop } for name in param.names { - if _, ok := name.derived.(ast.Poly_Type); ok { + if _, ok := name.derived.(^ast.Poly_Type); ok { is_generic = true break loop } @@ -2166,13 +2179,13 @@ parse_inlining_operand :: proc(p: ^Parser, lhs: bool, tok: tokenizer.Token) -> ^ } } - switch e in &ast.unparen_expr(expr).derived { - case ast.Proc_Lit: + #partial switch e in ast.unparen_expr(expr).derived_expr { + case ^ast.Proc_Lit: if e.inlining != .None && e.inlining != pi { error(p, expr.pos, "both 'inline' and 'no_inline' cannot be applied to a procedure literal") } e.inlining = pi - case ast.Call_Expr: + case ^ast.Call_Expr: if e.inlining != .None && e.inlining != pi { error(p, expr.pos, "both 'inline' and 'no_inline' cannot be applied to a procedure call") } @@ -2263,22 +2276,40 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr { bd.name = name.text original_type := parse_type(p) type := ast.unparen_expr(original_type) - switch t in &type.derived { - case ast.Array_Type: t.tag = bd - case ast.Dynamic_Array_Type: t.tag = bd + #partial switch t in type.derived_expr { + case ^ast.Array_Type: t.tag = bd + case ^ast.Dynamic_Array_Type: t.tag = bd case: error(p, original_type.pos, "expected an array type after #%s", name.text) } return original_type case "partial": + tag := ast.new(ast.Basic_Directive, tok.pos, end_pos(name)) + tag.tok = tok + tag.name = name.text + original_expr := parse_expr(p, lhs) + expr := ast.unparen_expr(original_expr) + #partial switch t in expr.derived_expr { + case ^ast.Comp_Lit: + t.tag = tag + case ^ast.Array_Type: + t.tag = tag + error(p, tok.pos, "#%s has been replaced with #sparse for non-contiguous enumerated array types", name.text) + case: + error(p, tok.pos, "expected a compound literal after #%s", name.text) + + } + return original_expr + + case "sparse": tag := ast.new(ast.Basic_Directive, tok.pos, end_pos(name)) tag.tok = tok tag.name = name.text original_type := parse_type(p) type := ast.unparen_expr(original_type) - switch t in &type.derived { - case ast.Array_Type: + #partial switch t in type.derived_expr { + case ^ast.Array_Type: t.tag = tag case: error(p, tok.pos, "expected an enumerated array type after #%s", name.text) @@ -2318,7 +2349,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr { return rt case "force_inline", "force_no_inline": - return parse_inlining_operand(p, lhs, tok) + return parse_inlining_operand(p, lhs, name) case: expr := parse_expr(p, lhs) te := ast.new(ast.Tag_Expr, tok.pos, expr.pos) @@ -2599,7 +2630,9 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr { tok := expect_token(p, .Union) poly_params: ^ast.Field_List align: ^ast.Expr - is_maybe: bool + is_maybe: bool + is_no_nil: bool + is_shared_nil: bool if allow_token(p, .Open_Paren) { param_count: int @@ -2626,12 +2659,39 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr { error(p, tag.pos, "duplicate union tag '#%s'", tag.text) } is_maybe = true + case "no_nil": + if is_no_nil { + error(p, tag.pos, "duplicate union tag '#%s'", tag.text) + } + is_no_nil = true + case "shared_nil": + if is_shared_nil { + error(p, tag.pos, "duplicate union tag '#%s'", tag.text) + } + is_shared_nil = true case: error(p, tag.pos, "invalid union tag '#%s", tag.text) } } p.expr_level = prev_level + if is_no_nil && is_maybe { + error(p, p.curr_tok.pos, "#maybe and #no_nil cannot be applied together") + } + if is_no_nil && is_shared_nil { + error(p, p.curr_tok.pos, "#shared_nil and #no_nil cannot be applied together") + } + if is_shared_nil && is_maybe { + error(p, p.curr_tok.pos, "#maybe and #shared_nil cannot be applied together") + } + + union_kind := ast.Union_Type_Kind.Normal + switch { + case is_maybe: union_kind = .maybe + case is_no_nil: union_kind = .no_nil + case is_shared_nil: union_kind = .shared_nil + } + where_token: tokenizer.Token where_clauses: []^ast.Expr @@ -2652,7 +2712,7 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr { variants: [dynamic]^ast.Expr for p.curr_tok.kind != .Close_Brace && p.curr_tok.kind != .EOF { type := parse_type(p) - if _, ok := type.derived.(ast.Bad_Expr); !ok { + if _, ok := type.derived.(^ast.Bad_Expr); !ok { append(&variants, type) } if !allow_token(p, .Comma) { @@ -2662,13 +2722,15 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr { close := expect_closing_brace_of_field_list(p) + + ut := ast.new(ast.Union_Type, tok.pos, end_pos(close)) ut.poly_params = poly_params ut.variants = variants[:] ut.align = align ut.where_token = where_token ut.where_clauses = where_clauses - ut.is_maybe = is_maybe + ut.kind = union_kind return ut @@ -2826,19 +2888,19 @@ is_literal_type :: proc(expr: ^ast.Expr) -> bool { if val == nil { return false } - switch _ in val.derived { - case ast.Bad_Expr, - ast.Ident, - ast.Selector_Expr, - ast.Array_Type, - ast.Struct_Type, - ast.Union_Type, - ast.Enum_Type, - ast.Dynamic_Array_Type, - ast.Map_Type, - ast.Bit_Set_Type, - ast.Matrix_Type, - ast.Call_Expr: + #partial switch _ in val.derived_expr { + case ^ast.Bad_Expr, + ^ast.Ident, + ^ast.Selector_Expr, + ^ast.Array_Type, + ^ast.Struct_Type, + ^ast.Union_Type, + ^ast.Enum_Type, + ^ast.Dynamic_Array_Type, + ^ast.Map_Type, + ^ast.Bit_Set_Type, + ^ast.Matrix_Type, + ^ast.Call_Expr: return true } return false @@ -2960,7 +3022,7 @@ parse_call_expr :: proc(p: ^Parser, operand: ^ast.Expr) -> ^ast.Expr { ce.close = close.pos o := ast.unparen_expr(operand) - if se, ok := o.derived.(ast.Selector_Expr); ok && se.op.kind == .Arrow_Right { + if se, ok := o.derived.(^ast.Selector_Expr); ok && se.op.kind == .Arrow_Right { sce := ast.new(ast.Selector_Call_Expr, ce.pos, ce.end) sce.expr = o sce.call = ce @@ -3390,13 +3452,13 @@ parse_simple_stmt :: proc(p: ^Parser, flags: Stmt_Allow_Flags) -> ^ast.Stmt { stmt := parse_stmt(p) if stmt != nil { - switch n in &stmt.derived { - case ast.Block_Stmt: n.label = label - case ast.If_Stmt: n.label = label - case ast.For_Stmt: n.label = label - case ast.Switch_Stmt: n.label = label - case ast.Type_Switch_Stmt: n.label = label - case ast.Range_Stmt: n.label = label + #partial switch n in stmt.derived_stmt { + case ^ast.Block_Stmt: n.label = label + case ^ast.If_Stmt: n.label = label + case ^ast.For_Stmt: n.label = label + case ^ast.Switch_Stmt: n.label = label + case ^ast.Type_Switch_Stmt: n.label = label + case ^ast.Range_Stmt: n.label = label } } diff --git a/core/odin/printer/printer.odin b/core/odin/printer/printer.odin index abda44fa2..807cc99bd 100644 --- a/core/odin/printer/printer.odin +++ b/core/odin/printer/printer.odin @@ -151,7 +151,7 @@ print :: proc(p: ^Printer, file: ^ast.File) -> string { fix_lines(p) - builder := strings.make_builder(0, mem.megabytes(5), p.allocator) + builder := strings.make_builder(0, 5 * mem.Megabyte, p.allocator) last_line := 0 diff --git a/core/odin/printer/visit.odin b/core/odin/printer/visit.odin index 023583bde..70140f180 100644 --- a/core/odin/printer/visit.odin +++ b/core/odin/printer/visit.odin @@ -342,16 +342,16 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) { return } - switch v in &decl.derived { - case Expr_Stmt: + #partial switch v in decl.derived_stmt { + case ^Expr_Stmt: move_line(p, decl.pos) visit_expr(p, v.expr) if p.config.semicolons { push_generic_token(p, .Semicolon, 0) } - case When_Stmt: + case ^When_Stmt: visit_stmt(p, cast(^Stmt)decl) - case Foreign_Import_Decl: + case ^Foreign_Import_Decl: if len(v.attributes) > 0 { sort.sort(sort_attribute(&v.attributes)) move_line(p, v.attributes[0].pos) @@ -370,7 +370,7 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) { for path in v.fullpaths { push_ident_token(p, path, 0) } - case Foreign_Block_Decl: + case ^Foreign_Block_Decl: if len(v.attributes) > 0 { sort.sort(sort_attribute(&v.attributes)) move_line(p, v.attributes[0].pos) @@ -383,7 +383,7 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) { visit_expr(p, v.foreign_library) visit_stmt(p, v.body) - case Import_Decl: + case ^Import_Decl: move_line(p, decl.pos) if v.name.text != "" { @@ -395,7 +395,7 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) { push_ident_token(p, v.fullpath, 1) } - case Value_Decl: + case ^Value_Decl: if len(v.attributes) > 0 { sort.sort(sort_attribute(&v.attributes)) move_line(p, v.attributes[0].pos) @@ -446,10 +446,10 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) { add_semicolon := true for value in v.values { - switch a in value.derived { - case Union_Type, Enum_Type, Struct_Type: + #partial switch a in value.derived { + case ^Union_Type, ^Enum_Type, ^Struct_Type: add_semicolon = false || called_in_stmt - case Proc_Lit: + case ^Proc_Lit: add_semicolon = false } } @@ -516,23 +516,34 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener return } - switch v in stmt.derived { - case Import_Decl: - visit_decl(p, cast(^Decl)stmt, true) - return - case Value_Decl: - visit_decl(p, cast(^Decl)stmt, true) - return - case Foreign_Import_Decl: - visit_decl(p, cast(^Decl)stmt, true) - return - case Foreign_Block_Decl: - visit_decl(p, cast(^Decl)stmt, true) - return - } - switch v in stmt.derived { - case Using_Stmt: + switch v in stmt.derived_stmt { + case ^Bad_Stmt: + case ^Bad_Decl: + case ^Package_Decl: + + case ^Empty_Stmt: + push_generic_token(p, .Semicolon, 0) + case ^Tag_Stmt: + push_generic_token(p, .Hash, 1) + push_generic_token(p, v.op.kind, 1, v.op.text) + visit_stmt(p, v.stmt) + + + case ^Import_Decl: + visit_decl(p, cast(^Decl)stmt, true) + return + case ^Value_Decl: + visit_decl(p, cast(^Decl)stmt, true) + return + case ^Foreign_Import_Decl: + visit_decl(p, cast(^Decl)stmt, true) + return + case ^Foreign_Block_Decl: + visit_decl(p, cast(^Decl)stmt, true) + return + + case ^Using_Stmt: move_line(p, v.pos) push_generic_token(p, .Using, 1) @@ -542,7 +553,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener if p.config.semicolons { push_generic_token(p, .Semicolon, 0) } - case Block_Stmt: + case ^Block_Stmt: move_line(p, v.pos) if v.pos.line == v.end.line { @@ -572,7 +583,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener visit_end_brace(p, v.end) } } - case If_Stmt: + case ^If_Stmt: move_line(p, v.pos) if v.label != nil { @@ -595,7 +606,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener uses_do := false - if check_stmt, ok := v.body.derived.(Block_Stmt); ok && check_stmt.uses_do { + if check_stmt, ok := v.body.derived.(^Block_Stmt); ok && check_stmt.uses_do { uses_do = true } @@ -626,7 +637,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener visit_stmt(p, v.else_stmt) } - case Switch_Stmt: + case ^Switch_Stmt: move_line(p, v.pos) if v.label != nil { @@ -654,7 +665,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener visit_expr(p, v.cond) visit_stmt(p, v.body) - case Case_Clause: + case ^Case_Clause: move_line(p, v.pos) if !p.config.indent_cases { @@ -678,7 +689,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener if !p.config.indent_cases { indent(p) } - case Type_Switch_Stmt: + case ^Type_Switch_Stmt: move_line(p, v.pos) hint_current_line(p, {.Switch_Stmt}) @@ -696,7 +707,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener visit_stmt(p, v.tag) visit_stmt(p, v.body) - case Assign_Stmt: + case ^Assign_Stmt: move_line(p, v.pos) hint_current_line(p, {.Assign}) @@ -710,13 +721,13 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener if block_stmt && p.config.semicolons { push_generic_token(p, .Semicolon, 0) } - case Expr_Stmt: + case ^Expr_Stmt: move_line(p, v.pos) visit_expr(p, v.expr) if block_stmt && p.config.semicolons { push_generic_token(p, .Semicolon, 0) } - case For_Stmt: + case ^For_Stmt: // this should be simplified move_line(p, v.pos) @@ -753,7 +764,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener visit_stmt(p, v.body) - case Inline_Range_Stmt: + case ^Inline_Range_Stmt: move_line(p, v.pos) if v.label != nil { @@ -779,7 +790,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener visit_expr(p, v.expr) visit_stmt(p, v.body) - case Range_Stmt: + case ^Range_Stmt: move_line(p, v.pos) if v.label != nil { @@ -805,7 +816,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener visit_expr(p, v.expr) visit_stmt(p, v.body) - case Return_Stmt: + case ^Return_Stmt: move_line(p, v.pos) push_generic_token(p, .Return, 1) @@ -817,7 +828,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener if block_stmt && p.config.semicolons { push_generic_token(p, .Semicolon, 0) } - case Defer_Stmt: + case ^Defer_Stmt: move_line(p, v.pos) push_generic_token(p, .Defer, 0) @@ -826,7 +837,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener if p.config.semicolons { push_generic_token(p, .Semicolon, 0) } - case When_Stmt: + case ^When_Stmt: move_line(p, v.pos) push_generic_token(p, .When, 1) visit_expr(p, v.cond) @@ -846,7 +857,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener visit_stmt(p, v.else_stmt) } - case Branch_Stmt: + case ^Branch_Stmt: move_line(p, v.pos) push_generic_token(p, v.tok.kind, 0) @@ -918,8 +929,15 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, options := List_Options{}) { set_source_position(p, expr.pos) - switch v in expr.derived { - case Inline_Asm_Expr: + switch v in expr.derived_expr { + case ^Bad_Expr: + + case ^Tag_Expr: + push_generic_token(p, .Hash, 1) + push_generic_token(p, v.op.kind, 1, v.op.text) + visit_expr(p, v.expr) + + case ^Inline_Asm_Expr: push_generic_token(p, v.tok.kind, 1, v.tok.text) push_generic_token(p, .Open_Paren, 1) @@ -936,42 +954,42 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, options := List_Options{}) { push_generic_token(p, .Comma, 0) visit_expr(p, v.constraints_string) push_generic_token(p, .Close_Brace, 0) - case Undef: + case ^Undef: push_generic_token(p, .Undef, 1) - case Auto_Cast: + case ^Auto_Cast: push_generic_token(p, v.op.kind, 1) visit_expr(p, v.expr) - case Ternary_If_Expr: + case ^Ternary_If_Expr: visit_expr(p, v.x) push_generic_token(p, v.op1.kind, 1) visit_expr(p, v.cond) push_generic_token(p, v.op2.kind, 1) visit_expr(p, v.y) - case Ternary_When_Expr: + case ^Ternary_When_Expr: visit_expr(p, v.x) push_generic_token(p, v.op1.kind, 1) visit_expr(p, v.cond) push_generic_token(p, v.op2.kind, 1) visit_expr(p, v.y) - case Or_Else_Expr: + case ^Or_Else_Expr: visit_expr(p, v.x) push_generic_token(p, v.token.kind, 1) visit_expr(p, v.y) - case Or_Return_Expr: + case ^Or_Return_Expr: visit_expr(p, v.expr) push_generic_token(p, v.token.kind, 1) - case Selector_Call_Expr: + case ^Selector_Call_Expr: visit_expr(p, v.call.expr) push_generic_token(p, .Open_Paren, 1) visit_exprs(p, v.call.args, {.Add_Comma}) push_generic_token(p, .Close_Paren, 0) - case Ellipsis: + case ^Ellipsis: push_generic_token(p, .Ellipsis, 1) visit_expr(p, v.expr) - case Relative_Type: + case ^Relative_Type: visit_expr(p, v.tag) visit_expr(p, v.type) - case Slice_Expr: + case ^Slice_Expr: visit_expr(p, v.expr) push_generic_token(p, .Open_Bracket, 0) visit_expr(p, v.low) @@ -981,37 +999,37 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, options := List_Options{}) { visit_expr(p, v.high) } push_generic_token(p, .Close_Bracket, 0) - case Ident: + case ^Ident: if .Enforce_Poly_Names in options { push_generic_token(p, .Dollar, 1) push_ident_token(p, v.name, 0) } else { push_ident_token(p, v.name, 1) } - case Deref_Expr: + case ^Deref_Expr: visit_expr(p, v.expr) push_generic_token(p, v.op.kind, 0) - case Type_Cast: + case ^Type_Cast: push_generic_token(p, v.tok.kind, 1) push_generic_token(p, .Open_Paren, 0) visit_expr(p, v.type) push_generic_token(p, .Close_Paren, 0) merge_next_token(p) visit_expr(p, v.expr) - case Basic_Directive: + case ^Basic_Directive: push_generic_token(p, v.tok.kind, 1) push_ident_token(p, v.name, 0) - case Distinct_Type: + case ^Distinct_Type: push_generic_token(p, .Distinct, 1) visit_expr(p, v.type) - case Dynamic_Array_Type: + case ^Dynamic_Array_Type: visit_expr(p, v.tag) push_generic_token(p, .Open_Bracket, 1) push_generic_token(p, .Dynamic, 0) push_generic_token(p, .Close_Bracket, 0) merge_next_token(p) visit_expr(p, v.elem) - case Bit_Set_Type: + case ^Bit_Set_Type: push_generic_token(p, .Bit_Set, 1) push_generic_token(p, .Open_Bracket, 0) @@ -1023,13 +1041,16 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, options := List_Options{}) { } push_generic_token(p, .Close_Bracket, 0) - case Union_Type: + case ^Union_Type: push_generic_token(p, .Union, 1) push_poly_params(p, v.poly_params) - if v.is_maybe { - push_ident_token(p, "#maybe", 1) + switch v.kind { + case .Normal: + case .maybe: push_ident_token(p, "#maybe", 1) + case .no_nil: push_ident_token(p, "#no_nil", 1) + case .shared_nil: push_ident_token(p, "#shared_nil", 1) } push_where_clauses(p, v.where_clauses) @@ -1045,7 +1066,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, options := List_Options{}) { visit_exprs(p, v.variants, {.Add_Comma, .Trailing}) visit_end_brace(p, v.end) } - case Enum_Type: + case ^Enum_Type: push_generic_token(p, .Enum, 1) hint_current_line(p, {.Enum}) @@ -1068,7 +1089,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, options := List_Options{}) { } set_source_position(p, v.end) - case Struct_Type: + case ^Struct_Type: push_generic_token(p, .Struct, 1) hint_current_line(p, {.Struct}) @@ -1103,7 +1124,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, options := List_Options{}) { } set_source_position(p, v.end) - case Proc_Lit: + case ^Proc_Lit: switch v.inlining { case .None: case .Inline: @@ -1112,7 +1133,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, options := List_Options{}) { push_ident_token(p, "#force_no_inline", 0) } - visit_proc_type(p, v.type^, true) + visit_proc_type(p, v.type, true) push_where_clauses(p, v.where_clauses) @@ -1122,16 +1143,16 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, options := List_Options{}) { } else { push_generic_token(p, .Undef, 1) } - case Proc_Type: + case ^Proc_Type: visit_proc_type(p, v) - case Basic_Lit: + case ^Basic_Lit: push_generic_token(p, v.tok.kind, 1, v.tok.text) - case Binary_Expr: + case ^Binary_Expr: visit_binary_expr(p, v) - case Implicit_Selector_Expr: + case ^Implicit_Selector_Expr: push_generic_token(p, .Period, 1) push_ident_token(p, v.field.name, 0) - case Call_Expr: + case ^Call_Expr: visit_expr(p, v.expr) push_format_token(p, @@ -1146,27 +1167,34 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, options := List_Options{}) { visit_call_exprs(p, v.args, v.ellipsis.kind == .Ellipsis) push_generic_token(p, .Close_Paren, 0) - case Typeid_Type: + case ^Typeid_Type: push_generic_token(p, .Typeid, 1) if v.specialization != nil { push_generic_token(p, .Quo, 0) visit_expr(p, v.specialization) } - case Selector_Expr: + case ^Selector_Expr: visit_expr(p, v.expr) push_generic_token(p, v.op.kind, 0) visit_expr(p, v.field) - case Paren_Expr: + case ^Paren_Expr: push_generic_token(p, .Open_Paren, 1) visit_expr(p, v.expr) push_generic_token(p, .Close_Paren, 0) - case Index_Expr: + case ^Index_Expr: visit_expr(p, v.expr) push_generic_token(p, .Open_Bracket, 0) visit_expr(p, v.index) push_generic_token(p, .Close_Bracket, 0) - case Proc_Group: + case ^Matrix_Index_Expr: + visit_expr(p, v.expr) + push_generic_token(p, .Open_Bracket, 0) + visit_expr(p, v.row_index) + push_generic_token(p, .Comma, 0) + visit_expr(p, v.column_index) + push_generic_token(p, .Close_Bracket, 0) + case ^Proc_Group: push_generic_token(p, v.tok.kind, 1) if len(v.args) != 0 && v.pos.line != v.args[len(v.args) - 1].pos.line { @@ -1181,7 +1209,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, options := List_Options{}) { push_generic_token(p, .Close_Brace, 0) } - case Comp_Lit: + case ^Comp_Lit: if v.type != nil { visit_expr(p, v.type) } @@ -1198,18 +1226,18 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, options := List_Options{}) { push_generic_token(p, .Close_Brace, 0) } - case Unary_Expr: + case ^Unary_Expr: push_generic_token(p, v.op.kind, 1) merge_next_token(p) visit_expr(p, v.expr) - case Field_Value: + case ^Field_Value: visit_expr(p, v.field) push_generic_token(p, .Eq, 1) visit_expr(p, v.value) - case Type_Assertion: + case ^Type_Assertion: visit_expr(p, v.expr) - if unary, ok := v.type.derived.(Unary_Expr); ok && unary.op.text == "?" { + if unary, ok := v.type.derived.(^Unary_Expr); ok && unary.op.text == "?" { push_generic_token(p, .Period, 0) visit_expr(p, v.type) } else { @@ -1219,13 +1247,13 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, options := List_Options{}) { push_generic_token(p, .Close_Paren, 0) } - case Pointer_Type: + case ^Pointer_Type: push_generic_token(p, .Pointer, 1) merge_next_token(p) visit_expr(p, v.elem) - case Implicit: + case ^Implicit: push_generic_token(p, v.tok.kind, 1) - case Poly_Type: + case ^Poly_Type: push_generic_token(p, .Dollar, 1) merge_next_token(p) visit_expr(p, v.type) @@ -1235,22 +1263,35 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, options := List_Options{}) { merge_next_token(p) visit_expr(p, v.specialization) } - case Array_Type: + case ^Array_Type: visit_expr(p, v.tag) push_generic_token(p, .Open_Bracket, 1) visit_expr(p, v.len) push_generic_token(p, .Close_Bracket, 0) merge_next_token(p) visit_expr(p, v.elem) - case Map_Type: + case ^Map_Type: push_generic_token(p, .Map, 1) push_generic_token(p, .Open_Bracket, 0) visit_expr(p, v.key) push_generic_token(p, .Close_Bracket, 0) merge_next_token(p) visit_expr(p, v.value) - case Helper_Type: + case ^Helper_Type: visit_expr(p, v.type) + case ^Multi_Pointer_Type: + push_generic_token(p, .Open_Bracket, 1) + push_generic_token(p, .Pointer, 0) + push_generic_token(p, .Close_Bracket, 0) + visit_expr(p, v.elem) + case ^Matrix_Type: + push_generic_token(p, .Matrix, 1) + push_generic_token(p, .Open_Bracket, 0) + visit_expr(p, v.row_count) + push_generic_token(p, .Comma, 0) + visit_expr(p, v.column_count) + push_generic_token(p, .Close_Bracket, 0) + visit_expr(p, v.elem) case: panic(fmt.aprint(expr.derived)) } @@ -1348,7 +1389,7 @@ visit_field_list :: proc(p: ^Printer, list: ^ast.Field_List, options := List_Opt } } -visit_proc_type :: proc(p: ^Printer, proc_type: ast.Proc_Type, is_proc_lit := false) { +visit_proc_type :: proc(p: ^Printer, proc_type: ^ast.Proc_Type, is_proc_lit := false) { if is_proc_lit { push_format_token(p, Format_Token { kind = .Proc, @@ -1392,7 +1433,7 @@ visit_proc_type :: proc(p: ^Printer, proc_type: ast.Proc_Type, is_proc_lit := fa } else if len(proc_type.results.list) == 1 { for name in proc_type.results.list[0].names { - if ident, ok := name.derived.(ast.Ident); ok { + if ident, ok := name.derived.(^ast.Ident); ok { if ident.name != "_" { use_parens = true } @@ -1410,19 +1451,19 @@ visit_proc_type :: proc(p: ^Printer, proc_type: ast.Proc_Type, is_proc_lit := fa } } -visit_binary_expr :: proc(p: ^Printer, binary: ast.Binary_Expr) { +visit_binary_expr :: proc(p: ^Printer, binary: ^ast.Binary_Expr) { move_line(p, binary.left.pos) - if v, ok := binary.left.derived.(ast.Binary_Expr); ok { + if v, ok := binary.left.derived.(^ast.Binary_Expr); ok { visit_binary_expr(p, v) } else { visit_expr(p, binary.left) } either_implicit_selector := false - if _, ok := binary.left.derived.(ast.Implicit_Selector_Expr); ok { + if _, ok := binary.left.derived.(^ast.Implicit_Selector_Expr); ok { either_implicit_selector = true - } else if _, ok := binary.right.derived.(ast.Implicit_Selector_Expr); ok { + } else if _, ok := binary.right.derived.(^ast.Implicit_Selector_Expr); ok { either_implicit_selector = true } @@ -1439,7 +1480,7 @@ visit_binary_expr :: proc(p: ^Printer, binary: ast.Binary_Expr) { move_line(p, binary.right.pos) - if v, ok := binary.right.derived.(ast.Binary_Expr); ok { + if v, ok := binary.right.derived.(^ast.Binary_Expr); ok { visit_binary_expr(p, v) } else { visit_expr(p, binary.right) @@ -1499,7 +1540,7 @@ visit_signature_list :: proc(p: ^Printer, list: ^ast.Field_List, remove_blank := named := false for name in field.names { - if ident, ok := name.derived.(ast.Ident); ok { + if ident, ok := name.derived.(^ast.Ident); ok { //for some reason the parser uses _ to mean empty if ident.name != "_" || !remove_blank { named = true diff --git a/core/os/dir_freebsd.odin b/core/os/dir_freebsd.odin new file mode 100644 index 000000000..74c410a51 --- /dev/null +++ b/core/os/dir_freebsd.odin @@ -0,0 +1,70 @@ +package os + +import "core:strings" +import "core:mem" + +read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []File_Info, err: Errno) { + dirp: Dir + dirp, err = _fdopendir(fd) + if err != ERROR_NONE { + return + } + + defer _closedir(dirp) + + dirpath: string + dirpath, err = absolute_path_from_handle(fd) + + if err != ERROR_NONE { + return + } + + defer delete(dirpath) + + n := n + size := n + if n <= 0 { + n = -1 + size = 100 + } + + dfi := make([dynamic]File_Info, 0, size, allocator) + + for { + entry: Dirent + end_of_stream: bool + entry, err, end_of_stream = _readdir(dirp) + if err != ERROR_NONE { + for fi_ in dfi { + file_info_delete(fi_, allocator) + } + delete(dfi) + return + } else if end_of_stream { + break + } + + fi_: File_Info + filename := cast(string)(transmute(cstring)mem.Raw_Cstring{ data = &entry.name[0] }) + + if filename == "." || filename == ".." { + continue + } + + fullpath := strings.join( []string{ dirpath, filename }, "/", context.temp_allocator) + defer delete(fullpath, context.temp_allocator) + + fi_, err = stat(fullpath, allocator) + if err != ERROR_NONE { + for fi__ in dfi { + file_info_delete(fi__, allocator) + } + delete(dfi) + return + } + + append(&dfi, fi_) + } + + return dfi[:], ERROR_NONE +} diff --git a/core/os/dir_openbsd.odin b/core/os/dir_openbsd.odin new file mode 100644 index 000000000..465fd35ae --- /dev/null +++ b/core/os/dir_openbsd.odin @@ -0,0 +1,71 @@ +package os + +import "core:strings" +import "core:mem" + +read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []File_Info, err: Errno) { + dirp: Dir + dirp, err = _fdopendir(fd) + if err != ERROR_NONE { + return + } + + defer _closedir(dirp) + + // XXX OpenBSD + dirpath: string + dirpath, err = absolute_path_from_handle(fd) + + if err != ERROR_NONE { + return + } + + defer delete(dirpath) + + n := n + size := n + if n <= 0 { + n = -1 + size = 100 + } + + dfi := make([dynamic]File_Info, 0, size, allocator) + + for { + entry: Dirent + end_of_stream: bool + entry, err, end_of_stream = _readdir(dirp) + if err != ERROR_NONE { + for fi_ in dfi { + file_info_delete(fi_, allocator) + } + delete(dfi) + return + } else if end_of_stream { + break + } + + fi_: File_Info + filename := cast(string)(transmute(cstring)mem.Raw_Cstring{ data = &entry.name[0] }) + + if filename == "." || filename == ".." { + continue + } + + fullpath := strings.join( []string{ dirpath, filename }, "/", context.temp_allocator) + defer delete(fullpath, context.temp_allocator) + + fi_, err = stat(fullpath, allocator) + if err != ERROR_NONE { + for fi__ in dfi { + file_info_delete(fi__, allocator) + } + delete(dfi) + return + } + + append(&dfi, fi_) + } + + return dfi[:], ERROR_NONE +} diff --git a/core/os/dir_windows.odin b/core/os/dir_windows.odin index ff7e53293..3261b8cb3 100644 --- a/core/os/dir_windows.odin +++ b/core/os/dir_windows.odin @@ -82,6 +82,7 @@ read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []F wpath_search[len(wpath)+2] = 0 path := cleanpath_from_buf(wpath) + defer delete(path) find_data := &win32.WIN32_FIND_DATAW{} find_handle := win32.FindFirstFileW(raw_data(wpath_search), find_data) diff --git a/core/os/file_windows.odin b/core/os/file_windows.odin index 419f8bbc2..a9f78070f 100644 --- a/core/os/file_windows.odin +++ b/core/os/file_windows.odin @@ -20,13 +20,13 @@ open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Errn case O_RDWR: access = win32.FILE_GENERIC_READ | win32.FILE_GENERIC_WRITE } + if mode&O_CREATE != 0 { + access |= win32.FILE_GENERIC_WRITE + } if mode&O_APPEND != 0 { access &~= win32.FILE_GENERIC_WRITE access |= win32.FILE_APPEND_DATA } - if mode&O_CREATE != 0 { - access |= win32.FILE_GENERIC_WRITE - } share_mode := win32.FILE_SHARE_READ|win32.FILE_SHARE_WRITE sa: ^win32.SECURITY_ATTRIBUTES = nil @@ -106,19 +106,23 @@ read_console :: proc(handle: win32.HANDLE, b: []byte) -> (n: int, err: Errno) { BUF_SIZE :: 386 buf16: [BUF_SIZE]u16 buf8: [4*BUF_SIZE]u8 - + for n < len(b) && err == 0 { - max_read := u32(min(BUF_SIZE, len(b)/4)) + min_read := max(len(b)/4, 1 if len(b) > 0 else 0) + max_read := u32(min(BUF_SIZE, min_read)) + if max_read == 0 { + break + } single_read_length: u32 ok := win32.ReadConsoleW(handle, &buf16[0], max_read, &single_read_length, nil) if !ok { err = Errno(win32.GetLastError()) } - + buf8_len := utf16.decode_to_utf8(buf8[:], buf16[:single_read_length]) src := buf8[:buf8_len] - + ctrl_z := false for i := 0; i < len(src) && n+i < len(b); i += 1 { x := src[i] @@ -129,9 +133,16 @@ read_console :: proc(handle: win32.HANDLE, b: []byte) -> (n: int, err: Errno) { b[n] = x n += 1 } - if ctrl_z || single_read_length < len(buf16) { + if ctrl_z || single_read_length < max_read { break } + + // NOTE(bill): if the last two values were a newline, then it is expected that + // this is the end of the input + if n >= 2 && single_read_length == max_read && string(b[n-2:n]) == "\r\n" { + break + } + } return @@ -309,9 +320,6 @@ stderr := get_std_handle(uint(win32.STD_ERROR_HANDLE)) get_std_handle :: proc "contextless" (h: uint) -> Handle { fd := win32.GetStdHandle(win32.DWORD(h)) - when size_of(uintptr) == 8 { - win32.SetHandleInformation(fd, win32.HANDLE_FLAG_INHERIT, 0) - } return Handle(fd) } @@ -399,7 +407,7 @@ is_abs :: proc(path: string) -> bool { if len(path) > 0 && path[0] == '/' { return true } - when ODIN_OS == "windows" { + when ODIN_OS == .Windows { if len(path) > 2 { switch path[0] { case 'A'..='Z', 'a'..='z': diff --git a/core/os/os.odin b/core/os/os.odin index 83158be80..e880ec21e 100644 --- a/core/os/os.odin +++ b/core/os/os.odin @@ -139,7 +139,7 @@ write_entire_file :: proc(name: string, data: []byte, truncate := true) -> (succ } mode: int = 0 - when OS == "linux" || OS == "darwin" { + when OS == .Linux || OS == .Darwin { // NOTE(justasd): 644 (owner read, write; group read; others read) mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH } @@ -206,11 +206,19 @@ heap_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode, } } - aligned_resize :: proc(p: rawptr, old_size: int, new_size: int, new_alignment: int) -> ([]byte, mem.Allocator_Error) { + aligned_resize :: proc(p: rawptr, old_size: int, new_size: int, new_alignment: int) -> (new_memory: []byte, err: mem.Allocator_Error) { if p == nil { return nil, nil } - return aligned_alloc(new_size, new_alignment, p) + + new_memory = aligned_alloc(new_size, new_alignment, p) or_return + + // NOTE: heap_resize does not zero the new memory, so we do it + if new_size > old_size { + new_region := mem.raw_data(new_memory[old_size:]) + mem.zero(new_region, new_size - old_size) + } + return } switch mode { diff --git a/core/os/os2/process.odin b/core/os/os2/process.odin index 028951fe3..7fc7a4ac0 100644 --- a/core/os/os2/process.odin +++ b/core/os/os2/process.odin @@ -1,6 +1,6 @@ package os2 -import sync "core:sync/sync2" +import "core:sync" import "core:time" import "core:runtime" diff --git a/core/os/os2/user.odin b/core/os/os2/user.odin index 6dd99c621..976e61bb1 100644 --- a/core/os/os2/user.odin +++ b/core/os/os2/user.odin @@ -3,13 +3,13 @@ package os2 import "core:strings" user_cache_dir :: proc(allocator := context.allocator) -> (dir: string, is_defined: bool) { - switch ODIN_OS { - case "windows": + #partial switch ODIN_OS { + case .Windows: dir = get_env("LocalAppData") if dir != "" { dir = strings.clone(dir, allocator) } - case "darwin": + case .Darwin: dir = get_env("HOME") if dir != "" { dir = strings.concatenate({dir, "/Library/Caches"}, allocator) @@ -29,13 +29,13 @@ user_cache_dir :: proc(allocator := context.allocator) -> (dir: string, is_defin } user_config_dir :: proc(allocator := context.allocator) -> (dir: string, is_defined: bool) { - switch ODIN_OS { - case "windows": + #partial switch ODIN_OS { + case .Windows: dir = get_env("AppData") if dir != "" { dir = strings.clone(dir, allocator) } - case "darwin": + case .Darwin: dir = get_env("HOME") if dir != "" { dir = strings.concatenate({dir, "/Library/Application Support"}, allocator) @@ -56,8 +56,8 @@ user_config_dir :: proc(allocator := context.allocator) -> (dir: string, is_defi user_home_dir :: proc() -> (dir: string, is_defined: bool) { env := "HOME" - switch ODIN_OS { - case "windows": + #partial switch ODIN_OS { + case .Windows: env = "USERPROFILE" } if v := get_env(env); v != "" { diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin index d40c80aeb..ae5336849 100644 --- a/core/os/os_darwin.odin +++ b/core/os/os_darwin.odin @@ -260,13 +260,13 @@ S_ISUID :: 0o4000 // Set user id on execution S_ISGID :: 0o2000 // Set group id on execution S_ISVTX :: 0o1000 // Directory restrcted delete -S_ISLNK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFLNK } -S_ISREG :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFREG } -S_ISDIR :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFDIR } -S_ISCHR :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFCHR } -S_ISBLK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFBLK } -S_ISFIFO :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFIFO } -S_ISSOCK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFSOCK } +S_ISLNK :: #force_inline proc(m: u16) -> bool { return (m & S_IFMT) == S_IFLNK } +S_ISREG :: #force_inline proc(m: u16) -> bool { return (m & S_IFMT) == S_IFREG } +S_ISDIR :: #force_inline proc(m: u16) -> bool { return (m & S_IFMT) == S_IFDIR } +S_ISCHR :: #force_inline proc(m: u16) -> bool { return (m & S_IFMT) == S_IFCHR } +S_ISBLK :: #force_inline proc(m: u16) -> bool { return (m & S_IFMT) == S_IFBLK } +S_ISFIFO :: #force_inline proc(m: u16) -> bool { return (m & S_IFMT) == S_IFIFO } +S_ISSOCK :: #force_inline proc(m: u16) -> bool { return (m & S_IFMT) == S_IFSOCK } R_OK :: 4 // Test for read permission W_OK :: 2 // Test for write permission @@ -290,12 +290,22 @@ foreign libc { @(link_name="fstat64") _unix_fstat :: proc(fd: Handle, stat: ^OS_Stat) -> c.int --- @(link_name="readlink") _unix_readlink :: proc(path: cstring, buf: ^byte, bufsiz: c.size_t) -> c.ssize_t --- @(link_name="access") _unix_access :: proc(path: cstring, mask: int) -> int --- - @(link_name="fdopendir$INODE64") _unix_fdopendir :: proc(fd: Handle) -> Dir --- + + @(link_name="fdopendir$INODE64") _unix_fdopendir_amd64 :: proc(fd: Handle) -> Dir --- + @(link_name="readdir_r$INODE64") _unix_readdir_r_amd64 :: proc(dirp: Dir, entry: ^Dirent, result: ^^Dirent) -> c.int --- + @(link_name="fdopendir") _unix_fdopendir_arm64 :: proc(fd: Handle) -> Dir --- + @(link_name="readdir_r") _unix_readdir_r_arm64 :: proc(dirp: Dir, entry: ^Dirent, result: ^^Dirent) -> c.int --- + @(link_name="closedir") _unix_closedir :: proc(dirp: Dir) -> c.int --- @(link_name="rewinddir") _unix_rewinddir :: proc(dirp: Dir) --- - @(link_name="readdir_r$INODE64") _unix_readdir_r :: proc(dirp: Dir, entry: ^Dirent, result: ^^Dirent) -> c.int --- + @(link_name="fcntl") _unix_fcntl :: proc(fd: Handle, cmd: c.int, buf: ^byte) -> c.int --- + @(link_name="rename") _unix_rename :: proc(old: cstring, new: cstring) -> c.int --- + @(link_name="remove") _unix_remove :: proc(path: cstring) -> c.int --- + + @(link_name="fchmod") _unix_fchmod :: proc(fildes: Handle, mode: u16) -> c.int --- + @(link_name="malloc") _unix_malloc :: proc(size: int) -> rawptr --- @(link_name="calloc") _unix_calloc :: proc(num, size: int) -> rawptr --- @(link_name="free") _unix_free :: proc(ptr: rawptr) --- @@ -303,11 +313,22 @@ foreign libc { @(link_name="getenv") _unix_getenv :: proc(cstring) -> cstring --- @(link_name="getcwd") _unix_getcwd :: proc(buf: cstring, len: c.size_t) -> cstring --- @(link_name="chdir") _unix_chdir :: proc(buf: cstring) -> c.int --- + @(link_name="mkdir") _unix_mkdir :: proc(buf: cstring, mode: u16) -> c.int --- @(link_name="realpath") _unix_realpath :: proc(path: cstring, resolved_path: rawptr) -> rawptr --- + @(link_name="strerror") _darwin_string_error :: proc(num : c.int) -> cstring --- + @(link_name="exit") _unix_exit :: proc(status: c.int) -> ! --- } +when ODIN_ARCH != .arm64 { + _unix_fdopendir :: proc {_unix_fdopendir_amd64} + _unix_readdir_r :: proc {_unix_readdir_r_amd64} +} else { + _unix_fdopendir :: proc {_unix_fdopendir_arm64} + _unix_readdir_r :: proc {_unix_readdir_r_arm64} +} + foreign dl { @(link_name="dlopen") _unix_dlopen :: proc(filename: cstring, flags: int) -> rawptr --- @(link_name="dlsym") _unix_dlsym :: proc(handle: rawptr, symbol: cstring) -> rawptr --- @@ -319,16 +340,34 @@ get_last_error :: proc() -> int { return __error()^ } -open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Errno) { - cstr := strings.clone_to_cstring(path) +get_last_error_string :: proc() -> string { + return cast(string)_darwin_string_error(cast(c.int)get_last_error()) +} + +open :: proc(path: string, flags: int = O_RDWR, mode: int = 0) -> (Handle, Errno) { + cstr := strings.clone_to_cstring(path, context.temp_allocator) handle := _unix_open(cstr, i32(flags), u16(mode)) - delete(cstr) if handle == -1 { return INVALID_HANDLE, 1 } + +when ODIN_OS == .Darwin && ODIN_ARCH == .arm64 { + if mode != 0 { + err := fchmod(handle, cast(u16)mode) + if err != 0 { + _unix_close(handle) + return INVALID_HANDLE, 1 + } + } +} + return handle, 0 } +fchmod :: proc(fildes: Handle, mode: u16) -> Errno { + return cast(Errno)_unix_fchmod(fildes, mode) +} + close :: proc(fd: Handle) { _unix_close(fd) } @@ -389,6 +428,65 @@ is_path_separator :: proc(r: rune) -> bool { return r == '/' } +is_file_handle :: proc(fd: Handle) -> bool { + s, err := _fstat(fd) + if err != ERROR_NONE { + return false + } + return S_ISREG(s.mode) +} + +is_file_path :: proc(path: string, follow_links: bool = true) -> bool { + s: OS_Stat + err: Errno + if follow_links { + s, err = _stat(path) + } else { + s, err = _lstat(path) + } + if err != ERROR_NONE { + return false + } + return S_ISREG(s.mode) +} + + +is_dir_handle :: proc(fd: Handle) -> bool { + s, err := _fstat(fd) + if err != ERROR_NONE { + return false + } + return S_ISDIR(s.mode) +} + +is_dir_path :: proc(path: string, follow_links: bool = true) -> bool { + s: OS_Stat + err: Errno + if follow_links { + s, err = _stat(path) + } else { + s, err = _lstat(path) + } + if err != ERROR_NONE { + return false + } + return S_ISDIR(s.mode) +} + +is_file :: proc {is_file_path, is_file_handle} +is_dir :: proc {is_dir_path, is_dir_handle} + + +rename :: proc(old: string, new: string) -> bool { + old_cstr := strings.clone_to_cstring(old, context.temp_allocator) + new_cstr := strings.clone_to_cstring(new, context.temp_allocator) + return _unix_rename(old_cstr, new_cstr) != -1 +} + +remove :: proc(path: string) -> bool { + path_cstr := strings.clone_to_cstring(path, context.temp_allocator) + return _unix_remove(path_cstr) != -1 +} @private _stat :: proc(path: string) -> (OS_Stat, Errno) { @@ -530,6 +628,8 @@ heap_alloc :: proc(size: int) -> rawptr { return _unix_calloc(1, size) } heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr { + // NOTE: _unix_realloc doesn't guarantee new memory will be zeroed on + // POSIX platforms. Ensure your caller takes this into account. return _unix_realloc(ptr, new_size) } heap_free :: proc(ptr: rawptr) { @@ -570,7 +670,17 @@ set_current_directory :: proc(path: string) -> (err: Errno) { return ERROR_NONE } +make_directory :: proc(path: string, mode: u16 = 0o775) -> Errno { + path_cstr := strings.clone_to_cstring(path, context.temp_allocator) + res := _unix_mkdir(path_cstr, mode) + if res == -1 { + return Errno(get_last_error()) + } + return ERROR_NONE +} + exit :: proc "contextless" (code: int) -> ! { + runtime._cleanup_runtime_contextless() _unix_exit(i32(code)) } diff --git a/core/os/os_freebsd.odin b/core/os/os_freebsd.odin index e9314b468..4a95028c1 100644 --- a/core/os/os_freebsd.odin +++ b/core/os/os_freebsd.odin @@ -7,465 +7,698 @@ import "core:runtime" import "core:strings" import "core:c" -Handle :: distinct i32; -File_Time :: distinct u64; -Errno :: distinct i32; -Syscall :: distinct i32; +Handle :: distinct i32 +File_Time :: distinct u64 +Errno :: distinct i32 -INVALID_HANDLE :: ~Handle(0); +INVALID_HANDLE :: ~Handle(0) -ERROR_NONE: Errno : 0; -EPERM: Errno : 1; -ENOENT: Errno : 2; -ESRCH: Errno : 3; -EINTR: Errno : 4; -EIO: Errno : 5; -ENXIO: Errno : 6; -E2BIG: Errno : 7; -ENOEXEC: Errno : 8; -EBADF: Errno : 9; -ECHILD: Errno : 10; -EBEADLK: Errno : 11; -ENOMEM: Errno : 12; -EACCESS: Errno : 13; -EFAULT: Errno : 14; -ENOTBLK: Errno : 15; -EBUSY: Errno : 16; -EEXIST: Errno : 17; -EXDEV: Errno : 18; -ENODEV: Errno : 19; -ENOTDIR: Errno : 20; -EISDIR: Errno : 21; -EINVAL: Errno : 22; -ENFILE: Errno : 23; -EMFILE: Errno : 24; -ENOTTY: Errno : 25; -ETXTBSY: Errno : 26; -EFBIG: Errno : 27; -ENOSPC: Errno : 28; -ESPIPE: Errno : 29; -EROFS: Errno : 30; -EMLINK: Errno : 31; -EPIPE: Errno : 32; -EDOM: Errno : 33; -ERANGE: Errno : 34; /* Result too large */ -EAGAIN: Errno : 35; -EINPROGRESS: Errno : 36; -EALREADY: Errno : 37; -ENOTSOCK: Errno : 38; -EDESTADDRREQ: Errno : 39; -EMSGSIZE: Errno : 40; -EPROTOTYPE: Errno : 41; -ENOPROTOOPT: Errno : 42; -EPROTONOSUPPORT: Errno : 43; -ESOCKTNOSUPPORT: Errno : 44; -EOPNOTSUPP: Errno : 45; -EPFNOSUPPORT: Errno : 46; -EAFNOSUPPORT: Errno : 47; -EADDRINUSE: Errno : 48; -EADDRNOTAVAIL: Errno : 49; -ENETDOWN: Errno : 50; -ENETUNREACH: Errno : 51; -ENETRESET: Errno : 52; -ECONNABORTED: Errno : 53; -ECONNRESET: Errno : 54; -ENOBUFS: Errno : 55; -EISCONN: Errno : 56; -ENOTCONN: Errno : 57; -ESHUTDOWN: Errno : 58; -ETIMEDOUT: Errno : 60; -ECONNREFUSED: Errno : 61; -ELOOP: Errno : 62; -ENAMETOOLING: Errno : 63; -EHOSTDOWN: Errno : 64; -EHOSTUNREACH: Errno : 65; -ENOTEMPTY: Errno : 66; -EPROCLIM: Errno : 67; -EUSERS: Errno : 68; -EDQUOT: Errno : 69; -ESTALE: Errno : 70; -EBADRPC: Errno : 72; -ERPCMISMATCH: Errno : 73; -EPROGUNAVAIL: Errno : 74; -EPROGMISMATCH: Errno : 75; -EPROCUNAVAIL: Errno : 76; -ENOLCK: Errno : 77; -ENOSYS: Errno : 78; -EFTYPE: Errno : 79; -EAUTH: Errno : 80; -ENEEDAUTH: Errno : 81; -EIDRM: Errno : 82; -ENOMSG: Errno : 83; -EOVERFLOW: Errno : 84; -ECANCELED: Errno : 85; -EILSEQ: Errno : 86; -ENOATTR: Errno : 87; -EDOOFUS: Errno : 88; -EBADMSG: Errno : 89; -EMULTIHOP: Errno : 90; -ENOLINK: Errno : 91; -EPROTO: Errno : 92; -ENOTCAPABLE: Errno : 93; -ECAPMODE: Errno : 94; -ENOTRECOVERABLE: Errno : 95; -EOWNERDEAD: Errno : 96; +ERROR_NONE: Errno : 0 +EPERM: Errno : 1 +ENOENT: Errno : 2 +ESRCH: Errno : 3 +EINTR: Errno : 4 +EIO: Errno : 5 +ENXIO: Errno : 6 +E2BIG: Errno : 7 +ENOEXEC: Errno : 8 +EBADF: Errno : 9 +ECHILD: Errno : 10 +EBEADLK: Errno : 11 +ENOMEM: Errno : 12 +EACCESS: Errno : 13 +EFAULT: Errno : 14 +ENOTBLK: Errno : 15 +EBUSY: Errno : 16 +EEXIST: Errno : 17 +EXDEV: Errno : 18 +ENODEV: Errno : 19 +ENOTDIR: Errno : 20 +EISDIR: Errno : 21 +EINVAL: Errno : 22 +ENFILE: Errno : 23 +EMFILE: Errno : 24 +ENOTTY: Errno : 25 +ETXTBSY: Errno : 26 +EFBIG: Errno : 27 +ENOSPC: Errno : 28 +ESPIPE: Errno : 29 +EROFS: Errno : 30 +EMLINK: Errno : 31 +EPIPE: Errno : 32 +EDOM: Errno : 33 +ERANGE: Errno : 34 /* Result too large */ +EAGAIN: Errno : 35 +EINPROGRESS: Errno : 36 +EALREADY: Errno : 37 +ENOTSOCK: Errno : 38 +EDESTADDRREQ: Errno : 39 +EMSGSIZE: Errno : 40 +EPROTOTYPE: Errno : 41 +ENOPROTOOPT: Errno : 42 +EPROTONOSUPPORT: Errno : 43 +ESOCKTNOSUPPORT: Errno : 44 +EOPNOTSUPP: Errno : 45 +EPFNOSUPPORT: Errno : 46 +EAFNOSUPPORT: Errno : 47 +EADDRINUSE: Errno : 48 +EADDRNOTAVAIL: Errno : 49 +ENETDOWN: Errno : 50 +ENETUNREACH: Errno : 51 +ENETRESET: Errno : 52 +ECONNABORTED: Errno : 53 +ECONNRESET: Errno : 54 +ENOBUFS: Errno : 55 +EISCONN: Errno : 56 +ENOTCONN: Errno : 57 +ESHUTDOWN: Errno : 58 +ETIMEDOUT: Errno : 60 +ECONNREFUSED: Errno : 61 +ELOOP: Errno : 62 +ENAMETOOLING: Errno : 63 +EHOSTDOWN: Errno : 64 +EHOSTUNREACH: Errno : 65 +ENOTEMPTY: Errno : 66 +EPROCLIM: Errno : 67 +EUSERS: Errno : 68 +EDQUOT: Errno : 69 +ESTALE: Errno : 70 +EBADRPC: Errno : 72 +ERPCMISMATCH: Errno : 73 +EPROGUNAVAIL: Errno : 74 +EPROGMISMATCH: Errno : 75 +EPROCUNAVAIL: Errno : 76 +ENOLCK: Errno : 77 +ENOSYS: Errno : 78 +EFTYPE: Errno : 79 +EAUTH: Errno : 80 +ENEEDAUTH: Errno : 81 +EIDRM: Errno : 82 +ENOMSG: Errno : 83 +EOVERFLOW: Errno : 84 +ECANCELED: Errno : 85 +EILSEQ: Errno : 86 +ENOATTR: Errno : 87 +EDOOFUS: Errno : 88 +EBADMSG: Errno : 89 +EMULTIHOP: Errno : 90 +ENOLINK: Errno : 91 +EPROTO: Errno : 92 +ENOTCAPABLE: Errno : 93 +ECAPMODE: Errno : 94 +ENOTRECOVERABLE: Errno : 95 +EOWNERDEAD: Errno : 96 -O_RDONLY :: 0x00000; -O_WRONLY :: 0x00001; -O_RDWR :: 0x00002; -O_CREATE :: 0x00040; -O_EXCL :: 0x00080; -O_NOCTTY :: 0x00100; -O_TRUNC :: 0x00200; -O_NONBLOCK :: 0x00800; -O_APPEND :: 0x00400; -O_SYNC :: 0x01000; -O_ASYNC :: 0x02000; -O_CLOEXEC :: 0x80000; +O_RDONLY :: 0x00000 +O_WRONLY :: 0x00001 +O_RDWR :: 0x00002 +O_CREATE :: 0x00040 +O_EXCL :: 0x00080 +O_NOCTTY :: 0x00100 +O_TRUNC :: 0x00200 +O_NONBLOCK :: 0x00800 +O_APPEND :: 0x00400 +O_SYNC :: 0x01000 +O_ASYNC :: 0x02000 +O_CLOEXEC :: 0x80000 -SEEK_SET :: 0; -SEEK_CUR :: 1; -SEEK_END :: 2; -SEEK_DATA :: 3; -SEEK_HOLE :: 4; -SEEK_MAX :: SEEK_HOLE; +SEEK_SET :: 0 +SEEK_CUR :: 1 +SEEK_END :: 2 +SEEK_DATA :: 3 +SEEK_HOLE :: 4 +SEEK_MAX :: SEEK_HOLE // NOTE: These are OS specific! // Do not mix these up! -RTLD_LAZY :: 0x001; -RTLD_NOW :: 0x002; -//RTLD_BINDING_MASK :: 0x3; // Called MODEMASK in dlfcn.h -RTLD_GLOBAL :: 0x100; -RTLD_LOCAL :: 0x000; -RTLD_TRACE :: 0x200; -RTLD_NODELETE :: 0x01000; -RTLD_NOLOAD :: 0x02000; +RTLD_LAZY :: 0x001 +RTLD_NOW :: 0x002 +//RTLD_BINDING_MASK :: 0x3 // Called MODEMASK in dlfcn.h +RTLD_GLOBAL :: 0x100 +RTLD_LOCAL :: 0x000 +RTLD_TRACE :: 0x200 +RTLD_NODELETE :: 0x01000 +RTLD_NOLOAD :: 0x02000 -args := _alloc_command_line_arguments(); +MAX_PATH :: 1024 + +args := _alloc_command_line_arguments() Unix_File_Time :: struct { - seconds: i64, + seconds: time_t, nanoseconds: c.long, } -pid_t :: u32; +dev_t :: u64 +ino_t :: u64 +nlink_t :: u64 +off_t :: i64 +mode_t :: u16 +pid_t :: u32 +uid_t :: u32 +gid_t :: u32 +blkcnt_t :: i64 +blksize_t :: i32 +fflags_t :: u32 + +when ODIN_ARCH == .amd64 /* LP64 */ { + time_t :: i64 +} else { + time_t :: i32 +} + OS_Stat :: struct { - device_id: u64, - serial: u64, - nlink: u64, - mode: u32, + device_id: dev_t, + serial: ino_t, + nlink: nlink_t, + mode: mode_t, _padding0: i16, - uid: u32, - gid: u32, + uid: uid_t, + gid: gid_t, _padding1: i32, - rdev: u64, + rdev: dev_t, last_access: Unix_File_Time, modified: Unix_File_Time, status_change: Unix_File_Time, birthtime: Unix_File_Time, - size: i64, - blocks: i64, - block_size: i32, + size: off_t, + blocks: blkcnt_t, + block_size: blksize_t, - flags: u32, + flags: fflags_t, gen: u64, - lspare: i64, + lspare: [10]u64, } + +// since FreeBSD v12 +Dirent :: struct { + ino: ino_t, + off: off_t, + reclen: u16, + type: u8, + _pad0: u8, + namlen: u16, + _pad1: u16, + name: [256]byte, +} + +Dir :: distinct rawptr // DIR* + // File type -S_IFMT :: 0o170000; // Type of file mask -S_IFIFO :: 0o010000; // Named pipe (fifo) -S_IFCHR :: 0o020000; // Character special -S_IFDIR :: 0o040000; // Directory -S_IFBLK :: 0o060000; // Block special -S_IFREG :: 0o100000; // Regular -S_IFLNK :: 0o120000; // Symbolic link -S_IFSOCK :: 0o140000; // Socket -//S_ISVTX :: 0o001000; // Save swapped text even after use +S_IFMT :: 0o170000 // Type of file mask +S_IFIFO :: 0o010000 // Named pipe (fifo) +S_IFCHR :: 0o020000 // Character special +S_IFDIR :: 0o040000 // Directory +S_IFBLK :: 0o060000 // Block special +S_IFREG :: 0o100000 // Regular +S_IFLNK :: 0o120000 // Symbolic link +S_IFSOCK :: 0o140000 // Socket +//S_ISVTX :: 0o001000 // Save swapped text even after use // File mode // Read, write, execute/search by owner -S_IRWXU :: 0o0700; // RWX mask for owner -S_IRUSR :: 0o0400; // R for owner -S_IWUSR :: 0o0200; // W for owner -S_IXUSR :: 0o0100; // X for owner +S_IRWXU :: 0o0700 // RWX mask for owner +S_IRUSR :: 0o0400 // R for owner +S_IWUSR :: 0o0200 // W for owner +S_IXUSR :: 0o0100 // X for owner // Read, write, execute/search by group -S_IRWXG :: 0o0070; // RWX mask for group -S_IRGRP :: 0o0040; // R for group -S_IWGRP :: 0o0020; // W for group -S_IXGRP :: 0o0010; // X for group +S_IRWXG :: 0o0070 // RWX mask for group +S_IRGRP :: 0o0040 // R for group +S_IWGRP :: 0o0020 // W for group +S_IXGRP :: 0o0010 // X for group // Read, write, execute/search by others -S_IRWXO :: 0o0007; // RWX mask for other -S_IROTH :: 0o0004; // R for other -S_IWOTH :: 0o0002; // W for other -S_IXOTH :: 0o0001; // X for other +S_IRWXO :: 0o0007 // RWX mask for other +S_IROTH :: 0o0004 // R for other +S_IWOTH :: 0o0002 // W for other +S_IXOTH :: 0o0001 // X for other -S_ISUID :: 0o4000; // Set user id on execution -S_ISGID :: 0o2000; // Set group id on execution -S_ISVTX :: 0o1000; // Directory restrcted delete +S_ISUID :: 0o4000 // Set user id on execution +S_ISGID :: 0o2000 // Set group id on execution +S_ISVTX :: 0o1000 // Directory restrcted delete -S_ISLNK :: #force_inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFLNK; -S_ISREG :: #force_inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFREG; -S_ISDIR :: #force_inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFDIR; -S_ISCHR :: #force_inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFCHR; -S_ISBLK :: #force_inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFBLK; -S_ISFIFO :: #force_inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFIFO; -S_ISSOCK :: #force_inline proc(m: u32) -> bool do return (m & S_IFMT) == S_IFSOCK; +S_ISLNK :: #force_inline proc(m: mode_t) -> bool do return (m & S_IFMT) == S_IFLNK +S_ISREG :: #force_inline proc(m: mode_t) -> bool do return (m & S_IFMT) == S_IFREG +S_ISDIR :: #force_inline proc(m: mode_t) -> bool do return (m & S_IFMT) == S_IFDIR +S_ISCHR :: #force_inline proc(m: mode_t) -> bool do return (m & S_IFMT) == S_IFCHR +S_ISBLK :: #force_inline proc(m: mode_t) -> bool do return (m & S_IFMT) == S_IFBLK +S_ISFIFO :: #force_inline proc(m: mode_t) -> bool do return (m & S_IFMT) == S_IFIFO +S_ISSOCK :: #force_inline proc(m: mode_t) -> bool do return (m & S_IFMT) == S_IFSOCK -F_OK :: 0; // Test for file existance -X_OK :: 1; // Test for execute permission -W_OK :: 2; // Test for write permission -R_OK :: 4; // Test for read permission +F_OK :: 0 // Test for file existance +X_OK :: 1 // Test for execute permission +W_OK :: 2 // Test for write permission +R_OK :: 4 // Test for read permission foreign libc { - @(link_name="__error") __errno_location :: proc() -> ^int ---; - @(link_name="syscall") syscall :: proc(number: Syscall, #c_vararg args: ..any) -> int ---; + @(link_name="__error") __errno_location :: proc() -> ^int --- - @(link_name="open") _unix_open :: proc(path: cstring, flags: c.int, mode: c.int) -> Handle ---; - @(link_name="close") _unix_close :: proc(fd: Handle) -> c.int ---; - @(link_name="read") _unix_read :: proc(fd: Handle, buf: rawptr, size: c.size_t) -> c.ssize_t ---; - @(link_name="write") _unix_write :: proc(fd: Handle, buf: rawptr, size: c.size_t) -> c.ssize_t ---; - @(link_name="lseek64") _unix_seek :: proc(fd: Handle, offset: i64, whence: c.int) -> i64 ---; - @(link_name="gettid") _unix_gettid :: proc() -> u64 ---; - @(link_name="getpagesize") _unix_getpagesize :: proc() -> c.int ---; - @(link_name="stat64") _unix_stat :: proc(path: cstring, stat: ^OS_Stat) -> c.int ---; - @(link_name="fstat") _unix_fstat :: proc(fd: Handle, stat: ^OS_Stat) -> c.int ---; - @(link_name="access") _unix_access :: proc(path: cstring, mask: c.int) -> c.int ---; + @(link_name="open") _unix_open :: proc(path: cstring, flags: c.int, mode: c.int) -> Handle --- + @(link_name="close") _unix_close :: proc(fd: Handle) -> c.int --- + @(link_name="read") _unix_read :: proc(fd: Handle, buf: rawptr, size: c.size_t) -> c.ssize_t --- + @(link_name="write") _unix_write :: proc(fd: Handle, buf: rawptr, size: c.size_t) -> c.ssize_t --- + @(link_name="lseek") _unix_seek :: proc(fd: Handle, offset: i64, whence: c.int) -> i64 --- + @(link_name="getpagesize") _unix_getpagesize :: proc() -> c.int --- + @(link_name="stat") _unix_stat :: proc(path: cstring, stat: ^OS_Stat) -> c.int --- + @(link_name="lstat") _unix_lstat :: proc(path: cstring, sb: ^OS_Stat) -> c.int --- + @(link_name="fstat") _unix_fstat :: proc(fd: Handle, stat: ^OS_Stat) -> c.int --- + @(link_name="readlink") _unix_readlink :: proc(path: cstring, buf: ^byte, bufsiz: c.size_t) -> c.ssize_t --- + @(link_name="access") _unix_access :: proc(path: cstring, mask: c.int) -> c.int --- + @(link_name="getcwd") _unix_getcwd :: proc(buf: cstring, len: c.size_t) -> cstring --- + @(link_name="chdir") _unix_chdir :: proc(buf: cstring) -> c.int --- + @(link_name="rename") _unix_rename :: proc(old, new: cstring) -> c.int --- + @(link_name="unlink") _unix_unlink :: proc(path: cstring) -> c.int --- + @(link_name="rmdir") _unix_rmdir :: proc(path: cstring) -> c.int --- + @(link_name="mkdir") _unix_mkdir :: proc(path: cstring, mode: mode_t) -> c.int --- + + @(link_name="fdopendir") _unix_fdopendir :: proc(fd: Handle) -> Dir --- + @(link_name="closedir") _unix_closedir :: proc(dirp: Dir) -> c.int --- + @(link_name="rewinddir") _unix_rewinddir :: proc(dirp: Dir) --- + @(link_name="readdir_r") _unix_readdir_r :: proc(dirp: Dir, entry: ^Dirent, result: ^^Dirent) -> c.int --- - @(link_name="malloc") _unix_malloc :: proc(size: c.size_t) -> rawptr ---; - @(link_name="calloc") _unix_calloc :: proc(num, size: c.size_t) -> rawptr ---; - @(link_name="free") _unix_free :: proc(ptr: rawptr) ---; - @(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: c.size_t) -> rawptr ---; - @(link_name="getenv") _unix_getenv :: proc(cstring) -> cstring ---; - @(link_name="getcwd") _unix_getcwd :: proc(buf: cstring, len: c.size_t) -> cstring ---; - @(link_name="chdir") _unix_chdir :: proc(buf: cstring) -> c.int ---; + @(link_name="malloc") _unix_malloc :: proc(size: c.size_t) -> rawptr --- + @(link_name="calloc") _unix_calloc :: proc(num, size: c.size_t) -> rawptr --- + @(link_name="free") _unix_free :: proc(ptr: rawptr) --- + @(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: c.size_t) -> rawptr --- + + @(link_name="getenv") _unix_getenv :: proc(cstring) -> cstring --- + @(link_name="realpath") _unix_realpath :: proc(path: cstring, resolved_path: rawptr) -> rawptr --- - @(link_name="exit") _unix_exit :: proc(status: c.int) -> ! ---; + @(link_name="exit") _unix_exit :: proc(status: c.int) -> ! --- } foreign dl { - @(link_name="dlopen") _unix_dlopen :: proc(filename: cstring, flags: c.int) -> rawptr ---; - @(link_name="dlsym") _unix_dlsym :: proc(handle: rawptr, symbol: cstring) -> rawptr ---; - @(link_name="dlclose") _unix_dlclose :: proc(handle: rawptr) -> c.int ---; - @(link_name="dlerror") _unix_dlerror :: proc() -> cstring ---; + @(link_name="dlopen") _unix_dlopen :: proc(filename: cstring, flags: c.int) -> rawptr --- + @(link_name="dlsym") _unix_dlsym :: proc(handle: rawptr, symbol: cstring) -> rawptr --- + @(link_name="dlclose") _unix_dlclose :: proc(handle: rawptr) -> c.int --- + @(link_name="dlerror") _unix_dlerror :: proc() -> cstring --- - @(link_name="pthread_getthreadid_np") pthread_getthreadid_np :: proc() -> c.int ---; + @(link_name="pthread_getthreadid_np") pthread_getthreadid_np :: proc() -> c.int --- } is_path_separator :: proc(r: rune) -> bool { - return r == '/'; + return r == '/' } get_last_error :: proc() -> int { - return __errno_location()^; + return __errno_location()^ } open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Errno) { - cstr := strings.clone_to_cstring(path); - handle := _unix_open(cstr, c.int(flags), c.int(mode)); - delete(cstr); + cstr := strings.clone_to_cstring(path, context.temp_allocator) + handle := _unix_open(cstr, c.int(flags), c.int(mode)) if handle == -1 { - return INVALID_HANDLE, Errno(get_last_error()); + return INVALID_HANDLE, Errno(get_last_error()) } - return handle, ERROR_NONE; + return handle, ERROR_NONE } close :: proc(fd: Handle) -> Errno { - result := _unix_close(fd); + result := _unix_close(fd) if result == -1 { - return Errno(get_last_error()); + return Errno(get_last_error()) } - return ERROR_NONE; + return ERROR_NONE } read :: proc(fd: Handle, data: []byte) -> (int, Errno) { - bytes_read := _unix_read(fd, &data[0], c.size_t(len(data))); + bytes_read := _unix_read(fd, &data[0], c.size_t(len(data))) if bytes_read == -1 { - return -1, Errno(get_last_error()); + return -1, Errno(get_last_error()) } - return int(bytes_read), ERROR_NONE; + return int(bytes_read), ERROR_NONE } write :: proc(fd: Handle, data: []byte) -> (int, Errno) { if len(data) == 0 { - return 0, ERROR_NONE; + return 0, ERROR_NONE } - bytes_written := _unix_write(fd, &data[0], c.size_t(len(data))); + bytes_written := _unix_write(fd, &data[0], c.size_t(len(data))) if bytes_written == -1 { - return -1, Errno(get_last_error()); + return -1, Errno(get_last_error()) } - return int(bytes_written), ERROR_NONE; + return int(bytes_written), ERROR_NONE } seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) { - res := _unix_seek(fd, offset, c.int(whence)); + res := _unix_seek(fd, offset, c.int(whence)) if res == -1 { - return -1, Errno(get_last_error()); + return -1, Errno(get_last_error()) } - return res, ERROR_NONE; + return res, ERROR_NONE } file_size :: proc(fd: Handle) -> (i64, Errno) { - s, err := fstat(fd); + s, err := fstat(fd) if err != ERROR_NONE { - return -1, err; + return -1, err } - return s.size, ERROR_NONE; + return s.size, ERROR_NONE } -stdin: Handle = 0; -stdout: Handle = 1; -stderr: Handle = 2; - -last_write_time :: proc(fd: Handle) -> (File_Time, Errno) { - s, err := fstat(fd); - if err != ERROR_NONE { - return 0, err; +rename :: proc(old_path, new_path: string) -> Errno { + old_path_cstr := strings.clone_to_cstring(old_path, context.temp_allocator) + new_path_cstr := strings.clone_to_cstring(new_path, context.temp_allocator) + res := _unix_rename(old_path_cstr, new_path_cstr) + if res == -1 { + return Errno(get_last_error()) } - modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds; - return File_Time(modified), ERROR_NONE; + return ERROR_NONE +} + +remove :: proc(path: string) -> Errno { + path_cstr := strings.clone_to_cstring(path, context.temp_allocator) + res := _unix_unlink(path_cstr) + if res == -1 { + return Errno(get_last_error()) + } + return ERROR_NONE +} + +make_directory :: proc(path: string, mode: mode_t = 0o775) -> Errno { + path_cstr := strings.clone_to_cstring(path, context.temp_allocator) + res := _unix_mkdir(path_cstr, mode) + if res == -1 { + return Errno(get_last_error()) + } + return ERROR_NONE +} + +remove_directory :: proc(path: string) -> Errno { + path_cstr := strings.clone_to_cstring(path, context.temp_allocator) + res := _unix_rmdir(path_cstr) + if res == -1 { + return Errno(get_last_error()) + } + return ERROR_NONE +} + +is_file_handle :: proc(fd: Handle) -> bool { + s, err := _fstat(fd) + if err != ERROR_NONE { + return false + } + return S_ISREG(s.mode) +} + +is_file_path :: proc(path: string, follow_links: bool = true) -> bool { + s: OS_Stat + err: Errno + if follow_links { + s, err = _stat(path) + } else { + s, err = _lstat(path) + } + if err != ERROR_NONE { + return false + } + return S_ISREG(s.mode) +} + +is_dir_handle :: proc(fd: Handle) -> bool { + s, err := _fstat(fd) + if err != ERROR_NONE { + return false + } + return S_ISDIR(s.mode) +} + +is_dir_path :: proc(path: string, follow_links: bool = true) -> bool { + s: OS_Stat + err: Errno + if follow_links { + s, err = _stat(path) + } else { + s, err = _lstat(path) + } + if err != ERROR_NONE { + return false + } + return S_ISDIR(s.mode) +} + +is_file :: proc {is_file_path, is_file_handle} +is_dir :: proc {is_dir_path, is_dir_handle} + +// NOTE(bill): Uses startup to initialize it + +stdin: Handle = 0 +stdout: Handle = 1 +stderr: Handle = 2 + +/* TODO(zangent): Implement these! +last_write_time :: proc(fd: Handle) -> File_Time {} +last_write_time_by_name :: proc(name: string) -> File_Time {} +*/ +last_write_time :: proc(fd: Handle) -> (File_Time, Errno) { + s, err := _fstat(fd) + if err != ERROR_NONE { + return 0, err + } + modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds + return File_Time(modified), ERROR_NONE } last_write_time_by_name :: proc(name: string) -> (File_Time, Errno) { - s, err := stat(name); + s, err := _stat(name) if err != ERROR_NONE { - return 0, err; + return 0, err } - modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds; - return File_Time(modified), ERROR_NONE; + modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds + return File_Time(modified), ERROR_NONE } -stat :: proc(path: string) -> (OS_Stat, Errno) { - cstr := strings.clone_to_cstring(path); - defer delete(cstr); - - s: OS_Stat; - result := _unix_stat(cstr, &s); +@private +_stat :: proc(path: string) -> (OS_Stat, Errno) { + cstr := strings.clone_to_cstring(path, context.temp_allocator) + s: OS_Stat = --- + result := _unix_lstat(cstr, &s) if result == -1 { - return s, Errno(get_last_error()); + return s, Errno(get_last_error()) } - return s, ERROR_NONE; + return s, ERROR_NONE } -fstat :: proc(fd: Handle) -> (OS_Stat, Errno) { - s: OS_Stat; - result := _unix_fstat(fd, &s); - if result == -1 { - return s, Errno(get_last_error()); +@private +_lstat :: proc(path: string) -> (OS_Stat, Errno) { + cstr := strings.clone_to_cstring(path, context.temp_allocator) + + // deliberately uninitialized + s: OS_Stat = --- + res := _unix_lstat(cstr, &s) + if res == -1 { + return s, Errno(get_last_error()) } - return s, ERROR_NONE; + return s, ERROR_NONE +} + +@private +_fstat :: proc(fd: Handle) -> (OS_Stat, Errno) { + s: OS_Stat = --- + result := _unix_fstat(fd, &s) + if result == -1 { + return s, Errno(get_last_error()) + } + return s, ERROR_NONE +} + +@private +_fdopendir :: proc(fd: Handle) -> (Dir, Errno) { + dirp := _unix_fdopendir(fd) + if dirp == cast(Dir)nil { + return nil, Errno(get_last_error()) + } + return dirp, ERROR_NONE +} + +@private +_closedir :: proc(dirp: Dir) -> Errno { + rc := _unix_closedir(dirp) + if rc != 0 { + return Errno(get_last_error()) + } + return ERROR_NONE +} + +@private +_rewinddir :: proc(dirp: Dir) { + _unix_rewinddir(dirp) +} + +@private +_readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Errno, end_of_stream: bool) { + result: ^Dirent + rc := _unix_readdir_r(dirp, &entry, &result) + + if rc != 0 { + err = Errno(get_last_error()) + return + } + err = ERROR_NONE + + if result == nil { + end_of_stream = true + return + } + + return +} + +@private +_readlink :: proc(path: string) -> (string, Errno) { + path_cstr := strings.clone_to_cstring(path, context.temp_allocator) + + bufsz : uint = MAX_PATH + buf := make([]byte, MAX_PATH) + for { + rc := _unix_readlink(path_cstr, &(buf[0]), bufsz) + if rc == -1 { + delete(buf) + return "", Errno(get_last_error()) + } else if rc == int(bufsz) { + bufsz += MAX_PATH + delete(buf) + buf = make([]byte, bufsz) + } else { + return strings.string_from_ptr(&buf[0], rc), ERROR_NONE + } + } + unreachable() +} + +// XXX FreeBSD +absolute_path_from_handle :: proc(fd: Handle) -> (string, Errno) { + return "", Errno(ENOSYS) +} + +absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) { + rel := rel + if rel == "" { + rel = "." + } + + rel_cstr := strings.clone_to_cstring(rel, context.temp_allocator) + + path_ptr := _unix_realpath(rel_cstr, nil) + if path_ptr == nil { + return "", Errno(get_last_error()) + } + defer _unix_free(path_ptr) + + path_cstr := transmute(cstring)path_ptr + path = strings.clone( string(path_cstr) ) + + return path, ERROR_NONE } access :: proc(path: string, mask: int) -> (bool, Errno) { - cstr := strings.clone_to_cstring(path); - defer delete(cstr); - result := _unix_access(cstr, c.int(mask)); + cstr := strings.clone_to_cstring(path, context.temp_allocator) + result := _unix_access(cstr, c.int(mask)) if result == -1 { - return false, Errno(get_last_error()); + return false, Errno(get_last_error()) } - return true, ERROR_NONE; + return true, ERROR_NONE } heap_alloc :: proc(size: int) -> rawptr { - assert(size >= 0); - return _unix_calloc(1, c.size_t(size)); + assert(size >= 0) + return _unix_calloc(1, c.size_t(size)) } heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr { - return _unix_realloc(ptr, c.size_t(new_size)); + // NOTE: _unix_realloc doesn't guarantee new memory will be zeroed on + // POSIX platforms. Ensure your caller takes this into account. + return _unix_realloc(ptr, c.size_t(new_size)) } heap_free :: proc(ptr: rawptr) { - _unix_free(ptr); + _unix_free(ptr) } getenv :: proc(name: string) -> (string, bool) { - path_str := strings.clone_to_cstring(name); - defer delete(path_str); - cstr := _unix_getenv(path_str); + path_str := strings.clone_to_cstring(name, context.temp_allocator) + cstr := _unix_getenv(path_str) if cstr == nil { - return "", false; + return "", false } - return string(cstr), true; + return string(cstr), true } get_current_directory :: proc() -> string { // NOTE(tetra): I would use PATH_MAX here, but I was not able to find // an authoritative value for it across all systems. // The largest value I could find was 4096, so might as well use the page size. - page_size := get_page_size(); - buf := make([dynamic]u8, page_size); + page_size := get_page_size() + buf := make([dynamic]u8, page_size) #no_bounds_check for { - cwd := _unix_getcwd(cstring(&buf[0]), c.size_t(len(buf))); + cwd := _unix_getcwd(cstring(&buf[0]), c.size_t(len(buf))) if cwd != nil { - return string(cwd); + return string(cwd) } if Errno(get_last_error()) != ERANGE { - return ""; + return "" } - resize(&buf, len(buf)+page_size); + resize(&buf, len(buf)+page_size) } - unreachable(); + unreachable() } set_current_directory :: proc(path: string) -> (err: Errno) { - cstr := strings.clone_to_cstring(path, context.temp_allocator); - res := _unix_chdir(cstr); - if res == -1 do return Errno(get_last_error()); - return ERROR_NONE; + cstr := strings.clone_to_cstring(path, context.temp_allocator) + res := _unix_chdir(cstr) + if res == -1 do return Errno(get_last_error()) + return ERROR_NONE } exit :: proc "contextless" (code: int) -> ! { - _unix_exit(c.int(code)); + runtime._cleanup_runtime_contextless() + _unix_exit(c.int(code)) } current_thread_id :: proc "contextless" () -> int { - return cast(int) pthread_getthreadid_np(); + return cast(int) pthread_getthreadid_np() } dlopen :: proc(filename: string, flags: int) -> rawptr { - cstr := strings.clone_to_cstring(filename); - defer delete(cstr); - handle := _unix_dlopen(cstr, c.int(flags)); - return handle; + cstr := strings.clone_to_cstring(filename, context.temp_allocator) + handle := _unix_dlopen(cstr, c.int(flags)) + return handle } dlsym :: proc(handle: rawptr, symbol: string) -> rawptr { - assert(handle != nil); - cstr := strings.clone_to_cstring(symbol); - defer delete(cstr); - proc_handle := _unix_dlsym(handle, cstr); - return proc_handle; + assert(handle != nil) + cstr := strings.clone_to_cstring(symbol, context.temp_allocator) + proc_handle := _unix_dlsym(handle, cstr) + return proc_handle } dlclose :: proc(handle: rawptr) -> bool { - assert(handle != nil); - return _unix_dlclose(handle) == 0; + assert(handle != nil) + return _unix_dlclose(handle) == 0 } dlerror :: proc() -> string { - return string(_unix_dlerror()); + return string(_unix_dlerror()) } get_page_size :: proc() -> int { // NOTE(tetra): The page size never changes, so why do anything complicated // if we don't have to. - @static page_size := -1; - if page_size != -1 do return page_size; + @static page_size := -1 + if page_size != -1 do return page_size - page_size = int(_unix_getpagesize()); - return page_size; + page_size = int(_unix_getpagesize()) + return page_size } _alloc_command_line_arguments :: proc() -> []string { - res := make([]string, len(runtime.args__)); + res := make([]string, len(runtime.args__)) for arg, i in runtime.args__ { - res[i] = string(arg); + res[i] = string(arg) } - return res; + return res } - diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin index 260a051ce..ed73341c0 100644 --- a/core/os/os_linux.odin +++ b/core/os/os_linux.odin @@ -11,6 +11,7 @@ import "core:intrinsics" import "core:sys/unix" Handle :: distinct i32 +Pid :: distinct i32 File_Time :: distinct u64 Errno :: distinct i32 @@ -150,6 +151,8 @@ ERFKILL: Errno : 132 /* Operation not possible due to RF-kill */ EHWPOISON: Errno : 133 /* Memory page has hardware error */ +ADDR_NO_RANDOMIZE :: 0x40000 + O_RDONLY :: 0x00000 O_WRONLY :: 0x00001 O_RDWR :: 0x00002 @@ -266,33 +269,155 @@ X_OK :: 1 // Test for execute permission W_OK :: 2 // Test for write permission R_OK :: 4 // Test for read permission +AT_FDCWD :: ~uintptr(99) /* -100 */ +AT_REMOVEDIR :: uintptr(0x200) +AT_SYMLINK_NOFOLLOW :: uintptr(0x100) + +_unix_personality :: proc(persona: u64) -> int { + return int(intrinsics.syscall(unix.SYS_personality, uintptr(persona))) +} + +_unix_fork :: proc() -> Pid { + when ODIN_ARCH != .arm64 { + res := int(intrinsics.syscall(unix.SYS_fork)) + } else { + res := int(intrinsics.syscall(unix.SYS_clone, unix.SIGCHLD)) + } + return -1 if res < 0 else Pid(res) +} + +_unix_open :: proc(path: cstring, flags: int, mode: int = 0o000) -> Handle { + when ODIN_ARCH != .arm64 { + res := int(intrinsics.syscall(unix.SYS_open, uintptr(rawptr(path)), uintptr(flags), uintptr(mode))) + } else { // NOTE: arm64 does not have open + res := int(intrinsics.syscall(unix.SYS_openat, AT_FDCWD, uintptr(rawptr(path)), uintptr(flags), uintptr(mode))) + } + return -1 if res < 0 else Handle(res) +} + +_unix_close :: proc(fd: Handle) -> int { + return int(intrinsics.syscall(unix.SYS_close, uintptr(fd))) +} + +_unix_read :: proc(fd: Handle, buf: rawptr, size: uint) -> int { + return int(intrinsics.syscall(unix.SYS_read, uintptr(fd), uintptr(buf), uintptr(size))) +} + +_unix_write :: proc(fd: Handle, buf: rawptr, size: uint) -> int { + return int(intrinsics.syscall(unix.SYS_write, uintptr(fd), uintptr(buf), uintptr(size))) +} + +_unix_seek :: proc(fd: Handle, offset: i64, whence: int) -> i64 { + when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 { + return i64(intrinsics.syscall(unix.SYS_lseek, uintptr(fd), uintptr(offset), uintptr(whence))) + } else { + low := uintptr(offset & 0xFFFFFFFF) + high := uintptr(offset >> 32) + result: i64 + res := i64(intrinsics.syscall(unix.SYS__llseek, uintptr(fd), high, low, &result, uintptr(whence))) + return -1 if res < 0 else result + } +} + +_unix_stat :: proc(path: cstring, stat: ^OS_Stat) -> int { + when ODIN_ARCH == .amd64 { + return int(intrinsics.syscall(unix.SYS_stat, uintptr(rawptr(path)), uintptr(stat))) + } else when ODIN_ARCH != .arm64 { + return int(intrinsics.syscall(unix.SYS_stat64, uintptr(rawptr(path)), uintptr(stat))) + } else { // NOTE: arm64 does not have stat + return int(intrinsics.syscall(unix.SYS_fstatat, AT_FDCWD, uintptr(rawptr(path)), uintptr(stat), 0)) + } +} + +_unix_fstat :: proc(fd: Handle, stat: ^OS_Stat) -> int { + when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 { + return int(intrinsics.syscall(unix.SYS_fstat, uintptr(fd), uintptr(stat))) + } else { + return int(intrinsics.syscall(unix.SYS_fstat64, uintptr(fd), uintptr(stat))) + } +} + +_unix_lstat :: proc(path: cstring, stat: ^OS_Stat) -> int { + when ODIN_ARCH == .amd64 { + return int(intrinsics.syscall(unix.SYS_lstat, uintptr(rawptr(path)), uintptr(stat))) + } else when ODIN_ARCH != .arm64 { + return int(intrinsics.syscall(unix.SYS_lstat64, uintptr(rawptr(path)), uintptr(stat))) + } else { // NOTE: arm64 does not have any lstat + return int(intrinsics.syscall(unix.SYS_fstatat, AT_FDCWD, uintptr(rawptr(path)), uintptr(stat), AT_SYMLINK_NOFOLLOW)) + } +} + +_unix_readlink :: proc(path: cstring, buf: rawptr, bufsiz: uint) -> int { + when ODIN_ARCH != .arm64 { + return int(intrinsics.syscall(unix.SYS_readlink, uintptr(rawptr(path)), uintptr(buf), uintptr(bufsiz))) + } else { // NOTE: arm64 does not have readlink + return int(intrinsics.syscall(unix.SYS_readlinkat, AT_FDCWD, uintptr(rawptr(path)), uintptr(buf), uintptr(bufsiz))) + } +} + +_unix_access :: proc(path: cstring, mask: int) -> int { + when ODIN_ARCH != .arm64 { + return int(intrinsics.syscall(unix.SYS_access, uintptr(rawptr(path)), uintptr(mask))) + } else { // NOTE: arm64 does not have access + return int(intrinsics.syscall(unix.SYS_faccessat, AT_FDCWD, uintptr(rawptr(path)), uintptr(mask))) + } +} + +_unix_getcwd :: proc(buf: rawptr, size: uint) -> int { + return int(intrinsics.syscall(unix.SYS_getcwd, uintptr(buf), uintptr(size))) +} + +_unix_chdir :: proc(path: cstring) -> int { + return int(intrinsics.syscall(unix.SYS_chdir, uintptr(rawptr(path)))) +} + +_unix_rename :: proc(old, new: cstring) -> int { + when ODIN_ARCH != .arm64 { + return int(intrinsics.syscall(unix.SYS_rename, uintptr(rawptr(old)), uintptr(rawptr(new)))) + } else { // NOTE: arm64 does not have rename + return int(intrinsics.syscall(unix.SYS_renameat, AT_FDCWD, uintptr(rawptr(old)), uintptr(rawptr(new)))) + } +} + +_unix_unlink :: proc(path: cstring) -> int { + when ODIN_ARCH != .arm64 { + return int(intrinsics.syscall(unix.SYS_unlink, uintptr(rawptr(path)))) + } else { // NOTE: arm64 does not have unlink + return int(intrinsics.syscall(unix.SYS_unlinkat, AT_FDCWD, uintptr(rawptr(path)), 0)) + } +} + +_unix_rmdir :: proc(path: cstring) -> int { + when ODIN_ARCH != .arm64 { + return int(intrinsics.syscall(unix.SYS_rmdir, uintptr(rawptr(path)))) + } else { // NOTE: arm64 does not have rmdir + return int(intrinsics.syscall(unix.SYS_unlinkat, AT_FDCWD, uintptr(rawptr(path)), AT_REMOVEDIR)) + } +} + +_unix_mkdir :: proc(path: cstring, mode: u32) -> int { + when ODIN_ARCH != .arm64 { + return int(intrinsics.syscall(unix.SYS_mkdir, uintptr(rawptr(path)), uintptr(mode))) + } else { // NOTE: arm64 does not have mkdir + return int(intrinsics.syscall(unix.SYS_mkdirat, AT_FDCWD, uintptr(rawptr(path)), uintptr(mode))) + } +} + foreign libc { @(link_name="__errno_location") __errno_location :: proc() -> ^int --- - @(link_name="open") _unix_open :: proc(path: cstring, flags: c.int, mode: c.int) -> Handle --- - @(link_name="close") _unix_close :: proc(fd: Handle) -> c.int --- - @(link_name="read") _unix_read :: proc(fd: Handle, buf: rawptr, size: c.size_t) -> c.ssize_t --- - @(link_name="write") _unix_write :: proc(fd: Handle, buf: rawptr, size: c.size_t) -> c.ssize_t --- - @(link_name="lseek64") _unix_seek :: proc(fd: Handle, offset: i64, whence: c.int) -> i64 --- - @(link_name="gettid") _unix_gettid :: proc() -> u64 --- @(link_name="getpagesize") _unix_getpagesize :: proc() -> c.int --- - @(link_name="stat64") _unix_stat :: proc(path: cstring, stat: ^OS_Stat) -> c.int --- - @(link_name="lstat") _unix_lstat :: proc(path: cstring, stat: ^OS_Stat) -> c.int --- - @(link_name="fstat") _unix_fstat :: proc(fd: Handle, stat: ^OS_Stat) -> c.int --- @(link_name="fdopendir") _unix_fdopendir :: proc(fd: Handle) -> Dir --- @(link_name="closedir") _unix_closedir :: proc(dirp: Dir) -> c.int --- @(link_name="rewinddir") _unix_rewinddir :: proc(dirp: Dir) --- @(link_name="readdir_r") _unix_readdir_r :: proc(dirp: Dir, entry: ^Dirent, result: ^^Dirent) -> c.int --- - @(link_name="readlink") _unix_readlink :: proc(path: cstring, buf: ^byte, bufsiz: c.size_t) -> c.ssize_t --- - @(link_name="access") _unix_access :: proc(path: cstring, mask: c.int) -> c.int --- @(link_name="malloc") _unix_malloc :: proc(size: c.size_t) -> rawptr --- @(link_name="calloc") _unix_calloc :: proc(num, size: c.size_t) -> rawptr --- @(link_name="free") _unix_free :: proc(ptr: rawptr) --- @(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: c.size_t) -> rawptr --- + @(link_name="getenv") _unix_getenv :: proc(cstring) -> cstring --- - @(link_name="getcwd") _unix_getcwd :: proc(buf: cstring, len: c.size_t) -> cstring --- - @(link_name="chdir") _unix_chdir :: proc(buf: cstring) -> c.int --- @(link_name="realpath") _unix_realpath :: proc(path: cstring, resolved_path: rawptr) -> rawptr --- @(link_name="exit") _unix_exit :: proc(status: c.int) -> ! --- @@ -308,63 +433,155 @@ is_path_separator :: proc(r: rune) -> bool { return r == '/' } +// determine errno from syscall return value +@private +_get_errno :: proc(res: int) -> Errno { + if res < 0 && res > -4096 { + return Errno(-res) + } + return 0 +} + +// get errno from libc get_last_error :: proc() -> int { return __errno_location()^ } +personality :: proc(persona: u64) -> (Errno) { + res := _unix_personality(persona) + if res == -1 { + return _get_errno(res) + } + return ERROR_NONE +} + +fork :: proc() -> (Pid, Errno) { + pid := _unix_fork() + if pid == -1 { + return -1, _get_errno(int(pid)) + } + return pid, ERROR_NONE +} + open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Errno) { - cstr := strings.clone_to_cstring(path) - handle := _unix_open(cstr, c.int(flags), c.int(mode)) - delete(cstr) - if handle == -1 { - return INVALID_HANDLE, Errno(get_last_error()) + cstr := strings.clone_to_cstring(path, context.temp_allocator) + handle := _unix_open(cstr, flags, mode) + if handle < 0 { + return INVALID_HANDLE, _get_errno(int(handle)) } return handle, ERROR_NONE } close :: proc(fd: Handle) -> Errno { - result := _unix_close(fd) - if result == -1 { - return Errno(get_last_error()) - } - return ERROR_NONE + return _get_errno(_unix_close(fd)) } read :: proc(fd: Handle, data: []byte) -> (int, Errno) { bytes_read := _unix_read(fd, &data[0], c.size_t(len(data))) - if bytes_read == -1 { - return -1, Errno(get_last_error()) + if bytes_read < 0 { + return -1, _get_errno(bytes_read) } - return int(bytes_read), ERROR_NONE + return bytes_read, ERROR_NONE } write :: proc(fd: Handle, data: []byte) -> (int, Errno) { if len(data) == 0 { return 0, ERROR_NONE } - bytes_written := _unix_write(fd, &data[0], c.size_t(len(data))) - if bytes_written == -1 { - return -1, Errno(get_last_error()) + bytes_written := _unix_write(fd, &data[0], uint(len(data))) + if bytes_written < 0 { + return -1, _get_errno(bytes_written) } return int(bytes_written), ERROR_NONE } seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) { - res := _unix_seek(fd, offset, c.int(whence)) - if res == -1 { - return -1, Errno(get_last_error()) + res := _unix_seek(fd, offset, whence) + if res < 0 { + return -1, _get_errno(int(res)) } return res, ERROR_NONE } file_size :: proc(fd: Handle) -> (i64, Errno) { + // deliberately uninitialized; the syscall fills this buffer for us + s: OS_Stat = --- + result := _unix_fstat(fd, &s) + if result < 0 { + return 0, _get_errno(result) + } + return max(s.size, 0), ERROR_NONE +} + +rename :: proc(old_path, new_path: string) -> Errno { + old_path_cstr := strings.clone_to_cstring(old_path, context.temp_allocator) + new_path_cstr := strings.clone_to_cstring(new_path, context.temp_allocator) + return _get_errno(_unix_rename(old_path_cstr, new_path_cstr)) +} + +remove :: proc(path: string) -> Errno { + path_cstr := strings.clone_to_cstring(path, context.temp_allocator) + return _get_errno(_unix_unlink(path_cstr)) +} + +make_directory :: proc(path: string, mode: u32 = 0o775) -> Errno { + path_cstr := strings.clone_to_cstring(path, context.temp_allocator) + return _get_errno(_unix_mkdir(path_cstr, mode)) +} + +remove_directory :: proc(path: string) -> Errno { + path_cstr := strings.clone_to_cstring(path, context.temp_allocator) + return _get_errno(_unix_rmdir(path_cstr)) +} + +is_file_handle :: proc(fd: Handle) -> bool { s, err := _fstat(fd) if err != ERROR_NONE { - return 0, err + return false } - return max(s.size, 0), ERROR_NONE + return S_ISREG(s.mode) } +is_file_path :: proc(path: string, follow_links: bool = true) -> bool { + s: OS_Stat + err: Errno + if follow_links { + s, err = _stat(path) + } else { + s, err = _lstat(path) + } + if err != ERROR_NONE { + return false + } + return S_ISREG(s.mode) +} + + +is_dir_handle :: proc(fd: Handle) -> bool { + s, err := _fstat(fd) + if err != ERROR_NONE { + return false + } + return S_ISDIR(s.mode) +} + +is_dir_path :: proc(path: string, follow_links: bool = true) -> bool { + s: OS_Stat + err: Errno + if follow_links { + s, err = _stat(path) + } else { + s, err = _lstat(path) + } + if err != ERROR_NONE { + return false + } + return S_ISDIR(s.mode) +} + +is_file :: proc {is_file_path, is_file_handle} +is_dir :: proc {is_dir_path, is_dir_handle} + // NOTE(bill): Uses startup to initialize it @@ -396,36 +613,37 @@ last_write_time_by_name :: proc(name: string) -> (File_Time, Errno) { @private _stat :: proc(path: string) -> (OS_Stat, Errno) { - cstr := strings.clone_to_cstring(path) - defer delete(cstr) + cstr := strings.clone_to_cstring(path, context.temp_allocator) - s: OS_Stat + // deliberately uninitialized; the syscall fills this buffer for us + s: OS_Stat = --- result := _unix_stat(cstr, &s) - if result == -1 { - return s, Errno(get_last_error()) + if result < 0 { + return s, _get_errno(result) } return s, ERROR_NONE } @private _lstat :: proc(path: string) -> (OS_Stat, Errno) { - cstr := strings.clone_to_cstring(path) - defer delete(cstr) + cstr := strings.clone_to_cstring(path, context.temp_allocator) - s: OS_Stat + // deliberately uninitialized; the syscall fills this buffer for us + s: OS_Stat = --- result := _unix_lstat(cstr, &s) - if result == -1 { - return s, Errno(get_last_error()) + if result < 0 { + return s, _get_errno(result) } return s, ERROR_NONE } @private _fstat :: proc(fd: Handle) -> (OS_Stat, Errno) { - s: OS_Stat + // deliberately uninitialized; the syscall fills this buffer for us + s: OS_Stat = --- result := _unix_fstat(fd, &s) - if result == -1 { - return s, Errno(get_last_error()) + if result < 0 { + return s, _get_errno(result) } return s, ERROR_NONE } @@ -475,16 +693,15 @@ _readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Errno, end_of_stream: bool) @private _readlink :: proc(path: string) -> (string, Errno) { - path_cstr := strings.clone_to_cstring(path) - defer delete(path_cstr) + path_cstr := strings.clone_to_cstring(path, context.temp_allocator) bufsz : uint = 256 buf := make([]byte, bufsz) for { rc := _unix_readlink(path_cstr, &(buf[0]), bufsz) - if rc == -1 { + if rc < 0 { delete(buf) - return "", Errno(get_last_error()) + return "", _get_errno(rc) } else if rc == int(bufsz) { // NOTE(laleksic, 2021-01-21): Any cleaner way to resize the slice? bufsz *= 2 @@ -512,8 +729,7 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) { rel = "." } - rel_cstr := strings.clone_to_cstring(rel) - defer delete(rel_cstr) + rel_cstr := strings.clone_to_cstring(rel, context.temp_allocator) path_ptr := _unix_realpath(rel_cstr, nil) if path_ptr == nil { @@ -528,11 +744,10 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) { } access :: proc(path: string, mask: int) -> (bool, Errno) { - cstr := strings.clone_to_cstring(path) - defer delete(cstr) - result := _unix_access(cstr, c.int(mask)) - if result == -1 { - return false, Errno(get_last_error()) + cstr := strings.clone_to_cstring(path, context.temp_allocator) + result := _unix_access(cstr, mask) + if result < 0 { + return false, _get_errno(result) } return true, ERROR_NONE } @@ -543,6 +758,8 @@ heap_alloc :: proc(size: int) -> rawptr { } heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr { + // NOTE: _unix_realloc doesn't guarantee new memory will be zeroed on + // POSIX platforms. Ensure your caller takes this into account. return _unix_realloc(ptr, c.size_t(new_size)) } @@ -551,8 +768,7 @@ heap_free :: proc(ptr: rawptr) { } getenv :: proc(name: string) -> (string, bool) { - path_str := strings.clone_to_cstring(name) - defer delete(path_str) + path_str := strings.clone_to_cstring(name, context.temp_allocator) cstr := _unix_getenv(path_str) if cstr == nil { return "", false @@ -567,11 +783,12 @@ get_current_directory :: proc() -> string { page_size := get_page_size() buf := make([dynamic]u8, page_size) for { - #no_bounds_check cwd := _unix_getcwd(cstring(&buf[0]), c.size_t(len(buf))) - if cwd != nil { - return string(cwd) + #no_bounds_check res := _unix_getcwd(&buf[0], uint(len(buf))) + + if res >= 0 { + return strings.string_from_nul_terminated_ptr(&buf[0], len(buf)) } - if Errno(get_last_error()) != ERANGE { + if _get_errno(res) != ERANGE { return "" } resize(&buf, len(buf)+page_size) @@ -582,13 +799,14 @@ get_current_directory :: proc() -> string { set_current_directory :: proc(path: string) -> (err: Errno) { cstr := strings.clone_to_cstring(path, context.temp_allocator) res := _unix_chdir(cstr) - if res == -1 { - return Errno(get_last_error()) + if res < 0 { + return _get_errno(res) } return ERROR_NONE } exit :: proc "contextless" (code: int) -> ! { + runtime._cleanup_runtime_contextless() _unix_exit(c.int(code)) } @@ -597,15 +815,13 @@ current_thread_id :: proc "contextless" () -> int { } dlopen :: proc(filename: string, flags: int) -> rawptr { - cstr := strings.clone_to_cstring(filename) - defer delete(cstr) + cstr := strings.clone_to_cstring(filename, context.temp_allocator) handle := _unix_dlopen(cstr, c.int(flags)) return handle } dlsym :: proc(handle: rawptr, symbol: string) -> rawptr { assert(handle != nil) - cstr := strings.clone_to_cstring(symbol) - defer delete(cstr) + cstr := strings.clone_to_cstring(symbol, context.temp_allocator) proc_handle := _unix_dlsym(handle, cstr) return proc_handle } diff --git a/core/os/os_openbsd.odin b/core/os/os_openbsd.odin new file mode 100644 index 000000000..a99c8fef0 --- /dev/null +++ b/core/os/os_openbsd.odin @@ -0,0 +1,707 @@ +package os + +foreign import libc "system:c" + +import "core:strings" +import "core:c" +import "core:runtime" + +Handle :: distinct i32 +Pid :: distinct i32 +File_Time :: distinct u64 +Errno :: distinct i32 + +INVALID_HANDLE :: ~Handle(0) + +ERROR_NONE: Errno: 0 + +EPERM: Errno: 1 +ENOENT: Errno: 2 +ESRCH: Errno: 3 +EINTR: Errno: 4 +EIO: Errno: 5 +ENXIO: Errno: 6 +E2BIG: Errno: 7 +ENOEXEC: Errno: 8 +EBADF: Errno: 9 +ECHILD: Errno: 10 +EDEADLK: Errno: 11 +ENOMEM: Errno: 12 +EACCES: Errno: 13 +EFAULT: Errno: 14 +ENOTBLK: Errno: 15 +EBUSY: Errno: 16 +EEXIST: Errno: 17 +EXDEV: Errno: 18 +ENODEV: Errno: 19 +ENOTDIR: Errno: 20 +EISDIR: Errno: 21 +EINVAL: Errno: 22 +ENFILE: Errno: 23 +EMFILE: Errno: 24 +ENOTTY: Errno: 25 +ETXTBSY: Errno: 26 +EFBIG: Errno: 27 +ENOSPC: Errno: 28 +ESPIPE: Errno: 29 +EROFS: Errno: 30 +EMLINK: Errno: 31 +EPIPE: Errno: 32 +EDOM: Errno: 33 +ERANGE: Errno: 34 +EAGAIN: Errno: 35 +EWOULDBLOCK: Errno: EAGAIN +EINPROGRESS: Errno: 36 +EALREADY: Errno: 37 +ENOTSOCK: Errno: 38 +EDESTADDRREQ: Errno: 39 +EMSGSIZE: Errno: 40 +EPROTOTYPE: Errno: 41 +ENOPROTOOPT: Errno: 42 +EPROTONOSUPPORT: Errno: 43 +ESOCKTNOSUPPORT: Errno: 44 +EOPNOTSUPP: Errno: 45 +EPFNOSUPPORT: Errno: 46 +EAFNOSUPPORT: Errno: 47 +EADDRINUSE: Errno: 48 +EADDRNOTAVAIL: Errno: 49 +ENETDOWN: Errno: 50 +ENETUNREACH: Errno: 51 +ENETRESET: Errno: 52 +ECONNABORTED: Errno: 53 +ECONNRESET: Errno: 54 +ENOBUFS: Errno: 55 +EISCONN: Errno: 56 +ENOTCONN: Errno: 57 +ESHUTDOWN: Errno: 58 +ETOOMANYREFS: Errno: 59 +ETIMEDOUT: Errno: 60 +ECONNREFUSED: Errno: 61 +ELOOP: Errno: 62 +ENAMETOOLONG: Errno: 63 +EHOSTDOWN: Errno: 64 +EHOSTUNREACH: Errno: 65 +ENOTEMPTY: Errno: 66 +EPROCLIM: Errno: 67 +EUSERS: Errno: 68 +EDQUOT: Errno: 69 +ESTALE: Errno: 70 +EREMOTE: Errno: 71 +EBADRPC: Errno: 72 +ERPCMISMATCH: Errno: 73 +EPROGUNAVAIL: Errno: 74 +EPROGMISMATCH: Errno: 75 +EPROCUNAVAIL: Errno: 76 +ENOLCK: Errno: 77 +ENOSYS: Errno: 78 +EFTYPE: Errno: 79 +EAUTH: Errno: 80 +ENEEDAUTH: Errno: 81 +EIPSEC: Errno: 82 +ENOATTR: Errno: 83 +EILSEQ: Errno: 84 +ENOMEDIUM: Errno: 85 +EMEDIUMTYPE: Errno: 86 +EOVERFLOW: Errno: 87 +ECANCELED: Errno: 88 +EIDRM: Errno: 89 +ENOMSG: Errno: 90 +ENOTSUP: Errno: 91 +EBADMSG: Errno: 92 +ENOTRECOVERABLE: Errno: 93 +EOWNERDEAD: Errno: 94 +EPROTO: Errno: 95 + +O_RDONLY :: 0x00000 +O_WRONLY :: 0x00001 +O_RDWR :: 0x00002 +O_NONBLOCK :: 0x00004 +O_APPEND :: 0x00008 +O_ASYNC :: 0x00040 +O_SYNC :: 0x00080 +O_CREATE :: 0x00200 +O_TRUNC :: 0x00400 +O_EXCL :: 0x00800 +O_NOCTTY :: 0x08000 +O_CLOEXEC :: 0x10000 + +SEEK_SET :: 0 +SEEK_CUR :: 1 +SEEK_END :: 2 + +RTLD_LAZY :: 0x001 +RTLD_NOW :: 0x002 +RTLD_LOCAL :: 0x000 +RTLD_GLOBAL :: 0x100 +RTLD_TRACE :: 0x200 +RTLD_NODELETE :: 0x400 + +MAX_PATH :: 1024 + +// "Argv" arguments converted to Odin strings +args := _alloc_command_line_arguments() + +pid_t :: i32 +time_t :: i64 +mode_t :: u32 +dev_t :: i32 +ino_t :: u64 +nlink_t :: u32 +uid_t :: u32 +gid_t :: u32 +off_t :: i64 +blkcnt_t :: u64 +blksize_t :: i32 + +Unix_File_Time :: struct { + seconds: time_t, + nanoseconds: c.long, +} + +OS_Stat :: struct { + mode: mode_t, // inode protection mode + device_id: dev_t, // inode's device + serial: ino_t, // inode's number + nlink: nlink_t, // number of hard links + uid: uid_t, // user ID of the file's owner + gid: gid_t, // group ID of the file's group + rdev: dev_t, // device type + + last_access: Unix_File_Time, // time of last access + modified: Unix_File_Time, // time of last data modification + status_change: Unix_File_Time, // time of last file status change + + size: off_t, // file size, in bytes + blocks: blkcnt_t, // blocks allocated for file + block_size: blksize_t, // optimal blocksize for I/O + + flags: u32, // user defined flags for file + gen: u32, // file generation number + birthtime: Unix_File_Time, // time of file creation +} + +MAXNAMLEN :: 255 + +// NOTE(laleksic, 2021-01-21): Comment and rename these to match OS_Stat above +Dirent :: struct { + ino: ino_t, // file number of entry + off: off_t, // offset after this entry + reclen: u16, // length of this record + type: u8, // file type + namlen: u8, // length of string in name + _padding: [4]u8, + name: [MAXNAMLEN + 1]byte, // name +} + +Dir :: distinct rawptr // DIR* + +// File type +S_IFMT :: 0o170000 // Type of file mask +S_IFIFO :: 0o010000 // Named pipe (fifo) +S_IFCHR :: 0o020000 // Character special +S_IFDIR :: 0o040000 // Directory +S_IFBLK :: 0o060000 // Block special +S_IFREG :: 0o100000 // Regular +S_IFLNK :: 0o120000 // Symbolic link +S_IFSOCK :: 0o140000 // Socket +S_ISVTX :: 0o001000 // Save swapped text even after use + +// File mode + // Read, write, execute/search by owner +S_IRWXU :: 0o0700 // RWX mask for owner +S_IRUSR :: 0o0400 // R for owner +S_IWUSR :: 0o0200 // W for owner +S_IXUSR :: 0o0100 // X for owner + + // Read, write, execute/search by group +S_IRWXG :: 0o0070 // RWX mask for group +S_IRGRP :: 0o0040 // R for group +S_IWGRP :: 0o0020 // W for group +S_IXGRP :: 0o0010 // X for group + + // Read, write, execute/search by others +S_IRWXO :: 0o0007 // RWX mask for other +S_IROTH :: 0o0004 // R for other +S_IWOTH :: 0o0002 // W for other +S_IXOTH :: 0o0001 // X for other + +S_ISUID :: 0o4000 // Set user id on execution +S_ISGID :: 0o2000 // Set group id on execution +S_ISTXT :: 0o1000 // Sticky bit + +S_ISLNK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFLNK } +S_ISREG :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFREG } +S_ISDIR :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFDIR } +S_ISCHR :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFCHR } +S_ISBLK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFBLK } +S_ISFIFO :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFIFO } +S_ISSOCK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFSOCK } + +F_OK :: 0x00 // Test for file existance +X_OK :: 0x01 // Test for execute permission +W_OK :: 0x02 // Test for write permission +R_OK :: 0x04 // Test for read permission + +AT_FDCWD :: -100 +AT_EACCESS :: 0x01 +AT_SYMLINK_NOFOLLOW :: 0x02 +AT_SYMLINK_FOLLOW :: 0x04 +AT_REMOVEDIR :: 0x08 + +@(default_calling_convention="c") +foreign libc { + @(link_name="__errno") __errno :: proc() -> ^int --- + + @(link_name="fork") _unix_fork :: proc() -> pid_t --- + @(link_name="getthrid") _unix_getthrid :: proc() -> int --- + + @(link_name="open") _unix_open :: proc(path: cstring, flags: c.int, mode: c.int) -> Handle --- + @(link_name="close") _unix_close :: proc(fd: Handle) -> c.int --- + @(link_name="read") _unix_read :: proc(fd: Handle, buf: rawptr, size: c.size_t) -> c.ssize_t --- + @(link_name="write") _unix_write :: proc(fd: Handle, buf: rawptr, size: c.size_t) -> c.ssize_t --- + @(link_name="lseek") _unix_seek :: proc(fd: Handle, offset: off_t, whence: c.int) -> off_t --- + @(link_name="stat") _unix_stat :: proc(path: cstring, sb: ^OS_Stat) -> c.int --- + @(link_name="fstat") _unix_fstat :: proc(fd: Handle, sb: ^OS_Stat) -> c.int --- + @(link_name="lstat") _unix_lstat :: proc(path: cstring, sb: ^OS_Stat) -> c.int --- + @(link_name="readlink") _unix_readlink :: proc(path: cstring, buf: ^byte, bufsiz: c.size_t) -> c.ssize_t --- + @(link_name="access") _unix_access :: proc(path: cstring, mask: c.int) -> c.int --- + @(link_name="getcwd") _unix_getcwd :: proc(buf: cstring, len: c.size_t) -> cstring --- + @(link_name="chdir") _unix_chdir :: proc(path: cstring) -> c.int --- + @(link_name="rename") _unix_rename :: proc(old, new: cstring) -> c.int --- + @(link_name="unlink") _unix_unlink :: proc(path: cstring) -> c.int --- + @(link_name="rmdir") _unix_rmdir :: proc(path: cstring) -> c.int --- + @(link_name="mkdir") _unix_mkdir :: proc(path: cstring, mode: mode_t) -> c.int --- + + @(link_name="getpagesize") _unix_getpagesize :: proc() -> c.int --- + @(link_name="fdopendir") _unix_fdopendir :: proc(fd: Handle) -> Dir --- + @(link_name="closedir") _unix_closedir :: proc(dirp: Dir) -> c.int --- + @(link_name="rewinddir") _unix_rewinddir :: proc(dirp: Dir) --- + @(link_name="readdir_r") _unix_readdir_r :: proc(dirp: Dir, entry: ^Dirent, result: ^^Dirent) -> c.int --- + + @(link_name="malloc") _unix_malloc :: proc(size: c.size_t) -> rawptr --- + @(link_name="calloc") _unix_calloc :: proc(num, size: c.size_t) -> rawptr --- + @(link_name="free") _unix_free :: proc(ptr: rawptr) --- + @(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: c.size_t) -> rawptr --- + + @(link_name="getenv") _unix_getenv :: proc(cstring) -> cstring --- + @(link_name="realpath") _unix_realpath :: proc(path: cstring, resolved_path: rawptr) -> rawptr --- + + @(link_name="exit") _unix_exit :: proc(status: c.int) -> ! --- + + @(link_name="dlopen") _unix_dlopen :: proc(filename: cstring, flags: c.int) -> rawptr --- + @(link_name="dlsym") _unix_dlsym :: proc(handle: rawptr, symbol: cstring) -> rawptr --- + @(link_name="dlclose") _unix_dlclose :: proc(handle: rawptr) -> c.int --- + @(link_name="dlerror") _unix_dlerror :: proc() -> cstring --- +} + +is_path_separator :: proc(r: rune) -> bool { + return r == '/' +} + +get_last_error :: proc() -> int { + return __errno()^ +} + +fork :: proc() -> (Pid, Errno) { + pid := _unix_fork() + if pid == -1 { + return Pid(-1), Errno(get_last_error()) + } + return Pid(pid), ERROR_NONE +} + +open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Errno) { + cstr := strings.clone_to_cstring(path, context.temp_allocator) + handle := _unix_open(cstr, c.int(flags), c.int(mode)) + if handle == -1 { + return INVALID_HANDLE, Errno(get_last_error()) + } + return handle, ERROR_NONE +} + +close :: proc(fd: Handle) -> Errno { + result := _unix_close(fd) + if result == -1 { + return Errno(get_last_error()) + } + return ERROR_NONE +} + +read :: proc(fd: Handle, data: []byte) -> (int, Errno) { + bytes_read := _unix_read(fd, &data[0], c.size_t(len(data))) + if bytes_read == -1 { + return -1, Errno(get_last_error()) + } + return int(bytes_read), ERROR_NONE +} + +write :: proc(fd: Handle, data: []byte) -> (int, Errno) { + if len(data) == 0 { + return 0, ERROR_NONE + } + bytes_written := _unix_write(fd, &data[0], c.size_t(len(data))) + if bytes_written == -1 { + return -1, Errno(get_last_error()) + } + return int(bytes_written), ERROR_NONE +} + +seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) { + res := _unix_seek(fd, offset, c.int(whence)) + if res == -1 { + return -1, Errno(get_last_error()) + } + return res, ERROR_NONE +} + +file_size :: proc(fd: Handle) -> (i64, Errno) { + s, err := _fstat(fd) + if err != ERROR_NONE { + return -1, err + } + return s.size, ERROR_NONE +} + +rename :: proc(old_path, new_path: string) -> Errno { + old_path_cstr := strings.clone_to_cstring(old_path, context.temp_allocator) + new_path_cstr := strings.clone_to_cstring(new_path, context.temp_allocator) + res := _unix_rename(old_path_cstr, new_path_cstr) + if res == -1 { + return Errno(get_last_error()) + } + return ERROR_NONE +} + +remove :: proc(path: string) -> Errno { + path_cstr := strings.clone_to_cstring(path, context.temp_allocator) + res := _unix_unlink(path_cstr) + if res == -1 { + return Errno(get_last_error()) + } + return ERROR_NONE +} + +make_directory :: proc(path: string, mode: mode_t = 0o775) -> Errno { + path_cstr := strings.clone_to_cstring(path, context.temp_allocator) + res := _unix_mkdir(path_cstr, mode) + if res == -1 { + return Errno(get_last_error()) + } + return ERROR_NONE +} + +remove_directory :: proc(path: string) -> Errno { + path_cstr := strings.clone_to_cstring(path, context.temp_allocator) + res := _unix_rmdir(path_cstr) + if res == -1 { + return Errno(get_last_error()) + } + return ERROR_NONE +} + +is_file_handle :: proc(fd: Handle) -> bool { + s, err := _fstat(fd) + if err != ERROR_NONE { + return false + } + return S_ISREG(s.mode) +} + +is_file_path :: proc(path: string, follow_links: bool = true) -> bool { + s: OS_Stat + err: Errno + if follow_links { + s, err = _stat(path) + } else { + s, err = _lstat(path) + } + if err != ERROR_NONE { + return false + } + return S_ISREG(s.mode) +} + +is_dir_handle :: proc(fd: Handle) -> bool { + s, err := _fstat(fd) + if err != ERROR_NONE { + return false + } + return S_ISDIR(s.mode) +} + +is_dir_path :: proc(path: string, follow_links: bool = true) -> bool { + s: OS_Stat + err: Errno + if follow_links { + s, err = _stat(path) + } else { + s, err = _lstat(path) + } + if err != ERROR_NONE { + return false + } + return S_ISDIR(s.mode) +} + +is_file :: proc {is_file_path, is_file_handle} +is_dir :: proc {is_dir_path, is_dir_handle} + +// NOTE(bill): Uses startup to initialize it + +stdin: Handle = 0 +stdout: Handle = 1 +stderr: Handle = 2 + +/* TODO(zangent): Implement these! +last_write_time :: proc(fd: Handle) -> File_Time {} +last_write_time_by_name :: proc(name: string) -> File_Time {} +*/ +last_write_time :: proc(fd: Handle) -> (File_Time, Errno) { + s, err := _fstat(fd) + if err != ERROR_NONE { + return 0, err + } + modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds + return File_Time(modified), ERROR_NONE +} + +last_write_time_by_name :: proc(name: string) -> (File_Time, Errno) { + s, err := _stat(name) + if err != ERROR_NONE { + return 0, err + } + modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds + return File_Time(modified), ERROR_NONE +} + +@private +_stat :: proc(path: string) -> (OS_Stat, Errno) { + cstr := strings.clone_to_cstring(path, context.temp_allocator) + + // deliberately uninitialized + s: OS_Stat = --- + res := _unix_stat(cstr, &s) + if res == -1 { + return s, Errno(get_last_error()) + } + return s, ERROR_NONE +} + +@private +_lstat :: proc(path: string) -> (OS_Stat, Errno) { + cstr := strings.clone_to_cstring(path, context.temp_allocator) + + // deliberately uninitialized + s: OS_Stat = --- + res := _unix_lstat(cstr, &s) + if res == -1 { + return s, Errno(get_last_error()) + } + return s, ERROR_NONE +} + +@private +_fstat :: proc(fd: Handle) -> (OS_Stat, Errno) { + // deliberately uninitialized + s: OS_Stat = --- + res := _unix_fstat(fd, &s) + if res == -1 { + return s, Errno(get_last_error()) + } + return s, ERROR_NONE +} + +@private +_fdopendir :: proc(fd: Handle) -> (Dir, Errno) { + dirp := _unix_fdopendir(fd) + if dirp == cast(Dir)nil { + return nil, Errno(get_last_error()) + } + return dirp, ERROR_NONE +} + +@private +_closedir :: proc(dirp: Dir) -> Errno { + rc := _unix_closedir(dirp) + if rc != 0 { + return Errno(get_last_error()) + } + return ERROR_NONE +} + +@private +_rewinddir :: proc(dirp: Dir) { + _unix_rewinddir(dirp) +} + +@private +_readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Errno, end_of_stream: bool) { + result: ^Dirent + rc := _unix_readdir_r(dirp, &entry, &result) + + if rc != 0 { + err = Errno(get_last_error()) + return + } + err = ERROR_NONE + + if result == nil { + end_of_stream = true + return + } + + return +} + +@private +_readlink :: proc(path: string) -> (string, Errno) { + path_cstr := strings.clone_to_cstring(path, context.temp_allocator) + + bufsz : uint = MAX_PATH + buf := make([]byte, MAX_PATH) + for { + rc := _unix_readlink(path_cstr, &(buf[0]), bufsz) + if rc == -1 { + delete(buf) + return "", Errno(get_last_error()) + } else if rc == int(bufsz) { + bufsz += MAX_PATH + delete(buf) + buf = make([]byte, bufsz) + } else { + return strings.string_from_ptr(&buf[0], rc), ERROR_NONE + } + } + unreachable() +} + +// XXX OpenBSD +absolute_path_from_handle :: proc(fd: Handle) -> (string, Errno) { + return "", Errno(ENOSYS) +} + +absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) { + rel := rel + if rel == "" { + rel = "." + } + + rel_cstr := strings.clone_to_cstring(rel, context.temp_allocator) + + path_ptr := _unix_realpath(rel_cstr, nil) + if path_ptr == nil { + return "", Errno(get_last_error()) + } + defer _unix_free(path_ptr) + + path_cstr := transmute(cstring)path_ptr + path = strings.clone( string(path_cstr) ) + + return path, ERROR_NONE +} + +access :: proc(path: string, mask: int) -> (bool, Errno) { + cstr := strings.clone_to_cstring(path, context.temp_allocator) + res := _unix_access(cstr, c.int(mask)) + if res == -1 { + return false, Errno(get_last_error()) + } + return true, ERROR_NONE +} + +heap_alloc :: proc(size: int) -> rawptr { + assert(size >= 0) + return _unix_calloc(1, c.size_t(size)) +} + +heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr { + // NOTE: _unix_realloc doesn't guarantee new memory will be zeroed on + // POSIX platforms. Ensure your caller takes this into account. + return _unix_realloc(ptr, c.size_t(new_size)) +} + +heap_free :: proc(ptr: rawptr) { + _unix_free(ptr) +} + +getenv :: proc(name: string) -> (string, bool) { + path_str := strings.clone_to_cstring(name, context.temp_allocator) + cstr := _unix_getenv(path_str) + if cstr == nil { + return "", false + } + return string(cstr), true +} + +get_current_directory :: proc() -> string { + buf := make([dynamic]u8, MAX_PATH) + for { + cwd := _unix_getcwd(cstring(raw_data(buf)), c.size_t(len(buf))) + if cwd != nil { + return string(cwd) + } + if Errno(get_last_error()) != ERANGE { + return "" + } + resize(&buf, len(buf) + MAX_PATH) + } + unreachable() +} + +set_current_directory :: proc(path: string) -> (err: Errno) { + cstr := strings.clone_to_cstring(path, context.temp_allocator) + res := _unix_chdir(cstr) + if res == -1 { + return Errno(get_last_error()) + } + return ERROR_NONE +} + +exit :: proc "contextless" (code: int) -> ! { + runtime._cleanup_runtime_contextless() + _unix_exit(c.int(code)) +} + +current_thread_id :: proc "contextless" () -> int { + return _unix_getthrid() +} + +dlopen :: proc(filename: string, flags: int) -> rawptr { + cstr := strings.clone_to_cstring(filename, context.temp_allocator) + handle := _unix_dlopen(cstr, c.int(flags)) + return handle +} +dlsym :: proc(handle: rawptr, symbol: string) -> rawptr { + assert(handle != nil) + cstr := strings.clone_to_cstring(symbol, context.temp_allocator) + proc_handle := _unix_dlsym(handle, cstr) + return proc_handle +} +dlclose :: proc(handle: rawptr) -> bool { + assert(handle != nil) + return _unix_dlclose(handle) == 0 +} +dlerror :: proc() -> string { + return string(_unix_dlerror()) +} + +get_page_size :: proc() -> int { + // NOTE(tetra): The page size never changes, so why do anything complicated + // if we don't have to. + @static page_size := -1 + if page_size != -1 { + return page_size + } + + page_size = int(_unix_getpagesize()) + return page_size +} + + +_alloc_command_line_arguments :: proc() -> []string { + res := make([]string, len(runtime.args__)) + for arg, i in runtime.args__ { + res[i] = string(arg) + } + return res +} diff --git a/core/os/os_wasi.odin b/core/os/os_wasi.odin index d2ba166bd..7bab1b949 100644 --- a/core/os/os_wasi.odin +++ b/core/os/os_wasi.odin @@ -1,6 +1,7 @@ package os import "core:sys/wasm/wasi" +import "core:runtime" Handle :: distinct i32 Errno :: distinct i32 @@ -93,5 +94,6 @@ heap_free :: proc(ptr: rawptr) { exit :: proc "contextless" (code: int) -> ! { + runtime._cleanup_runtime_contextless() wasi.proc_exit(wasi.exitcode_t(code)) } \ No newline at end of file diff --git a/core/os/os_windows.odin b/core/os/os_windows.odin index e6efb89df..fe9496e4c 100644 --- a/core/os/os_windows.odin +++ b/core/os/os_windows.odin @@ -2,6 +2,7 @@ package os import win32 "core:sys/windows" +import "core:runtime" Handle :: distinct uintptr File_Time :: distinct u64 @@ -128,6 +129,7 @@ get_page_size :: proc() -> int { exit :: proc "contextless" (code: int) -> ! { + runtime._cleanup_runtime_contextless() win32.ExitProcess(win32.DWORD(code)) } diff --git a/core/os/stat.odin b/core/os/stat.odin index 6f4c8b0ef..1b64ad33b 100644 --- a/core/os/stat.odin +++ b/core/os/stat.odin @@ -2,7 +2,6 @@ package os import "core:time" - File_Info :: struct { fullpath: string, name: string, diff --git a/core/os/stat_unix.odin b/core/os/stat_unix.odin index 08c6f53c4..395d2e73e 100644 --- a/core/os/stat_unix.odin +++ b/core/os/stat_unix.odin @@ -1,4 +1,4 @@ -//+build linux, darwin, freebsd +//+build linux, darwin, freebsd, openbsd package os import "core:time" @@ -61,7 +61,7 @@ _make_time_from_unix_file_time :: proc(uft: Unix_File_Time) -> time.Time { _fill_file_info_from_stat :: proc(fi: ^File_Info, s: OS_Stat) { fi.size = s.size fi.mode = cast(File_Mode)s.mode - fi.is_dir = S_ISDIR(u32(s.mode)) + fi.is_dir = S_ISDIR(s.mode) // NOTE(laleksic, 2021-01-21): Not really creation time, but closest we can get (maybe better to leave it 0?) fi.creation_time = _make_time_from_unix_file_time(s.status_change) diff --git a/core/os/stat_windows.odin b/core/os/stat_windows.odin index 2d9f98fd4..5da925560 100644 --- a/core/os/stat_windows.odin +++ b/core/os/stat_windows.odin @@ -80,7 +80,7 @@ stat :: proc(name: string, allocator := context.allocator) -> (File_Info, Errno) return _stat(name, attrs, allocator) } -fstat :: proc(fd: Handle, allocator := context.allocator) -> (File_Info, Errno) { +fstat :: proc(fd: Handle, allocator := context.allocator) -> (fi: File_Info, errno: Errno) { if fd == 0 { return {}, ERROR_INVALID_HANDLE } @@ -94,14 +94,14 @@ fstat :: proc(fd: Handle, allocator := context.allocator) -> (File_Info, Errno) h := win32.HANDLE(fd) switch win32.GetFileType(h) { case win32.FILE_TYPE_PIPE, win32.FILE_TYPE_CHAR: - fi: File_Info - fi.fullpath = path fi.name = basename(path) fi.mode |= file_type_mode(h) - return fi, ERROR_NONE + errno = ERROR_NONE + case: + fi, errno = file_info_from_get_file_information_by_handle(path, h) } - - return file_info_from_get_file_information_by_handle(path, h) + fi.fullpath = path + return } @@ -132,26 +132,11 @@ cleanpath_strip_prefix :: proc(buf: []u16) -> []u16 { @(private) cleanpath_from_handle :: proc(fd: Handle) -> (string, Errno) { - if fd == 0 { - return "", ERROR_INVALID_HANDLE + buf, err := cleanpath_from_handle_u16(fd) + if err != 0 { + return "", err } - h := win32.HANDLE(fd) - - MAX_PATH := win32.DWORD(260) + 1 - buf: []u16 - for { - buf = make([]u16, MAX_PATH, context.temp_allocator) - err := win32.GetFinalPathNameByHandleW(h, raw_data(buf), MAX_PATH, 0) - switch Errno(err) { - case ERROR_PATH_NOT_FOUND, ERROR_INVALID_PARAMETER: - return "", Errno(err) - case ERROR_NOT_ENOUGH_MEMORY: - MAX_PATH = MAX_PATH*2 + 1 - continue - } - break - } - return cleanpath_from_buf(buf), ERROR_NONE + return win32.utf16_to_utf8(buf, context.allocator), err } @(private) cleanpath_from_handle_u16 :: proc(fd: Handle) -> ([]u16, Errno) { @@ -160,21 +145,13 @@ cleanpath_from_handle_u16 :: proc(fd: Handle) -> ([]u16, Errno) { } h := win32.HANDLE(fd) - MAX_PATH := win32.DWORD(260) + 1 - buf: []u16 - for { - buf = make([]u16, MAX_PATH, context.temp_allocator) - err := win32.GetFinalPathNameByHandleW(h, raw_data(buf), MAX_PATH, 0) - switch Errno(err) { - case ERROR_PATH_NOT_FOUND, ERROR_INVALID_PARAMETER: - return nil, Errno(err) - case ERROR_NOT_ENOUGH_MEMORY: - MAX_PATH = MAX_PATH*2 + 1 - continue - } - break + n := win32.GetFinalPathNameByHandleW(h, nil, 0, 0) + if n == 0 { + return nil, Errno(win32.GetLastError()) } - return cleanpath_strip_prefix(buf), ERROR_NONE + buf := make([]u16, max(n, win32.DWORD(260))+1, context.temp_allocator) + buf_len := win32.GetFinalPathNameByHandleW(h, raw_data(buf), n, 0) + return buf[:buf_len], ERROR_NONE } @(private) cleanpath_from_buf :: proc(buf: []u16) -> string { diff --git a/core/os/stream.odin b/core/os/stream.odin index 5cf5c8405..2c6e1d47f 100644 --- a/core/os/stream.odin +++ b/core/os/stream.odin @@ -19,7 +19,7 @@ _file_stream_vtable := &io.Stream_VTable{ return }, impl_read_at = proc(s: io.Stream, p: []byte, offset: i64) -> (n: int, err: io.Error) { - when ODIN_OS == "windows" || ODIN_OS == "wasi" { + when ODIN_OS == .Windows || ODIN_OS == .WASI { fd := Handle(uintptr(s.stream_data)) os_err: Errno n, os_err = read_at(fd, p, offset) @@ -33,7 +33,7 @@ _file_stream_vtable := &io.Stream_VTable{ return }, impl_write_at = proc(s: io.Stream, p: []byte, offset: i64) -> (n: int, err: io.Error) { - when ODIN_OS == "windows" || ODIN_OS == "wasi" { + when ODIN_OS == .Windows || ODIN_OS == .WASI { fd := Handle(uintptr(s.stream_data)) os_err: Errno n, os_err = write_at(fd, p, offset) @@ -53,7 +53,7 @@ _file_stream_vtable := &io.Stream_VTable{ return sz }, impl_flush = proc(s: io.Stream) -> io.Error { - when ODIN_OS == "windows" { + when ODIN_OS == .Windows { fd := Handle(uintptr(s.stream_data)) flush(fd) } else { diff --git a/core/path/filepath/match.odin b/core/path/filepath/match.odin index cba44953d..252912710 100644 --- a/core/path/filepath/match.odin +++ b/core/path/filepath/match.odin @@ -89,7 +89,7 @@ scan_chunk :: proc(pattern: string) -> (star: bool, chunk, rest: string) { scan_loop: for i = 0; i < len(pattern); i += 1 { switch pattern[i] { case '\\': - when ODIN_OS != "windows" { + when ODIN_OS != .Windows { if i+1 < len(pattern) { i += 1 } @@ -161,7 +161,7 @@ match_chunk :: proc(chunk, s: string) -> (rest: string, ok: bool, err: Match_Err chunk = chunk[1:] case '\\': - when ODIN_OS != "windows" { + when ODIN_OS != .Windows { chunk = chunk[1:] if len(chunk) == 0 { err = .Syntax_Error @@ -188,7 +188,7 @@ get_escape :: proc(chunk: string) -> (r: rune, next_chunk: string, err: Match_Er return } chunk := chunk - if chunk[0] == '\\' && ODIN_OS != "windows" { + if chunk[0] == '\\' && ODIN_OS != .Windows { chunk = chunk[1:] if len(chunk) == 0 { err = .Syntax_Error @@ -220,19 +220,21 @@ get_escape :: proc(chunk: string) -> (r: rune, next_chunk: string, err: Match_Er // glob :: proc(pattern: string, allocator := context.allocator) -> (matches: []string, err: Match_Error) { + context.allocator = allocator + if !has_meta(pattern) { // TODO(bill): os.lstat on here to check for error - m := make([]string, 1, allocator) + m := make([]string, 1) m[0] = pattern return m[:], .None } - temp_buf: [8]byte - dir, file := split(pattern) volume_len := 0 - when ODIN_OS == "windows" { + when ODIN_OS == .Windows { + temp_buf: [8]byte volume_len, dir = clean_glob_path_windows(dir, temp_buf[:]) + } else { dir = clean_glob_path(dir) } @@ -247,7 +249,7 @@ glob :: proc(pattern: string, allocator := context.allocator) -> (matches: []str if err != .None { return } - dmatches := make([dynamic]string, 0, 0, allocator) + dmatches := make([dynamic]string, 0, 0) for d in m { dmatches, err = _glob(d, file, &dmatches) if err != .None { @@ -259,11 +261,13 @@ glob :: proc(pattern: string, allocator := context.allocator) -> (matches: []str } return } -_glob :: proc(dir, pattern: string, matches: ^[dynamic]string) -> (m: [dynamic]string, e: Match_Error) { +_glob :: proc(dir, pattern: string, matches: ^[dynamic]string, allocator := context.allocator) -> (m: [dynamic]string, e: Match_Error) { + context.allocator = allocator + if matches != nil { m = matches^ } else { - m = make([dynamic]string, 0, 0, context.allocator) + m = make([dynamic]string, 0, 0) } @@ -276,6 +280,7 @@ _glob :: proc(dir, pattern: string, matches: ^[dynamic]string) -> (m: [dynamic]s { file_info, ferr := os.fstat(d) defer os.file_info_delete(file_info) + if ferr != 0 { return } @@ -308,7 +313,7 @@ _glob :: proc(dir, pattern: string, matches: ^[dynamic]string) -> (m: [dynamic]s @(private) has_meta :: proc(path: string) -> bool { - when ODIN_OS == "windows" { + when ODIN_OS == .Windows { CHARS :: `*?[` } else { CHARS :: `*?[\` diff --git a/core/path/filepath/path.odin b/core/path/filepath/path.odin index 39cd80a47..32e4a8a37 100644 --- a/core/path/filepath/path.odin +++ b/core/path/filepath/path.odin @@ -1,14 +1,16 @@ // The path/filepath package uses either forward slashes or backslashes depending on the operating system -// To process paths usch as URLs that depend on forward slashes regardless of the OS, use the path package +// To process paths such as URLs that depend on forward slashes regardless of the OS, use the path package package filepath import "core:strings" +SEPARATOR_CHARS :: `/\` + // is_separator checks whether the byte is a valid separator character is_separator :: proc(c: byte) -> bool { switch c { case '/': return true - case '\\': return ODIN_OS == "windows" + case '\\': return ODIN_OS == .Windows } return false } @@ -32,7 +34,7 @@ volume_name :: proc(path: string) -> string { } volume_name_len :: proc(path: string) -> int { - if ODIN_OS == "windows" { + if ODIN_OS == .Windows { if len(path) < 2 { return 0 } @@ -69,6 +71,16 @@ volume_name_len :: proc(path: string) -> int { return 0 } +/* + Gets the file name and extension from a path. + + i.e: + 'path/to/name.tar.gz' -> 'name.tar.gz' + 'path/to/name.txt' -> 'name.txt' + 'path/to/name' -> 'name' + + Returns "." if the path is an empty string. +*/ base :: proc(path: string) -> string { if path == "" { return "." @@ -94,6 +106,118 @@ base :: proc(path: string) -> string { return path } +/* + Gets the name of a file from a path. + + The stem of a file is such that stem(path) + ext(path) = base(path). + + Only the last dot is considered when splitting the file extension. + See `short_stem`. + + i.e: + 'name.tar.gz' -> 'name.tar' + 'name.txt' -> 'name' + + Returns an empty string if there is no stem. e.g: '.gitignore'. + Returns an empty string if there's a trailing path separator. +*/ +stem :: proc(path: string) -> string { + if len(path) > 0 && is_separator(path[len(path) - 1]) { + // NOTE(tetra): Trailing separator + return "" + } + + // NOTE(tetra): Get the basename + path := path + if i := strings.last_index_any(path, SEPARATOR_CHARS); i != -1 { + path = path[i+1:] + } + + if i := strings.last_index_byte(path, '.'); i != -1 { + return path[:i] + } + + return path +} + +/* + Gets the name of a file from a path. + + The short stem is such that short_stem(path) + long_ext(path) = base(path). + + The first dot is used to split off the file extension, unlike `stem` which uses the last dot. + + i.e: + 'name.tar.gz' -> 'name' + 'name.txt' -> 'name' + + Returns an empty string if there is no stem. e.g: '.gitignore'. + Returns an empty string if there's a trailing path separator. +*/ +short_stem :: proc(path: string) -> string { + s := stem(path) + if i := strings.index_byte(s, '.'); i != -1 { + return s[:i] + } + return s +} + +/* + Gets the file extension from a path, including the dot. + + The file extension is such that stem(path) + ext(path) = base(path). + + Only the last dot is considered when splitting the file extension. + See `long_ext`. + + i.e: + 'name.tar.gz' -> '.gz' + 'name.txt' -> '.txt' + + Returns an empty string if there is no dot. + Returns an empty string if there is a trailing path separator. +*/ +ext :: proc(path: string) -> string { + for i := len(path)-1; i >= 0 && !is_separator(path[i]); i -= 1 { + if path[i] == '.' { + return path[i:] + } + } + return "" +} + +/* + Gets the file extension from a path, including the dot. + + The long file extension is such that short_stem(path) + long_ext(path) = base(path). + + The first dot is used to split off the file extension, unlike `ext` which uses the last dot. + + i.e: + 'name.tar.gz' -> '.tar.gz' + 'name.txt' -> '.txt' + + Returns an empty string if there is no dot. + Returns an empty string if there is a trailing path separator. +*/ +long_ext :: proc(path: string) -> string { + if len(path) > 0 && is_separator(path[len(path) - 1]) { + // NOTE(tetra): Trailing separator + return "" + } + + // NOTE(tetra): Get the basename + path := path + if i := strings.last_index_any(path, SEPARATOR_CHARS); i != -1 { + path = path[i+1:] + } + + if i := strings.index_byte(path, '.'); i != -1 { + return path[i:] + } + + return "" +} clean :: proc(path: string, allocator := context.allocator) -> string { context.allocator = allocator @@ -122,6 +246,7 @@ clean :: proc(path: string, allocator := context.allocator) -> string { vol_and_path = original_path, vol_len = vol_len, } + defer lazy_buffer_destroy(out) r, dot_dot := 0, 0 if rooted { @@ -170,7 +295,6 @@ clean :: proc(path: string, allocator := context.allocator) -> string { cleaned, new_allocation := from_slash(s) if new_allocation { delete(s) - lazy_buffer_destroy(out) } return cleaned } @@ -189,15 +313,6 @@ to_slash :: proc(path: string, allocator := context.allocator) -> (new_path: str return strings.replace_all(path, SEPARATOR_STRING, "/", allocator) } -ext :: proc(path: string) -> string { - for i := len(path)-1; i >= 0 && !is_separator(path[i]); i -= 1 { - if path[i] == '.' { - return path[i:] - } - } - return "" -} - Relative_Error :: enum { None, @@ -284,13 +399,14 @@ rel :: proc(base_path, target_path: string, allocator := context.allocator) -> ( } dir :: proc(path: string, allocator := context.allocator) -> string { + context.allocator = allocator vol := volume_name(path) i := len(path) - 1 for i >= len(vol) && !is_separator(path[i]) { i -= 1 } - dir := clean(path[len(vol) : i+1], allocator) - defer delete(dir, allocator) + dir := clean(path[len(vol) : i+1]) + defer delete(dir) if dir == "." && len(vol) > 2 { return strings.clone(vol) } @@ -299,6 +415,11 @@ dir :: proc(path: string, allocator := context.allocator) -> string { +// Splits the PATH-like `path` string, returning an array of its separated components (delete after use). +// For Windows the separator is `;`, for Unix it's `:`. +// An empty string returns nil. A non-empty string with no separators returns a 1-element array. +// Any empty components will be included, e.g. `a::b` will return a 3-element array, as will `::`. +// Separators within pairs of double-quotes will be ignored and stripped, e.g. `"a:b"c:d` will return []{`a:bc`, `d`}. split_list :: proc(path: string, allocator := context.allocator) -> []string { if path == "" { return nil @@ -321,7 +442,7 @@ split_list :: proc(path: string, allocator := context.allocator) -> []string { } start, quote = 0, false - list := make([]string, count, allocator) + list := make([]string, count + 1, allocator) index := 0 for i := 0; i < len(path); i += 1 { c := path[i] @@ -335,6 +456,7 @@ split_list :: proc(path: string, allocator := context.allocator) -> []string { } } assert(index == count) + list[index] = path[start:] for s0, i in list { s, new := strings.replace_all(s0, `"`, ``, allocator) diff --git a/core/path/filepath/path_unix.odin b/core/path/filepath/path_unix.odin index 1db528a2f..d0eaa3635 100644 --- a/core/path/filepath/path_unix.odin +++ b/core/path/filepath/path_unix.odin @@ -1,7 +1,7 @@ -//+build linux, darwin, freebsd +//+build linux, darwin, freebsd, openbsd package filepath -when ODIN_OS == "darwin" { +when ODIN_OS == .Darwin { foreign import libc "System.framework" } else { foreign import libc "system:c" @@ -54,11 +54,16 @@ foreign libc { @(link_name="free") _unix_free :: proc(ptr: rawptr) --- } -when ODIN_OS == "darwin" { +when ODIN_OS == .Darwin { @(private) foreign libc { @(link_name="__error") __error :: proc() -> ^i32 --- } +} else when ODIN_OS == .OpenBSD { + @(private) + foreign libc { + @(link_name="__errno") __error :: proc() -> ^i32 --- + } } else { @(private) foreign libc { diff --git a/core/path/filepath/walk.odin b/core/path/filepath/walk.odin index 29d4fd5b1..dad63cc09 100644 --- a/core/path/filepath/walk.odin +++ b/core/path/filepath/walk.odin @@ -71,7 +71,7 @@ _walk :: proc(info: os.File_Info, walk_proc: Walk_Proc) -> (err: os.Errno, skip_ @(private) read_dir :: proc(dir_name: string, allocator := context.temp_allocator) -> ([]os.File_Info, os.Errno) { - f, err := os.open(dir_name) + f, err := os.open(dir_name, os.O_RDONLY) if err != 0 { return nil, err } diff --git a/core/path/path_error.odin b/core/path/path_error.odin new file mode 100644 index 000000000..2be0b4cf4 --- /dev/null +++ b/core/path/path_error.odin @@ -0,0 +1,5 @@ +package path + +#panic( +`core:path/slashpath - for paths separated by forward slashes, e.g. paths in URLs, this does not deal with OS-specific paths +core:path/filepath - uses either forward slashes or backslashes depending on the operating system, deals with Windows/NT paths with volume letters or backslashes (on the related platforms)`) diff --git a/core/path/match.odin b/core/path/slashpath/match.odin similarity index 99% rename from core/path/match.odin rename to core/path/slashpath/match.odin index 0bea4f6e7..09e774275 100644 --- a/core/path/match.odin +++ b/core/path/slashpath/match.odin @@ -1,4 +1,4 @@ -package path +package slashpath import "core:strings" import "core:unicode/utf8" diff --git a/core/path/path.odin b/core/path/slashpath/path.odin similarity index 94% rename from core/path/path.odin rename to core/path/slashpath/path.odin index 186176b42..8ac10e655 100644 --- a/core/path/path.odin +++ b/core/path/slashpath/path.odin @@ -1,9 +1,9 @@ -// The path package is only to be used for paths separated by forward slashes, +// The slashpath package is only to be used for paths separated by forward slashes, // e.g. paths in URLs // // This package does not deal with Windows/NT paths with volume letters or backslashes // To manipulate operating system specific paths, use the path/filepath package -package path +package slashpath import "core:strings" diff --git a/core/reflect/reflect.odin b/core/reflect/reflect.odin index 7f64d0974..49d7ef9b5 100644 --- a/core/reflect/reflect.odin +++ b/core/reflect/reflect.odin @@ -234,7 +234,7 @@ is_nil :: proc(v: any) -> bool { return true } data := as_bytes(v) - if data != nil { + if data == nil { return true } for v in data { @@ -365,6 +365,19 @@ index :: proc(val: any, i: int, loc := #caller_location) -> any { return nil } +deref :: proc(val: any) -> any { + if val != nil { + ti := type_info_base(type_info_of(val.id)) + if info, ok := ti.variant.(Type_Info_Pointer); ok { + return any{ + (^rawptr)(val.data)^, + info.elem.id, + } + } + } + return val +} + // Struct_Tag represents the type of the string of a struct field @@ -680,7 +693,6 @@ union_variant_typeid :: proc(a: any) -> typeid { return nil } panic("expected a union to reflect.union_variant_typeid") - } get_union_variant_raw_tag :: proc(a: any) -> i64 { @@ -1042,6 +1054,7 @@ as_u64 :: proc(a: any) -> (value: u64, valid: bool) { case Type_Info_Float: valid = true switch v in a { + case f16: value = u64(v) case f32: value = u64(v) case f64: value = u64(v) case f32le: value = u64(v) @@ -1147,6 +1160,7 @@ as_f64 :: proc(a: any) -> (value: f64, valid: bool) { case Type_Info_Float: valid = true switch v in a { + case f16: value = f64(v) case f32: value = f64(v) case f64: value = (v) case f32le: value = f64(v) diff --git a/core/reflect/types.odin b/core/reflect/types.odin index 74778013a..2e2149820 100644 --- a/core/reflect/types.odin +++ b/core/reflect/types.odin @@ -334,11 +334,11 @@ is_relative_slice :: proc(info: ^Type_Info) -> bool { -write_typeid_builder :: proc(buf: ^strings.Builder, id: typeid) { - write_type(buf, type_info_of(id)) +write_typeid_builder :: proc(buf: ^strings.Builder, id: typeid, n_written: ^int = nil) -> (n: int, err: io.Error) { + return write_type_writer(strings.to_writer(buf), type_info_of(id)) } -write_typeid_writer :: proc(writer: io.Writer, id: typeid) { - write_type(writer, type_info_of(id)) +write_typeid_writer :: proc(writer: io.Writer, id: typeid, n_written: ^int = nil) -> (n: int, err: io.Error) { + return write_type_writer(writer, type_info_of(id), n_written) } write_typeid :: proc{ @@ -472,6 +472,9 @@ write_type_writer :: proc(w: io.Writer, ti: ^Type_Info, n_written: ^int = nil) - write_type(w, info.elem, &n) or_return case Type_Info_Enumerated_Array: + if info.is_sparse { + io.write_string(w, "#sparse", &n) or_return + } io.write_string(w, "[", &n) or_return write_type(w, info.index, &n) or_return io.write_string(w, "]", &n) or_return diff --git a/core/runtime/core.odin b/core/runtime/core.odin index be30eef02..4269450de 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -33,6 +33,11 @@ Calling_Convention :: enum u8 { None = 6, Naked = 7, + + _ = 8, // reserved + + Win64 = 9, + SysV = 10, } Type_Info_Enum_Value :: distinct i64 @@ -95,6 +100,7 @@ Type_Info_Enumerated_Array :: struct { count: int, min_value: Type_Info_Enum_Value, max_value: Type_Info_Enum_Value, + is_sparse: bool, } Type_Info_Dynamic_Array :: struct {elem: ^Type_Info, elem_size: int} Type_Info_Slice :: struct {elem: ^Type_Info, elem_size: int} @@ -130,6 +136,7 @@ Type_Info_Union :: struct { custom_align: bool, no_nil: bool, maybe: bool, + shared_nil: bool, } Type_Info_Enum :: struct { base: ^Type_Info, @@ -345,7 +352,6 @@ Context :: struct { assertion_failure_proc: Assertion_Failure_Proc, logger: Logger, - user_data: any, user_ptr: rawptr, user_index: int, @@ -386,6 +392,59 @@ Raw_Cstring :: struct { } +/* + // Defined internally by the compiler + Odin_OS_Type :: enum int { + Unknown, + Windows, + Darwin, + Linux, + Essence, + FreeBSD, + OpenBSD, + WASI, + JS, + Freestanding, + } +*/ +Odin_OS_Type :: type_of(ODIN_OS) + +/* + // Defined internally by the compiler + Odin_Arch_Type :: enum int { + Unknown, + amd64, + i386, + arm64, + wasm32, + wasm64, + } +*/ +Odin_Arch_Type :: type_of(ODIN_ARCH) + +/* + // Defined internally by the compiler + Odin_Build_Mode_Type :: enum int { + Executable, + Dynamic, + Object, + Assembly, + LLVM_IR, + } +*/ +Odin_Build_Mode_Type :: type_of(ODIN_BUILD_MODE) + +/* + // Defined internally by the compiler + Odin_Endian_Type :: enum int { + Unknown, + Little, + Big, + } +*/ +Odin_Endian_Type :: type_of(ODIN_ENDIAN) + + ///////////////////////////// // Init Startup Procedures // ///////////////////////////// @@ -394,7 +453,7 @@ Raw_Cstring :: struct { // This is probably only useful for freestanding targets foreign { @(link_name="__$startup_runtime") - _startup_runtime :: proc() --- + _startup_runtime :: proc "odin" () --- } @(link_name="__$cleanup_runtime") @@ -402,6 +461,11 @@ _cleanup_runtime :: proc() { default_temp_allocator_destroy(&global_default_temp_allocator_data) } +_cleanup_runtime_contextless :: proc "contextless" () { + context = default_context() + _cleanup_runtime() +} + ///////////////////////////// ///////////////////////////// @@ -451,16 +515,18 @@ __type_info_of :: proc "contextless" (id: typeid) -> ^Type_Info #no_bounds_check return &type_table[n] } -typeid_base :: proc "contextless" (id: typeid) -> typeid { - ti := type_info_of(id) - ti = type_info_base(ti) - return ti.id +when !ODIN_DISALLOW_RTTI { + typeid_base :: proc "contextless" (id: typeid) -> typeid { + ti := type_info_of(id) + ti = type_info_base(ti) + return ti.id + } + typeid_core :: proc "contextless" (id: typeid) -> typeid { + ti := type_info_core(type_info_of(id)) + return ti.id + } + typeid_base_without_enum :: typeid_core } -typeid_core :: proc "contextless" (id: typeid) -> typeid { - ti := type_info_core(type_info_of(id)) - return ti.id -} -typeid_base_without_enum :: typeid_core @@ -500,7 +566,7 @@ __init_context :: proc "contextless" (c: ^Context) { return } - // NOTE(bill): Do not initialize these procedures with a call as they are not defined with the "contexless" calling convention + // NOTE(bill): Do not initialize these procedures with a call as they are not defined with the "contextless" calling convention c.allocator.procedure = default_allocator_proc c.allocator.data = nil @@ -516,7 +582,7 @@ __init_context :: proc "contextless" (c: ^Context) { } default_assertion_failure_proc :: proc(prefix, message: string, loc: Source_Code_Location) -> ! { - when ODIN_OS == "freestanding" { + when ODIN_OS == .Freestanding { // Do nothing } else { print_caller_location(loc) diff --git a/core/runtime/core_builtin.odin b/core/runtime/core_builtin.odin index 44da894c1..13e464a76 100644 --- a/core/runtime/core_builtin.odin +++ b/core/runtime/core_builtin.odin @@ -5,6 +5,16 @@ import "core:intrinsics" @builtin Maybe :: union($T: typeid) #maybe {T} + +@builtin +container_of :: #force_inline proc "contextless" (ptr: $P/^$Field_Type, $T: typeid, $field_name: string) -> ^T + where intrinsics.type_has_field(T, field_name), + intrinsics.type_field_type(T, field_name) == Field_Type { + offset :: offset_of_by_string(T, field_name) + return (^T)(uintptr(ptr) - offset) if ptr != nil else nil +} + + @thread_local global_default_temp_allocator_data: Default_Temp_Allocator @builtin @@ -386,12 +396,13 @@ insert_at_elem :: proc(array: ^$T/[dynamic]$E, index: int, arg: E, loc := #calle if array == nil { return } - n := len(array) + n := max(len(array), index) m :: 1 - resize(array, n+m, loc) - if n+m <= len(array) { + new_size := n + m + + if resize(array, new_size, loc) { when size_of(E) != 0 { - copy(array[index+m:], array[index:]) + copy(array[index + m:], array[index:]) array[index] = arg } ok = true @@ -409,12 +420,13 @@ insert_at_elems :: proc(array: ^$T/[dynamic]$E, index: int, args: ..E, loc := #c return } - n := len(array) + n := max(len(array), index) m := len(args) - resize(array, n+m, loc) - if n+m <= len(array) { + new_size := n + m + + if resize(array, new_size, loc) { when size_of(E) != 0 { - copy(array[index+m:], array[index:]) + copy(array[index + m:], array[index:]) copy(array[index:], args) } ok = true @@ -427,17 +439,18 @@ insert_at_elem_string :: proc(array: ^$T/[dynamic]$E/u8, index: int, arg: string if array == nil { return } - if len(args) == 0 { + if len(arg) == 0 { ok = true return } - n := len(array) - m := len(args) - resize(array, n+m, loc) - if n+m <= len(array) { + n := max(len(array), index) + m := len(arg) + new_size := n + m + + if resize(array, new_size, loc) { copy(array[index+m:], array[index:]) - copy(array[index:], args) + copy(array[index:], arg) ok = true } return @@ -614,6 +627,10 @@ raw_data :: proc{raw_array_data, raw_slice_data, raw_dynamic_array_data, raw_str @(disabled=ODIN_DISABLE_ASSERT) assert :: proc(condition: bool, message := "", loc := #caller_location) { if !condition { + // NOTE(bill): This is wrapped in a procedure call + // to improve performance to make the CPU not + // execute speculatively, making it about an order of + // magnitude faster proc(message: string, loc: Source_Code_Location) { p := context.assertion_failure_proc if p == nil { diff --git a/core/runtime/core_builtin_matrix.odin b/core/runtime/core_builtin_matrix.odin index 08dca288e..53589587c 100644 --- a/core/runtime/core_builtin_matrix.odin +++ b/core/runtime/core_builtin_matrix.odin @@ -146,14 +146,14 @@ matrix2x2_inverse_transpose :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: d := x[0, 0]*x[1, 1] - x[0, 1]*x[1, 0] when intrinsics.type_is_integer(T) { y[0, 0] = +x[1, 1] / d - y[1, 0] = -x[1, 0] / d - y[0, 1] = -x[0, 1] / d + y[1, 0] = -x[0, 1] / d + y[0, 1] = -x[1, 0] / d y[1, 1] = +x[0, 0] / d } else { id := 1 / d y[0, 0] = +x[1, 1] * id - y[1, 0] = -x[1, 0] * id - y[0, 1] = -x[0, 1] * id + y[1, 0] = -x[0, 1] * id + y[0, 1] = -x[1, 0] * id y[1, 1] = +x[0, 0] * id } return @@ -214,16 +214,16 @@ matrix1x1_inverse :: proc "contextless" (x: $M/matrix[1, 1]$T) -> (y: M) { matrix2x2_inverse :: proc "contextless" (x: $M/matrix[2, 2]$T) -> (y: M) { d := x[0, 0]*x[1, 1] - x[0, 1]*x[1, 0] when intrinsics.type_is_integer(T) { - y[0, 0] = x[1, 1] / d - y[0, 1] = x[1, 0] / d - y[1, 0] = x[0, 1] / d - y[1, 1] = x[0, 0] / d + y[0, 0] = +x[1, 1] / d + y[0, 1] = -x[0, 1] / d + y[1, 0] = -x[1, 0] / d + y[1, 1] = +x[0, 0] / d } else { id := 1 / d - y[0, 0] = x[1, 1] * id - y[0, 1] = x[1, 0] * id - y[1, 0] = x[0, 1] * id - y[1, 1] = x[0, 0] * id + y[0, 0] = +x[1, 1] * id + y[0, 1] = -x[0, 1] * id + y[1, 0] = -x[1, 0] * id + y[1, 1] = +x[0, 0] * id } return } diff --git a/core/runtime/default_allocators_nil.odin b/core/runtime/default_allocators_nil.odin index ccb4a3381..04dea0e19 100644 --- a/core/runtime/default_allocators_nil.odin +++ b/core/runtime/default_allocators_nil.odin @@ -32,7 +32,7 @@ nil_allocator :: proc() -> Allocator { -when ODIN_OS == "freestanding" { +when ODIN_OS == .Freestanding { default_allocator_proc :: nil_allocator_proc default_allocator :: nil_allocator } \ No newline at end of file diff --git a/core/runtime/default_temporary_allocator.odin b/core/runtime/default_temporary_allocator.odin index 01143e222..4337e555b 100644 --- a/core/runtime/default_temporary_allocator.odin +++ b/core/runtime/default_temporary_allocator.odin @@ -3,7 +3,7 @@ package runtime DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE: int : #config(DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE, 1<<22) -when ODIN_OS == "freestanding" || ODIN_OS == "js" || ODIN_DEFAULT_TO_NIL_ALLOCATOR { +when ODIN_OS == .Freestanding || ODIN_OS == .JS || ODIN_DEFAULT_TO_NIL_ALLOCATOR { Default_Temp_Allocator :: struct {} default_temp_allocator_init :: proc(s: ^Default_Temp_Allocator, size: int, backup_allocator := context.allocator) {} diff --git a/core/runtime/entry_unix.odin b/core/runtime/entry_unix.odin new file mode 100644 index 000000000..9f7d219c3 --- /dev/null +++ b/core/runtime/entry_unix.odin @@ -0,0 +1,33 @@ +//+private +//+build linux, darwin, freebsd, openbsd +package runtime + +import "core:intrinsics" + +when ODIN_BUILD_MODE == .Dynamic { + @(link_name="_odin_entry_point", linkage="strong", require/*, link_section=".init"*/) + _odin_entry_point :: proc "c" () { + context = default_context() + #force_no_inline _startup_runtime() + intrinsics.__entry_point() + } + @(link_name="_odin_exit_point", linkage="strong", require/*, link_section=".fini"*/) + _odin_exit_point :: proc "c" () { + context = default_context() + #force_no_inline _cleanup_runtime() + } + @(link_name="main", linkage="strong", require) + main :: proc "c" (argc: i32, argv: [^]cstring) -> i32 { + return 0 + } +} else when !ODIN_TEST && !ODIN_NO_ENTRY_POINT { + @(link_name="main", linkage="strong", require) + main :: proc "c" (argc: i32, argv: [^]cstring) -> i32 { + args__ = argv[:argc] + context = default_context() + #force_no_inline _startup_runtime() + intrinsics.__entry_point() + #force_no_inline _cleanup_runtime() + return 0 + } +} diff --git a/core/runtime/entry_wasm.odin b/core/runtime/entry_wasm.odin new file mode 100644 index 000000000..125abc756 --- /dev/null +++ b/core/runtime/entry_wasm.odin @@ -0,0 +1,19 @@ +//+private +//+build wasm32, wasm64 +package runtime + +import "core:intrinsics" + +when !ODIN_TEST && !ODIN_NO_ENTRY_POINT { + @(link_name="_start", linkage="strong", require, export) + _start :: proc "c" () { + context = default_context() + #force_no_inline _startup_runtime() + intrinsics.__entry_point() + } + @(link_name="_end", linkage="strong", require, export) + _end :: proc "c" () { + context = default_context() + #force_no_inline _cleanup_runtime() + } +} \ No newline at end of file diff --git a/core/runtime/entry_windows.odin b/core/runtime/entry_windows.odin new file mode 100644 index 000000000..2f323cb41 --- /dev/null +++ b/core/runtime/entry_windows.odin @@ -0,0 +1,45 @@ +//+private +//+build windows +package runtime + +import "core:intrinsics" + +when ODIN_BUILD_MODE == .Dynamic { + @(link_name="DllMain", linkage="strong", require) + DllMain :: proc "stdcall" (hinstDLL: rawptr, fdwReason: u32, lpReserved: rawptr) -> b32 { + context = default_context() + switch fdwReason { + case 1: // DLL_PROCESS_ATTACH + #force_no_inline _startup_runtime() + intrinsics.__entry_point() + case 0: // DLL_PROCESS_DETACH + #force_no_inline _cleanup_runtime() + case 2: // DLL_THREAD_ATTACH + break + case 3: // DLL_THREAD_DETACH + break + } + return true + } +} else when !ODIN_TEST && !ODIN_NO_ENTRY_POINT { + when ODIN_ARCH == .i386 || ODIN_NO_CRT { + @(link_name="mainCRTStartup", linkage="strong", require) + mainCRTStartup :: proc "stdcall" () -> i32 { + context = default_context() + #force_no_inline _startup_runtime() + intrinsics.__entry_point() + #force_no_inline _cleanup_runtime() + return 0 + } + } else { + @(link_name="main", linkage="strong", require) + main :: proc "c" (argc: i32, argv: [^]cstring) -> i32 { + args__ = argv[:argc] + context = default_context() + #force_no_inline _startup_runtime() + intrinsics.__entry_point() + #force_no_inline _cleanup_runtime() + return 0 + } + } +} \ No newline at end of file diff --git a/core/runtime/error_checks.odin b/core/runtime/error_checks.odin index 7f1aeb2d7..0d0b39072 100644 --- a/core/runtime/error_checks.odin +++ b/core/runtime/error_checks.odin @@ -1,7 +1,7 @@ package runtime bounds_trap :: proc "contextless" () -> ! { - when ODIN_OS == "windows" { + when ODIN_OS == .Windows { windows_trap_array_bounds() } else { trap() @@ -9,7 +9,7 @@ bounds_trap :: proc "contextless" () -> ! { } type_assertion_trap :: proc "contextless" () -> ! { - when ODIN_OS == "windows" { + when ODIN_OS == .Windows { windows_trap_type_assertion() } else { trap() @@ -21,11 +21,12 @@ bounds_check_error :: proc "contextless" (file: string, line, column: i32, index if 0 <= index && index < count { return } + @(cold) handle_error :: proc "contextless" (file: string, line, column: i32, index, count: int) { print_caller_location(Source_Code_Location{file, line, column, ""}) print_string(" Index ") print_i64(i64(index)) - print_string(" is out of bounds range 0:") + print_string(" is out of range 0..<") print_i64(i64(count)) print_byte('\n') bounds_trap() @@ -35,11 +36,11 @@ bounds_check_error :: proc "contextless" (file: string, line, column: i32, index slice_handle_error :: proc "contextless" (file: string, line, column: i32, lo, hi: int, len: int) -> ! { print_caller_location(Source_Code_Location{file, line, column, ""}) - print_string(" Invalid slice indices: ") + print_string(" Invalid slice indices ") print_i64(i64(lo)) print_string(":") print_i64(i64(hi)) - print_string(":") + print_string(" is out of range 0..<") print_i64(i64(len)) print_byte('\n') bounds_trap() @@ -47,7 +48,7 @@ slice_handle_error :: proc "contextless" (file: string, line, column: i32, lo, h multi_pointer_slice_handle_error :: proc "contextless" (file: string, line, column: i32, lo, hi: int) -> ! { print_caller_location(Source_Code_Location{file, line, column, ""}) - print_string(" Invalid slice indices: ") + print_string(" Invalid slice indices ") print_i64(i64(lo)) print_string(":") print_i64(i64(hi)) @@ -81,13 +82,14 @@ dynamic_array_expr_error :: proc "contextless" (file: string, line, column: i32, if 0 <= low && low <= high && high <= max { return } + @(cold) handle_error :: proc "contextless" (file: string, line, column: i32, low, high, max: int) { print_caller_location(Source_Code_Location{file, line, column, ""}) - print_string(" Invalid dynamic array values: ") + print_string(" Invalid dynamic array indices ") print_i64(i64(low)) print_string(":") print_i64(i64(high)) - print_string(":") + print_string(" is out of range 0..<") print_i64(i64(max)) print_byte('\n') bounds_trap() @@ -97,17 +99,18 @@ dynamic_array_expr_error :: proc "contextless" (file: string, line, column: i32, matrix_bounds_check_error :: proc "contextless" (file: string, line, column: i32, row_index, column_index, row_count, column_count: int) { - if 0 <= row_index && row_index < row_count && + if 0 <= row_index && row_index < row_count && 0 <= column_index && column_index < column_count { return } + @(cold) handle_error :: proc "contextless" (file: string, line, column: i32, row_index, column_index, row_count, column_count: int) { print_caller_location(Source_Code_Location{file, line, column, ""}) print_string(" Matrix indices [") print_i64(i64(row_index)) print_string(", ") print_i64(i64(column_index)) - print_string(" is out of bounds range [0..<") + print_string(" is out of range [0..<") print_i64(i64(row_count)) print_string(", 0..<") print_i64(i64(column_count)) @@ -119,71 +122,101 @@ matrix_bounds_check_error :: proc "contextless" (file: string, line, column: i32 } -type_assertion_check :: proc "contextless" (ok: bool, file: string, line, column: i32, from, to: typeid) { - if ok { - return - } - handle_error :: proc "contextless" (file: string, line, column: i32, from, to: typeid) { - print_caller_location(Source_Code_Location{file, line, column, ""}) - print_string(" Invalid type assertion from ") - print_typeid(from) - print_string(" to ") - print_typeid(to) - print_byte('\n') - type_assertion_trap() - } - handle_error(file, line, column, from, to) -} - -type_assertion_check2 :: proc "contextless" (ok: bool, file: string, line, column: i32, from, to: typeid, from_data: rawptr) { - if ok { - return +when ODIN_DISALLOW_RTTI { + type_assertion_check :: proc "contextless" (ok: bool, file: string, line, column: i32) { + if ok { + return + } + @(cold) + handle_error :: proc "contextless" (file: string, line, column: i32) { + print_caller_location(Source_Code_Location{file, line, column, ""}) + print_string(" Invalid type assertion\n") + type_assertion_trap() + } + handle_error(file, line, column) } - variant_type :: proc "contextless" (id: typeid, data: rawptr) -> typeid { - if id == nil || data == nil { + type_assertion_check2 :: proc "contextless" (ok: bool, file: string, line, column: i32) { + if ok { + return + } + @(cold) + handle_error :: proc "contextless" (file: string, line, column: i32) { + print_caller_location(Source_Code_Location{file, line, column, ""}) + print_string(" Invalid type assertion\n") + type_assertion_trap() + } + handle_error(file, line, column) + } +} else { + type_assertion_check :: proc "contextless" (ok: bool, file: string, line, column: i32, from, to: typeid) { + if ok { + return + } + @(cold) + handle_error :: proc "contextless" (file: string, line, column: i32, from, to: typeid) { + print_caller_location(Source_Code_Location{file, line, column, ""}) + print_string(" Invalid type assertion from ") + print_typeid(from) + print_string(" to ") + print_typeid(to) + print_byte('\n') + type_assertion_trap() + } + handle_error(file, line, column, from, to) + } + + type_assertion_check2 :: proc "contextless" (ok: bool, file: string, line, column: i32, from, to: typeid, from_data: rawptr) { + if ok { + return + } + + variant_type :: proc "contextless" (id: typeid, data: rawptr) -> typeid { + if id == nil || data == nil { + return id + } + ti := type_info_base(type_info_of(id)) + #partial switch v in ti.variant { + case Type_Info_Any: + return (^any)(data).id + case Type_Info_Union: + tag_ptr := uintptr(data) + v.tag_offset + idx := 0 + switch v.tag_type.size { + case 1: idx = int((^u8)(tag_ptr)^) - 1 + case 2: idx = int((^u16)(tag_ptr)^) - 1 + case 4: idx = int((^u32)(tag_ptr)^) - 1 + case 8: idx = int((^u64)(tag_ptr)^) - 1 + case 16: idx = int((^u128)(tag_ptr)^) - 1 + } + if idx < 0 { + return nil + } else if idx < len(v.variants) { + return v.variants[idx].id + } + } return id } - ti := type_info_base(type_info_of(id)) - #partial switch v in ti.variant { - case Type_Info_Any: - return (^any)(data).id - case Type_Info_Union: - tag_ptr := uintptr(data) + v.tag_offset - idx := 0 - switch v.tag_type.size { - case 1: idx = int((^u8)(tag_ptr)^) - 1 - case 2: idx = int((^u16)(tag_ptr)^) - 1 - case 4: idx = int((^u32)(tag_ptr)^) - 1 - case 8: idx = int((^u64)(tag_ptr)^) - 1 - case 16: idx = int((^u128)(tag_ptr)^) - 1 - } - if idx < 0 { - return nil - } else if idx < len(v.variants) { - return v.variants[idx].id + + @(cold) + handle_error :: proc "contextless" (file: string, line, column: i32, from, to: typeid, from_data: rawptr) { + + actual := variant_type(from, from_data) + + print_caller_location(Source_Code_Location{file, line, column, ""}) + print_string(" Invalid type assertion from ") + print_typeid(from) + print_string(" to ") + print_typeid(to) + if actual != from { + print_string(", actual type: ") + print_typeid(actual) } + print_byte('\n') + type_assertion_trap() } - return id + handle_error(file, line, column, from, to, from_data) } - - handle_error :: proc "contextless" (file: string, line, column: i32, from, to: typeid, from_data: rawptr) { - - actual := variant_type(from, from_data) - - print_caller_location(Source_Code_Location{file, line, column, ""}) - print_string(" Invalid type assertion from ") - print_typeid(from) - print_string(" to ") - print_typeid(to) - if actual != from { - print_string(", actual type: ") - print_typeid(actual) - } - print_byte('\n') - type_assertion_trap() - } - handle_error(file, line, column, from, to, from_data) } @@ -191,6 +224,7 @@ make_slice_error_loc :: #force_inline proc "contextless" (loc := #caller_locatio if 0 <= len { return } + @(cold) handle_error :: proc "contextless" (loc: Source_Code_Location, len: int) { print_caller_location(loc) print_string(" Invalid slice length for make: ") @@ -205,6 +239,7 @@ make_dynamic_array_error_loc :: #force_inline proc "contextless" (using loc := # if 0 <= len && len <= cap { return } + @(cold) handle_error :: proc "contextless" (loc: Source_Code_Location, len, cap: int) { print_caller_location(loc) print_string(" Invalid dynamic array parameters for make: ") @@ -221,6 +256,7 @@ make_map_expr_error_loc :: #force_inline proc "contextless" (loc := #caller_loca if 0 <= cap { return } + @(cold) handle_error :: proc "contextless" (loc: Source_Code_Location, cap: int) { print_caller_location(loc) print_string(" Invalid map capacity for make: ") diff --git a/core/runtime/internal.odin b/core/runtime/internal.odin index ed58f4318..30798f623 100644 --- a/core/runtime/internal.odin +++ b/core/runtime/internal.odin @@ -2,13 +2,15 @@ package runtime import "core:intrinsics" +@(private="file") +IS_WASM :: ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64 + @(private) RUNTIME_LINKAGE :: "strong" when ( (ODIN_USE_SEPARATE_MODULES || - ODIN_BUILD_MODE == "dynamic" || + ODIN_BUILD_MODE == .Dynamic || !ODIN_NO_CRT) && - !(ODIN_ARCH == "wasm32" || - ODIN_ARCH == "wasm64")) else "internal" + !IS_WASM) else "internal" RUNTIME_REQUIRE :: true @@ -35,10 +37,8 @@ bswap_64 :: proc "contextless" (x: u64) -> u64 { bswap_128 :: proc "contextless" (x: u128) -> u128 { z := transmute([4]u32)x - z[0] = bswap_32(z[3]) - z[1] = bswap_32(z[2]) - z[2] = bswap_32(z[1]) - z[3] = bswap_32(z[0]) + z[0], z[3] = bswap_32(z[3]), bswap_32(z[0]) + z[1], z[2] = bswap_32(z[2]), bswap_32(z[1]) return transmute(u128)z } @@ -752,6 +752,9 @@ extendhfsf2 :: proc "c" (value: u16) -> f32 { @(link_name="__floattidf", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE) floattidf :: proc "c" (a: i128) -> f64 { +when IS_WASM { + return 0 +} else { DBL_MANT_DIG :: 53 if a == 0 { return 0.0 @@ -791,10 +794,14 @@ floattidf :: proc "c" (a: i128) -> f64 { fb[0] = u32(a) // mantissa-low return transmute(f64)fb } +} @(link_name="__floattidf_unsigned", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE) floattidf_unsigned :: proc "c" (a: u128) -> f64 { +when IS_WASM { + return 0 +} else { DBL_MANT_DIG :: 53 if a == 0 { return 0.0 @@ -832,6 +839,7 @@ floattidf_unsigned :: proc "c" (a: u128) -> f64 { fb[0] = u32(a) // mantissa-low return transmute(f64)fb } +} diff --git a/core/runtime/print.odin b/core/runtime/print.odin index 8a14eba08..89c196fc2 100644 --- a/core/runtime/print.odin +++ b/core/runtime/print.odin @@ -143,18 +143,36 @@ print_int :: proc "contextless" (x: int) { print_i64(i64(x)) } print_caller_location :: proc "contextless" (using loc: Source_Code_Location) { print_string(file_path) - print_byte('(') - print_u64(u64(line)) - print_byte(':') - print_u64(u64(column)) - print_byte(')') + when ODIN_ERROR_POS_STYLE == .Default { + print_byte('(') + print_u64(u64(line)) + print_byte(':') + print_u64(u64(column)) + print_byte(')') + } else when ODIN_ERROR_POS_STYLE == .Unix { + print_byte(':') + print_u64(u64(line)) + print_byte(':') + print_u64(u64(column)) + print_byte(':') + } else { + #panic("unhandled ODIN_ERROR_POS_STYLE") + } } print_typeid :: proc "contextless" (id: typeid) { - if id == nil { - print_string("nil") + when ODIN_DISALLOW_RTTI { + if id == nil { + print_string("nil") + } else { + print_string("") + } } else { - ti := type_info_of(id) - print_type(ti) + if id == nil { + print_string("nil") + } else { + ti := type_info_of(id) + print_type(ti) + } } } print_type :: proc "contextless" (ti: ^Type_Info) { @@ -250,6 +268,9 @@ print_type :: proc "contextless" (ti: ^Type_Info) { print_type(info.elem) case Type_Info_Enumerated_Array: + if info.is_sparse { + print_string("#sparse") + } print_byte('[') print_type(info.index) print_byte(']') diff --git a/core/runtime/procs.odin b/core/runtime/procs.odin index 961f6376f..5a1d11fe0 100644 --- a/core/runtime/procs.odin +++ b/core/runtime/procs.odin @@ -1,6 +1,6 @@ package runtime -when ODIN_NO_CRT && ODIN_OS == "windows" { +when ODIN_NO_CRT && ODIN_OS == .Windows { foreign import lib "system:NtDll.lib" @(private="file") @@ -25,7 +25,7 @@ when ODIN_NO_CRT && ODIN_OS == "windows" { RtlMoveMemory(dst, src, len) return dst } -} else when ODIN_NO_CRT || (ODIN_ARCH == "wasm32" || ODIN_ARCH == "wasm64") { +} else when ODIN_NO_CRT || (ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64) { @(link_name="memset", linkage="strong", require) memset :: proc "c" (ptr: rawptr, val: i32, len: int) -> rawptr { if ptr != nil && len != 0 { diff --git a/core/runtime/procs_darwin.odin b/core/runtime/procs_darwin.odin new file mode 100644 index 000000000..b54a28dcc --- /dev/null +++ b/core/runtime/procs_darwin.odin @@ -0,0 +1,21 @@ +//+private +package runtime + +foreign import "system:Foundation.framework" + +import "core:intrinsics" + +objc_id :: ^intrinsics.objc_object +objc_Class :: ^intrinsics.objc_class +objc_SEL :: ^intrinsics.objc_selector + +foreign Foundation { + objc_lookUpClass :: proc "c" (name: cstring) -> objc_Class --- + sel_registerName :: proc "c" (name: cstring) -> objc_SEL --- + objc_allocateClassPair :: proc "c" (superclass: objc_Class, name: cstring, extraBytes: uint) --- + + objc_msgSend :: proc "c" (self: objc_id, op: objc_SEL, #c_vararg args: ..any) --- + objc_msgSend_fpret :: proc "c" (self: objc_id, op: objc_SEL, #c_vararg args: ..any) -> f64 --- + objc_msgSend_fp2ret :: proc "c" (self: objc_id, op: objc_SEL, #c_vararg args: ..any) -> complex128 --- + objc_msgSend_stret :: proc "c" (self: objc_id, op: objc_SEL, #c_vararg args: ..any) --- +} diff --git a/core/runtime/procs_wasm32.odin b/core/runtime/procs_wasm32.odin index 5caf6d2f8..2a4210c1e 100644 --- a/core/runtime/procs_wasm32.odin +++ b/core/runtime/procs_wasm32.odin @@ -1,23 +1,40 @@ //+build wasm32 package runtime +@(private="file") +ti_int :: struct #raw_union { + using s: struct { lo, hi: u64 }, + all: i128, +} + @(link_name="__ashlti3", linkage="strong") -__ashlti3 :: proc "c" (a: i64, b_: i32) -> i64 { - /* +__ashlti3 :: proc "c" (a: i128, b_: u32) -> i128 { + bits_in_dword :: size_of(u32)*8 b := u32(b_) - input := transmute([2]i32)a - result: [2]i32 - if b & 32 != 0 { - result[0] = 0 - result[1] = input[0] << (b - 32) + + input, result: ti_int + input.all = a + if b & bits_in_dword != 0 { + result.lo = 0 + result.hi = input.lo << (b-bits_in_dword) } else { if b == 0 { return a } - result[0] = input[0]<>(32-b)) + result.lo = input.lo<>(bits_in_dword-b)) } - return transmute(i64)result - */ - return 0 + return result.all +} + + +@(link_name="__multi3", linkage="strong") +__multi3 :: proc "c" (a, b: i128) -> i128 { + x, y, r: ti_int + + x.all = a + y.all = b + r.all = i128(x.lo * y.lo) // TODO this is incorrect + r.hi += x.hi*y.lo + x.lo*y.hi + return r.all } \ No newline at end of file diff --git a/core/runtime/procs_windows_amd64.odin b/core/runtime/procs_windows_amd64.odin index 273bb57b2..e430357be 100644 --- a/core/runtime/procs_windows_amd64.odin +++ b/core/runtime/procs_windows_amd64.odin @@ -22,4 +22,4 @@ windows_trap_type_assertion :: proc "contextless" () -> ! { when ODIN_NO_CRT { @(require) foreign import crt_lib "procs_windows_amd64.asm" -} \ No newline at end of file +} diff --git a/core/runtime/procs_windows_386.odin b/core/runtime/procs_windows_i386.odin similarity index 100% rename from core/runtime/procs_windows_386.odin rename to core/runtime/procs_windows_i386.odin diff --git a/core/runtime/udivmod128.odin b/core/runtime/udivmod128.odin index 1fd1b5f84..87ef73c2c 100644 --- a/core/runtime/udivmod128.odin +++ b/core/runtime/udivmod128.odin @@ -11,7 +11,7 @@ udivmod128 :: proc "c" (a, b: u128, rem: ^u128) -> u128 { q, r: [2]u64 sr: u32 = 0 - low :: 1 when ODIN_ENDIAN == "big" else 0 + low :: 1 when ODIN_ENDIAN == .Big else 0 high :: 1 - low U64_BITS :: 8*size_of(u64) U128_BITS :: 8*size_of(u128) diff --git a/core/slice/slice.odin b/core/slice/slice.odin index 487dd46c2..b8fb29ab3 100644 --- a/core/slice/slice.odin +++ b/core/slice/slice.odin @@ -10,6 +10,53 @@ _ :: builtin _ :: bits _ :: mem +/* + Turn a pointer and a length into a slice. +*/ +from_ptr :: proc "contextless" (ptr: ^$T, count: int) -> []T { + return ([^]T)(ptr)[:count] +} + +/* + Turn a pointer and a length into a byte slice. +*/ +bytes_from_ptr :: proc "contextless" (ptr: rawptr, byte_count: int) -> []byte { + return ([^]byte)(ptr)[:byte_count] +} + +/* + Turn a slice into a byte slice. + + See `slice.reinterpret` to go the other way. +*/ +to_bytes :: proc "contextless" (s: []$T) -> []byte { + return ([^]byte)(raw_data(s))[:len(s) * size_of(T)] +} + +/* + Turn a slice of one type, into a slice of another type. + + Only converts the type and length of the slice itself. + The length is rounded down to the nearest whole number of items. + + ``` + large_items := []i64{1, 2, 3, 4} + small_items := slice.reinterpret([]i32, large_items) + assert(len(small_items) == 8) + ``` + ``` + small_items := []byte{1, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0} + large_items := slice.reinterpret([]i64, small_items) + assert(len(large_items) == 1) // only enough bytes to make 1 x i64; two would need at least 8 bytes. + ``` +*/ +reinterpret :: proc "contextless" ($T: typeid/[]$U, s: []$V) -> []U { + bytes := to_bytes(s) + n := len(bytes) / size_of(U) + return ([^]U)(raw_data(bytes))[:n] +} + swap :: proc(array: $T/[]$E, a, b: int) { when size_of(E) > 8 { @@ -185,7 +232,7 @@ concatenate :: proc(a: []$T/[]$E, allocator := context.allocator) -> (res: T) { return } -// copies slice into a new dynamic array +// copies a slice into a new slice clone :: proc(a: $T/[]$E, allocator := context.allocator) -> []E { d := make([]E, len(a), allocator) copy(d[:], a) @@ -194,11 +241,12 @@ clone :: proc(a: $T/[]$E, allocator := context.allocator) -> []E { // copies slice into a new dynamic array -to_dynamic :: proc(a: $T/[]$E, allocator := context.allocator) -> [dynamic]E { +clone_to_dynamic :: proc(a: $T/[]$E, allocator := context.allocator) -> [dynamic]E { d := make([dynamic]E, len(a), allocator) copy(d[:], a) return d } +to_dynamic :: clone_to_dynamic // Converts slice into a dynamic array without cloning or allocating memory into_dynamic :: proc(a: $T/[]$E) -> [dynamic]E { @@ -272,7 +320,7 @@ get_ptr :: proc(array: $T/[]$E, index: int) -> (value: ^E, ok: bool) { return } -as_ptr :: proc(array: $T/[]$E) -> ^E { +as_ptr :: proc(array: $T/[]$E) -> [^]E { return raw_data(array) } @@ -303,6 +351,23 @@ filter :: proc(s: $S/[]$U, f: proc(U) -> bool, allocator := context.allocator) - return r[:] } +scanner :: proc (s: $S/[]$U, initializer: $V, f: proc(V, U) -> V, allocator := context.allocator) -> []V { + if len(s) == 0 { return {} } + + res := make([]V, len(s), allocator) + p := as_ptr(s) + q := as_ptr(res) + r := initializer + + for l := len(s); l > 0; l -= 1 { + r = f(r, p[0]) + q[0] = r + p = p[1:] + q = q[1:] + } + + return res +} min :: proc(s: $S/[]$T) -> (res: T, ok: bool) where intrinsics.type_is_ordered(T) #optional_ok { @@ -326,15 +391,106 @@ max :: proc(s: $S/[]$T) -> (res: T, ok: bool) where intrinsics.type_is_ordered(T return } +min_max :: proc(s: $S/[]$T) -> (min, max: T, ok: bool) where intrinsics.type_is_ordered(T) { + if len(s) != 0 { + min, max = s[0], s[0] + ok = true + for v in s[1:] { + min = builtin.min(min, v) + max = builtin.max(max, v) + } + } + return +} -dot_product :: proc(a, b: $S/[]$T) -> T +any_of :: proc(s: $S/[]$T, value: T) -> bool where intrinsics.type_is_comparable(T) { + for v in s { + if v == value { + return true + } + } + return false +} + +none_of :: proc(s: $S/[]$T, value: T) -> bool where intrinsics.type_is_comparable(T) { + for v in s { + if v == value { + return false + } + } + return true +} + +all_of :: proc(s: $S/[]$T, value: T) -> bool where intrinsics.type_is_comparable(T) { + if len(s) == 0 { + return false + } + for v in s { + if v != value { + return false + } + } + return true +} + + +any_of_proc :: proc(s: $S/[]$T, f: proc(T) -> bool) -> bool { + for v in s { + if f(v) { + return true + } + } + return false +} + +none_of_proc :: proc(s: $S/[]$T, f: proc(T) -> bool) -> bool { + for v in s { + if f(v) { + return false + } + } + return true +} + +all_of_proc :: proc(s: $S/[]$T, f: proc(T) -> bool) -> bool { + if len(s) == 0 { + return false + } + for v in s { + if !f(v) { + return false + } + } + return true +} + + +count :: proc(s: $S/[]$T, value: T) -> (n: int) where intrinsics.type_is_comparable(T) { + for v in s { + if v == value { + n += 1 + } + } + return +} + +count_proc :: proc(s: $S/[]$T, f: proc(T) -> bool) -> (n: int) { + for v in s { + if f(v) { + n += 1 + } + } + return +} + + +dot_product :: proc(a, b: $S/[]$T) -> (r: T, ok: bool) where intrinsics.type_is_numeric(T) { if len(a) != len(b) { - panic("slice.dot_product: slices of unequal length") + return } - r: T #no_bounds_check for _, i in a { r += a[i] * b[i] } - return r + return r, true } diff --git a/core/slice/sort.odin b/core/slice/sort.odin index d9755ad0e..8a2dec039 100644 --- a/core/slice/sort.odin +++ b/core/slice/sort.odin @@ -1,10 +1,5 @@ package slice -import "core:intrinsics" -_ :: intrinsics - -ORD :: intrinsics.type_is_ordered - Ordering :: enum { Less = -1, Equal = 0, @@ -38,7 +33,7 @@ cmp_proc :: proc($E: typeid) -> (proc(E, E) -> Ordering) where ORD(E) { sort :: proc(data: $T/[]$E) where ORD(E) { when size_of(E) != 0 { if n := len(data); n > 1 { - _quick_sort(data, 0, n, _max_depth(n)) + _quick_sort_general(data, 0, n, _max_depth(n), struct{}{}, .Ordered) } } } @@ -48,7 +43,7 @@ sort :: proc(data: $T/[]$E) where ORD(E) { sort_by :: proc(data: $T/[]$E, less: proc(i, j: E) -> bool) { when size_of(E) != 0 { if n := len(data); n > 1 { - _quick_sort_less(data, 0, n, _max_depth(n), less) + _quick_sort_general(data, 0, n, _max_depth(n), less, .Less) } } } @@ -56,7 +51,33 @@ sort_by :: proc(data: $T/[]$E, less: proc(i, j: E) -> bool) { sort_by_cmp :: proc(data: $T/[]$E, cmp: proc(i, j: E) -> Ordering) { when size_of(E) != 0 { if n := len(data); n > 1 { - _quick_sort_cmp(data, 0, n, _max_depth(n), cmp) + _quick_sort_general(data, 0, n, _max_depth(n), cmp, .Cmp) + } + } +} + +// stable_sort sorts a slice +stable_sort :: proc(data: $T/[]$E) where ORD(E) { + when size_of(E) != 0 { + if n := len(data); n > 1 { + _stable_sort_general(data, struct{}{}, .Ordered) + } + } +} + +// stable_sort_by sorts a slice with a given procedure to test whether two values are ordered "i < j" +stable_sort_by :: proc(data: $T/[]$E, less: proc(i, j: E) -> bool) { + when size_of(E) != 0 { + if n := len(data); n > 1 { + _stable_sort_general(data, less, .Less) + } + } +} + +stable_sort_by_cmp :: proc(data: $T/[]$E, cmp: proc(i, j: E) -> Ordering) { + when size_of(E) != 0 { + if n := len(data); n > 1 { + _stable_sort_general(data, cmp, .Cmp) } } } @@ -79,6 +100,7 @@ is_sorted_by :: proc(array: $T/[]$E, less: proc(i, j: E) -> bool) -> bool { return true } +is_sorted_by_cmp :: is_sorted_cmp is_sorted_cmp :: proc(array: $T/[]$E, cmp: proc(i, j: E) -> Ordering) -> bool { for i := len(array)-1; i > 0; i -= 1 { if cmp(array[i], array[i-1]) == .Equal { @@ -140,489 +162,10 @@ is_sorted_by_key :: proc(array: $T/[]$E, key: proc(E) -> $K) -> bool where ORD(K return true } - - @(private) -_max_depth :: proc(n: int) -> int { // 2*ceil(log2(n+1)) - depth: int +_max_depth :: proc(n: int) -> (depth: int) { // 2*ceil(log2(n+1)) for i := n; i > 0; i >>= 1 { depth += 1 } return depth * 2 } - -@(private) -_quick_sort :: proc(data: $T/[]$E, a, b, max_depth: int) where ORD(E) #no_bounds_check { - median3 :: proc(data: T, m1, m0, m2: int) #no_bounds_check { - if data[m1] < data[m0] { - swap(data, m1, m0) - } - if data[m2] < data[m1] { - swap(data, m2, m1) - if data[m1] < data[m0] { - swap(data, m1, m0) - } - } - } - - do_pivot :: proc(data: T, lo, hi: int) -> (midlo, midhi: int) #no_bounds_check { - m := int(uint(lo+hi)>>1) - if hi-lo > 40 { - s := (hi-lo)/8 - median3(data, lo, lo+s, lo+s*2) - median3(data, m, m-s, m+s) - median3(data, hi-1, hi-1-s, hi-1-s*2) - } - median3(data, lo, m, hi-1) - - - pivot := lo - a, c := lo+1, hi-1 - - for ; a < c && data[a] < data[pivot]; a += 1 { - } - b := a - - for { - for ; b < c && !(data[pivot] < data[b]); b += 1 { // data[b] <= pivot - } - for ; b < c && data[pivot] < data[c-1]; c -=1 { // data[c-1] > pivot - } - if b >= c { - break - } - - swap(data, b, c-1) - b += 1 - c -= 1 - } - - protect := hi-c < 5 - if !protect && hi-c < (hi-lo)/4 { - dups := 0 - if !(data[pivot] < data[hi-1]) { - swap(data, c, hi-1) - c += 1 - dups += 1 - } - if !(data[b-1] < data[pivot]) { - b -= 1 - dups += 1 - } - - if !(data[m] < data[pivot]) { - swap(data, m, b-1) - b -= 1 - dups += 1 - } - protect = dups > 1 - } - if protect { - for { - for ; a < b && !(data[b-1] < data[pivot]); b -= 1 { - } - for ; a < b && data[a] < data[pivot]; a += 1 { - } - if a >= b { - break - } - swap(data, a, b-1) - a += 1 - b -= 1 - } - } - swap(data, pivot, b-1) - return b-1, c - } - - - a, b, max_depth := a, b, max_depth - - if b-a > 12 { // only use shell sort for lengths <= 12 - if max_depth == 0 { - _heap_sort(data, a, b) - return - } - max_depth -= 1 - mlo, mhi := do_pivot(data, a, b) - if mlo-a < b-mhi { - _quick_sort(data, a, mlo, max_depth) - a = mhi - } else { - _quick_sort(data, mhi, b, max_depth) - b = mlo - } - } - if b-a > 1 { - // Shell short with gap 6 - for i in a+6.. a && data[j] < data[j-1]; j -= 1 { - swap(data, j, j-1) - } - } -} - -@(private) -_heap_sort :: proc(data: $T/[]$E, a, b: int) where ORD(E) #no_bounds_check { - sift_down :: proc(data: T, lo, hi, first: int) #no_bounds_check { - root := lo - for { - child := 2*root + 1 - if child >= hi { - break - } - if child+1 < hi && data[first+child] < data[first+child+1] { - child += 1 - } - if !(data[first+root] < data[first+child]) { - return - } - swap(data, first+root, first+child) - root = child - } - } - - - first, lo, hi := a, 0, b-a - - for i := (hi-1)/2; i >= 0; i -= 1 { - sift_down(data, i, hi, first) - } - - for i := hi-1; i >= 0; i -= 1 { - swap(data, first, first+i) - sift_down(data, lo, i, first) - } -} - - - - - - -@(private) -_quick_sort_less :: proc(data: $T/[]$E, a, b, max_depth: int, less: proc(i, j: E) -> bool) #no_bounds_check { - median3 :: proc(data: T, m1, m0, m2: int, less: proc(i, j: E) -> bool) #no_bounds_check { - if less(data[m1], data[m0]) { - swap(data, m1, m0) - } - if less(data[m2], data[m1]) { - swap(data, m2, m1) - if less(data[m1], data[m0]) { - swap(data, m1, m0) - } - } - } - - do_pivot :: proc(data: T, lo, hi: int, less: proc(i, j: E) -> bool) -> (midlo, midhi: int) #no_bounds_check { - m := int(uint(lo+hi)>>1) - if hi-lo > 40 { - s := (hi-lo)/8 - median3(data, lo, lo+s, lo+s*2, less) - median3(data, m, m-s, m+s, less) - median3(data, hi-1, hi-1-s, hi-1-s*2, less) - } - median3(data, lo, m, hi-1, less) - - pivot := lo - a, c := lo+1, hi-1 - - for ; a < c && less(data[a], data[pivot]); a += 1 { - } - b := a - - for { - for ; b < c && !less(data[pivot], data[b]); b += 1 { // data[b] <= pivot - } - for ; b < c && less(data[pivot], data[c-1]); c -=1 { // data[c-1] > pivot - } - if b >= c { - break - } - - swap(data, b, c-1) - b += 1 - c -= 1 - } - - protect := hi-c < 5 - if !protect && hi-c < (hi-lo)/4 { - dups := 0 - if !less(data[pivot], data[hi-1]) { - swap(data, c, hi-1) - c += 1 - dups += 1 - } - if !less(data[b-1], data[pivot]) { - b -= 1 - dups += 1 - } - - if !less(data[m], data[pivot]) { - swap(data, m, b-1) - b -= 1 - dups += 1 - } - protect = dups > 1 - } - if protect { - for { - for ; a < b && !less(data[b-1], data[pivot]); b -= 1 { - } - for ; a < b && less(data[a], data[pivot]); a += 1 { - } - if a >= b { - break - } - swap(data, a, b-1) - a += 1 - b -= 1 - } - } - swap(data, pivot, b-1) - return b-1, c - } - - - a, b, max_depth := a, b, max_depth - - if b-a > 12 { // only use shell sort for lengths <= 12 - if max_depth == 0 { - _heap_sort_less(data, a, b, less) - return - } - max_depth -= 1 - mlo, mhi := do_pivot(data, a, b, less) - if mlo-a < b-mhi { - _quick_sort_less(data, a, mlo, max_depth, less) - a = mhi - } else { - _quick_sort_less(data, mhi, b, max_depth, less) - b = mlo - } - } - if b-a > 1 { - // Shell short with gap 6 - for i in a+6.. bool) #no_bounds_check { - for i in a+1.. a && less(data[j], data[j-1]); j -= 1 { - swap(data, j, j-1) - } - } -} - -@(private) -_heap_sort_less :: proc(data: $T/[]$E, a, b: int, less: proc(i, j: E) -> bool) #no_bounds_check { - sift_down :: proc(data: T, lo, hi, first: int, less: proc(i, j: E) -> bool) #no_bounds_check { - root := lo - for { - child := 2*root + 1 - if child >= hi { - break - } - if child+1 < hi && less(data[first+child], data[first+child+1]) { - child += 1 - } - if !less(data[first+root], data[first+child]) { - return - } - swap(data, first+root, first+child) - root = child - } - } - - - first, lo, hi := a, 0, b-a - - for i := (hi-1)/2; i >= 0; i -= 1 { - sift_down(data, i, hi, first, less) - } - - for i := hi-1; i >= 0; i -= 1 { - swap(data, first, first+i) - sift_down(data, lo, i, first, less) - } -} - - - - - - -@(private) -_quick_sort_cmp :: proc(data: $T/[]$E, a, b, max_depth: int, cmp: proc(i, j: E) -> Ordering) #no_bounds_check { - median3 :: proc(data: T, m1, m0, m2: int, cmp: proc(i, j: E) -> Ordering) #no_bounds_check { - if cmp(data[m1], data[m0]) == .Less { - swap(data, m1, m0) - } - if cmp(data[m2], data[m1]) == .Less { - swap(data, m2, m1) - if cmp(data[m1], data[m0]) == .Less { - swap(data, m1, m0) - } - } - } - - do_pivot :: proc(data: T, lo, hi: int, cmp: proc(i, j: E) -> Ordering) -> (midlo, midhi: int) #no_bounds_check { - m := int(uint(lo+hi)>>1) - if hi-lo > 40 { - s := (hi-lo)/8 - median3(data, lo, lo+s, lo+s*2, cmp) - median3(data, m, m-s, m+s, cmp) - median3(data, hi-1, hi-1-s, hi-1-s*2, cmp) - } - median3(data, lo, m, hi-1, cmp) - - pivot := lo - a, c := lo+1, hi-1 - - for ; a < c && cmp(data[a], data[pivot]) == .Less; a += 1 { - } - b := a - - for { - for ; b < c && cmp(data[pivot], data[b]) >= .Equal; b += 1 { // data[b] <= pivot - } - for ; b < c && cmp(data[pivot], data[c-1]) == .Less; c -=1 { // data[c-1] > pivot - } - if b >= c { - break - } - - swap(data, b, c-1) - b += 1 - c -= 1 - } - - protect := hi-c < 5 - if !protect && hi-c < (hi-lo)/4 { - dups := 0 - if cmp(data[pivot], data[hi-1]) != .Less { - swap(data, c, hi-1) - c += 1 - dups += 1 - } - if cmp(data[b-1], data[pivot]) != .Less { - b -= 1 - dups += 1 - } - - if cmp(data[m], data[pivot]) != .Less { - swap(data, m, b-1) - b -= 1 - dups += 1 - } - protect = dups > 1 - } - if protect { - for { - for ; a < b && cmp(data[b-1], data[pivot]) >= .Equal; b -= 1 { - } - for ; a < b && cmp(data[a], data[pivot]) == .Less; a += 1 { - } - if a >= b { - break - } - swap(data, a, b-1) - a += 1 - b -= 1 - } - } - swap(data, pivot, b-1) - return b-1, c - } - - - a, b, max_depth := a, b, max_depth - - if b-a > 12 { // only use shell sort for lengths <= 12 - if max_depth == 0 { - _heap_sort_cmp(data, a, b, cmp) - return - } - max_depth -= 1 - mlo, mhi := do_pivot(data, a, b, cmp) - if mlo-a < b-mhi { - _quick_sort_cmp(data, a, mlo, max_depth, cmp) - a = mhi - } else { - _quick_sort_cmp(data, mhi, b, max_depth, cmp) - b = mlo - } - } - if b-a > 1 { - // Shell short with gap 6 - for i in a+6.. Ordering) #no_bounds_check { - for i in a+1.. a && cmp(data[j], data[j-1]) == .Less; j -= 1 { - swap(data, j, j-1) - } - } -} - -@(private) -_heap_sort_cmp :: proc(data: $T/[]$E, a, b: int, cmp: proc(i, j: E) -> Ordering) #no_bounds_check { - sift_down :: proc(data: T, lo, hi, first: int, cmp: proc(i, j: E) -> Ordering) #no_bounds_check { - root := lo - for { - child := 2*root + 1 - if child >= hi { - break - } - if child+1 < hi && cmp(data[first+child], data[first+child+1]) == .Less { - child += 1 - } - if cmp(data[first+root], data[first+child]) >= .Equal { - return - } - swap(data, first+root, first+child) - root = child - } - } - - - first, lo, hi := a, 0, b-a - - for i := (hi-1)/2; i >= 0; i -= 1 { - sift_down(data, i, hi, first, cmp) - } - - for i := hi-1; i >= 0; i -= 1 { - swap(data, first, first+i) - sift_down(data, lo, i, first, cmp) - } -} - - - diff --git a/core/slice/sort_private.odin b/core/slice/sort_private.odin new file mode 100644 index 000000000..d93d74bf9 --- /dev/null +++ b/core/slice/sort_private.odin @@ -0,0 +1,200 @@ +//+private +package slice + +import "core:intrinsics" +_ :: intrinsics + +ORD :: intrinsics.type_is_ordered + +Sort_Kind :: enum { + Ordered, + Less, + Cmp, +} + +_quick_sort_general :: proc(data: $T/[]$E, a, b, max_depth: int, call: $P, $KIND: Sort_Kind) where (ORD(E) && KIND == .Ordered) || (KIND != .Ordered) #no_bounds_check { + less :: #force_inline proc(a, b: E, call: P) -> bool { + when KIND == .Ordered { + return a < b + } else when KIND == .Less { + return call(a, b) + } else when KIND == .Cmp { + return call(a, b) == .Less + } else { + #panic("unhandled Sort_Kind") + } + } + + insertion_sort :: proc(data: $T/[]$E, a, b: int, call: P) #no_bounds_check { + for i in a+1.. a && less(data[j], data[j-1], call); j -= 1 { + swap(data, j, j-1) + } + } + } + + heap_sort :: proc(data: $T/[]$E, a, b: int, call: P) #no_bounds_check { + sift_down :: proc(data: T, lo, hi, first: int, call: P) #no_bounds_check { + root := lo + for { + child := 2*root + 1 + if child >= hi { + break + } + if child+1 < hi && less(data[first+child], data[first+child+1], call) { + child += 1 + } + if !less(data[first+root], data[first+child], call) { + return + } + swap(data, first+root, first+child) + root = child + } + } + + + first, lo, hi := a, 0, b-a + + for i := (hi-1)/2; i >= 0; i -= 1 { + sift_down(data, i, hi, first, call) + } + + for i := hi-1; i >= 0; i -= 1 { + swap(data, first, first+i) + sift_down(data, lo, i, first, call) + } + } + + median3 :: proc(data: T, m1, m0, m2: int, call: P) #no_bounds_check { + if less(data[m1], data[m0], call) { + swap(data, m1, m0) + } + if less(data[m2], data[m1], call) { + swap(data, m2, m1) + if less(data[m1], data[m0], call) { + swap(data, m1, m0) + } + } + } + + do_pivot :: proc(data: T, lo, hi: int, call: P) -> (midlo, midhi: int) #no_bounds_check { + m := int(uint(lo+hi)>>1) + if hi-lo > 40 { + s := (hi-lo)/8 + median3(data, lo, lo+s, lo+s*2, call) + median3(data, m, m-s, m+s, call) + median3(data, hi-1, hi-1-s, hi-1-s*2, call) + } + median3(data, lo, m, hi-1, call) + + pivot := lo + a, c := lo+1, hi-1 + + + for ; a < c && less(data[a], data[pivot], call); a += 1 { + } + b := a + + for { + for ; b < c && !less(data[pivot], data[b], call); b += 1 { // data[b] <= pivot + } + for ; b < c && less(data[pivot], data[c-1], call); c -=1 { // data[c-1] > pivot + } + if b >= c { + break + } + + swap(data, b, c-1) + b += 1 + c -= 1 + } + + protect := hi-c < 5 + if !protect && hi-c < (hi-lo)/4 { + dups := 0 + if !less(data[pivot], data[hi-1], call) { + swap(data, c, hi-1) + c += 1 + dups += 1 + } + if !less(data[b-1], data[pivot], call) { + b -= 1 + dups += 1 + } + + if !less(data[m], data[pivot], call) { + swap(data, m, b-1) + b -= 1 + dups += 1 + } + protect = dups > 1 + } + if protect { + for { + for ; a < b && !less(data[b-1], data[pivot], call); b -= 1 { + } + for ; a < b && less(data[a], data[pivot], call); a += 1 { + } + if a >= b { + break + } + swap(data, a, b-1) + a += 1 + b -= 1 + } + } + swap(data, pivot, b-1) + return b-1, c + } + + + a, b, max_depth := a, b, max_depth + + for b-a > 12 { // only use shell sort for lengths <= 12 + if max_depth == 0 { + heap_sort(data, a, b, call) + return + } + max_depth -= 1 + mlo, mhi := do_pivot(data, a, b, call) + if mlo-a < b-mhi { + _quick_sort_general(data, a, mlo, max_depth, call, KIND) + a = mhi + } else { + _quick_sort_general(data, mhi, b, max_depth, call, KIND) + b = mlo + } + } + if b-a > 1 { + // Shell short with gap 6 + for i in a+6.. bool { + when KIND == .Ordered { + return a < b + } else when KIND == .Less { + return call(a, b) + } else when KIND == .Cmp { + return call(a, b) == .Less + } else { + #panic("unhandled Sort_Kind") + } + } + + n := len(data) + for i in 1.. 0 && less(data[j], data[j-1], call); j -= 1 { + swap(data, j, j-1) + } + } +} diff --git a/core/sort/map.odin b/core/sort/map.odin new file mode 100644 index 000000000..32f5e09a2 --- /dev/null +++ b/core/sort/map.odin @@ -0,0 +1,36 @@ +package sort + +import "core:intrinsics" +import "core:runtime" +import "core:slice" + +_ :: runtime +_ :: slice + +map_entries_by_key :: proc(m: ^$M/map[$K]$V, loc := #caller_location) where intrinsics.type_is_ordered(K) { + Entry :: struct { + hash: uintptr, + next: int, + key: K, + value: V, + } + + header := runtime.__get_map_header(m) + entries := (^[dynamic]Entry)(&header.m.entries) + slice.sort_by_key(entries[:], proc(e: Entry) -> K { return e.key }) + runtime.__dynamic_map_reset_entries(header, loc) +} + +map_entries_by_value :: proc(m: ^$M/map[$K]$V, loc := #caller_location) where intrinsics.type_is_ordered(V) { + Entry :: struct { + hash: uintptr, + next: int, + key: K, + value: V, + } + + header := runtime.__get_map_header(m) + entries := (^[dynamic]Entry)(&header.m.entries) + slice.sort_by_key(entries[:], proc(e: Entry) -> V { return e.value }) + runtime.__dynamic_map_reset_entries(header, loc) +} \ No newline at end of file diff --git a/core/strconv/strconv.odin b/core/strconv/strconv.odin index 6b3a91b4c..65161a820 100644 --- a/core/strconv/strconv.odin +++ b/core/strconv/strconv.odin @@ -882,7 +882,9 @@ unquote_string :: proc(lit: string, allocator := context.allocator) -> (res: str return -1 } - assert(len(lit) >= 2) + if len(lit) < 2 { + return + } if lit[0] == '`' { return lit[1:len(lit)-1], false, true } @@ -893,6 +895,7 @@ unquote_string :: proc(lit: string, allocator := context.allocator) -> (res: str if s == `""` { return "", false, true } + s = s[1:len(s)-1] if contains_rune(s, '\n') >= 0 { return s, false, false diff --git a/core/strings/ascii_set.odin b/core/strings/ascii_set.odin index 582049eee..9b59666f3 100644 --- a/core/strings/ascii_set.odin +++ b/core/strings/ascii_set.odin @@ -5,6 +5,7 @@ import "core:unicode/utf8" Ascii_Set :: distinct [8]u32 +// create an ascii set of all unique characters in the string ascii_set_make :: proc(chars: string) -> (as: Ascii_Set, ok: bool) #no_bounds_check { for i in 0.. (as: Ascii_Set, ok: bool) #no_bounds_ch return } +// returns true when the `c` byte is contained in the `as` ascii set ascii_set_contains :: proc(as: Ascii_Set, c: byte) -> bool #no_bounds_check { return as[c>>5] & (1<<(c&31)) != 0 } \ No newline at end of file diff --git a/core/strings/builder.odin b/core/strings/builder.odin index 6952ba088..d6065cf70 100644 --- a/core/strings/builder.odin +++ b/core/strings/builder.odin @@ -7,40 +7,56 @@ import "core:io" Builder_Flush_Proc :: #type proc(b: ^Builder) -> (do_reset: bool) +/* + dynamic byte buffer / string builder with helper procedures + the dynamic array is wrapped inside the struct to be more opaque + you can use `fmt.sbprint*` procedures with a `^strings.Builder` directly +*/ Builder :: struct { buf: [dynamic]byte, } +// return a builder, default length 0 / cap 16 are done through make make_builder_none :: proc(allocator := context.allocator) -> Builder { return Builder{buf=make([dynamic]byte, allocator)} } +// return a builder, with a set length `len` and cap 16 byte buffer make_builder_len :: proc(len: int, allocator := context.allocator) -> Builder { return Builder{buf=make([dynamic]byte, len, allocator)} } +// return a builder, with a set length `len` byte buffer and a custom `cap` make_builder_len_cap :: proc(len, cap: int, allocator := context.allocator) -> Builder { return Builder{buf=make([dynamic]byte, len, cap, allocator)} } +// overload simple `make_builder_*` with or without len / cap parameters make_builder :: proc{ make_builder_none, make_builder_len, make_builder_len_cap, } +// initialize a builder, default length 0 / cap 16 are done through make +// replaces the existing `buf` init_builder_none :: proc(b: ^Builder, allocator := context.allocator) { b.buf = make([dynamic]byte, allocator) } +// initialize a builder, with a set length `len` and cap 16 byte buffer +// replaces the existing `buf` init_builder_len :: proc(b: ^Builder, len: int, allocator := context.allocator) { b.buf = make([dynamic]byte, len, allocator) } +// initialize a builder, with a set length `len` byte buffer and a custom `cap` +// replaces the existing `buf` init_builder_len_cap :: proc(b: ^Builder, len, cap: int, allocator := context.allocator) { b.buf = make([dynamic]byte, len, cap, allocator) } +// overload simple `init_builder_*` with or without len / ap parameters init_builder :: proc{ init_builder_none, init_builder_len, @@ -76,30 +92,42 @@ _builder_stream_vtable := &io.Stream_VTable{ }, } +// return an `io.Stream` from a builder to_stream :: proc(b: ^Builder) -> io.Stream { return io.Stream{stream_vtable=_builder_stream_vtable, stream_data=b} } + +// return an `io.Writer` from a builder to_writer :: proc(b: ^Builder) -> io.Writer { return io.to_writer(to_stream(b)) } - - - +// delete and clear the builder byte buffer content destroy_builder :: proc(b: ^Builder) { delete(b.buf) clear(&b.buf) } +// reserve the builfer byte buffer to a specific cap, when it's higher than before grow_builder :: proc(b: ^Builder, cap: int) { reserve(&b.buf, cap) } +// clear the builder byte buffer content reset_builder :: proc(b: ^Builder) { clear(&b.buf) } - +/* + create an empty builder with the same slice length as its cap + uses the `mem.nil_allocator` to avoid allocation and keep a fixed length + used in `fmt.bprint*` + + bytes: [8]byte // <-- gets filled + builder := strings.builder_from_slice(bytes[:]) + strings.write_byte(&builder, 'a') -> "a" + strings.write_byte(&builder, 'b') -> "ab" +*/ builder_from_slice :: proc(backing: []byte) -> Builder { s := transmute(mem.Raw_Slice)backing d := mem.Raw_Dynamic_Array{ @@ -112,20 +140,36 @@ builder_from_slice :: proc(backing: []byte) -> Builder { buf = transmute([dynamic]byte)d, } } + +// cast the builder byte buffer to a string and return it to_string :: proc(b: Builder) -> string { return string(b.buf[:]) } +// return the length of the builder byte buffer builder_len :: proc(b: Builder) -> int { return len(b.buf) } + +// return the cap of the builder byte buffer builder_cap :: proc(b: Builder) -> int { return cap(b.buf) } + +// returns the space left in the builder byte buffer to use up builder_space :: proc(b: Builder) -> int { - return max(cap(b.buf), len(b.buf), 0) + return cap(b.buf) - len(b.buf) } +/* + appends a byte to the builder, returns the append diff + + builder := strings.make_builder() + strings.write_byte(&builder, 'a') // 1 + strings.write_byte(&builder, 'b') // 1 + strings.write_byte(&builder, 'c') // 1 + fmt.println(strings.to_string(builder)) // -> abc +*/ write_byte :: proc(b: ^Builder, x: byte) -> (n: int) { n0 := len(b.buf) append(&b.buf, x) @@ -133,6 +177,14 @@ write_byte :: proc(b: ^Builder, x: byte) -> (n: int) { return n1-n0 } +/* + appends a slice of bytes to the builder, returns the append diff + + builder := strings.make_builder() + bytes := [?]byte { 'a', 'b', 'c' } + strings.write_bytes(&builder, bytes[:]) // 3 + fmt.println(strings.to_string(builder)) // -> abc +*/ write_bytes :: proc(b: ^Builder, x: []byte) -> (n: int) { n0 := len(b.buf) append(&b.buf, ..x) @@ -140,11 +192,28 @@ write_bytes :: proc(b: ^Builder, x: []byte) -> (n: int) { return n1-n0 } +/* + appends a single rune into the builder, returns written rune size and an `io.Error` + + builder := strings.make_builder() + strings.write_rune_builder(&builder, 'ä') // 2 None + strings.write_rune_builder(&builder, 'b') // 1 None + strings.write_rune_builder(&builder, 'c') // 1 None + fmt.println(strings.to_string(builder)) // -> äbc +*/ write_rune_builder :: proc(b: ^Builder, r: rune) -> (int, io.Error) { return io.write_rune(to_writer(b), r) } +/* + appends a quoted rune into the builder, returns written size + builder := strings.make_builder() + strings.write_string(&builder, "abc") // 3 + strings.write_quoted_rune_builder(&builder, 'ä') // 4 + strings.write_string(&builder, "abc") // 3 + fmt.println(strings.to_string(builder)) // -> abc'ä'abc +*/ write_quoted_rune_builder :: proc(b: ^Builder, r: rune) -> (n: int) { return write_quoted_rune(to_writer(b), r) } @@ -155,7 +224,7 @@ _write_byte :: proc(w: io.Writer, c: byte) -> int { return 1 if err == nil else 0 } - +// writer append a quoted rune into the byte buffer, return the written size write_quoted_rune :: proc(w: io.Writer, r: rune) -> (n: int) { quote := byte('\'') n += _write_byte(w, quote) @@ -173,50 +242,75 @@ write_quoted_rune :: proc(w: io.Writer, r: rune) -> (n: int) { return } - +// overload for `write_string_*` variants write_string :: proc{ write_string_builder, write_string_writer, } +/* + appends a string to the builder, return the written byte size + + builder := strings.make_builder() + strings.write_string(&builder, "a") // 1 + strings.write_string(&builder, "bc") // 2 + strings.write_string(&builder, "xyz") // 3 + fmt.println(strings.to_string(builder)) // -> abcxyz +*/ write_string_builder :: proc(b: ^Builder, s: string) -> (n: int) { return write_string_writer(to_writer(b), s) } +// appends a string to the writer write_string_writer :: proc(w: io.Writer, s: string) -> (n: int) { n, _ = io.write(w, transmute([]byte)s) return } - - - +// pops and returns the last byte in the builder +// returns 0 when the builder is empty pop_byte :: proc(b: ^Builder) -> (r: byte) { if len(b.buf) == 0 { return 0 } + r = b.buf[len(b.buf)-1] d := cast(^mem.Raw_Dynamic_Array)&b.buf d.len = max(d.len-1, 0) return } +// pops the last rune in the builder and returns the popped rune and its rune width +// returns 0, 0 when the builder is empty pop_rune :: proc(b: ^Builder) -> (r: rune, width: int) { + if len(b.buf) == 0 { + return 0, 0 + } + r, width = utf8.decode_last_rune(b.buf[:]) d := cast(^mem.Raw_Dynamic_Array)&b.buf d.len = max(d.len-width, 0) return } - @(private) DIGITS_LOWER := "0123456789abcdefx" +// overload for `write_quoted_string_*` variants write_quoted_string :: proc{ write_quoted_string_builder, write_quoted_string_writer, } +/* + append a quoted string into the builder, return the written byte size + + builder := strings.make_builder() + strings.write_quoted_string(&builder, "a") // 3 + strings.write_quoted_string(&builder, "bc", '\'') // 4 + strings.write_quoted_string(&builder, "xyz") // 5 + fmt.println(strings.to_string(builder)) // -> "a"'bc'xyz" +*/ write_quoted_string_builder :: proc(b: ^Builder, str: string, quote: byte = '"') -> (n: int) { n, _ = io.write_quoted_string(to_writer(b), str, quote) return @@ -228,11 +322,13 @@ write_quoted_string_writer :: proc(w: io.Writer, str: string, quote: byte = '"') return } +// overload for `write_encoded_rune_*` write_encoded_rune :: proc{ write_encoded_rune_builder, write_encoded_rune_writer, } +// appends a rune to the builder, optional `write_quote` boolean tag, returns the written rune size write_encoded_rune_builder :: proc(b: ^Builder, r: rune, write_quote := true) -> (n: int) { n, _ = io.write_encoded_rune(to_writer(b), r, write_quote) return @@ -244,12 +340,15 @@ write_encoded_rune_writer :: proc(w: io.Writer, r: rune, write_quote := true) -> return } - +// overload for `write_escaped_rune_*` write_escaped_rune :: proc{ write_escaped_rune_builder, write_escaped_rune_writer, } +// appends a rune to the builder, fully written out in case of escaped runes e.g. '\a' will be written as such +// when `r` and `quote` match and `quote` is `\\` - they will be written as two slashes +// `html_safe` flag in case the runes '<', '>', '&' should be encoded as digits e.g. `\u0026` write_escaped_rune_builder :: proc(b: ^Builder, r: rune, quote: byte, html_safe := false) -> (n: int) { n, _ = io.write_escaped_rune(to_writer(b), r, quote, html_safe) return @@ -261,21 +360,26 @@ write_escaped_rune_writer :: proc(w: io.Writer, r: rune, quote: byte, html_safe return } - +// writes a u64 value `i` in `base` = 10 into the builder, returns the written amount of characters write_u64 :: proc(b: ^Builder, i: u64, base: int = 10) -> (n: int) { buf: [32]byte s := strconv.append_bits(buf[:], i, base, false, 64, strconv.digits, nil) return write_string(b, s) } + +// writes a i64 value `i` in `base` = 10 into the builder, returns the written amount of characters write_i64 :: proc(b: ^Builder, i: i64, base: int = 10) -> (n: int) { buf: [32]byte s := strconv.append_bits(buf[:], u64(i), base, true, 64, strconv.digits, nil) return write_string(b, s) } +// writes a uint value `i` in `base` = 10 into the builder, returns the written amount of characters write_uint :: proc(b: ^Builder, i: uint, base: int = 10) -> (n: int) { return write_u64(b, u64(i), base) } + +// writes a int value `i` in `base` = 10 into the builder, returns the written amount of characters write_int :: proc(b: ^Builder, i: int, base: int = 10) -> (n: int) { return write_i64(b, i64(i), base) } diff --git a/core/strings/conversion.odin b/core/strings/conversion.odin index b0d42b2eb..5e7110281 100644 --- a/core/strings/conversion.odin +++ b/core/strings/conversion.odin @@ -58,6 +58,13 @@ to_valid_utf8 :: proc(s, replacement: string, allocator := context.allocator) -> return to_string(b) } +/* + returns the input string `s` with all runes set to lowered case + always allocates using the `allocator` + + strings.to_lower("test") -> test + strings.to_lower("Test") -> test +*/ to_lower :: proc(s: string, allocator := context.allocator) -> string { b: Builder init_builder(&b, 0, len(s), allocator) @@ -66,6 +73,14 @@ to_lower :: proc(s: string, allocator := context.allocator) -> string { } return to_string(b) } + +/* + returns the input string `s` with all runes set to upper case + always allocates using the `allocator` + + strings.to_lower("test") -> TEST + strings.to_lower("Test") -> TEST +*/ to_upper :: proc(s: string, allocator := context.allocator) -> string { b: Builder init_builder(&b, 0, len(s), allocator) @@ -75,13 +90,13 @@ to_upper :: proc(s: string, allocator := context.allocator) -> string { return to_string(b) } - - - +// returns true when the `c` rune is a space, '-' or '_' +// useful when treating strings like words in a text editor or html paths is_delimiter :: proc(c: rune) -> bool { return c == '-' || c == '_' || is_space(c) } +// returns true when the `r` rune is a non alpha or `unicode.is_space` rune is_separator :: proc(r: rune) -> bool { if r <= 0x7f { switch r { @@ -101,7 +116,10 @@ is_separator :: proc(r: rune) -> bool { return unicode.is_space(r) } - +/* + iterator that loops through the string and calls the callback with the `prev`, `curr` and `next` rune + on empty string `s` the callback gets called once with empty runes +*/ string_case_iterator :: proc(w: io.Writer, s: string, callback: proc(w: io.Writer, prev, curr, next: rune)) { prev, curr: rune for next in s { @@ -122,8 +140,9 @@ string_case_iterator :: proc(w: io.Writer, s: string, callback: proc(w: io.Write } } - to_lower_camel_case :: to_camel_case + +// converts the `s` string to "lowerCamelCase" to_camel_case :: proc(s: string, allocator := context.allocator) -> string { s := s s = trim_space(s) @@ -147,6 +166,8 @@ to_camel_case :: proc(s: string, allocator := context.allocator) -> string { } to_upper_camel_case :: to_pascal_case + +// converts the `s` string to "PascalCase" to_pascal_case :: proc(s: string, allocator := context.allocator) -> string { s := s s = trim_space(s) @@ -169,6 +190,15 @@ to_pascal_case :: proc(s: string, allocator := context.allocator) -> string { return to_string(b) } +/* + returns the `s` string to words seperated by the given `delimiter` rune + all runes will be upper or lowercased based on the `all_uppercase` bool + + strings.to_delimiter_case("Hello World", '_', false) -> hello_world + strings.to_delimiter_case("Hello World", ' ', true) -> HELLO WORLD + strings.to_delimiter_case("Hello World", ' ', true) -> HELLO WORLD + strings.to_delimiter_case("aBC", '_', false) -> a_b_c +*/ to_delimiter_case :: proc(s: string, delimiter: rune, all_upper_case: bool, allocator := context.allocator) -> string { s := s s = trim_space(s) @@ -208,24 +238,34 @@ to_delimiter_case :: proc(s: string, delimiter: rune, all_upper_case: bool, allo return to_string(b) } - +/* + converts the `s` string to "snake_case" with all runes lowercased + + strings.to_snake_case("HelloWorld") -> hello_world + strings.to_snake_case("Hello World") -> hello_world +*/ to_snake_case :: proc(s: string, allocator := context.allocator) -> string { return to_delimiter_case(s, '_', false, allocator) } to_screaming_snake_case :: to_upper_snake_case + +// converts the `s` string to "SNAKE_CASE" with all runes uppercased to_upper_snake_case :: proc(s: string, allocator := context.allocator) -> string { return to_delimiter_case(s, '_', true, allocator) } +// converts the `s` string to "kebab-case" with all runes lowercased to_kebab_case :: proc(s: string, allocator := context.allocator) -> string { return to_delimiter_case(s, '-', false, allocator) } -to_upper_case :: proc(s: string, allocator := context.allocator) -> string { +// converts the `s` string to "KEBAB-CASE" with all runes uppercased +to_upper_kebab_case :: proc(s: string, allocator := context.allocator) -> string { return to_delimiter_case(s, '-', true, allocator) } +// converts the `s` string to "Ada_case" to_ada_case :: proc(s: string, allocator := context.allocator) -> string { delimiter :: '_' diff --git a/core/strings/intern.odin b/core/strings/intern.odin index ff26d7dbb..27c3db084 100644 --- a/core/strings/intern.odin +++ b/core/strings/intern.odin @@ -2,21 +2,26 @@ package strings import "core:mem" +// custom string entry struct Intern_Entry :: struct { len: int, str: [1]byte, // string is allocated inline with the entry to keep allocations simple } +// "intern" is a more memory efficient string map +// `allocator` is used to allocate the actual `Intern_Entry` strings Intern :: struct { allocator: mem.Allocator, entries: map[string]^Intern_Entry, } +// initialize the entries map and set the allocator for the string entries intern_init :: proc(m: ^Intern, allocator := context.allocator, map_allocator := context.allocator) { m.allocator = allocator m.entries = make(map[string]^Intern_Entry, 16, map_allocator) } +// free the map and all its content allocated using the `.allocator` intern_destroy :: proc(m: ^Intern) { for _, value in m.entries { free(value, m.allocator) @@ -24,15 +29,22 @@ intern_destroy :: proc(m: ^Intern) { delete(m.entries) } +// returns the `text` string from the intern map - gets set if it didnt exist yet +// the returned string lives as long as the map entry lives intern_get :: proc(m: ^Intern, text: string) -> string { entry := _intern_get_entry(m, text) #no_bounds_check return string(entry.str[:entry.len]) } + +// returns the `text` cstring from the intern map - gets set if it didnt exist yet +// the returned cstring lives as long as the map entry lives intern_get_cstring :: proc(m: ^Intern, text: string) -> cstring { entry := _intern_get_entry(m, text) return cstring(&entry.str[0]) } +// looks up wether the `text` string exists in the map, returns the entry +// sets & allocates the entry if it wasnt set yet _intern_get_entry :: proc(m: ^Intern, text: string) -> ^Intern_Entry #no_bounds_check { if prev, ok := m.entries[text]; ok { return prev diff --git a/core/strings/reader.odin b/core/strings/reader.odin index ba266c0b5..9b2e10b68 100644 --- a/core/strings/reader.odin +++ b/core/strings/reader.odin @@ -3,46 +3,60 @@ package strings import "core:io" import "core:unicode/utf8" +/* + io stream data for a string reader that can read based on bytes or runes + implements the vtable when using the io.Reader variants + "read" calls advance the current reading offset `i` +*/ Reader :: struct { s: string, // read-only buffer i: i64, // current reading index prev_rune: int, // previous reading index of rune or < 0 } +// init the reader to the string `s` reader_init :: proc(r: ^Reader, s: string) { r.s = s r.i = 0 r.prev_rune = -1 } +// returns a stream from the reader data reader_to_stream :: proc(r: ^Reader) -> (s: io.Stream) { s.stream_data = r s.stream_vtable = _reader_vtable return } +// init a reader to the string `s` and return an io.Reader to_reader :: proc(r: ^Reader, s: string) -> io.Reader { reader_init(r, s) rr, _ := io.to_reader(reader_to_stream(r)) return rr } + +// init a reader to the string `s` and return an io.Reader_At to_reader_at :: proc(r: ^Reader, s: string) -> io.Reader_At { reader_init(r, s) rr, _ := io.to_reader_at(reader_to_stream(r)) return rr } + +// init a reader to the string `s` and return an io.Byte_Reader to_byte_reader :: proc(r: ^Reader, s: string) -> io.Byte_Reader { reader_init(r, s) rr, _ := io.to_byte_reader(reader_to_stream(r)) return rr } + +// init a reader to the string `s` and return an io.Rune_Reader to_rune_reader :: proc(r: ^Reader, s: string) -> io.Rune_Reader { reader_init(r, s) rr, _ := io.to_rune_reader(reader_to_stream(r)) return rr } - +// remaining length of the reader reader_length :: proc(r: ^Reader) -> int { if r.i >= i64(len(r.s)) { return 0 @@ -50,10 +64,13 @@ reader_length :: proc(r: ^Reader) -> int { return int(i64(len(r.s)) - r.i) } +// returns the string length stored by the reader reader_size :: proc(r: ^Reader) -> i64 { return i64(len(r.s)) } +// reads len(p) bytes into the slice from the string in the reader +// returns `n` amount of read bytes and an io.Error reader_read :: proc(r: ^Reader, p: []byte) -> (n: int, err: io.Error) { if r.i >= i64(len(r.s)) { return 0, .EOF @@ -63,6 +80,9 @@ reader_read :: proc(r: ^Reader, p: []byte) -> (n: int, err: io.Error) { r.i += i64(n) return } + +// reads len(p) bytes into the slice from the string in the reader at an offset +// returns `n` amount of read bytes and an io.Error reader_read_at :: proc(r: ^Reader, p: []byte, off: i64) -> (n: int, err: io.Error) { if off < 0 { return 0, .Invalid_Offset @@ -76,6 +96,8 @@ reader_read_at :: proc(r: ^Reader, p: []byte, off: i64) -> (n: int, err: io.Erro } return } + +// reads and returns a single byte - error when out of bounds reader_read_byte :: proc(r: ^Reader) -> (byte, io.Error) { r.prev_rune = -1 if r.i >= i64(len(r.s)) { @@ -85,6 +107,8 @@ reader_read_byte :: proc(r: ^Reader) -> (byte, io.Error) { r.i += 1 return b, nil } + +// decreases the reader offset - error when below 0 reader_unread_byte :: proc(r: ^Reader) -> io.Error { if r.i <= 0 { return .Invalid_Unread @@ -93,6 +117,8 @@ reader_unread_byte :: proc(r: ^Reader) -> io.Error { r.i -= 1 return nil } + +// reads and returns a single rune and the rune size - error when out bounds reader_read_rune :: proc(r: ^Reader) -> (ch: rune, size: int, err: io.Error) { if r.i >= i64(len(r.s)) { r.prev_rune = -1 @@ -107,6 +133,9 @@ reader_read_rune :: proc(r: ^Reader) -> (ch: rune, size: int, err: io.Error) { r.i += i64(size) return } + +// decreases the reader offset by the last rune +// can only be used once and after a valid read_rune call reader_unread_rune :: proc(r: ^Reader) -> io.Error { if r.i <= 0 { return .Invalid_Unread @@ -118,6 +147,8 @@ reader_unread_rune :: proc(r: ^Reader) -> io.Error { r.prev_rune = -1 return nil } + +// seeks the reader offset to a wanted offset reader_seek :: proc(r: ^Reader, offset: i64, whence: io.Seek_From) -> (i64, io.Error) { r.prev_rune = -1 abs: i64 @@ -138,6 +169,8 @@ reader_seek :: proc(r: ^Reader, offset: i64, whence: io.Seek_From) -> (i64, io.E r.i = abs return abs, nil } + +// writes the string content left to read into the io.Writer `w` reader_write_to :: proc(r: ^Reader, w: io.Writer) -> (n: i64, err: io.Error) { r.prev_rune = -1 if r.i >= i64(len(r.s)) { @@ -157,7 +190,6 @@ reader_write_to :: proc(r: ^Reader, w: io.Writer) -> (n: i64, err: io.Error) { return } - @(private) _reader_vtable := &io.Stream_VTable{ impl_size = proc(s: io.Stream) -> i64 { diff --git a/core/strings/strings.odin b/core/strings/strings.odin index a8199e0cf..a3d9fa93e 100644 --- a/core/strings/strings.odin +++ b/core/strings/strings.odin @@ -1,17 +1,21 @@ +// simple procedures to manipulate UTF-8 encoded strings package strings import "core:io" import "core:mem" +import "core:slice" import "core:unicode" import "core:unicode/utf8" +// returns a clone of the string `s` allocated using the `allocator` clone :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> string { - c := make([]byte, len(s)+1, allocator, loc) + c := make([]byte, len(s), allocator, loc) copy(c, s) - c[len(s)] = 0 return string(c[:len(s)]) } +// returns a clone of the string `s` allocated using the `allocator` as a cstring +// a nul byte is appended to the clone, to make the cstring safe clone_to_cstring :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> cstring { c := make([]byte, len(s)+1, allocator, loc) copy(c, s) @@ -19,27 +23,35 @@ clone_to_cstring :: proc(s: string, allocator := context.allocator, loc := #call return cstring(&c[0]) } +// returns a string from a byte pointer `ptr` and byte length `len` +// the string is valid as long as the parameters stay alive string_from_ptr :: proc(ptr: ^byte, len: int) -> string { return transmute(string)mem.Raw_String{ptr, len} } +// returns a string from a byte pointer `ptr and byte length `len` +// searches for a nul byte from 0.. string { s := transmute(string)mem.Raw_String{ptr, len} s = truncate_to_byte(s, 0) return s } - +// returns the raw ^byte start of the string `str` ptr_from_string :: proc(str: string) -> ^byte { d := transmute(mem.Raw_String)str return d.data } +// returns the transmute of string `str` to a cstring +// not safe since the origin string may not contain a nul byte unsafe_string_to_cstring :: proc(str: string) -> cstring { d := transmute(mem.Raw_String)str return cstring(d.data) } +// returns a string truncated to the first time it finds the byte `b` +// uses the `len` of the string `str` when it couldn't find the input truncate_to_byte :: proc(str: string, b: byte) -> string { n := index_byte(str, b) if n < 0 { @@ -47,6 +59,9 @@ truncate_to_byte :: proc(str: string, b: byte) -> string { } return str[:n] } + +// returns a string truncated to the first time it finds the rune `r` +// uses the `len` of the string `str` when it couldn't find the input truncate_to_rune :: proc(str: string, r: rune) -> string { n := index_rune(str, r) if n < 0 { @@ -55,20 +70,28 @@ truncate_to_rune :: proc(str: string, r: rune) -> string { return str[:n] } +// returns a cloned string of the byte array `s` using the `allocator` +// appends a leading nul byte clone_from_bytes :: proc(s: []byte, allocator := context.allocator, loc := #caller_location) -> string { c := make([]byte, len(s)+1, allocator, loc) copy(c, s) c[len(s)] = 0 return string(c[:len(s)]) } + +// returns a clone of the cstring `s` using the `allocator` as a string clone_from_cstring :: proc(s: cstring, allocator := context.allocator, loc := #caller_location) -> string { return clone(string(s), allocator, loc) } + +// returns a cloned string from the pointer `ptr` and a byte length `len` using the `allocator` +// same to `string_from_ptr` but allocates clone_from_ptr :: proc(ptr: ^byte, len: int, allocator := context.allocator, loc := #caller_location) -> string { s := string_from_ptr(ptr, len) return clone(s, allocator, loc) } +// overload to clone from a `string`, `[]byte`, `cstring` or a `^byte + length` to a string clone_from :: proc{ clone, clone_from_bytes, @@ -76,6 +99,8 @@ clone_from :: proc{ clone_from_ptr, } +// returns a cloned string from the cstring `ptr` and a byte length `len` using the `allocator` +// truncates till the first nul byte it finds or the byte len clone_from_cstring_bounded :: proc(ptr: cstring, len: int, allocator := context.allocator, loc := #caller_location) -> string { s := string_from_ptr((^u8)(ptr), len) s = truncate_to_byte(s, 0) @@ -83,11 +108,12 @@ clone_from_cstring_bounded :: proc(ptr: cstring, len: int, allocator := context. } // Compares two strings, returning a value representing which one comes first lexiographically. -// -1 for `a`; 1 for `b`, or 0 if they are equal. +// -1 for `lhs`; 1 for `rhs`, or 0 if they are equal. compare :: proc(lhs, rhs: string) -> int { return mem.compare(transmute([]byte)lhs, transmute([]byte)rhs) } +// returns the byte offset of the rune `r` in the string `s`, -1 when not found contains_rune :: proc(s: string, r: rune) -> int { for c, offset in s { if c == r { @@ -97,20 +123,48 @@ contains_rune :: proc(s: string, r: rune) -> int { return -1 } +/* + returns true when the string `substr` is contained inside the string `s` + + strings.contains("testing", "test") -> true + strings.contains("testing", "ing") -> true + strings.contains("testing", "text") -> false +*/ contains :: proc(s, substr: string) -> bool { return index(s, substr) >= 0 } +/* + returns true when the string `s` contains any of the characters inside the string `chars` + + strings.contains_any("test", "test") -> true + strings.contains_any("test", "ts") -> true + strings.contains_any("test", "et") -> true + strings.contains_any("test", "a") -> false +*/ contains_any :: proc(s, chars: string) -> bool { return index_any(s, chars) >= 0 } +/* + returns the utf8 rune count of the string `s` + strings.rune_count("test") -> 4 + strings.rune_count("testö") -> 5, where len("testö") -> 6 +*/ rune_count :: proc(s: string) -> int { return utf8.rune_count_in_string(s) } +/* + returns wether the strings `u` and `v` are the same alpha characters + works with utf8 string content and ignores different casings + strings.equal_fold("test", "test") -> true + strings.equal_fold("Test", "test") -> true + strings.equal_fold("Test", "tEsT") -> true + strings.equal_fold("test", "tes") -> false +*/ equal_fold :: proc(u, v: string) -> bool { s, t := u, v loop: for s != "" && t != "" { @@ -154,15 +208,39 @@ equal_fold :: proc(u, v: string) -> bool { return s == t } +/* + return true when the string `prefix` is contained at the start of the string `s` + + strings.has_prefix("testing", "test") -> true + strings.has_prefix("testing", "te") -> true + strings.has_prefix("telephone", "te") -> true + strings.has_prefix("testing", "est") -> false +*/ has_prefix :: proc(s, prefix: string) -> bool { return len(s) >= len(prefix) && s[0:len(prefix)] == prefix } +/* + returns true when the string `suffix` is contained at the end of the string `s` + good example to use this is for file extensions + + strings.has_suffix("todo.txt", ".txt") -> true + strings.has_suffix("todo.doc", ".txt") -> false + strings.has_suffix("todo.doc.txt", ".txt") -> true +*/ has_suffix :: proc(s, suffix: string) -> bool { return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix } +/* + returns a combined string from the slice of strings `a` seperated with the `sep` string + allocates the string using the `allocator` + a := [?]string { "a", "b", "c" } + b := strings.join(a[:], " ") -> "a b c" + c := strings.join(a[:], "-") -> "a-b-c" + d := strings.join(a[:], "...") -> "a...b...c" +*/ join :: proc(a: []string, sep: string, allocator := context.allocator) -> string { if len(a) == 0 { return "" @@ -182,6 +260,14 @@ join :: proc(a: []string, sep: string, allocator := context.allocator) -> string return string(b) } +/* + returns a combined string from the slice of strings `a` without a seperator + allocates the string using the `allocator` + + + a := [?]string { "a", "b", "c" } + b := strings.concatenate(a[:]) -> "abc" +*/ concatenate :: proc(a: []string, allocator := context.allocator) -> string { if len(a) == 0 { return "" @@ -201,30 +287,56 @@ concatenate :: proc(a: []string, allocator := context.allocator) -> string { /* `rune_offset` and `rune_length` are in runes, not bytes. - If `rune_length` <= 0, then it'll return the remainder of the string starting with `rune_offset`. + If `rune_length` <= 0, then it'll return the remainder of the string starting at `rune_offset`. + + strings.cut("some example text", 0, 4) -> "some" + strings.cut("some example text", 2, 2) -> "me" + strings.cut("some example text", 5, 7) -> "example" */ cut :: proc(s: string, rune_offset := int(0), rune_length := int(0), allocator := context.allocator) -> (res: string) { s := s; rune_length := rune_length - l := utf8.rune_count_in_string(s) + context.allocator = allocator - if rune_offset >= l { return "" } + // If we signal that we want the entire remainder (length <= 0) *and* + // the offset is zero, then we can early out by cloning the input if rune_offset == 0 && rune_length <= 0 { - return clone(s, allocator) + return clone(s) } - if rune_length == 0 { rune_length = l } + // We need to know if we have enough runes to cover offset + length. + rune_count := utf8.rune_count_in_string(s) + + // We're asking for a substring starting after the end of the input string. + // That's just an empty string. + if rune_offset >= rune_count { + return "" + } + + // If we don't specify the length of the substring, use the remainder. + if rune_length <= 0 { + rune_length = rune_count - rune_offset + } + + // We don't yet know how many bytes we need exactly. + // But we do know it's bounded by the number of runes * 4 bytes, + // and can be no more than the size of the input string. bytes_needed := min(rune_length * 4, len(s)) - buf := make([]u8, bytes_needed, allocator) + buf := make([]u8, bytes_needed) byte_offset := 0 - for i := 0; i < l; i += 1 { + for i := 0; i < rune_count; i += 1 { _, w := utf8.decode_rune_in_string(s) + + // If the rune is part of the substring, copy it to the output buffer. if i >= rune_offset { for j := 0; j < w; j += 1 { buf[byte_offset+j] = s[j] } byte_offset += w } + + // We're done if we reach the end of the input string, *or* + // if we've reached a specified length in runes. if rune_length > 0 { if i == rune_offset + rune_length - 1 { break } } @@ -281,28 +393,61 @@ _split :: proc(s_, sep: string, sep_save, n_: int, allocator := context.allocato return res[:i+1] } +/* + Splits a string into parts, based on a separator. + Returned strings are substrings of 's'. + ``` + s := "aaa.bbb.ccc.ddd.eee" // 5 parts + ss := split(s, ".") + fmt.println(ss) // [aaa, bbb, ccc, ddd, eee] + ``` +*/ split :: proc(s, sep: string, allocator := context.allocator) -> []string { return _split(s, sep, 0, -1, allocator) } +/* + Splits a string into a total of 'n' parts, based on a separator. + Returns fewer parts if there wasn't enough occurrences of the separator. + Returned strings are substrings of 's'. + ``` + s := "aaa.bbb.ccc.ddd.eee" // 5 parts present + ss := split_n(s, ".", 3) // total of 3 wanted + fmt.println(ss) // [aaa, bbb, ccc.ddd.eee] + ``` +*/ split_n :: proc(s, sep: string, n: int, allocator := context.allocator) -> []string { return _split(s, sep, 0, n, allocator) } +/* + splits the string `s` after the seperator string `sep` appears + returns the slice of split strings allocated using `allocator` + + a := "aaa.bbb.ccc.ddd.eee" + aa := strings.split_after(a, ".") + fmt.eprintln(aa) // [aaa., bbb., ccc., ddd., eee] +*/ split_after :: proc(s, sep: string, allocator := context.allocator) -> []string { return _split(s, sep, len(sep), -1, allocator) } +/* + splits the string `s` after the seperator string `sep` appears into a total of `n` parts + returns the slice of split strings allocated using `allocator` + + a := "aaa.bbb.ccc.ddd.eee" + aa := strings.split_after(a, ".") + fmt.eprintln(aa) // [aaa., bbb., ccc., ddd., eee] +*/ split_after_n :: proc(s, sep: string, n: int, allocator := context.allocator) -> []string { return _split(s, sep, len(sep), n, allocator) } - @private -_split_iterator :: proc(s: ^string, sep: string, sep_save, n: int) -> (res: string, ok: bool) { - s, n := s, n - - if n == 0 { +_split_iterator :: proc(s: ^string, sep: string, sep_save: int) -> (res: string, ok: bool) { + // stop once the string is empty or nil + if s == nil || len(s^) == 0 { return } @@ -313,51 +458,190 @@ _split_iterator :: proc(s: ^string, sep: string, sep_save, n: int) -> (res: stri return } - if n < 0 { - n = count(s^, sep) + 1 - } - - n -= 1 - - i := 0 - for ; i < n; i += 1 { - m := index(s^, sep) - if m < 0 { - break - } + m := index(s^, sep) + if m < 0 { + // not found + res = s[:] + ok = res != "" + s^ = s[len(s):] + } else { res = s[:m+sep_save] ok = true s^ = s[m+len(sep):] - return } - res = s[:] - ok = res != "" - s^ = s[len(s):] return } +/* + split the ^string `s` by the byte seperator `sep` in an iterator fashion + consumes the original string till the end, leaving the string `s` with len == 0 + text := "a.b.c.d.e" + for str in strings.split_by_byte_iterator(&text, '.') { + fmt.eprintln(str) // every loop -> a b c d e + } +*/ +split_by_byte_iterator :: proc(s: ^string, sep: u8) -> (res: string, ok: bool) { + m := index_byte(s^, sep) + if m < 0 { + // not found + res = s[:] + ok = res != "" + s^ = {} + } else { + res = s[:m] + ok = true + s^ = s[m+1:] + } + return +} + +/* + split the ^string `s` by the seperator string `sep` in an iterator fashion + consumes the original string till the end + + text := "a.b.c.d.e" + for str in strings.split_iterator(&text, ".") { + fmt.eprintln(str) // every loop -> a b c d e + } +*/ split_iterator :: proc(s: ^string, sep: string) -> (string, bool) { - return _split_iterator(s, sep, 0, -1) + return _split_iterator(s, sep, 0) } -split_n_iterator :: proc(s: ^string, sep: string, n: int) -> (string, bool) { - return _split_iterator(s, sep, 0, n) -} +/* + split the ^string `s` after every seperator string `sep` in an iterator fashion + consumes the original string till the end + text := "a.b.c.d.e" + for str in strings.split_after_iterator(&text, ".") { + fmt.eprintln(str) // every loop -> a. b. c. d. e + } +*/ split_after_iterator :: proc(s: ^string, sep: string) -> (string, bool) { - return _split_iterator(s, sep, len(sep), -1) -} - -split_after_n_iterator :: proc(s: ^string, sep: string, n: int) -> (string, bool) { - return _split_iterator(s, sep, len(sep), n) + return _split_iterator(s, sep, len(sep)) } +@(private) +_trim_cr :: proc(s: string) -> string { + n := len(s) + if n > 0 { + if s[n-1] == '\r' { + return s[:n-1] + } + } + return s +} +/* + split the string `s` at every line break '\n' + return an allocated slice of strings + a := "a\nb\nc\nd\ne" + b := strings.split_lines(a) + fmt.eprintln(b) // [a, b, c, d, e] +*/ +split_lines :: proc(s: string, allocator := context.allocator) -> []string { + sep :: "\n" + lines := _split(s, sep, 0, -1, allocator) + for line in &lines { + line = _trim_cr(line) + } + return lines +} +/* + split the string `s` at every line break '\n' for `n` parts + return an allocated slice of strings + a := "a\nb\nc\nd\ne" + b := strings.split_lines_n(a, 3) + fmt.eprintln(b) // [a, b, c, d\ne\n] +*/ +split_lines_n :: proc(s: string, n: int, allocator := context.allocator) -> []string { + sep :: "\n" + lines := _split(s, sep, 0, n, allocator) + for line in &lines { + line = _trim_cr(line) + } + return lines +} + +/* + split the string `s` at every line break '\n' leaving the '\n' in the resulting strings + return an allocated slice of strings + + a := "a\nb\nc\nd\ne" + b := strings.split_lines_after(a) + fmt.eprintln(b) // [a\n, b\n, c\n, d\n, e\n] +*/ +split_lines_after :: proc(s: string, allocator := context.allocator) -> []string { + sep :: "\n" + lines := _split(s, sep, len(sep), -1, allocator) + for line in &lines { + line = _trim_cr(line) + } + return lines +} + +/* + split the string `s` at every line break '\n' leaving the '\n' in the resulting strings + only runs for `n` parts + return an allocated slice of strings + + a := "a\nb\nc\nd\ne" + b := strings.split_lines_after_n(a, 3) + fmt.eprintln(b) // [a\n, b\n, c\n, d\ne\n] +*/ +split_lines_after_n :: proc(s: string, n: int, allocator := context.allocator) -> []string { + sep :: "\n" + lines := _split(s, sep, len(sep), n, allocator) + for line in &lines { + line = _trim_cr(line) + } + return lines +} + +/* + split the string `s` at every line break '\n' + returns the current split string every iteration till the string is consumed + + text := "a\nb\nc\nd\ne" + for str in strings.split_lines_iterator(&text) { + fmt.eprintln(text) // every loop -> a b c d e + } +*/ +split_lines_iterator :: proc(s: ^string) -> (line: string, ok: bool) { + sep :: "\n" + line = _split_iterator(s, sep, 0) or_return + return _trim_cr(line), true +} + +/* + split the string `s` at every line break '\n' + returns the current split string every iteration till the string is consumed + + text := "a\nb\nc\nd\ne" + for str in strings.split_lines_after_iterator(&text) { + fmt.eprintln(text) // every loop -> a\n b\n c\n d\n e\n + } +*/ +split_lines_after_iterator :: proc(s: ^string) -> (line: string, ok: bool) { + sep :: "\n" + line = _split_iterator(s, sep, len(sep)) or_return + return _trim_cr(line), true +} + +/* + returns the byte offset of the first byte `c` in the string `s` it finds, -1 when not found + can't find utf8 based runes + + strings.index_byte("test", 't') -> 0 + strings.index_byte("test", 'e') -> 1 + strings.index_byte("test", 'x') -> -1 + strings.index_byte("teäst", 'ä') -> -1 +*/ index_byte :: proc(s: string, c: byte) -> int { for i := 0; i < len(s); i += 1 { if s[i] == c { @@ -367,7 +651,15 @@ index_byte :: proc(s: string, c: byte) -> int { return -1 } -// Returns -1 if c is not present +/* + returns the byte offset of the last byte `c` in the string `s` it finds, -1 when not found + can't find utf8 based runes + + strings.index_byte("test", 't') -> 3 + strings.index_byte("test", 'e') -> 1 + strings.index_byte("test", 'x') -> -1 + strings.index_byte("teäst", 'ä') -> -1 +*/ last_index_byte :: proc(s: string, c: byte) -> int { for i := len(s)-1; i >= 0; i -= 1 { if s[i] == c { @@ -378,9 +670,50 @@ last_index_byte :: proc(s: string, c: byte) -> int { } +/* + returns the byte offset of the first rune `r` in the string `s` it finds, -1 when not found + avoids invalid runes + + strings.index_rune("abcädef", 'x') -> -1 + strings.index_rune("abcädef", 'a') -> 0 + strings.index_rune("abcädef", 'b') -> 1 + strings.index_rune("abcädef", 'c') -> 2 + strings.index_rune("abcädef", 'ä') -> 3 + strings.index_rune("abcädef", 'd') -> 5 + strings.index_rune("abcädef", 'e') -> 6 + strings.index_rune("abcädef", 'f') -> 7 +*/ +index_rune :: proc(s: string, r: rune) -> int { + switch { + case 0 <= r && r < utf8.RUNE_SELF: + return index_byte(s, byte(r)) + + case r == utf8.RUNE_ERROR: + for c, i in s { + if c == utf8.RUNE_ERROR { + return i + } + } + return -1 + + case !utf8.valid_rune(r): + return -1 + } + + b, w := utf8.encode_rune(r) + return index(s, string(b[:w])) +} @private PRIME_RABIN_KARP :: 16777619 +/* + returns the byte offset of the string `substr` in the string `s`, -1 when not found + + strings.index("test", "t") -> 0 + strings.index("test", "te") -> 0 + strings.index("test", "st") -> 2 + strings.index("test", "tt") -> -1 +*/ index :: proc(s, substr: string) -> int { hash_str_rabin_karp :: proc(s: string) -> (hash: u32 = 0, pow: u32 = 1) { for i := 0; i < len(s); i += 1 { @@ -431,6 +764,14 @@ index :: proc(s, substr: string) -> int { return -1 } +/* + returns the last byte offset of the string `substr` in the string `s`, -1 when not found + + strings.index("test", "t") -> 3 + strings.index("test", "te") -> 0 + strings.index("test", "st") -> 2 + strings.index("test", "tt") -> -1 +*/ last_index :: proc(s, substr: string) -> int { hash_str_rabin_karp_reverse :: proc(s: string) -> (hash: u32 = 0, pow: u32 = 1) { for i := len(s) - 1; i >= 0; i -= 1 { @@ -479,7 +820,15 @@ last_index :: proc(s, substr: string) -> int { return -1 } -// index_any returns the index of the first char of `chars` found in `s`. -1 if not found. +/* + returns the index of any first char of `chars` found in `s`, -1 if not found + + strings.index_any("test", "s") -> 2 + strings.index_any("test", "se") -> 1 + strings.index_any("test", "et") -> 0 + strings.index_any("test", "set") -> 0 + strings.index_any("test", "x") -> -1 +*/ index_any :: proc(s, chars: string) -> int { if chars == "" { return -1 @@ -504,14 +853,24 @@ index_any :: proc(s, chars: string) -> int { } } - for c in chars { - if i := index_rune(s, c); i >= 0 { + for c, i in s { + if index_rune(chars, c) >= 0 { return i } } return -1 } +/* + returns the index of any first char of `chars` found in `s`, -1 if not found + iterates the string in reverse + + strings.index_any("test", "s") -> 2 + strings.index_any("test", "se") -> 2 + strings.index_any("test", "et") -> 1 + strings.index_any("test", "set") -> 3 + strings.index_any("test", "x") -> -1 +*/ last_index_any :: proc(s, chars: string) -> int { if chars == "" { return -1 @@ -561,6 +920,16 @@ last_index_any :: proc(s, chars: string) -> int { return -1 } +/* + returns the count of the string `substr` found in the string `s` + returns the rune_count + 1 of the string `s` on empty `substr` + + strings.count("abbccc", "a") -> 1 + strings.count("abbccc", "b") -> 2 + strings.count("abbccc", "c") -> 3 + strings.count("abbccc", "ab") -> 1 + strings.count("abbccc", " ") -> 0 +*/ count :: proc(s, substr: string) -> int { if len(substr) == 0 { // special case return rune_count(s) + 1 @@ -596,7 +965,12 @@ count :: proc(s, substr: string) -> int { return n } +/* + repeats the string `s` multiple `count` times and returns the allocated string + panics when `count` is below 0 + strings.repeat("abc", 2) -> "abcabc" +*/ repeat :: proc(s: string, count: int, allocator := context.allocator) -> string { if count < 0 { panic("strings: negative repeat count") @@ -613,11 +987,28 @@ repeat :: proc(s: string, count: int, allocator := context.allocator) -> string return string(b) } +/* + replaces all instances of `old` in the string `s` with the `new` string + returns the `output` string and true when an a allocation through a replace happened + + strings.replace_all("xyzxyz", "xyz", "abc") -> "abcabc", true + strings.replace_all("xyzxyz", "abc", "xyz") -> "xyzxyz", false + strings.replace_all("xyzxyz", "xy", "z") -> "zzzz", true +*/ replace_all :: proc(s, old, new: string, allocator := context.allocator) -> (output: string, was_allocation: bool) { return replace(s, old, new, -1, allocator) } -// if n < 0, no limit on the number of replacements +/* + replaces `n` instances of `old` in the string `s` with the `new` string + if n < 0, no limit on the number of replacements + returns the `output` string and true when an a allocation through a replace happened + + strings.replace("xyzxyz", "xyz", "abc", 2) -> "abcabc", true + strings.replace("xyzxyz", "xyz", "abc", 1) -> "abcxyz", true + strings.replace("xyzxyz", "abc", "xyz", -1) -> "xyzxyz", false + strings.replace("xyzxyz", "xy", "z", -1) -> "zzzz", true +*/ replace :: proc(s, old, new: string, n: int, allocator := context.allocator) -> (output: string, was_allocation: bool) { if old == new || n == 0 { was_allocation = false @@ -658,17 +1049,35 @@ replace :: proc(s, old, new: string, n: int, allocator := context.allocator) -> return } +/* + removes the `key` string `n` times from the `s` string + if n < 0, no limit on the number of removes + returns the `output` string and true when an a allocation through a remove happened + + strings.remove("abcabc", "abc", 1) -> "abc", true + strings.remove("abcabc", "abc", -1) -> "", true + strings.remove("abcabc", "a", -1) -> "bcbc", true + strings.remove("abcabc", "x", -1) -> "abcabc", false +*/ remove :: proc(s, key: string, n: int, allocator := context.allocator) -> (output: string, was_allocation: bool) { return replace(s, key, "", n, allocator) } +/* + removes all the `key` string instanes from the `s` string + returns the `output` string and true when an a allocation through a remove happened + + strings.remove("abcabc", "abc") -> "", true + strings.remove("abcabc", "a") -> "bcbc", true + strings.remove("abcabc", "x") -> "abcabc", false +*/ remove_all :: proc(s, key: string, allocator := context.allocator) -> (output: string, was_allocation: bool) { return remove(s, key, -1, allocator) } @(private) _ascii_space := [256]bool{'\t' = true, '\n' = true, '\v' = true, '\f' = true, '\r' = true, ' ' = true} - +// return true when the `r` rune is '\t', '\n', '\v', '\f', '\r' or ' ' is_ascii_space :: proc(r: rune) -> bool { if r < utf8.RUNE_SELF { return _ascii_space[u8(r)] @@ -676,6 +1085,7 @@ is_ascii_space :: proc(r: rune) -> bool { return false } +// returns true when the `r` rune is any asci or utf8 based whitespace is_space :: proc(r: rune) -> bool { if r < 0x2000 { switch r { @@ -694,10 +1104,24 @@ is_space :: proc(r: rune) -> bool { return false } +// returns true when the `r` rune is a nul byte is_null :: proc(r: rune) -> bool { return r == 0x0000 } +/* + runs trough the `s` string linearly and watches wether the `p` procedure matches the `truth` bool + returns the rune offset or -1 when no match was found + + call :: proc(r: rune) -> bool { + return r == 'a' + } + strings.index_proc("abcabc", call) -> 0 + strings.index_proc("cbacba", call) -> 2 + strings.index_proc("cbacba", call, false) -> 0 + strings.index_proc("abcabc", call, false) -> 1 + strings.index_proc("xyz", call) -> -1 +*/ index_proc :: proc(s: string, p: proc(rune) -> bool, truth := true) -> int { for r, i in s { if p(r) == truth { @@ -707,6 +1131,7 @@ index_proc :: proc(s: string, p: proc(rune) -> bool, truth := true) -> int { return -1 } +// same as `index_proc` but with a `p` procedure taking a rawptr for state index_proc_with_state :: proc(s: string, p: proc(rawptr, rune) -> bool, state: rawptr, truth := true) -> int { for r, i in s { if p(state, r) == truth { @@ -716,6 +1141,7 @@ index_proc_with_state :: proc(s: string, p: proc(rawptr, rune) -> bool, state: r return -1 } +// same as `index_proc` but runs through the string in reverse last_index_proc :: proc(s: string, p: proc(rune) -> bool, truth := true) -> int { // TODO(bill): Probably use Rabin-Karp Search for i := len(s); i > 0; { @@ -728,6 +1154,7 @@ last_index_proc :: proc(s: string, p: proc(rune) -> bool, truth := true) -> int return -1 } +// same as `index_proc_with_state` but runs through the string in reverse last_index_proc_with_state :: proc(s: string, p: proc(rawptr, rune) -> bool, state: rawptr, truth := true) -> int { // TODO(bill): Probably use Rabin-Karp Search for i := len(s); i > 0; { @@ -739,7 +1166,17 @@ last_index_proc_with_state :: proc(s: string, p: proc(rawptr, rune) -> bool, sta } return -1 } + +/* + trims the input string `s` until the procedure `p` returns false + does not allocate - only returns a cut variant of the input string + returns an empty string when no match was found at all + find :: proc(r: rune) -> bool { + return r != 'i' + } + strings.trim_left_proc("testing", find) -> "ing" +*/ trim_left_proc :: proc(s: string, p: proc(rune) -> bool) -> string { i := index_proc(s, p, false) if i == -1 { @@ -748,29 +1185,10 @@ trim_left_proc :: proc(s: string, p: proc(rune) -> bool) -> string { return s[i:] } - -index_rune :: proc(s: string, r: rune) -> int { - switch { - case 0 <= r && r < utf8.RUNE_SELF: - return index_byte(s, byte(r)) - - case r == utf8.RUNE_ERROR: - for c, i in s { - if c == utf8.RUNE_ERROR { - return i - } - } - return -1 - - case !utf8.valid_rune(r): - return -1 - } - - b, w := utf8.encode_rune(r) - return index(s, string(b[:w])) -} - - +/* + trims the input string `s` until the procedure `p` with state returns false + returns an empty string when no match was found at all +*/ trim_left_proc_with_state :: proc(s: string, p: proc(rawptr, rune) -> bool, state: rawptr) -> string { i := index_proc_with_state(s, p, state, false) if i == -1 { @@ -779,6 +1197,16 @@ trim_left_proc_with_state :: proc(s: string, p: proc(rawptr, rune) -> bool, stat return s[i:] } +/* + trims the input string `s` from the right until the procedure `p` returns false + does not allocate - only returns a cut variant of the input string + returns an empty string when no match was found at all + + find :: proc(r: rune) -> bool { + return r != 't' + } + strings.trim_left_proc("testing", find) -> "test" +*/ trim_right_proc :: proc(s: string, p: proc(rune) -> bool) -> string { i := last_index_proc(s, p, false) if i >= 0 && s[i] >= utf8.RUNE_SELF { @@ -790,6 +1218,10 @@ trim_right_proc :: proc(s: string, p: proc(rune) -> bool) -> string { return s[0:i] } +/* + trims the input string `s` from the right until the procedure `p` with state returns false + returns an empty string when no match was found at all +*/ trim_right_proc_with_state :: proc(s: string, p: proc(rawptr, rune) -> bool, state: rawptr) -> string { i := last_index_proc_with_state(s, p, state, false) if i >= 0 && s[i] >= utf8.RUNE_SELF { @@ -801,7 +1233,7 @@ trim_right_proc_with_state :: proc(s: string, p: proc(rawptr, rune) -> bool, sta return s[0:i] } - +// procedure for `trim_*_proc` variants, which has a string rawptr cast + rune comparison is_in_cutset :: proc(state: rawptr, r: rune) -> bool { if state == nil { return false @@ -815,7 +1247,7 @@ is_in_cutset :: proc(state: rawptr, r: rune) -> bool { return false } - +// trims the `cutset` string from the `s` string trim_left :: proc(s: string, cutset: string) -> string { if s == "" || cutset == "" { return s @@ -824,6 +1256,7 @@ trim_left :: proc(s: string, cutset: string) -> string { return trim_left_proc_with_state(s, is_in_cutset, &state) } +// trims the `cutset` string from the `s` string from the right trim_right :: proc(s: string, cutset: string) -> string { if s == "" || cutset == "" { return s @@ -832,35 +1265,48 @@ trim_right :: proc(s: string, cutset: string) -> string { return trim_right_proc_with_state(s, is_in_cutset, &state) } +// trims the `cutset` string from the `s` string, both from left and right trim :: proc(s: string, cutset: string) -> string { return trim_right(trim_left(s, cutset), cutset) } +// trims until a valid non space rune: "\t\txyz\t\t" -> "xyz\t\t" trim_left_space :: proc(s: string) -> string { return trim_left_proc(s, is_space) } +// trims from the right until a valid non space rune: "\t\txyz\t\t" -> "\t\txyz" trim_right_space :: proc(s: string) -> string { return trim_right_proc(s, is_space) } +// trims from both sides until a valid non space rune: "\t\txyz\t\t" -> "xyz" trim_space :: proc(s: string) -> string { return trim_right_space(trim_left_space(s)) } - +// trims nul runes from the left: "\x00\x00testing\x00\x00" -> "testing\x00\x00" trim_left_null :: proc(s: string) -> string { return trim_left_proc(s, is_null) } +// trims nul runes from the right: "\x00\x00testing\x00\x00" -> "\x00\x00testing" trim_right_null :: proc(s: string) -> string { return trim_right_proc(s, is_null) } +// trims nul runes from both sides: "\x00\x00testing\x00\x00" -> "testing" trim_null :: proc(s: string) -> string { return trim_right_null(trim_left_null(s)) } +/* + trims a `prefix` string from the start of the `s` string and returns the trimmed string + returns the input string `s` when no prefix was found + + strings.trim_prefix("testing", "test") -> "ing" + strings.trim_prefix("testing", "abc") -> "testing" +*/ trim_prefix :: proc(s, prefix: string) -> string { if has_prefix(s, prefix) { return s[len(prefix):] @@ -868,6 +1314,13 @@ trim_prefix :: proc(s, prefix: string) -> string { return s } +/* + trims a `suffix` string from the end of the `s` string and returns the trimmed string + returns the input string `s` when no suffix was found + + strings.trim_suffix("todo.txt", ".txt") -> "todo" + strings.trim_suffix("todo.doc", ".txt") -> "todo.doc" +*/ trim_suffix :: proc(s, suffix: string) -> string { if has_suffix(s, suffix) { return s[:len(s)-len(suffix)] @@ -875,142 +1328,151 @@ trim_suffix :: proc(s, suffix: string) -> string { return s } -split_multi :: proc(s: string, substrs: []string, skip_empty := false, allocator := context.allocator) -> []string #no_bounds_check { +/* + splits the input string `s` by all possible `substrs` []string + returns the allocated []string, nil on any empty substring or no matches + + splits := [?]string { "---", "~~~", ".", "_", "," } + res := strings.split_multi("testing,this.out_nice---done~~~last", splits[:]) + fmt.eprintln(res) // -> [testing, this, out, nice, done, last] +*/ +split_multi :: proc(s: string, substrs: []string, allocator := context.allocator) -> (buf: []string) #no_bounds_check { if s == "" || len(substrs) <= 0 { - return nil + return } - sublen := len(substrs[0]) - - for substr in substrs[1:] { - sublen = min(sublen, len(substr)) + // disallow "" substr + for substr in substrs { + if len(substr) == 0 { + return + } } - shared := len(s) - sublen + // TODO maybe remove duplicate substrs + // sort substrings by string size, largest to smallest + temp_substrs := slice.clone(substrs, context.temp_allocator) + slice.sort_by(temp_substrs, proc(a, b: string) -> bool { + return len(a) > len(b) + }) - if shared <= 0 { - return nil - } + substrings_found: int + temp := s - // number, index, last - n, i, l := 0, 0, 0 - - // count results - first_pass: for i <= shared { - for substr in substrs { - if s[i:i+sublen] == substr { - if !skip_empty || i - l > 0 { - n += 1 - } - - i += sublen - l = i + // count substr results found in string + first_pass: for len(temp) > 0 { + for substr in temp_substrs { + size := len(substr) + // check range and compare string to substr + if size <= len(temp) && temp[:size] == substr { + substrings_found += 1 + temp = temp[size:] continue first_pass } } - _, skip := utf8.decode_rune_in_string(s[i:]) - i += skip + // step through string + _, skip := utf8.decode_rune_in_string(temp[:]) + temp = temp[skip:] } - if !skip_empty || len(s) - l > 0 { - n += 1 + // skip when no results + if substrings_found < 1 { + return } - if n < 1 { - // no results - return nil - } + buf = make([]string, substrings_found + 1, allocator) + buf_index: int + temp = s + temp_old := temp - buf := make([]string, n, allocator) - - n, i, l = 0, 0, 0 - - // slice results - second_pass: for i <= shared { - for substr in substrs { - if s[i:i+sublen] == substr { - if !skip_empty || i - l > 0 { - buf[n] = s[l:i] - n += 1 - } - - i += sublen - l = i + // gather results in the same fashion + second_pass: for len(temp) > 0 { + for substr in temp_substrs { + size := len(substr) + // check range and compare string to substr + if size <= len(temp) && temp[:size] == substr { + buf[buf_index] = temp_old[:len(temp_old) - len(temp)] + buf_index += 1 + temp = temp[size:] + temp_old = temp continue second_pass } } - _, skip := utf8.decode_rune_in_string(s[i:]) - i += skip + // step through string + _, skip := utf8.decode_rune_in_string(temp[:]) + temp = temp[skip:] } - if !skip_empty || len(s) - l > 0 { - buf[n] = s[l:] - } + buf[buf_index] = temp_old[:] return buf } +// state for the split multi iterator +Split_Multi :: struct { + temp: string, + temp_old: string, + substrs: []string, +} +// returns split multi state with sorted `substrs` +split_multi_init :: proc(s: string, substrs: []string) -> Split_Multi { + // sort substrings, largest to smallest + temp_substrs := slice.clone(substrs, context.temp_allocator) + slice.sort_by(temp_substrs, proc(a, b: string) -> bool { + return len(a) > len(b) + }) - -split_multi_iterator :: proc(s: ^string, substrs: []string, skip_empty := false) -> (string, bool) #no_bounds_check { - if s == nil || s^ == "" || len(substrs) <= 0 { - return "", false + return { + temp = s, + temp_old = s, + substrs = temp_substrs, } +} - sublen := len(substrs[0]) +/* + splits the input string `s` by all possible `substrs` []string in an iterator fashion + returns the split string every iteration, the full string on no match - for substr in substrs[1:] { - sublen = min(sublen, len(substr)) + splits := [?]string { "---", "~~~", ".", "_", "," } + state := strings.split_multi_init("testing,this.out_nice---done~~~last", splits[:]) + for str in strings.split_multi_iterate(&state) { + fmt.eprintln(str) // every iteration -> [testing, this, out, nice, done, last] } - - shared := len(s) - sublen - - if shared <= 0 { - return "", false - } - - // index, last - i, l := 0, 0 - - loop: for i <= shared { +*/ +split_multi_iterate :: proc(using sm: ^Split_Multi) -> (res: string, ok: bool) #no_bounds_check { + pass: for len(temp) > 0 { for substr in substrs { - if s[i:i+sublen] == substr { - if !skip_empty || i - l > 0 { - res := s[l:i] - s^ = s[i:] - return res, true - } + size := len(substr) - i += sublen - l = i - - continue loop + // check range and compare string to substr + if size <= len(temp) && temp[:size] == substr { + res = temp_old[:len(temp_old) - len(temp)] + temp = temp[size:] + temp_old = temp + ok = true + return } } - _, skip := utf8.decode_rune_in_string(s[i:]) - i += skip + // step through string + _, skip := utf8.decode_rune_in_string(temp[:]) + temp = temp[skip:] } - if !skip_empty || len(s) - l > 0 { - res := s[l:] - s^ = s[len(s):] - return res, true + // allow last iteration + if temp_old != "" { + res = temp_old[:] + ok = true + temp_old = "" } - return "", false + return } - - - - - // scrub scruvs invalid utf-8 characters and replaces them with the replacement string // Adjacent invalid bytes are only replaced once scrub :: proc(s: string, replacement: string, allocator := context.allocator) -> string { @@ -1045,7 +1507,13 @@ scrub :: proc(s: string, replacement: string, allocator := context.allocator) -> return to_string(b) } +/* + returns a reversed version of the `s` string + a := "abcxyz" + b := strings.reverse(a) + fmt.eprintln(a, b) // abcxyz zyxcba +*/ reverse :: proc(s: string, allocator := context.allocator) -> string { str := s n := len(str) @@ -1061,12 +1529,19 @@ reverse :: proc(s: string, allocator := context.allocator) -> string { return string(buf) } +/* + expands the string to a grid spaced by `tab_size` whenever a `\t` character appears + returns the tabbed string, panics on tab_size <= 0 + + strings.expand_tabs("abc1\tabc2\tabc3", 4) -> abc1 abc2 abc3 + strings.expand_tabs("abc1\tabc2\tabc3", 5) -> abc1 abc2 abc3 + strings.expand_tabs("abc1\tabc2\tabc3", 6) -> abc1 abc2 abc3 +*/ expand_tabs :: proc(s: string, tab_size: int, allocator := context.allocator) -> string { if tab_size <= 0 { panic("tab size must be positive") } - if s == "" { return "" } @@ -1104,7 +1579,16 @@ expand_tabs :: proc(s: string, tab_size: int, allocator := context.allocator) -> return to_string(b) } +/* + splits the `str` string by the seperator `sep` string and returns 3 parts + `head`: before the split, `match`: the seperator, `tail`: the end of the split + returns the input string when the `sep` was not found + text := "testing this out" + strings.partition(text, " this ") -> head: "testing", match: " this ", tail: "out" + strings.partition(text, "hi") -> head: "testing t", match: "hi", tail: "s out" + strings.partition(text, "xyz") -> head: "testing this out", match: "", tail: "" +*/ partition :: proc(str, sep: string) -> (head, match, tail: string) { i := index(str, sep) if i == -1 { @@ -1288,8 +1772,102 @@ fields_proc :: proc(s: string, f: proc(rune) -> bool, allocator := context.alloc } if start >= 0 { - append(&substrings, s[start : end]) + append(&substrings, s[start : len(s)]) } return substrings[:] } + + +// `fields_iterator` returns the first run of characters in `s` that does not contain white space, defined by `unicode.is_space` +// `s` will then start from any space after the substring, or be an empty string if the substring was the remaining characters +fields_iterator :: proc(s: ^string) -> (field: string, ok: bool) { + start, end := -1, -1 + for r, offset in s { + end = offset + if unicode.is_space(r) { + if start >= 0 { + field = s[start : end] + ok = true + s^ = s[end:] + return + } + } else { + if start < 0 { + start = end + } + } + } + + // if either of these are true, the string did not contain any characters + if end < 0 || start < 0 { + return "", false + } + + field = s[start:] + ok = true + s^ = s[len(s):] + return +} + +// `levenshtein_distance` returns the Levenshtein edit distance between 2 strings. +// This is a single-row-version of the Wagner–Fischer algorithm, based on C code by Martin Ettl. +// Note: allocator isn't used if the length of string b in runes is smaller than 64. +levenshtein_distance :: proc(a, b: string, allocator := context.allocator) -> int { + LEVENSHTEIN_DEFAULT_COSTS: []int : { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, + } + + m, n := utf8.rune_count_in_string(a), utf8.rune_count_in_string(b) + + if m == 0 { + return n + } + if n == 0 { + return m + } + + costs: []int + + if n + 1 > len(LEVENSHTEIN_DEFAULT_COSTS) { + costs = make([]int, n + 1, allocator) + for k in 0..=n { + costs[k] = k + } + } else { + costs = LEVENSHTEIN_DEFAULT_COSTS + } + + defer if n + 1 > len(LEVENSHTEIN_DEFAULT_COSTS) { + delete(costs, allocator) + } + + i: int + for c1 in a { + costs[0] = i + 1 + corner := i + j: int + for c2 in b { + upper := costs[j + 1] + if c1 == c2 { + costs[j + 1] = corner + } else { + t := upper if upper < corner else corner + costs[j + 1] = (costs[j] if costs[j] < t else t) + 1 + } + + corner = upper + j += 1 + } + + i += 1 + } + + return costs[n] +} diff --git a/core/sync/atomic.odin b/core/sync/atomic.odin index 21dcea178..f537764c4 100644 --- a/core/sync/atomic.odin +++ b/core/sync/atomic.odin @@ -2,167 +2,44 @@ package sync import "core:intrinsics" -Ordering :: enum { - Relaxed, // Monotonic - Release, - Acquire, - Acquire_Release, - Sequentially_Consistent, -} - -strongest_failure_ordering_table := [Ordering]Ordering{ - .Relaxed = .Relaxed, - .Release = .Relaxed, - .Acquire = .Acquire, - .Acquire_Release = .Acquire, - .Sequentially_Consistent = .Sequentially_Consistent, -} - -strongest_failure_ordering :: #force_inline proc(order: Ordering) -> Ordering { - return strongest_failure_ordering_table[order] -} - -fence :: #force_inline proc($order: Ordering) { - when order == .Relaxed { #panic("there is no such thing as a relaxed fence") } - else when order == .Release { intrinsics.atomic_fence_rel() } - else when order == .Acquire { intrinsics.atomic_fence_acq() } - else when order == .Acquire_Release { intrinsics.atomic_fence_acqrel() } - else when order == .Sequentially_Consistent { intrinsics.atomic_fence() } - else { #panic("unknown order") } +cpu_relax :: intrinsics.cpu_relax + +/* +Atomic_Memory_Order :: enum { + Relaxed = 0, + Consume = 1, + Acquire = 2, + Release = 3, + Acq_Rel = 4, + Seq_Cst = 5, } +*/ +Atomic_Memory_Order :: intrinsics.Atomic_Memory_Order -atomic_store :: #force_inline proc(dst: ^$T, val: T, $order: Ordering) { - when order == .Relaxed { intrinsics.atomic_store_relaxed(dst, val) } - else when order == .Release { intrinsics.atomic_store_rel(dst, val) } - else when order == .Sequentially_Consistent { intrinsics.atomic_store(dst, val) } - else when order == .Acquire { #panic("there is not such thing as an acquire store") } - else when order == .Acquire_Release { #panic("there is not such thing as an acquire/release store") } - else { #panic("unknown order") } -} - -atomic_load :: #force_inline proc(dst: ^$T, $order: Ordering) -> T { - when order == .Relaxed { return intrinsics.atomic_load_relaxed(dst) } - else when order == .Acquire { return intrinsics.atomic_load_acq(dst) } - else when order == .Sequentially_Consistent { return intrinsics.atomic_load(dst) } - else when order == .Release { #panic("there is no such thing as a release load") } - else when order == .Acquire_Release { #panic("there is no such thing as an acquire/release load") } - else { #panic("unknown order") } -} - -atomic_swap :: #force_inline proc(dst: ^$T, val: T, $order: Ordering) -> T { - when order == .Relaxed { return intrinsics.atomic_xchg_relaxed(dst, val) } - else when order == .Release { return intrinsics.atomic_xchg_rel(dst, val) } - else when order == .Acquire { return intrinsics.atomic_xchg_acq(dst, val) } - else when order == .Acquire_Release { return intrinsics.atomic_xchg_acqrel(dst, val) } - else when order == .Sequentially_Consistent { return intrinsics.atomic_xchg(dst, val) } - else { #panic("unknown order") } -} - -atomic_compare_exchange :: #force_inline proc(dst: ^$T, old, new: T, $success, $failure: Ordering) -> (val: T, ok: bool) { - when failure == .Relaxed { - when success == .Relaxed { return intrinsics.atomic_cxchg_relaxed(dst, old, new) } - else when success == .Acquire { return intrinsics.atomic_cxchg_acq_failrelaxed(dst, old, new) } - else when success == .Acquire_Release { return intrinsics.atomic_cxchg_acqrel_failrelaxed(dst, old, new) } - else when success == .Sequentially_Consistent { return intrinsics.atomic_cxchg_failrelaxed(dst, old, new) } - else when success == .Release { return intrinsics.atomic_cxchg_rel(dst, old, new) } - else { #panic("an unknown ordering combination") } - } else when failure == .Acquire { - when success == .Release { return intrinsics.atomic_cxchg_acqrel(dst, old, new) } - else when success == .Acquire { return intrinsics.atomic_cxchg_acq(dst, old, new) } - else { #panic("an unknown ordering combination") } - } else when failure == .Sequentially_Consistent { - when success == .Sequentially_Consistent { return intrinsics.atomic_cxchg(dst, old, new) } - else { #panic("an unknown ordering combination") } - } else when failure == .Acquire_Release { - #panic("there is not such thing as an acquire/release failure ordering") - } else when failure == .Release { - when success == .Acquire { return instrinsics.atomic_cxchg_failacq(dst, old, new) } - else { #panic("an unknown ordering combination") } - } else { - return T{}, false - } - -} - -atomic_compare_exchange_weak :: #force_inline proc(dst: ^$T, old, new: T, $success, $failure: Ordering) -> (val: T, ok: bool) { - when failure == .Relaxed { - when success == .Relaxed { return intrinsics.atomic_cxchgweak_relaxed(dst, old, new) } - else when success == .Acquire { return intrinsics.atomic_cxchgweak_acq_failrelaxed(dst, old, new) } - else when success == .Acquire_Release { return intrinsics.atomic_cxchgweak_acqrel_failrelaxed(dst, old, new) } - else when success == .Sequentially_Consistent { return intrinsics.atomic_cxchgweak_failrelaxed(dst, old, new) } - else when success == .Release { return intrinsics.atomic_cxchgweak_rel(dst, old, new) } - else { #panic("an unknown ordering combination") } - } else when failure == .Acquire { - when success == .Release { return intrinsics.atomic_cxchgweak_acqrel(dst, old, new) } - else when success == .Acquire { return intrinsics.atomic_cxchgweak_acq(dst, old, new) } - else { #panic("an unknown ordering combination") } - } else when failure == .Sequentially_Consistent { - when success == .Sequentially_Consistent { return intrinsics.atomic_cxchgweak(dst, old, new) } - else { #panic("an unknown ordering combination") } - } else when failure == .Acquire_Release { - #panic("there is not such thing as an acquire/release failure ordering") - } else when failure == .Release { - when success == .Acquire { return intrinsics.atomic_cxchgweak_failacq(dst, old, new) } - else { #panic("an unknown ordering combination") } - } else { - return T{}, false - } - -} - - -atomic_add :: #force_inline proc(dst: ^$T, val: T, $order: Ordering) -> T { - when order == .Relaxed { return intrinsics.atomic_add_relaxed(dst, val) } - else when order == .Release { return intrinsics.atomic_add_rel(dst, val) } - else when order == .Acquire { return intrinsics.atomic_add_acq(dst, val) } - else when order == .Acquire_Release { return intrinsics.atomic_add_acqrel(dst, val) } - else when order == .Sequentially_Consistent { return intrinsics.atomic_add(dst, val) } - else { #panic("unknown order") } -} - -atomic_sub :: #force_inline proc(dst: ^$T, val: T, $order: Ordering) -> T { - when order == .Relaxed { return intrinsics.atomic_sub_relaxed(dst, val) } - else when order == .Release { return intrinsics.atomic_sub_rel(dst, val) } - else when order == .Acquire { return intrinsics.atomic_sub_acq(dst, val) } - else when order == .Acquire_Release { return intrinsics.atomic_sub_acqrel(dst, val) } - else when order == .Sequentially_Consistent { return intrinsics.atomic_sub(dst, val) } - else { #panic("unknown order") } -} - -atomic_and :: #force_inline proc(dst: ^$T, val: T, $order: Ordering) -> T { - when order == .Relaxed { return intrinsics.atomic_and_relaxed(dst, val) } - else when order == .Release { return intrinsics.atomic_and_rel(dst, val) } - else when order == .Acquire { return intrinsics.atomic_and_acq(dst, val) } - else when order == .Acquire_Release { return intrinsics.atomic_and_acqrel(dst, val) } - else when order == .Sequentially_Consistent { return intrinsics.atomic_and(dst, val) } - else { #panic("unknown order") } -} - -atomic_nand :: #force_inline proc(dst: ^$T, val: T, $order: Ordering) -> T { - when order == .Relaxed { return intrinsics.atomic_nand_relaxed(dst, val) } - else when order == .Release { return intrinsics.atomic_nand_rel(dst, val) } - else when order == .Acquire { return intrinsics.atomic_nand_acq(dst, val) } - else when order == .Acquire_Release { return intrinsics.atomic_nand_acqrel(dst, val) } - else when order == .Sequentially_Consistent { return intrinsics.atomic_nand(dst, val) } - else { #panic("unknown order") } -} - -atomic_or :: #force_inline proc(dst: ^$T, val: T, $order: Ordering) -> T { - when order == .Relaxed { return intrinsics.atomic_or_relaxed(dst, val) } - else when order == .Release { return intrinsics.atomic_or_rel(dst, val) } - else when order == .Acquire { return intrinsics.atomic_or_acq(dst, val) } - else when order == .Acquire_Release { return intrinsics.atomic_or_acqrel(dst, val) } - else when order == .Sequentially_Consistent { return intrinsics.atomic_or(dst, val) } - else { #panic("unknown order") } -} - -atomic_xor :: #force_inline proc(dst: ^$T, val: T, $order: Ordering) -> T { - when order == .Relaxed { return intrinsics.atomic_xor_relaxed(dst, val) } - else when order == .Release { return intrinsics.atomic_xor_rel(dst, val) } - else when order == .Acquire { return intrinsics.atomic_xor_acq(dst, val) } - else when order == .Acquire_Release { return intrinsics.atomic_xor_acqrel(dst, val) } - else when order == .Sequentially_Consistent { return intrinsics.atomic_xor(dst, val) } - else { #panic("unknown order") } -} +atomic_thread_fence :: intrinsics.atomic_thread_fence +atomic_signal_fence :: intrinsics.atomic_signal_fence +atomic_store :: intrinsics.atomic_store +atomic_store_explicit :: intrinsics.atomic_store_explicit +atomic_load :: intrinsics.atomic_load +atomic_load_explicit :: intrinsics.atomic_load_explicit +atomic_add :: intrinsics.atomic_add +atomic_add_explicit :: intrinsics.atomic_add_explicit +atomic_sub :: intrinsics.atomic_sub +atomic_sub_explicit :: intrinsics.atomic_sub_explicit +atomic_and :: intrinsics.atomic_and +atomic_and_explicit :: intrinsics.atomic_and_explicit +atomic_nand :: intrinsics.atomic_nand +atomic_nand_explicit :: intrinsics.atomic_nand_explicit +atomic_or :: intrinsics.atomic_or +atomic_or_explicit :: intrinsics.atomic_or_explicit +atomic_xor :: intrinsics.atomic_xor +atomic_xor_explicit :: intrinsics.atomic_xor_explicit +atomic_exchange :: intrinsics.atomic_exchange +atomic_exchange_explicit :: intrinsics.atomic_exchange_explicit +// Returns value and optional ok boolean +atomic_compare_exchange_strong :: intrinsics.atomic_compare_exchange_strong +atomic_compare_exchange_strong_explicit :: intrinsics.atomic_compare_exchange_strong_explicit +atomic_compare_exchange_weak :: intrinsics.atomic_compare_exchange_weak +atomic_compare_exchange_weak_explicit :: intrinsics.atomic_compare_exchange_weak_explicit \ No newline at end of file diff --git a/core/sync/barrier.odin b/core/sync/barrier.odin deleted file mode 100644 index 997fde82d..000000000 --- a/core/sync/barrier.odin +++ /dev/null @@ -1,81 +0,0 @@ -package sync - - -// A barrier enabling multiple threads to synchronize the beginning of some computation -/* - * Example: - * - * package example - * - * import "core:fmt" - * import "core:sync" - * import "core:thread" - * - * barrier := &sync.Barrier{}; - * - * main :: proc() { - * fmt.println("Start"); - * - * THREAD_COUNT :: 4; - * threads: [THREAD_COUNT]^thread.Thread; - * - * sync.barrier_init(barrier, THREAD_COUNT); - * defer sync.barrier_destroy(barrier); - * - * - * for _, i in threads { - * threads[i] = thread.create_and_start(proc(t: ^thread.Thread) { - * // Same messages will be printed together but without any interleaving - * fmt.println("Getting ready!"); - * sync.barrier_wait(barrier); - * fmt.println("Off their marks they go!"); - * }); - * } - * - * for t in threads { - * thread.destroy(t); // join and free thread - * } - * fmt.println("Finished"); - * } - * - */ -Barrier :: struct { - mutex: Blocking_Mutex, - cond: Condition, - index: int, - generation_id: int, - thread_count: int, -} - -barrier_init :: proc(b: ^Barrier, thread_count: int) { - blocking_mutex_init(&b.mutex) - condition_init(&b.cond, &b.mutex) - b.index = 0 - b.generation_id = 0 - b.thread_count = thread_count -} - -barrier_destroy :: proc(b: ^Barrier) { - blocking_mutex_destroy(&b.mutex) - condition_destroy(&b.cond) -} - -// Block the current thread until all threads have rendezvoused -// Barrier can be reused after all threads rendezvoused once, and can be used continuously -barrier_wait :: proc(b: ^Barrier) -> (is_leader: bool) { - blocking_mutex_lock(&b.mutex) - defer blocking_mutex_unlock(&b.mutex) - local_gen := b.generation_id - b.index += 1 - if b.index < b.thread_count { - for local_gen == b.generation_id && b.index < b.thread_count { - condition_wait_for(&b.cond) - } - return false - } - - b.index = 0 - b.generation_id += 1 - condition_broadcast(&b.cond) - return true -} diff --git a/core/sync/channel.odin b/core/sync/channel.odin deleted file mode 100644 index 82b9504f4..000000000 --- a/core/sync/channel.odin +++ /dev/null @@ -1,889 +0,0 @@ -package sync - -import "core:mem" -import "core:time" -import "core:intrinsics" -import "core:math/rand" - -_, _ :: time, rand - -Channel_Direction :: enum i8 { - Both = 0, - Send = +1, - Recv = -1, -} - -Channel :: struct($T: typeid, $Direction := Channel_Direction.Both) { - using _internal: ^Raw_Channel, -} - -channel_init :: proc(ch: ^$C/Channel($T, $D), cap := 0, allocator := context.allocator) { - context.allocator = allocator - ch._internal = raw_channel_create(size_of(T), align_of(T), cap) - return -} - -channel_make :: proc($T: typeid, cap := 0, allocator := context.allocator) -> (ch: Channel(T, .Both)) { - context.allocator = allocator - ch._internal = raw_channel_create(size_of(T), align_of(T), cap) - return -} - -channel_make_send :: proc($T: typeid, cap := 0, allocator := context.allocator) -> (ch: Channel(T, .Send)) { - context.allocator = allocator - ch._internal = raw_channel_create(size_of(T), align_of(T), cap) - return -} -channel_make_recv :: proc($T: typeid, cap := 0, allocator := context.allocator) -> (ch: Channel(T, .Recv)) { - context.allocator = allocator - ch._internal = raw_channel_create(size_of(T), align_of(T), cap) - return -} - -channel_destroy :: proc(ch: $C/Channel($T, $D)) { - raw_channel_destroy(ch._internal) -} - -channel_as_send :: proc(ch: $C/Channel($T, .Both)) -> (res: Channel(T, .Send)) { - res._internal = ch._internal - return -} - -channel_as_recv :: proc(ch: $C/Channel($T, .Both)) -> (res: Channel(T, .Recv)) { - res._internal = ch._internal - return -} - - -channel_len :: proc(ch: $C/Channel($T, $D)) -> int { - return ch._internal.len if ch._internal != nil else 0 -} -channel_cap :: proc(ch: $C/Channel($T, $D)) -> int { - return ch._internal.cap if ch._internal != nil else 0 -} - - -channel_send :: proc(ch: $C/Channel($T, $D), msg: T, loc := #caller_location) where D >= .Both { - msg := msg - _ = raw_channel_send_impl(ch._internal, &msg, /*block*/true, loc) -} -channel_try_send :: proc(ch: $C/Channel($T, $D), msg: T, loc := #caller_location) -> bool where D >= .Both { - msg := msg - return raw_channel_send_impl(ch._internal, &msg, /*block*/false, loc) -} - -channel_recv :: proc(ch: $C/Channel($T, $D), loc := #caller_location) -> (msg: T) where D <= .Both { - c := ch._internal - if c == nil { - panic(message="cannot recv message; channel is nil", loc=loc) - } - mutex_lock(&c.mutex) - raw_channel_recv_impl(c, &msg, loc) - mutex_unlock(&c.mutex) - return -} -channel_try_recv :: proc(ch: $C/Channel($T, $D), loc := #caller_location) -> (msg: T, ok: bool) where D <= .Both { - c := ch._internal - if c != nil && mutex_try_lock(&c.mutex) { - if c.len > 0 { - raw_channel_recv_impl(c, &msg, loc) - ok = true - } - mutex_unlock(&c.mutex) - } - return -} -channel_try_recv_ptr :: proc(ch: $C/Channel($T, $D), msg: ^T, loc := #caller_location) -> (ok: bool) where D <= .Both { - res: T - res, ok = channel_try_recv(ch, loc) - if ok && msg != nil { - msg^ = res - } - return -} - - -channel_is_nil :: proc(ch: $C/Channel($T, $D)) -> bool { - return ch._internal == nil -} -channel_is_open :: proc(ch: $C/Channel($T, $D)) -> bool { - c := ch._internal - return c != nil && !c.closed -} - - -channel_eq :: proc(a, b: $C/Channel($T, $D)) -> bool { - return a._internal == b._internal -} -channel_ne :: proc(a, b: $C/Channel($T, $D)) -> bool { - return a._internal != b._internal -} - - -channel_can_send :: proc(ch: $C/Channel($T, $D)) -> (ok: bool) where D >= .Both { - return raw_channel_can_send(ch._internal) -} -channel_can_recv :: proc(ch: $C/Channel($T, $D)) -> (ok: bool) where D <= .Both { - return raw_channel_can_recv(ch._internal) -} - - -channel_peek :: proc(ch: $C/Channel($T, $D)) -> int { - c := ch._internal - if c == nil { - return -1 - } - if intrinsics.atomic_load(&c.closed) { - return -1 - } - return intrinsics.atomic_load(&c.len) -} - - -channel_close :: proc(ch: $C/Channel($T, $D), loc := #caller_location) { - raw_channel_close(ch._internal, loc) -} - - -channel_iterator :: proc(ch: $C/Channel($T, $D)) -> (msg: T, ok: bool) where D <= .Both { - c := ch._internal - if c == nil { - return - } - - if !c.closed || c.len > 0 { - msg, ok = channel_recv(ch), true - } - return -} -channel_drain :: proc(ch: $C/Channel($T, $D)) where D >= .Both { - raw_channel_drain(ch._internal) -} - - -channel_move :: proc(dst: $C1/Channel($T, $D1) src: $C2/Channel(T, $D2)) where D1 <= .Both, D2 >= .Both { - for msg in channel_iterator(src) { - channel_send(dst, msg) - } -} - - -Raw_Channel_Wait_Queue :: struct { - next: ^Raw_Channel_Wait_Queue, - state: ^uintptr, -} - - -Raw_Channel :: struct { - closed: bool, - ready: bool, // ready to recv - data_offset: u16, // data is stored at the end of this data structure - elem_size: u32, - len, cap: int, - read, write: int, - mutex: Mutex, - cond: Condition, - allocator: mem.Allocator, - - sendq: ^Raw_Channel_Wait_Queue, - recvq: ^Raw_Channel_Wait_Queue, -} - -raw_channel_wait_queue_insert :: proc(head: ^^Raw_Channel_Wait_Queue, val: ^Raw_Channel_Wait_Queue) { - val.next = head^ - head^ = val -} -raw_channel_wait_queue_remove :: proc(head: ^^Raw_Channel_Wait_Queue, val: ^Raw_Channel_Wait_Queue) { - p := head - for p^ != nil && p^ != val { - p = &p^.next - } - if p != nil { - p^ = p^.next - } -} - - -raw_channel_create :: proc(elem_size, elem_align: int, cap := 0) -> ^Raw_Channel { - assert(int(u32(elem_size)) == elem_size) - - s := size_of(Raw_Channel) - s = mem.align_forward_int(s, elem_align) - data_offset := uintptr(s) - s += elem_size * max(cap, 1) - - a := max(elem_align, align_of(Raw_Channel)) - - c := (^Raw_Channel)(mem.alloc(s, a)) - if c == nil { - return nil - } - - c.data_offset = u16(data_offset) - c.elem_size = u32(elem_size) - c.len, c.cap = 0, max(cap, 0) - c.read, c.write = 0, 0 - mutex_init(&c.mutex) - condition_init(&c.cond, &c.mutex) - c.allocator = context.allocator - c.closed = false - - return c -} - - -raw_channel_destroy :: proc(c: ^Raw_Channel) { - if c == nil { - return - } - context.allocator = c.allocator - intrinsics.atomic_store(&c.closed, true) - - condition_destroy(&c.cond) - mutex_destroy(&c.mutex) - free(c) -} - -raw_channel_close :: proc(c: ^Raw_Channel, loc := #caller_location) { - if c == nil { - panic(message="cannot close nil channel", loc=loc) - } - mutex_lock(&c.mutex) - defer mutex_unlock(&c.mutex) - intrinsics.atomic_store(&c.closed, true) - - // Release readers and writers - raw_channel_wait_queue_broadcast(c.recvq) - raw_channel_wait_queue_broadcast(c.sendq) - condition_broadcast(&c.cond) -} - - - -raw_channel_send_impl :: proc(c: ^Raw_Channel, msg: rawptr, block: bool, loc := #caller_location) -> bool { - send :: proc(c: ^Raw_Channel, src: rawptr) { - data := uintptr(c) + uintptr(c.data_offset) - dst := data + uintptr(c.write * int(c.elem_size)) - mem.copy(rawptr(dst), src, int(c.elem_size)) - c.len += 1 - c.write = (c.write + 1) % max(c.cap, 1) - } - - switch { - case c == nil: - panic(message="cannot send message; channel is nil", loc=loc) - case c.closed: - panic(message="cannot send message; channel is closed", loc=loc) - } - - mutex_lock(&c.mutex) - defer mutex_unlock(&c.mutex) - - if c.cap > 0 { - if !block && c.len >= c.cap { - return false - } - - for c.len >= c.cap { - condition_wait_for(&c.cond) - } - } else if c.len > 0 { // TODO(bill): determine correct behaviour - if !block { - return false - } - condition_wait_for(&c.cond) - } else if c.len == 0 && !block { - return false - } - - send(c, msg) - condition_signal(&c.cond) - raw_channel_wait_queue_signal(c.recvq) - - return true -} - -raw_channel_recv_impl :: proc(c: ^Raw_Channel, res: rawptr, loc := #caller_location) { - recv :: proc(c: ^Raw_Channel, dst: rawptr, loc := #caller_location) { - if c.len < 1 { - panic(message="cannot recv message; channel is empty", loc=loc) - } - c.len -= 1 - - data := uintptr(c) + uintptr(c.data_offset) - src := data + uintptr(c.read * int(c.elem_size)) - mem.copy(dst, rawptr(src), int(c.elem_size)) - c.read = (c.read + 1) % max(c.cap, 1) - } - - if c == nil { - panic(message="cannot recv message; channel is nil", loc=loc) - } - intrinsics.atomic_store(&c.ready, true) - for c.len < 1 { - raw_channel_wait_queue_signal(c.sendq) - condition_wait_for(&c.cond) - } - intrinsics.atomic_store(&c.ready, false) - recv(c, res, loc) - if c.cap > 0 { - if c.len == c.cap - 1 { - // NOTE(bill): Only signal on the last one - condition_signal(&c.cond) - } - } else { - condition_signal(&c.cond) - } -} - - -raw_channel_can_send :: proc(c: ^Raw_Channel) -> (ok: bool) { - if c == nil { - return false - } - mutex_lock(&c.mutex) - switch { - case c.closed: - ok = false - case c.cap > 0: - ok = c.ready && c.len < c.cap - case: - ok = c.ready && c.len == 0 - } - mutex_unlock(&c.mutex) - return -} -raw_channel_can_recv :: proc(c: ^Raw_Channel) -> (ok: bool) { - if c == nil { - return false - } - mutex_lock(&c.mutex) - ok = c.len > 0 - mutex_unlock(&c.mutex) - return -} - - -raw_channel_drain :: proc(c: ^Raw_Channel) { - if c == nil { - return - } - mutex_lock(&c.mutex) - c.len = 0 - c.read = 0 - c.write = 0 - mutex_unlock(&c.mutex) -} - - - -MAX_SELECT_CHANNELS :: 64 -SELECT_MAX_TIMEOUT :: max(time.Duration) - -Select_Command :: enum { - Recv, - Send, -} - -Select_Channel :: struct { - channel: ^Raw_Channel, - command: Select_Command, -} - - - -select :: proc(channels: ..Select_Channel) -> (index: int) { - return select_timeout(SELECT_MAX_TIMEOUT, ..channels) -} -select_timeout :: proc(timeout: time.Duration, channels: ..Select_Channel) -> (index: int) { - switch len(channels) { - case 0: - panic("sync: select with no channels") - } - - assert(len(channels) <= MAX_SELECT_CHANNELS) - - backing: [MAX_SELECT_CHANNELS]int - queues: [MAX_SELECT_CHANNELS]Raw_Channel_Wait_Queue - candidates := backing[:] - cap := len(channels) - candidates = candidates[:cap] - - count := u32(0) - for c, i in channels { - if c.channel == nil { - continue - } - switch c.command { - case .Recv: - if raw_channel_can_recv(c.channel) { - candidates[count] = i - count += 1 - } - case .Send: - if raw_channel_can_send(c.channel) { - candidates[count] = i - count += 1 - } - } - } - - if count == 0 { - wait_state: uintptr = 0 - for _, i in channels { - q := &queues[i] - q.state = &wait_state - } - - for c, i in channels { - if c.channel == nil { - continue - } - q := &queues[i] - switch c.command { - case .Recv: raw_channel_wait_queue_insert(&c.channel.recvq, q) - case .Send: raw_channel_wait_queue_insert(&c.channel.sendq, q) - } - } - raw_channel_wait_queue_wait_on(&wait_state, timeout) - for c, i in channels { - if c.channel == nil { - continue - } - q := &queues[i] - switch c.command { - case .Recv: raw_channel_wait_queue_remove(&c.channel.recvq, q) - case .Send: raw_channel_wait_queue_remove(&c.channel.sendq, q) - } - } - - for c, i in channels { - switch c.command { - case .Recv: - if raw_channel_can_recv(c.channel) { - candidates[count] = i - count += 1 - } - case .Send: - if raw_channel_can_send(c.channel) { - candidates[count] = i - count += 1 - } - } - } - if count == 0 && timeout == SELECT_MAX_TIMEOUT { - index = -1 - return - } - - assert(count != 0) - } - - t := time.now() - r := rand.create(transmute(u64)t) - i := rand.uint32(&r) - - index = candidates[i % count] - return -} - -select_recv :: proc(channels: ..^Raw_Channel) -> (index: int) { - switch len(channels) { - case 0: - panic("sync: select with no channels") - } - - assert(len(channels) <= MAX_SELECT_CHANNELS) - - backing: [MAX_SELECT_CHANNELS]int - queues: [MAX_SELECT_CHANNELS]Raw_Channel_Wait_Queue - candidates := backing[:] - cap := len(channels) - candidates = candidates[:cap] - - count := u32(0) - for c, i in channels { - if raw_channel_can_recv(c) { - candidates[count] = i - count += 1 - } - } - - if count == 0 { - state: uintptr - for c, i in channels { - q := &queues[i] - q.state = &state - raw_channel_wait_queue_insert(&c.recvq, q) - } - raw_channel_wait_queue_wait_on(&state, SELECT_MAX_TIMEOUT) - for c, i in channels { - q := &queues[i] - raw_channel_wait_queue_remove(&c.recvq, q) - } - - for c, i in channels { - if raw_channel_can_recv(c) { - candidates[count] = i - count += 1 - } - } - assert(count != 0) - } - - t := time.now() - r := rand.create(transmute(u64)t) - i := rand.uint32(&r) - - index = candidates[i % count] - return -} - -select_recv_msg :: proc(channels: ..$C/Channel($T, $D)) -> (msg: T, index: int) { - switch len(channels) { - case 0: - panic("sync: select with no channels") - } - - assert(len(channels) <= MAX_SELECT_CHANNELS) - - queues: [MAX_SELECT_CHANNELS]Raw_Channel_Wait_Queue - candidates: [MAX_SELECT_CHANNELS]int - - count := u32(0) - for c, i in channels { - if raw_channel_can_recv(c) { - candidates[count] = i - count += 1 - } - } - - if count == 0 { - state: uintptr - for c, i in channels { - q := &queues[i] - q.state = &state - raw_channel_wait_queue_insert(&c.recvq, q) - } - raw_channel_wait_queue_wait_on(&state, SELECT_MAX_TIMEOUT) - for c, i in channels { - q := &queues[i] - raw_channel_wait_queue_remove(&c.recvq, q) - } - - for c, i in channels { - if raw_channel_can_recv(c) { - candidates[count] = i - count += 1 - } - } - assert(count != 0) - } - - t := time.now() - r := rand.create(transmute(u64)t) - i := rand.uint32(&r) - - index = candidates[i % count] - msg = channel_recv(channels[index]) - - return -} - -select_send_msg :: proc(msg: $T, channels: ..$C/Channel(T, $D)) -> (index: int) { - switch len(channels) { - case 0: - panic("sync: select with no channels") - } - - assert(len(channels) <= MAX_SELECT_CHANNELS) - - backing: [MAX_SELECT_CHANNELS]int - queues: [MAX_SELECT_CHANNELS]Raw_Channel_Wait_Queue - candidates := backing[:] - cap := len(channels) - candidates = candidates[:cap] - - count := u32(0) - for c, i in channels { - if raw_channel_can_recv(c) { - candidates[count] = i - count += 1 - } - } - - if count == 0 { - state: uintptr - for c, i in channels { - q := &queues[i] - q.state = &state - raw_channel_wait_queue_insert(&c.recvq, q) - } - raw_channel_wait_queue_wait_on(&state, SELECT_MAX_TIMEOUT) - for c, i in channels { - q := &queues[i] - raw_channel_wait_queue_remove(&c.recvq, q) - } - - for c, i in channels { - if raw_channel_can_recv(c) { - candidates[count] = i - count += 1 - } - } - assert(count != 0) - } - - t := time.now() - r := rand.create(transmute(u64)t) - i := rand.uint32(&r) - - index = candidates[i % count] - - if msg != nil { - channel_send(channels[index], msg) - } - - return -} - -select_send :: proc(channels: ..^Raw_Channel) -> (index: int) { - switch len(channels) { - case 0: - panic("sync: select with no channels") - } - - assert(len(channels) <= MAX_SELECT_CHANNELS) - candidates: [MAX_SELECT_CHANNELS]int - queues: [MAX_SELECT_CHANNELS]Raw_Channel_Wait_Queue - - count := u32(0) - for c, i in channels { - if raw_channel_can_send(c) { - candidates[count] = i - count += 1 - } - } - - if count == 0 { - state: uintptr - for c, i in channels { - q := &queues[i] - q.state = &state - raw_channel_wait_queue_insert(&c.sendq, q) - } - raw_channel_wait_queue_wait_on(&state, SELECT_MAX_TIMEOUT) - for c, i in channels { - q := &queues[i] - raw_channel_wait_queue_remove(&c.sendq, q) - } - - for c, i in channels { - if raw_channel_can_send(c) { - candidates[count] = i - count += 1 - } - } - assert(count != 0) - } - - t := time.now() - r := rand.create(transmute(u64)t) - i := rand.uint32(&r) - - index = candidates[i % count] - return -} - -select_try :: proc(channels: ..Select_Channel) -> (index: int) { - switch len(channels) { - case 0: - panic("sync: select with no channels") - } - - assert(len(channels) <= MAX_SELECT_CHANNELS) - - backing: [MAX_SELECT_CHANNELS]int - candidates := backing[:] - cap := len(channels) - candidates = candidates[:cap] - - count := u32(0) - for c, i in channels { - switch c.command { - case .Recv: - if raw_channel_can_recv(c.channel) { - candidates[count] = i - count += 1 - } - case .Send: - if raw_channel_can_send(c.channel) { - candidates[count] = i - count += 1 - } - } - } - - if count == 0 { - index = -1 - return - } - - t := time.now() - r := rand.create(transmute(u64)t) - i := rand.uint32(&r) - - index = candidates[i % count] - return -} - - -select_try_recv :: proc(channels: ..^Raw_Channel) -> (index: int) { - switch len(channels) { - case 0: - index = -1 - return - case 1: - index = -1 - if raw_channel_can_recv(channels[0]) { - index = 0 - } - return - } - - assert(len(channels) <= MAX_SELECT_CHANNELS) - candidates: [MAX_SELECT_CHANNELS]int - - count := u32(0) - for c, i in channels { - if raw_channel_can_recv(c) { - candidates[count] = i - count += 1 - } - } - - if count == 0 { - index = -1 - return - } - - t := time.now() - r := rand.create(transmute(u64)t) - i := rand.uint32(&r) - - index = candidates[i % count] - return -} - - -select_try_send :: proc(channels: ..^Raw_Channel) -> (index: int) #no_bounds_check { - switch len(channels) { - case 0: - return -1 - case 1: - if raw_channel_can_send(channels[0]) { - return 0 - } - return -1 - } - - assert(len(channels) <= MAX_SELECT_CHANNELS) - candidates: [MAX_SELECT_CHANNELS]int - - count := u32(0) - for c, i in channels { - if raw_channel_can_send(c) { - candidates[count] = i - count += 1 - } - } - - if count == 0 { - index = -1 - return - } - - t := time.now() - r := rand.create(transmute(u64)t) - i := rand.uint32(&r) - - index = candidates[i % count] - return -} - -select_try_recv_msg :: proc(channels: ..$C/Channel($T, $D)) -> (msg: T, index: int) { - switch len(channels) { - case 0: - index = -1 - return - case 1: - ok: bool - if msg, ok = channel_try_recv(channels[0]); ok { - index = 0 - } - return - } - - assert(len(channels) <= MAX_SELECT_CHANNELS) - candidates: [MAX_SELECT_CHANNELS]int - - count := u32(0) - for c, i in channels { - if channel_can_recv(c) { - candidates[count] = i - count += 1 - } - } - - if count == 0 { - index = -1 - return - } - - t := time.now() - r := rand.create(transmute(u64)t) - i := rand.uint32(&r) - - index = candidates[i % count] - msg = channel_recv(channels[index]) - return -} - -select_try_send_msg :: proc(msg: $T, channels: ..$C/Channel(T, $D)) -> (index: int) { - index = -1 - switch len(channels) { - case 0: - return - case 1: - if channel_try_send(channels[0], msg) { - index = 0 - } - return - } - - - assert(len(channels) <= MAX_SELECT_CHANNELS) - candidates: [MAX_SELECT_CHANNELS]int - - count := u32(0) - for c, i in channels { - if raw_channel_can_send(c) { - candidates[count] = i - count += 1 - } - } - - if count == 0 { - index = -1 - return - } - - t := time.now() - r := rand.create(transmute(u64)t) - i := rand.uint32(&r) - - index = candidates[i % count] - channel_send(channels[index], msg) - return -} - diff --git a/core/sync/channel_unix.odin b/core/sync/channel_unix.odin deleted file mode 100644 index d6bac2d71..000000000 --- a/core/sync/channel_unix.odin +++ /dev/null @@ -1,16 +0,0 @@ -// +build linux, darwin, freebsd -package sync - -import "core:time" - -raw_channel_wait_queue_wait_on :: proc(state: ^uintptr, timeout: time.Duration) { - // stub -} - -raw_channel_wait_queue_signal :: proc(q: ^Raw_Channel_Wait_Queue) { - // stub -} - -raw_channel_wait_queue_broadcast :: proc(q: ^Raw_Channel_Wait_Queue) { - // stub -} diff --git a/core/sync/channel_windows.odin b/core/sync/channel_windows.odin deleted file mode 100644 index 5d469ffff..000000000 --- a/core/sync/channel_windows.odin +++ /dev/null @@ -1,33 +0,0 @@ -package sync - -import "core:intrinsics" -import win32 "core:sys/windows" -import "core:time" - -raw_channel_wait_queue_wait_on :: proc(state: ^uintptr, timeout: time.Duration) { - ms: win32.DWORD = win32.INFINITE - if max(time.Duration) != SELECT_MAX_TIMEOUT { - ms = win32.DWORD((max(time.duration_nanoseconds(timeout), 0) + 999999)/1000000) - } - - v := intrinsics.atomic_load(state) - for v == 0 { - win32.WaitOnAddress(state, &v, size_of(state^), ms) - v = intrinsics.atomic_load(state) - } - intrinsics.atomic_store(state, 0) -} - -raw_channel_wait_queue_signal :: proc(q: ^Raw_Channel_Wait_Queue) { - for x := q; x != nil; x = x.next { - intrinsics.atomic_add(x.state, 1) - win32.WakeByAddressSingle(x.state) - } -} - -raw_channel_wait_queue_broadcast :: proc(q: ^Raw_Channel_Wait_Queue) { - for x := q; x != nil; x = x.next { - intrinsics.atomic_add(x.state, 1) - win32.WakeByAddressAll(x.state) - } -} diff --git a/core/sync/sync2/extended.odin b/core/sync/extended.odin similarity index 73% rename from core/sync/sync2/extended.odin rename to core/sync/extended.odin index d6a99fe04..2cca6f961 100644 --- a/core/sync/sync2/extended.odin +++ b/core/sync/extended.odin @@ -1,4 +1,4 @@ -package sync2 +package sync import "core:time" @@ -67,44 +67,41 @@ wait_group_wait_with_timeout :: proc(wg: ^Wait_Group, duration: time.Duration) - -// A barrier enabling multiple threads to synchronize the beginning of some computation /* - * Example: - * - * package example - * - * import "core:fmt" - * import "core:sync" - * import "core:thread" - * - * barrier := &sync.Barrier{} - * - * main :: proc() { - * fmt.println("Start") - * - * THREAD_COUNT :: 4 - * threads: [THREAD_COUNT]^thread.Thread - * - * sync.barrier_init(barrier, THREAD_COUNT) - * defer sync.barrier_destroy(barrier) - * - * - * for _, i in threads { - * threads[i] = thread.create_and_start(proc(t: ^thread.Thread) { - * // Same messages will be printed together but without any interleaving - * fmt.println("Getting ready!") - * sync.barrier_wait(barrier) - * fmt.println("Off their marks they go!") - * }) - * } - * - * for t in threads { - * thread.destroy(t) // join and free thread - * } - * fmt.println("Finished") - * } - * - */ +A barrier enabling multiple threads to synchronize the beginning of some computation + +Example: + package example + + import "core:fmt" + import "core:sync" + import "core:thread" + + barrier := &sync.Barrier{} + + main :: proc() { + fmt.println("Start") + + THREAD_COUNT :: 4 + threads: [THREAD_COUNT]^thread.Thread + + sync.barrier_init(barrier, THREAD_COUNT) + + for _, i in threads { + threads[i] = thread.create_and_start(proc(t: ^thread.Thread) { + // Same messages will be printed together but without any interleaving + fmt.println("Getting ready!") + sync.barrier_wait(barrier) + fmt.println("Off their marks they go!") + }) + } + + for t in threads { + thread.destroy(t) // join and free thread + } + fmt.println("Finished") + } +*/ Barrier :: struct { mutex: Mutex, cond: Cond, @@ -149,10 +146,10 @@ Auto_Reset_Event :: struct { } auto_reset_event_signal :: proc(e: ^Auto_Reset_Event) { - old_status := atomic_load_relaxed(&e.status) + old_status := atomic_load_explicit(&e.status, .Relaxed) for { new_status := old_status + 1 if old_status < 1 else 1 - if _, ok := atomic_compare_exchange_weak_release(&e.status, old_status, new_status); ok { + if _, ok := atomic_compare_exchange_weak_explicit(&e.status, old_status, new_status, .Release, .Relaxed); ok { break } @@ -163,7 +160,7 @@ auto_reset_event_signal :: proc(e: ^Auto_Reset_Event) { } auto_reset_event_wait :: proc(e: ^Auto_Reset_Event) { - old_status := atomic_sub_acquire(&e.status, 1) + old_status := atomic_sub_explicit(&e.status, 1, .Acquire) if old_status < 1 { sema_wait(&e.sema) } @@ -177,14 +174,14 @@ Ticket_Mutex :: struct { } ticket_mutex_lock :: #force_inline proc(m: ^Ticket_Mutex) { - ticket := atomic_add_relaxed(&m.ticket, 1) - for ticket != atomic_load_acquire(&m.serving) { + ticket := atomic_add_explicit(&m.ticket, 1, .Relaxed) + for ticket != atomic_load_explicit(&m.serving, .Acquire) { cpu_relax() } } ticket_mutex_unlock :: #force_inline proc(m: ^Ticket_Mutex) { - atomic_add_relaxed(&m.serving, 1) + atomic_add_explicit(&m.serving, 1, .Relaxed) } @(deferred_in=ticket_mutex_unlock) ticket_mutex_guard :: proc(m: ^Ticket_Mutex) -> bool { @@ -199,18 +196,18 @@ Benaphore :: struct { } benaphore_lock :: proc(b: ^Benaphore) { - if atomic_add_acquire(&b.counter, 1) > 1 { + if atomic_add_explicit(&b.counter, 1, .Acquire) > 1 { sema_wait(&b.sema) } } benaphore_try_lock :: proc(b: ^Benaphore) -> bool { - v, _ := atomic_compare_exchange_strong_acquire(&b.counter, 1, 0) + v, _ := atomic_compare_exchange_strong_explicit(&b.counter, 0, 1, .Acquire, .Acquire) return v == 0 } benaphore_unlock :: proc(b: ^Benaphore) { - if atomic_sub_release(&b.counter, 1) > 0 { + if atomic_sub_explicit(&b.counter, 1, .Release) > 0 { sema_post(&b.sema) } } @@ -230,7 +227,7 @@ Recursive_Benaphore :: struct { recursive_benaphore_lock :: proc(b: ^Recursive_Benaphore) { tid := current_thread_id() - if atomic_add_acquire(&b.counter, 1) > 1 { + if atomic_add_explicit(&b.counter, 1, .Acquire) > 1 { if tid != b.owner { sema_wait(&b.sema) } @@ -243,10 +240,10 @@ recursive_benaphore_lock :: proc(b: ^Recursive_Benaphore) { recursive_benaphore_try_lock :: proc(b: ^Recursive_Benaphore) -> bool { tid := current_thread_id() if b.owner == tid { - atomic_add_acquire(&b.counter, 1) + atomic_add_explicit(&b.counter, 1, .Acquire) } - if v, _ := atomic_compare_exchange_strong_acquire(&b.counter, 1, 0); v != 0 { + if v, _ := atomic_compare_exchange_strong_explicit(&b.counter, 0, 1, .Acquire, .Acquire); v != 0 { return false } // inside the lock @@ -263,7 +260,7 @@ recursive_benaphore_unlock :: proc(b: ^Recursive_Benaphore) { if recursion == 0 { b.owner = 0 } - if atomic_sub_release(&b.counter, 1) > 0 { + if atomic_sub_explicit(&b.counter, 1, .Release) > 0 { if recursion == 0 { sema_post(&b.sema) } @@ -296,12 +293,12 @@ once_do :: proc(o: ^Once, fn: proc()) { defer mutex_unlock(&o.m) if !o.done { fn() - atomic_store_release(&o.done, true) + atomic_store_explicit(&o.done, true, .Release) } } - if atomic_load_acquire(&o.done) == false { + if atomic_load_explicit(&o.done, .Acquire) == false { do_slow(o, fn) } } diff --git a/core/sync/sync2/futex_darwin.odin b/core/sync/futex_darwin.odin similarity index 99% rename from core/sync/sync2/futex_darwin.odin rename to core/sync/futex_darwin.odin index 9dad8d375..88e354827 100644 --- a/core/sync/sync2/futex_darwin.odin +++ b/core/sync/futex_darwin.odin @@ -1,6 +1,6 @@ //+private //+build darwin -package sync2 +package sync import "core:c" import "core:time" diff --git a/core/sync/futex_freebsd.odin b/core/sync/futex_freebsd.odin new file mode 100644 index 000000000..2e1d065bc --- /dev/null +++ b/core/sync/futex_freebsd.odin @@ -0,0 +1,75 @@ +//+private +//+build freebsd +package sync + +import "core:c" +import "core:os" +import "core:time" + +UMTX_OP_WAIT :: 2 +UMTX_OP_WAKE :: 3 + +foreign import libc "system:c" + +foreign libc { + _umtx_op :: proc "c" (obj: rawptr, op: c.int, val: c.ulong, uaddr: rawptr, uaddr2: rawptr) -> c.int --- +} + +_futex_wait :: proc(f: ^Futex, expected: u32) -> bool { + timeout := os.Unix_File_Time{ + seconds = 5, + nanoseconds = 0, + } + + for { + res := _umtx_op(f, UMTX_OP_WAIT, c.ulong(expected), nil, &timeout) + + if res != -1 { + return true + } + + if os.Errno(os.get_last_error()) == os.ETIMEDOUT { + continue + } + + panic("_futex_wait failure") + } + unreachable() +} + +_futex_wait_with_timeout :: proc(f: ^Futex, expected: u32, duration: time.Duration) -> bool { + if duration <= 0 { + return false + } + + res := _umtx_op(f, UMTX_OP_WAIT, c.ulong(expected), nil, &os.Unix_File_Time{ + seconds = (os.time_t)(duration/1e9), + nanoseconds = (c.long)(duration%1e9), + }) + + if res != -1 { + return true + } + + if os.Errno(os.get_last_error()) == os.ETIMEDOUT { + return false + } + + panic("_futex_wait_with_timeout failure") +} + +_futex_signal :: proc(f: ^Futex) { + res := _umtx_op(f, UMTX_OP_WAKE, 1, nil, nil) + + if res == -1 { + panic("_futex_signal failure") + } +} + +_futex_broadcast :: proc(f: ^Futex) { + res := _umtx_op(f, UMTX_OP_WAKE, c.ulong(max(i32)), nil, nil) + + if res == -1 { + panic("_futex_broadcast failure") + } +} diff --git a/core/sync/sync2/futex_linux.odin b/core/sync/futex_linux.odin similarity index 94% rename from core/sync/sync2/futex_linux.odin rename to core/sync/futex_linux.odin index fca28cace..c429a9d64 100644 --- a/core/sync/sync2/futex_linux.odin +++ b/core/sync/futex_linux.odin @@ -1,6 +1,6 @@ //+private //+build linux -package sync2 +package sync import "core:c" import "core:time" @@ -14,12 +14,6 @@ FUTEX_PRIVATE_FLAG :: 128 FUTEX_WAIT_PRIVATE :: (FUTEX_WAIT | FUTEX_PRIVATE_FLAG) FUTEX_WAKE_PRIVATE :: (FUTEX_WAKE | FUTEX_PRIVATE_FLAG) -foreign import libc "system:c" - -foreign libc { - __errno_location :: proc "c" () -> ^c.int --- -} - ESUCCESS :: 0 EINTR :: -4 EAGAIN :: -11 diff --git a/core/sync/futex_openbsd.odin b/core/sync/futex_openbsd.odin new file mode 100644 index 000000000..6ac9d3efb --- /dev/null +++ b/core/sync/futex_openbsd.odin @@ -0,0 +1,78 @@ +//+private +//+build openbsd +package sync + +import "core:c" +import "core:os" +import "core:time" + +FUTEX_WAIT :: 1 +FUTEX_WAKE :: 2 + +FUTEX_PRIVATE_FLAG :: 128 + +FUTEX_WAIT_PRIVATE :: (FUTEX_WAIT | FUTEX_PRIVATE_FLAG) +FUTEX_WAKE_PRIVATE :: (FUTEX_WAKE | FUTEX_PRIVATE_FLAG) + +foreign import libc "system:c" + +foreign libc { + @(link_name="futex") + _unix_futex :: proc "c" (f: ^Futex, op: c.int, val: u32, timeout: rawptr) -> c.int --- +} + +_futex_wait :: proc(f: ^Futex, expected: u32) -> bool { + res := _unix_futex(f, FUTEX_WAIT_PRIVATE, expected, nil) + + if res != -1 { + return true + } + + if os.Errno(os.get_last_error()) == os.ETIMEDOUT { + return false + } + + panic("futex_wait failure") +} + +_futex_wait_with_timeout :: proc(f: ^Futex, expected: u32, duration: time.Duration) -> bool { + if duration <= 0 { + return false + } + + timespec_t :: struct { + tv_sec: c.long, + tv_nsec: c.long, + } + + res := _unix_futex(f, FUTEX_WAIT_PRIVATE, expected, ×pec_t{ + tv_sec = (c.long)(duration/1e9), + tv_nsec = (c.long)(duration%1e9), + }) + + if res != -1 { + return true + } + + if os.Errno(os.get_last_error()) == os.ETIMEDOUT { + return false + } + + panic("futex_wait_with_timeout failure") +} + +_futex_signal :: proc(f: ^Futex) { + res := _unix_futex(f, FUTEX_WAKE_PRIVATE, 1, nil) + + if res == -1 { + panic("futex_wake_single failure") + } +} + +_futex_broadcast :: proc(f: ^Futex) { + res := _unix_futex(f, FUTEX_WAKE_PRIVATE, u32(max(i32)), nil) + + if res == -1 { + panic("_futex_wake_all failure") + } +} diff --git a/core/sync/sync2/futex_windows.odin b/core/sync/futex_windows.odin similarity index 98% rename from core/sync/sync2/futex_windows.odin rename to core/sync/futex_windows.odin index 200a119ff..1c9d8b845 100644 --- a/core/sync/sync2/futex_windows.odin +++ b/core/sync/futex_windows.odin @@ -1,6 +1,6 @@ //+private //+build windows -package sync2 +package sync import "core:time" diff --git a/core/sync/sync2/primitives.odin b/core/sync/primitives.odin similarity index 94% rename from core/sync/sync2/primitives.odin rename to core/sync/primitives.odin index d9e013664..483f85343 100644 --- a/core/sync/sync2/primitives.odin +++ b/core/sync/primitives.odin @@ -1,4 +1,4 @@ -package sync2 +package sync import "core:time" @@ -29,12 +29,12 @@ mutex_try_lock :: proc(m: ^Mutex) -> bool { return _mutex_try_lock(m) } -// Example: -// -// if mutex_guard(&m) { -// ... -// } -// +/* +Example: + if mutex_guard(&m) { + ... + } +*/ @(deferred_in=mutex_unlock) mutex_guard :: proc(m: ^Mutex) -> bool { mutex_lock(m) @@ -80,25 +80,24 @@ rw_mutex_shared_unlock :: proc(rw: ^RW_Mutex) { rw_mutex_try_shared_lock :: proc(rw: ^RW_Mutex) -> bool { return _rw_mutex_try_shared_lock(rw) } - -// Example: -// -// if rw_mutex_guard(&m) { -// ... -// } -// +/* +Example: + if rw_mutex_guard(&m) { + ... + } +*/ @(deferred_in=rw_mutex_unlock) rw_mutex_guard :: proc(m: ^RW_Mutex) -> bool { rw_mutex_lock(m) return true } -// Example: -// -// if rw_mutex_shared_guard(&m) { -// ... -// } -// +/* +Example: + if rw_mutex_shared_guard(&m) { + ... + } +*/ @(deferred_in=rw_mutex_shared_unlock) rw_mutex_shared_guard :: proc(m: ^RW_Mutex) -> bool { rw_mutex_shared_lock(m) @@ -127,13 +126,12 @@ recursive_mutex_try_lock :: proc(m: ^Recursive_Mutex) -> bool { return _recursive_mutex_try_lock(m) } - -// Example: -// -// if recursive_mutex_guard(&m) { -// ... -// } -// +/* +Example: + if recursive_mutex_guard(&m) { + ... + } +*/ @(deferred_in=recursive_mutex_unlock) recursive_mutex_guard :: proc(m: ^Recursive_Mutex) -> bool { recursive_mutex_lock(m) diff --git a/core/sync/sync2/primitives_atomic.odin b/core/sync/primitives_atomic.odin similarity index 91% rename from core/sync/sync2/primitives_atomic.odin rename to core/sync/primitives_atomic.odin index a13b73a99..11fff4e60 100644 --- a/core/sync/sync2/primitives_atomic.odin +++ b/core/sync/primitives_atomic.odin @@ -1,4 +1,4 @@ -package sync2 +package sync import "core:time" @@ -24,7 +24,7 @@ atomic_mutex_lock :: proc(m: ^Atomic_Mutex) { new_state := curr_state // Make a copy of it spin_lock: for spin in 0.. bool { - _, ok := atomic_compare_exchange_strong_acquire(&m.state, .Unlocked, .Locked) + _, ok := atomic_compare_exchange_strong_explicit(&m.state, .Unlocked, .Locked, .Acquire, .Consume) return ok } - -// Example: -// -// if atomic_mutex_guard(&m) { -// ... -// } -// +/* +Example: + if atomic_mutex_guard(&m) { + ... + } +*/ @(deferred_in=atomic_mutex_unlock) atomic_mutex_guard :: proc(m: ^Atomic_Mutex) -> bool { atomic_mutex_lock(m) @@ -193,25 +191,24 @@ atomic_rw_mutex_try_shared_lock :: proc(rw: ^Atomic_RW_Mutex) -> bool { return false } - -// Example: -// -// if atomic_rw_mutex_guard(&m) { -// ... -// } -// +/* +Example: + if atomic_rw_mutex_guard(&m) { + ... + } +*/ @(deferred_in=atomic_rw_mutex_unlock) atomic_rw_mutex_guard :: proc(m: ^Atomic_RW_Mutex) -> bool { atomic_rw_mutex_lock(m) return true } -// Example: -// -// if atomic_rw_mutex_shared_guard(&m) { -// ... -// } -// +/* +Example: + if atomic_rw_mutex_shared_guard(&m) { + ... + } +*/ @(deferred_in=atomic_rw_mutex_shared_unlock) atomic_rw_mutex_shared_guard :: proc(m: ^Atomic_RW_Mutex) -> bool { atomic_rw_mutex_shared_lock(m) @@ -270,13 +267,12 @@ atomic_recursive_mutex_try_lock :: proc(m: ^Atomic_Recursive_Mutex) -> bool { return true } - -// Example: -// -// if atomic_recursive_mutex_guard(&m) { -// ... -// } -// +/* +Example: + if atomic_recursive_mutex_guard(&m) { + ... + } +*/ @(deferred_in=atomic_recursive_mutex_unlock) atomic_recursive_mutex_guard :: proc(m: ^Atomic_Recursive_Mutex) -> bool { atomic_recursive_mutex_lock(m) @@ -294,7 +290,7 @@ Queue_Item :: struct { @(private="file") queue_item_wait :: proc(item: ^Queue_Item) { - for atomic_load_acquire(&item.futex) == 0 { + for atomic_load_explicit(&item.futex, .Acquire) == 0 { futex_wait(&item.futex, 0) cpu_relax() } @@ -302,7 +298,7 @@ queue_item_wait :: proc(item: ^Queue_Item) { @(private="file") queue_item_wait_with_timeout :: proc(item: ^Queue_Item, duration: time.Duration) -> bool { start := time.tick_now() - for atomic_load_acquire(&item.futex) == 0 { + for atomic_load_explicit(&item.futex, .Acquire) == 0 { remaining := duration - time.tick_since(start) if remaining < 0 { return false @@ -316,7 +312,7 @@ queue_item_wait_with_timeout :: proc(item: ^Queue_Item, duration: time.Duration) } @(private="file") queue_item_signal :: proc(item: ^Queue_Item) { - atomic_store_release(&item.futex, 1) + atomic_store_explicit(&item.futex, 1, .Release) futex_signal(&item.futex) } diff --git a/core/sync/sync2/primitives_darwin.odin b/core/sync/primitives_darwin.odin similarity index 98% rename from core/sync/sync2/primitives_darwin.odin rename to core/sync/primitives_darwin.odin index 66995bd01..514f66f3e 100644 --- a/core/sync/sync2/primitives_darwin.odin +++ b/core/sync/primitives_darwin.odin @@ -1,6 +1,6 @@ //+build darwin //+private -package sync2 +package sync import "core:c" import "core:time" diff --git a/core/sync/primitives_freebsd.odin b/core/sync/primitives_freebsd.odin new file mode 100644 index 000000000..b88fca181 --- /dev/null +++ b/core/sync/primitives_freebsd.odin @@ -0,0 +1,46 @@ +//+build freebsd +//+private +package sync + +import "core:os" +import "core:time" + +_current_thread_id :: proc "contextless" () -> int { + return os.current_thread_id() +} + +_Mutex :: struct { + mutex: Atomic_Mutex, +} + +_mutex_lock :: proc(m: ^Mutex) { + atomic_mutex_lock(&m.impl.mutex) +} + +_mutex_unlock :: proc(m: ^Mutex) { + atomic_mutex_unlock(&m.impl.mutex) +} + +_mutex_try_lock :: proc(m: ^Mutex) -> bool { + return atomic_mutex_try_lock(&m.impl.mutex) +} + +_Cond :: struct { + cond: Atomic_Cond, +} + +_cond_wait :: proc(c: ^Cond, m: ^Mutex) { + atomic_cond_wait(&c.impl.cond, &m.impl.mutex) +} + +_cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool { + return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration) +} + +_cond_signal :: proc(c: ^Cond) { + atomic_cond_signal(&c.impl.cond) +} + +_cond_broadcast :: proc(c: ^Cond) { + atomic_cond_broadcast(&c.impl.cond) +} diff --git a/core/sync/primitives_internal.odin b/core/sync/primitives_internal.odin new file mode 100644 index 000000000..de9aca991 --- /dev/null +++ b/core/sync/primitives_internal.odin @@ -0,0 +1,125 @@ +//+private +package sync + +when #config(ODIN_SYNC_RECURSIVE_MUTEX_USE_FUTEX, true) { + _Recursive_Mutex :: struct { + owner: Futex, + recursion: i32, + } + + _recursive_mutex_lock :: proc(m: ^Recursive_Mutex) { + tid := Futex(current_thread_id()) + for { + prev_owner := atomic_compare_exchange_strong_explicit(&m.impl.owner, 0, tid, .Acquire, .Acquire) + switch prev_owner { + case 0, tid: + m.impl.recursion += 1 + // inside the lock + return + } + + futex_wait(&m.impl.owner, u32(prev_owner)) + } + } + + _recursive_mutex_unlock :: proc(m: ^Recursive_Mutex) { + m.impl.recursion -= 1 + if m.impl.recursion != 0 { + return + } + atomic_exchange_explicit(&m.impl.owner, 0, .Release) + + futex_signal(&m.impl.owner) + // outside the lock + + } + + _recursive_mutex_try_lock :: proc(m: ^Recursive_Mutex) -> bool { + tid := Futex(current_thread_id()) + prev_owner := atomic_compare_exchange_strong_explicit(&m.impl.owner, 0, tid, .Acquire, .Acquire) + switch prev_owner { + case 0, tid: + m.impl.recursion += 1 + // inside the lock + return true + } + return false + } +} else { + _Recursive_Mutex :: struct { + owner: int, + recursion: int, + mutex: Mutex, + } + + _recursive_mutex_lock :: proc(m: ^Recursive_Mutex) { + tid := current_thread_id() + if tid != m.impl.owner { + mutex_lock(&m.impl.mutex) + } + // inside the lock + m.impl.owner = tid + m.impl.recursion += 1 + } + + _recursive_mutex_unlock :: proc(m: ^Recursive_Mutex) { + tid := current_thread_id() + assert(tid == m.impl.owner) + m.impl.recursion -= 1 + recursion := m.impl.recursion + if recursion == 0 { + m.impl.owner = 0 + } + if recursion == 0 { + mutex_unlock(&m.impl.mutex) + } + // outside the lock + + } + + _recursive_mutex_try_lock :: proc(m: ^Recursive_Mutex) -> bool { + tid := current_thread_id() + if m.impl.owner == tid { + return mutex_try_lock(&m.impl.mutex) + } + if !mutex_try_lock(&m.impl.mutex) { + return false + } + // inside the lock + m.impl.owner = tid + m.impl.recursion += 1 + return true + } +} + + +when ODIN_OS != .Windows { + _RW_Mutex :: struct { + mutex: Atomic_RW_Mutex, + } + + _rw_mutex_lock :: proc(rw: ^RW_Mutex) { + atomic_rw_mutex_lock(&rw.impl.mutex) + } + + _rw_mutex_unlock :: proc(rw: ^RW_Mutex) { + atomic_rw_mutex_unlock(&rw.impl.mutex) + } + + _rw_mutex_try_lock :: proc(rw: ^RW_Mutex) -> bool { + return atomic_rw_mutex_try_lock(&rw.impl.mutex) + } + + _rw_mutex_shared_lock :: proc(rw: ^RW_Mutex) { + atomic_rw_mutex_shared_lock(&rw.impl.mutex) + } + + _rw_mutex_shared_unlock :: proc(rw: ^RW_Mutex) { + atomic_rw_mutex_shared_unlock(&rw.impl.mutex) + } + + _rw_mutex_try_shared_lock :: proc(rw: ^RW_Mutex) -> bool { + return atomic_rw_mutex_try_shared_lock(&rw.impl.mutex) + } + +} \ No newline at end of file diff --git a/core/sync/primitives_linux.odin b/core/sync/primitives_linux.odin new file mode 100644 index 000000000..0a9f0cc33 --- /dev/null +++ b/core/sync/primitives_linux.odin @@ -0,0 +1,47 @@ +//+build linux +//+private +package sync + +import "core:sys/unix" +import "core:time" + +_current_thread_id :: proc "contextless" () -> int { + return unix.sys_gettid() +} + + +_Mutex :: struct { + mutex: Atomic_Mutex, +} + +_mutex_lock :: proc(m: ^Mutex) { + atomic_mutex_lock(&m.impl.mutex) +} + +_mutex_unlock :: proc(m: ^Mutex) { + atomic_mutex_unlock(&m.impl.mutex) +} + +_mutex_try_lock :: proc(m: ^Mutex) -> bool { + return atomic_mutex_try_lock(&m.impl.mutex) +} + +_Cond :: struct { + cond: Atomic_Cond, +} + +_cond_wait :: proc(c: ^Cond, m: ^Mutex) { + atomic_cond_wait(&c.impl.cond, &m.impl.mutex) +} + +_cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool { + return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration) +} + +_cond_signal :: proc(c: ^Cond) { + atomic_cond_signal(&c.impl.cond) +} + +_cond_broadcast :: proc(c: ^Cond) { + atomic_cond_broadcast(&c.impl.cond) +} diff --git a/core/sync/primitives_openbsd.odin b/core/sync/primitives_openbsd.odin new file mode 100644 index 000000000..7794016f8 --- /dev/null +++ b/core/sync/primitives_openbsd.odin @@ -0,0 +1,46 @@ +//+build openbsd +//+private +package sync + +import "core:os" +import "core:time" + +_current_thread_id :: proc "contextless" () -> int { + return os.current_thread_id() +} + +_Mutex :: struct { + mutex: Atomic_Mutex, +} + +_mutex_lock :: proc(m: ^Mutex) { + atomic_mutex_lock(&m.impl.mutex) +} + +_mutex_unlock :: proc(m: ^Mutex) { + atomic_mutex_unlock(&m.impl.mutex) +} + +_mutex_try_lock :: proc(m: ^Mutex) -> bool { + return atomic_mutex_try_lock(&m.impl.mutex) +} + +_Cond :: struct { + cond: Atomic_Cond, +} + +_cond_wait :: proc(c: ^Cond, m: ^Mutex) { + atomic_cond_wait(&c.impl.cond, &m.impl.mutex) +} + +_cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool { + return atomic_cond_wait_with_timeout(&c.impl.cond, &m.impl.mutex, duration) +} + +_cond_signal :: proc(c: ^Cond) { + atomic_cond_signal(&c.impl.cond) +} + +_cond_broadcast :: proc(c: ^Cond) { + atomic_cond_broadcast(&c.impl.cond) +} diff --git a/core/sync/sync2/primitives_windows.odin b/core/sync/primitives_windows.odin similarity index 99% rename from core/sync/sync2/primitives_windows.odin rename to core/sync/primitives_windows.odin index ca7a5c9ee..055167892 100644 --- a/core/sync/sync2/primitives_windows.odin +++ b/core/sync/primitives_windows.odin @@ -1,6 +1,6 @@ //+build windows //+private -package sync2 +package sync import "core:time" import win32 "core:sys/windows" diff --git a/core/sync/sync2/sema_internal.odin b/core/sync/sema_internal.odin similarity index 71% rename from core/sync/sync2/sema_internal.odin rename to core/sync/sema_internal.odin index 64fc4ed96..e4a3c0bfc 100644 --- a/core/sync/sync2/sema_internal.odin +++ b/core/sync/sema_internal.odin @@ -1,4 +1,5 @@ -package sync2 +//+private +package sync import "core:time" @@ -9,7 +10,7 @@ when #config(ODIN_SYNC_SEMA_USE_FUTEX, true) { } _sema_post :: proc(s: ^Sema, count := 1) { - atomic_add(&s.impl.count, Futex(count)) + atomic_add_explicit(&s.impl.count, Futex(count), .Release) if count == 1 { futex_signal(&s.impl.count) } else { @@ -19,12 +20,12 @@ when #config(ODIN_SYNC_SEMA_USE_FUTEX, true) { _sema_wait :: proc(s: ^Sema) { for { - original_count := atomic_load(&s.impl.count) + original_count := atomic_load_explicit(&s.impl.count, .Relaxed) for original_count == 0 { futex_wait(&s.impl.count, u32(original_count)) original_count = s.impl.count } - if original_count == atomic_compare_exchange_strong(&s.impl.count, original_count-1, original_count) { + if original_count == atomic_compare_exchange_strong_explicit(&s.impl.count, original_count, original_count-1, .Acquire, .Acquire) { return } } @@ -36,7 +37,7 @@ when #config(ODIN_SYNC_SEMA_USE_FUTEX, true) { } for { - original_count := atomic_load(&s.impl.count) + original_count := atomic_load_explicit(&s.impl.count, .Relaxed) for start := time.tick_now(); original_count == 0; /**/ { remaining := duration - time.tick_since(start) if remaining < 0 { @@ -48,7 +49,7 @@ when #config(ODIN_SYNC_SEMA_USE_FUTEX, true) { } original_count = s.impl.count } - if original_count == atomic_compare_exchange_strong(&s.impl.count, original_count-1, original_count) { + if original_count == atomic_compare_exchange_strong_explicit(&s.impl.count, original_count, original_count-1, .Acquire, .Acquire) { return true } } diff --git a/core/sync/sync.odin b/core/sync/sync.odin deleted file mode 100644 index 05c86a868..000000000 --- a/core/sync/sync.odin +++ /dev/null @@ -1,123 +0,0 @@ -package sync - -import "core:intrinsics" - -cpu_relax :: #force_inline proc "contextless" () { - intrinsics.cpu_relax() -} - -Condition_Mutex_Ptr :: union{^Mutex, ^Blocking_Mutex} - - -Ticket_Mutex :: struct { - ticket: u64, - serving: u64, -} - -ticket_mutex_init :: proc(m: ^Ticket_Mutex) { - atomic_store(&m.ticket, 0, .Relaxed) - atomic_store(&m.serving, 0, .Relaxed) -} - -ticket_mutex_lock :: #force_inline proc(m: ^Ticket_Mutex) { - ticket := atomic_add(&m.ticket, 1, .Relaxed) - for ticket != atomic_load(&m.serving, .Acquire) { - intrinsics.cpu_relax() - } -} - -ticket_mutex_unlock :: #force_inline proc(m: ^Ticket_Mutex) { - atomic_add(&m.serving, 1, .Relaxed) -} - - -Benaphore :: struct { - counter: int, - sema: Semaphore, -} - -benaphore_init :: proc(b: ^Benaphore) { - intrinsics.atomic_store(&b.counter, 0) - semaphore_init(&b.sema) -} - -benaphore_destroy :: proc(b: ^Benaphore) { - semaphore_destroy(&b.sema) -} - -benaphore_lock :: proc(b: ^Benaphore) { - if intrinsics.atomic_add_acq(&b.counter, 1) > 1 { - semaphore_wait_for(&b.sema) - } -} - -benaphore_try_lock :: proc(b: ^Benaphore) -> bool { - v, _ := intrinsics.atomic_cxchg_acq(&b.counter, 1, 0) - return v == 0 -} - -benaphore_unlock :: proc(b: ^Benaphore) { - if intrinsics.atomic_sub_rel(&b.counter, 1) > 0 { - semaphore_post(&b.sema) - } -} - -Recursive_Benaphore :: struct { - counter: int, - owner: int, - recursion: int, - sema: Semaphore, -} - -recursive_benaphore_init :: proc(b: ^Recursive_Benaphore) { - intrinsics.atomic_store(&b.counter, 0) - semaphore_init(&b.sema) -} - -recursive_benaphore_destroy :: proc(b: ^Recursive_Benaphore) { - semaphore_destroy(&b.sema) -} - -recursive_benaphore_lock :: proc(b: ^Recursive_Benaphore) { - tid := current_thread_id() - if intrinsics.atomic_add_acq(&b.counter, 1) > 1 { - if tid != b.owner { - semaphore_wait_for(&b.sema) - } - } - // inside the lock - b.owner = tid - b.recursion += 1 -} - -recursive_benaphore_try_lock :: proc(b: ^Recursive_Benaphore) -> bool { - tid := current_thread_id() - if b.owner == tid { - intrinsics.atomic_add_acq(&b.counter, 1) - } else { - v, _ := intrinsics.atomic_cxchg_acq(&b.counter, 1, 0) - if v != 0 { - return false - } - // inside the lock - b.owner = tid - } - b.recursion += 1 - return true -} - -recursive_benaphore_unlock :: proc(b: ^Recursive_Benaphore) { - tid := current_thread_id() - assert(tid == b.owner) - b.recursion -= 1 - recursion := b.recursion - if recursion == 0 { - b.owner = 0 - } - if intrinsics.atomic_sub_rel(&b.counter, 1) > 0 { - if recursion == 0 { - semaphore_post(&b.sema) - } - } - // outside the lock -} diff --git a/core/sync/sync2/atomic.odin b/core/sync/sync2/atomic.odin deleted file mode 100644 index fe19f17c8..000000000 --- a/core/sync/sync2/atomic.odin +++ /dev/null @@ -1,79 +0,0 @@ -package sync2 - -import "core:intrinsics" - -cpu_relax :: intrinsics.cpu_relax - -atomic_fence :: intrinsics.atomic_fence -atomic_fence_acquire :: intrinsics.atomic_fence_acq -atomic_fence_release :: intrinsics.atomic_fence_rel -atomic_fence_acqrel :: intrinsics.atomic_fence_acqrel - -atomic_store :: intrinsics.atomic_store -atomic_store_release :: intrinsics.atomic_store_rel -atomic_store_relaxed :: intrinsics.atomic_store_relaxed -atomic_store_unordered :: intrinsics.atomic_store_unordered - -atomic_load :: intrinsics.atomic_load -atomic_load_acquire :: intrinsics.atomic_load_acq -atomic_load_relaxed :: intrinsics.atomic_load_relaxed -atomic_load_unordered :: intrinsics.atomic_load_unordered - -atomic_add :: intrinsics.atomic_add -atomic_add_acquire :: intrinsics.atomic_add_acq -atomic_add_release :: intrinsics.atomic_add_rel -atomic_add_acqrel :: intrinsics.atomic_add_acqrel -atomic_add_relaxed :: intrinsics.atomic_add_relaxed -atomic_sub :: intrinsics.atomic_sub -atomic_sub_acquire :: intrinsics.atomic_sub_acq -atomic_sub_release :: intrinsics.atomic_sub_rel -atomic_sub_acqrel :: intrinsics.atomic_sub_acqrel -atomic_sub_relaxed :: intrinsics.atomic_sub_relaxed -atomic_and :: intrinsics.atomic_and -atomic_and_acquire :: intrinsics.atomic_and_acq -atomic_and_release :: intrinsics.atomic_and_rel -atomic_and_acqrel :: intrinsics.atomic_and_acqrel -atomic_and_relaxed :: intrinsics.atomic_and_relaxed -atomic_nand :: intrinsics.atomic_nand -atomic_nand_acquire :: intrinsics.atomic_nand_acq -atomic_nand_release :: intrinsics.atomic_nand_rel -atomic_nand_acqrel :: intrinsics.atomic_nand_acqrel -atomic_nand_relaxed :: intrinsics.atomic_nand_relaxed -atomic_or :: intrinsics.atomic_or -atomic_or_acquire :: intrinsics.atomic_or_acq -atomic_or_release :: intrinsics.atomic_or_rel -atomic_or_acqrel :: intrinsics.atomic_or_acqrel -atomic_or_relaxed :: intrinsics.atomic_or_relaxed -atomic_xor :: intrinsics.atomic_xor -atomic_xor_acquire :: intrinsics.atomic_xor_acq -atomic_xor_release :: intrinsics.atomic_xor_rel -atomic_xor_acqrel :: intrinsics.atomic_xor_acqrel -atomic_xor_relaxed :: intrinsics.atomic_xor_relaxed - -atomic_exchange :: intrinsics.atomic_xchg -atomic_exchange_acquire :: intrinsics.atomic_xchg_acq -atomic_exchange_release :: intrinsics.atomic_xchg_rel -atomic_exchange_acqrel :: intrinsics.atomic_xchg_acqrel -atomic_exchange_relaxed :: intrinsics.atomic_xchg_relaxed - -// Returns value and optional ok boolean -atomic_compare_exchange_strong :: intrinsics.atomic_cxchg -atomic_compare_exchange_strong_acquire :: intrinsics.atomic_cxchg_acq -atomic_compare_exchange_strong_release :: intrinsics.atomic_cxchg_rel -atomic_compare_exchange_strong_acqrel :: intrinsics.atomic_cxchg_acqrel -atomic_compare_exchange_strong_relaxed :: intrinsics.atomic_cxchg_relaxed -atomic_compare_exchange_strong_failrelaxed :: intrinsics.atomic_cxchg_failrelaxed -atomic_compare_exchange_strong_failacquire :: intrinsics.atomic_cxchg_failacq -atomic_compare_exchange_strong_acquire_failrelaxed :: intrinsics.atomic_cxchg_acq_failrelaxed -atomic_compare_exchange_strong_acqrel_failrelaxed :: intrinsics.atomic_cxchg_acqrel_failrelaxed - -// Returns value and optional ok boolean -atomic_compare_exchange_weak :: intrinsics.atomic_cxchgweak -atomic_compare_exchange_weak_acquire :: intrinsics.atomic_cxchgweak_acq -atomic_compare_exchange_weak_release :: intrinsics.atomic_cxchgweak_rel -atomic_compare_exchange_weak_acqrel :: intrinsics.atomic_cxchgweak_acqrel -atomic_compare_exchange_weak_relaxed :: intrinsics.atomic_cxchgweak_relaxed -atomic_compare_exchange_weak_failrelaxed :: intrinsics.atomic_cxchgweak_failrelaxed -atomic_compare_exchange_weak_failacquire :: intrinsics.atomic_cxchgweak_failacq -atomic_compare_exchange_weak_acquire_failrelaxed :: intrinsics.atomic_cxchgweak_acq_failrelaxed -atomic_compare_exchange_weak_acqrel_failrelaxed :: intrinsics.atomic_cxchgweak_acqrel_failrelaxed diff --git a/core/sync/sync2/primitives_internal.odin b/core/sync/sync2/primitives_internal.odin deleted file mode 100644 index ae7e2599c..000000000 --- a/core/sync/sync2/primitives_internal.odin +++ /dev/null @@ -1,184 +0,0 @@ -//+private -package sync2 - -when #config(ODIN_SYNC_RECURSIVE_MUTEX_USE_FUTEX, true) { - _Recursive_Mutex :: struct { - owner: Futex, - recursion: i32, - } - - _recursive_mutex_lock :: proc(m: ^Recursive_Mutex) { - tid := Futex(current_thread_id()) - for { - prev_owner := atomic_compare_exchange_strong_acquire(&m.impl.owner, tid, 0) - switch prev_owner { - case 0, tid: - m.impl.recursion += 1 - // inside the lock - return - } - - futex_wait(&m.impl.owner, u32(prev_owner)) - } - } - - _recursive_mutex_unlock :: proc(m: ^Recursive_Mutex) { - m.impl.recursion -= 1 - if m.impl.recursion != 0 { - return - } - atomic_exchange_release(&m.impl.owner, 0) - - futex_signal(&m.impl.owner) - // outside the lock - - } - - _recursive_mutex_try_lock :: proc(m: ^Recursive_Mutex) -> bool { - tid := Futex(current_thread_id()) - prev_owner := atomic_compare_exchange_strong_acquire(&m.impl.owner, tid, 0) - switch prev_owner { - case 0, tid: - m.impl.recursion += 1 - // inside the lock - return true - } - return false - } -} else { - _Recursive_Mutex :: struct { - owner: int, - recursion: int, - mutex: Mutex, - } - - _recursive_mutex_lock :: proc(m: ^Recursive_Mutex) { - tid := current_thread_id() - if tid != m.impl.owner { - mutex_lock(&m.impl.mutex) - } - // inside the lock - m.impl.owner = tid - m.impl.recursion += 1 - } - - _recursive_mutex_unlock :: proc(m: ^Recursive_Mutex) { - tid := current_thread_id() - assert(tid == m.impl.owner) - m.impl.recursion -= 1 - recursion := m.impl.recursion - if recursion == 0 { - m.impl.owner = 0 - } - if recursion == 0 { - mutex_unlock(&m.impl.mutex) - } - // outside the lock - - } - - _recursive_mutex_try_lock :: proc(m: ^Recursive_Mutex) -> bool { - tid := current_thread_id() - if m.impl.owner == tid { - return mutex_try_lock(&m.impl.mutex) - } - if !mutex_try_lock(&m.impl.mutex) { - return false - } - // inside the lock - m.impl.owner = tid - m.impl.recursion += 1 - return true - } -} - - -when ODIN_OS != "windows" { - RW_Mutex_State :: distinct uint - RW_Mutex_State_Half_Width :: size_of(RW_Mutex_State)*8/2 - RW_Mutex_State_Is_Writing :: RW_Mutex_State(1) - RW_Mutex_State_Writer :: RW_Mutex_State(1)<<1 - RW_Mutex_State_Reader :: RW_Mutex_State(1)< bool { - if mutex_try_lock(&rw.impl.mutex) { - state := atomic_load(&rw.impl.state) - if state & RW_Mutex_State_Reader_Mask == 0 { - _ = atomic_or(&rw.impl.state, RW_Mutex_State_Is_Writing) - return true - } - - mutex_unlock(&rw.impl.mutex) - } - return false - } - - _rw_mutex_shared_lock :: proc(rw: ^RW_Mutex) { - state := atomic_load(&rw.impl.state) - for state & (RW_Mutex_State_Is_Writing|RW_Mutex_State_Writer_Mask) == 0 { - ok: bool - state, ok = atomic_compare_exchange_weak(&rw.impl.state, state, state + RW_Mutex_State_Reader) - if ok { - return - } - } - - mutex_lock(&rw.impl.mutex) - _ = atomic_add(&rw.impl.state, RW_Mutex_State_Reader) - mutex_unlock(&rw.impl.mutex) - } - - _rw_mutex_shared_unlock :: proc(rw: ^RW_Mutex) { - state := atomic_sub(&rw.impl.state, RW_Mutex_State_Reader) - - if (state & RW_Mutex_State_Reader_Mask == RW_Mutex_State_Reader) && - (state & RW_Mutex_State_Is_Writing != 0) { - sema_post(&rw.impl.sema) - } - } - - _rw_mutex_try_shared_lock :: proc(rw: ^RW_Mutex) -> bool { - state := atomic_load(&rw.impl.state) - if state & (RW_Mutex_State_Is_Writing|RW_Mutex_State_Writer_Mask) == 0 { - _, ok := atomic_compare_exchange_strong(&rw.impl.state, state, state + RW_Mutex_State_Reader) - if ok { - return true - } - } - if mutex_try_lock(&rw.impl.mutex) { - _ = atomic_add(&rw.impl.state, RW_Mutex_State_Reader) - mutex_unlock(&rw.impl.mutex) - return true - } - - return false - } - -} \ No newline at end of file diff --git a/core/sync/sync2/primitives_linux.odin b/core/sync/sync2/primitives_linux.odin deleted file mode 100644 index 89ed97985..000000000 --- a/core/sync/sync2/primitives_linux.odin +++ /dev/null @@ -1,9 +0,0 @@ -//+build linux -//+private -package sync2 - -import "core:sys/unix" - -_current_thread_id :: proc "contextless" () -> int { - return unix.sys_gettid() -} diff --git a/core/sync/sync2/primitives_pthreads.odin b/core/sync/sync2/primitives_pthreads.odin deleted file mode 100644 index 8d2c3986d..000000000 --- a/core/sync/sync2/primitives_pthreads.odin +++ /dev/null @@ -1,58 +0,0 @@ -//+build linux, freebsd -//+private -package sync2 - -import "core:time" -import "core:sys/unix" - -_Mutex_State :: enum i32 { - Unlocked = 0, - Locked = 1, - Waiting = 2, -} -_Mutex :: struct { - pthread_mutex: unix.pthread_mutex_t, -} - -_mutex_lock :: proc(m: ^Mutex) { - err := unix.pthread_mutex_lock(&m.impl.pthread_mutex) - assert(err == 0) -} - -_mutex_unlock :: proc(m: ^Mutex) { - err := unix.pthread_mutex_unlock(&m.impl.pthread_mutex) - assert(err == 0) -} - -_mutex_try_lock :: proc(m: ^Mutex) -> bool { - err := unix.pthread_mutex_trylock(&m.impl.pthread_mutex) - return err == 0 -} - -_Cond :: struct { - pthread_cond: unix.pthread_cond_t, -} - -_cond_wait :: proc(c: ^Cond, m: ^Mutex) { - err := unix.pthread_cond_wait(&c.impl.pthread_cond, &m.impl.pthread_mutex) - assert(err == 0) -} - - -_cond_wait_with_timeout :: proc(c: ^Cond, m: ^Mutex, duration: time.Duration) -> bool { - tv_sec := i64(duration/1e9) - tv_nsec := i64(duration%1e9) - err := unix.pthread_cond_timedwait(&c.impl.pthread_cond, &m.impl.pthread_mutex, &{tv_sec, tv_nsec}) - return err == 0 -} - - -_cond_signal :: proc(c: ^Cond) { - err := unix.pthread_cond_signal(&c.impl.pthread_cond) - assert(err == 0) -} - -_cond_broadcast :: proc(c: ^Cond) { - err := unix.pthread_cond_broadcast(&c.impl.pthread_cond) - assert(err == 0) -} diff --git a/core/sync/sync_darwin.odin b/core/sync/sync_darwin.odin deleted file mode 100644 index f3bb4d5a3..000000000 --- a/core/sync/sync_darwin.odin +++ /dev/null @@ -1,54 +0,0 @@ -package sync - -import "core:sys/darwin" - -import "core:c" - -foreign import pthread "System.framework" - -current_thread_id :: proc "contextless" () -> int { - tid: u64 - // NOTE(Oskar): available from OSX 10.6 and iOS 3.2. - // For older versions there is `syscall(SYS_thread_selfid)`, but not really - // the same thing apparently. - foreign pthread { pthread_threadid_np :: proc "c" (rawptr, ^u64) -> c.int --- } - pthread_threadid_np(nil, &tid) - return int(tid) -} - - -// The Darwin docs say it best: -// A semaphore is much like a lock, except that a finite number of threads can hold it simultaneously. -// Semaphores can be thought of as being much like piles of tokens; multiple threads can take these tokens, -// but when there are none left, a thread must wait until another thread returns one. -Semaphore :: struct #align 16 { - handle: darwin.semaphore_t, -} -// TODO(tetra): Only marked with alignment because we cannot mark distinct integers with alignments. -// See core/sys/unix/pthread_linux.odin/pthread_t. - -semaphore_init :: proc(s: ^Semaphore, initial_count := 0) { - ct := darwin.mach_task_self() - res := darwin.semaphore_create(ct, &s.handle, 0, c.int(initial_count)) - assert(res == 0) -} - -semaphore_destroy :: proc(s: ^Semaphore) { - ct := darwin.mach_task_self() - res := darwin.semaphore_destroy(ct, s.handle) - assert(res == 0) - s.handle = {} -} - -semaphore_post :: proc(s: ^Semaphore, count := 1) { - // NOTE: SPEED: If there's one syscall to do this, we should use it instead of the loop. - for in 0.. int { - SYS_GETTID :: 186; - return int(intrinsics.syscall(SYS_GETTID)); -} - - -// The Darwin docs say it best: -// A semaphore is much like a lock, except that a finite number of threads can hold it simultaneously. -// Semaphores can be thought of as being much like piles of tokens; multiple threads can take these tokens, -// but when there are none left, a thread must wait until another thread returns one. -Semaphore :: struct #align 16 { - handle: unix.sem_t, -} - -semaphore_init :: proc(s: ^Semaphore, initial_count := 0) { - assert(unix.sem_init(&s.handle, 0, u32(initial_count)) == 0); -} - -semaphore_destroy :: proc(s: ^Semaphore) { - assert(unix.sem_destroy(&s.handle) == 0); - s.handle = {}; -} - -semaphore_post :: proc(s: ^Semaphore, count := 1) { - // NOTE: SPEED: If there's one syscall to do this, we should use it instead of the loop. - for in 0.. int { - return unix.sys_gettid() -} - - -// The Darwin docs say it best: -// A semaphore is much like a lock, except that a finite number of threads can hold it simultaneously. -// Semaphores can be thought of as being much like piles of tokens; multiple threads can take these tokens, -// but when there are none left, a thread must wait until another thread returns one. -Semaphore :: struct #align 16 { - handle: unix.sem_t, -} - -semaphore_init :: proc(s: ^Semaphore, initial_count := 0) { - assert(unix.sem_init(&s.handle, 0, u32(initial_count)) == 0) -} - -semaphore_destroy :: proc(s: ^Semaphore) { - assert(unix.sem_destroy(&s.handle) == 0) - s.handle = {} -} - -semaphore_post :: proc(s: ^Semaphore, count := 1) { - // NOTE: SPEED: If there's one syscall to do this, we should use it instead of the loop. - for in 0.. bool { - return unix.pthread_mutex_trylock(&m.handle) == 0 -} - -mutex_unlock :: proc(m: ^Mutex) { - assert(unix.pthread_mutex_unlock(&m.handle) == 0) -} - - -Blocking_Mutex :: struct { - handle: unix.pthread_mutex_t, -} - - -blocking_mutex_init :: proc(m: ^Blocking_Mutex) { - // NOTE(tetra, 2019-11-01): POSIX OOM if we cannot init the attrs or the mutex. - attrs: unix.pthread_mutexattr_t - assert(unix.pthread_mutexattr_init(&attrs) == 0) - defer unix.pthread_mutexattr_destroy(&attrs) // ignores destruction error - - assert(unix.pthread_mutex_init(&m.handle, &attrs) == 0) -} - -blocking_mutex_destroy :: proc(m: ^Blocking_Mutex) { - assert(unix.pthread_mutex_destroy(&m.handle) == 0) - m.handle = {} -} - -blocking_mutex_lock :: proc(m: ^Blocking_Mutex) { - assert(unix.pthread_mutex_lock(&m.handle) == 0) -} - -// Returns false if someone else holds the lock. -blocking_mutex_try_lock :: proc(m: ^Blocking_Mutex) -> bool { - return unix.pthread_mutex_trylock(&m.handle) == 0 -} - -blocking_mutex_unlock :: proc(m: ^Blocking_Mutex) { - assert(unix.pthread_mutex_unlock(&m.handle) == 0) -} - - - -// Blocks until signalled, and then lets past exactly -// one thread. -Condition :: struct { - handle: unix.pthread_cond_t, - mutex: Condition_Mutex_Ptr, - - // NOTE(tetra, 2019-11-11): Used to mimic the more sane behavior of Windows' AutoResetEvent. - // This means that you may signal the condition before anyone is waiting to cause the - // next thread that tries to wait to just pass by uninterrupted, without sleeping. - // Without this, signalling a condition will only wake up a thread which is already waiting, - // but not one that is about to wait, which can cause your program to become out of sync in - // ways that are hard to debug or fix. - flag: bool, // atomically mutated -} - -condition_init :: proc(c: ^Condition, mutex: Condition_Mutex_Ptr) -> bool { - // NOTE(tetra, 2019-11-01): POSIX OOM if we cannot init the attrs or the condition. - attrs: unix.pthread_condattr_t - if unix.pthread_condattr_init(&attrs) != 0 { - return false - } - defer unix.pthread_condattr_destroy(&attrs) // ignores destruction error - - c.flag = false - c.mutex = mutex - return unix.pthread_cond_init(&c.handle, &attrs) == 0 -} - -condition_destroy :: proc(c: ^Condition) { - assert(unix.pthread_cond_destroy(&c.handle) == 0) - c.handle = {} -} - -// Awaken exactly one thread who is waiting on the condition -condition_signal :: proc(c: ^Condition) -> bool { - switch m in c.mutex { - case ^Mutex: - mutex_lock(m) - defer mutex_unlock(m) - atomic_swap(&c.flag, true, .Sequentially_Consistent) - return unix.pthread_cond_signal(&c.handle) == 0 - case ^Blocking_Mutex: - blocking_mutex_lock(m) - defer blocking_mutex_unlock(m) - atomic_swap(&c.flag, true, .Sequentially_Consistent) - return unix.pthread_cond_signal(&c.handle) == 0 - } - return false -} - -// Awaken all threads who are waiting on the condition -condition_broadcast :: proc(c: ^Condition) -> bool { - return unix.pthread_cond_broadcast(&c.handle) == 0 -} - -// Wait for the condition to be signalled. -// Does not block if the condition has been signalled and no one -// has waited on it yet. -condition_wait_for :: proc(c: ^Condition) -> bool { - switch m in c.mutex { - case ^Mutex: - mutex_lock(m) - defer mutex_unlock(m) - // NOTE(tetra): If a thread comes by and steals the flag immediately after the signal occurs, - // the thread that gets signalled and wakes up, discovers that the flag was taken and goes - // back to sleep. - // Though this overall behavior is the most sane, there may be a better way to do this that means that - // the first thread to wait, gets the flag first. - if atomic_swap(&c.flag, false, .Sequentially_Consistent) { - return true - } - for { - if unix.pthread_cond_wait(&c.handle, &m.handle) != 0 { - return false - } - if atomic_swap(&c.flag, false, .Sequentially_Consistent) { - return true - } - } - return false - - case ^Blocking_Mutex: - blocking_mutex_lock(m) - defer blocking_mutex_unlock(m) - // NOTE(tetra): If a thread comes by and steals the flag immediately after the signal occurs, - // the thread that gets signalled and wakes up, discovers that the flag was taken and goes - // back to sleep. - // Though this overall behavior is the most sane, there may be a better way to do this that means that - // the first thread to wait, gets the flag first. - if atomic_swap(&c.flag, false, .Sequentially_Consistent) { - return true - } - for { - if unix.pthread_cond_wait(&c.handle, &m.handle) != 0 { - return false - } - if atomic_swap(&c.flag, false, .Sequentially_Consistent) { - return true - } - } - return false - } - return false -} - -// Wait for the condition to be signalled. -// Does not block if the condition has been signalled and no one -// has waited on it yet. -condition_wait_for_timeout :: proc(c: ^Condition, duration: time.Duration) -> bool { - switch m in c.mutex { - case ^Mutex: - mutex_lock(m) - defer mutex_unlock(m) - // NOTE(tetra): If a thread comes by and steals the flag immediately after the signal occurs, - // the thread that gets signalled and wakes up, discovers that the flag was taken and goes - // back to sleep. - // Though this overall behavior is the most sane, there may be a better way to do this that means that - // the first thread to wait, gets the flag first. - if atomic_swap(&c.flag, false, .Sequentially_Consistent) { - return true - } - - ns := time.duration_nanoseconds(duration) - timeout: time.TimeSpec - timeout.tv_sec = ns / 1e9 - timeout.tv_nsec = ns % 1e9 - - for { - if unix.pthread_cond_timedwait(&c.handle, &m.handle, &timeout) != 0 { - return false - } - if atomic_swap(&c.flag, false, .Sequentially_Consistent) { - return true - } - } - return false - - case ^Blocking_Mutex: - blocking_mutex_lock(m) - defer blocking_mutex_unlock(m) - // NOTE(tetra): If a thread comes by and steals the flag immediately after the signal occurs, - // the thread that gets signalled and wakes up, discovers that the flag was taken and goes - // back to sleep. - // Though this overall behavior is the most sane, there may be a better way to do this that means that - // the first thread to wait, gets the flag first. - if atomic_swap(&c.flag, false, .Sequentially_Consistent) { - return true - } - - ns := time.duration_nanoseconds(duration) - - timeout: time.TimeSpec - timeout.tv_sec = ns / 1e9 - timeout.tv_nsec = ns % 1e9 - - for { - if unix.pthread_cond_timedwait(&c.handle, &m.handle, &timeout) != 0 { - return false - } - if atomic_swap(&c.flag, false, .Sequentially_Consistent) { - return true - } - } - return false - } - return false -} - - - -thread_yield :: proc() { - unix.sched_yield() -} diff --git a/core/sync/sync2/sync_util.odin b/core/sync/sync_util.odin similarity index 93% rename from core/sync/sync2/sync_util.odin rename to core/sync/sync_util.odin index 853c3c685..4add9064d 100644 --- a/core/sync/sync2/sync_util.odin +++ b/core/sync/sync_util.odin @@ -1,12 +1,11 @@ -package sync2 +package sync - -// Example: -// -// if guard(&m) { -// ... -// } -// +/* +Example: + if guard(&m) { + ... + } +*/ guard :: proc{ mutex_guard, rw_mutex_guard, @@ -17,13 +16,12 @@ guard :: proc{ atomic_recursive_mutex_guard, atomic_rw_mutex_guard, } - -// Example: -// -// if shared_guard(&m) { -// ... -// } -// +/* +Example: + if shared_guard(&m) { + ... + } +*/ shared_guard :: proc{ rw_mutex_shared_guard, atomic_rw_mutex_shared_guard, diff --git a/core/sync/sync_windows.odin b/core/sync/sync_windows.odin deleted file mode 100644 index 0a7cf71b2..000000000 --- a/core/sync/sync_windows.odin +++ /dev/null @@ -1,180 +0,0 @@ -// +build windows -package sync - -import win32 "core:sys/windows" -import "core:time" - -current_thread_id :: proc "contextless" () -> int { - return int(win32.GetCurrentThreadId()) -} - - -// When waited upon, blocks until the internal count is greater than zero, then subtracts one. -// Posting to the semaphore increases the count by one, or the provided amount. -Semaphore :: struct { - _handle: win32.HANDLE, -} - -semaphore_init :: proc(s: ^Semaphore, initial_count := 0) { - s._handle = win32.CreateSemaphoreW(nil, i32(initial_count), 1<<31-1, nil) -} - -semaphore_destroy :: proc(s: ^Semaphore) { - win32.CloseHandle(s._handle) -} - -semaphore_post :: proc(s: ^Semaphore, count := 1) { - win32.ReleaseSemaphore(s._handle, i32(count), nil) -} - -semaphore_wait_for :: proc(s: ^Semaphore) { - // NOTE(tetra, 2019-10-30): wait_for_single_object decrements the count before it returns. - result := win32.WaitForSingleObject(s._handle, win32.INFINITE) - assert(result != win32.WAIT_FAILED) -} - - -Mutex :: struct { - _critical_section: win32.CRITICAL_SECTION, -} - - -mutex_init :: proc(m: ^Mutex, spin_count := 0) { - win32.InitializeCriticalSectionAndSpinCount(&m._critical_section, u32(spin_count)) -} - -mutex_destroy :: proc(m: ^Mutex) { - win32.DeleteCriticalSection(&m._critical_section) -} - -mutex_lock :: proc(m: ^Mutex) { - win32.EnterCriticalSection(&m._critical_section) -} - -mutex_try_lock :: proc(m: ^Mutex) -> bool { - return bool(win32.TryEnterCriticalSection(&m._critical_section)) -} - -mutex_unlock :: proc(m: ^Mutex) { - win32.LeaveCriticalSection(&m._critical_section) -} - -Blocking_Mutex :: struct { - _handle: win32.SRWLOCK, -} - - -blocking_mutex_init :: proc(m: ^Blocking_Mutex) { - win32.InitializeSRWLock(&m._handle) -} - -blocking_mutex_destroy :: proc(m: ^Blocking_Mutex) { - // -} - -blocking_mutex_lock :: proc(m: ^Blocking_Mutex) { - win32.AcquireSRWLockExclusive(&m._handle) -} - -blocking_mutex_try_lock :: proc(m: ^Blocking_Mutex) -> bool { - return bool(win32.TryAcquireSRWLockExclusive(&m._handle)) -} - -blocking_mutex_unlock :: proc(m: ^Blocking_Mutex) { - win32.ReleaseSRWLockExclusive(&m._handle) -} - - -// Blocks until signalled. -// When signalled, awakens exactly one waiting thread. -Condition :: struct { - _handle: win32.CONDITION_VARIABLE, - - mutex: Condition_Mutex_Ptr, -} - - -condition_init :: proc(c: ^Condition, mutex: Condition_Mutex_Ptr) -> bool { - assert(mutex != nil) - win32.InitializeConditionVariable(&c._handle) - c.mutex = mutex - return true -} - -condition_destroy :: proc(c: ^Condition) { - // -} - -condition_signal :: proc(c: ^Condition) -> bool { - if c._handle.ptr == nil { - return false - } - win32.WakeConditionVariable(&c._handle) - return true -} - -condition_broadcast :: proc(c: ^Condition) -> bool { - if c._handle.ptr == nil { - return false - } - win32.WakeAllConditionVariable(&c._handle) - return true -} - -condition_wait_for :: proc(c: ^Condition) -> bool { - switch m in &c.mutex { - case ^Mutex: - return cast(bool)win32.SleepConditionVariableCS(&c._handle, &m._critical_section, win32.INFINITE) - case ^Blocking_Mutex: - return cast(bool)win32.SleepConditionVariableSRW(&c._handle, &m._handle, win32.INFINITE, 0) - } - return false -} -condition_wait_for_timeout :: proc(c: ^Condition, duration: time.Duration) -> bool { - ms := win32.DWORD((max(time.duration_nanoseconds(duration), 0) + 999999)/1000000) - switch m in &c.mutex { - case ^Mutex: - return cast(bool)win32.SleepConditionVariableCS(&c._handle, &m._critical_section, ms) - case ^Blocking_Mutex: - return cast(bool)win32.SleepConditionVariableSRW(&c._handle, &m._handle, ms, 0) - } - return false -} - - - - -RW_Lock :: struct { - _handle: win32.SRWLOCK, -} - -rw_lock_init :: proc(l: ^RW_Lock) { - l._handle = win32.SRWLOCK_INIT -} -rw_lock_destroy :: proc(l: ^RW_Lock) { - // -} -rw_lock_read :: proc(l: ^RW_Lock) { - win32.AcquireSRWLockShared(&l._handle) -} -rw_lock_try_read :: proc(l: ^RW_Lock) -> bool { - return bool(win32.TryAcquireSRWLockShared(&l._handle)) -} -rw_lock_write :: proc(l: ^RW_Lock) { - win32.AcquireSRWLockExclusive(&l._handle) -} -rw_lock_try_write :: proc(l: ^RW_Lock) -> bool { - return bool(win32.TryAcquireSRWLockExclusive(&l._handle)) -} -rw_lock_read_unlock :: proc(l: ^RW_Lock) { - win32.ReleaseSRWLockShared(&l._handle) -} -rw_lock_write_unlock :: proc(l: ^RW_Lock) { - win32.ReleaseSRWLockExclusive(&l._handle) -} - - -thread_yield :: proc() { - win32.SwitchToThread() -} - diff --git a/core/sync/wait_group.odin b/core/sync/wait_group.odin deleted file mode 100644 index 63d882ed1..000000000 --- a/core/sync/wait_group.odin +++ /dev/null @@ -1,58 +0,0 @@ -package sync - -import "core:intrinsics" - -Wait_Group :: struct { - counter: int, - mutex: Blocking_Mutex, - cond: Condition, -} - -wait_group_init :: proc(wg: ^Wait_Group) { - wg.counter = 0 - blocking_mutex_init(&wg.mutex) - condition_init(&wg.cond, &wg.mutex) -} - - -wait_group_destroy :: proc(wg: ^Wait_Group) { - condition_destroy(&wg.cond) - blocking_mutex_destroy(&wg.mutex) -} - -wait_group_add :: proc(wg: ^Wait_Group, delta: int) { - if delta == 0 { - return - } - - blocking_mutex_lock(&wg.mutex) - defer blocking_mutex_unlock(&wg.mutex) - - intrinsics.atomic_add(&wg.counter, delta) - if wg.counter < 0 { - panic("sync.Wait_Group negative counter") - } - if wg.counter == 0 { - condition_broadcast(&wg.cond) - if wg.counter != 0 { - panic("sync.Wait_Group misuse: sync.wait_group_add called concurrently with sync.wait_group_wait") - } - } -} - -wait_group_done :: proc(wg: ^Wait_Group) { - wait_group_add(wg, -1) -} - -wait_group_wait :: proc(wg: ^Wait_Group) { - blocking_mutex_lock(&wg.mutex) - defer blocking_mutex_unlock(&wg.mutex) - - if wg.counter != 0 { - condition_wait_for(&wg.cond) - if wg.counter != 0 { - panic("sync.Wait_Group misuse: sync.wait_group_add called concurrently with sync.wait_group_wait") - } - } -} - diff --git a/core/sys/cpu/cpu_x86.odin b/core/sys/cpu/cpu_x86.odin index 8f3560a87..146822e61 100644 --- a/core/sys/cpu/cpu_x86.odin +++ b/core/sys/cpu/cpu_x86.odin @@ -1,4 +1,4 @@ -//+build 386, amd64 +//+build i386, amd64 package sys_cpu _cache_line_size :: 64; diff --git a/core/sys/darwin/xnu_system_call_helpers.odin b/core/sys/darwin/xnu_system_call_helpers.odin new file mode 100644 index 000000000..94fe0bf47 --- /dev/null +++ b/core/sys/darwin/xnu_system_call_helpers.odin @@ -0,0 +1,168 @@ +package darwin + +import "core:strings" +import "core:c" + +// this package uses the sys prefix for the proc names to indicate that these aren't native syscalls but directly call such +sys_write_string :: proc (fd: c.int, message: string) -> bool { + return syscall_write(fd, strings.ptr_from_string(message), cast(u64)len(message)) +} + +Offset_From :: enum c.int { + SEEK_SET = 0, // the offset is set to offset bytes. + SEEK_CUR = 1, // the offset is set to its current location plus offset bytes. + SEEK_END = 2, // the offset is set to the size of the file plus offset bytes. + SEEK_HOLE = 3, // the offset is set to the start of the next hole greater than or equal to the supplied offset. + SEEK_DATA = 4, // the offset is set to the start of the next non-hole file region greater than or equal to the supplied offset. +} + +Open_Flags_Enum :: enum u8 { + RDONLY, /* open for reading only */ + WRONLY, /* open for writing only */ + RDWR, /* open for reading and writing */ + + NONBLOCK, /* no delay */ + APPEND, /* set append mode */ + CREAT, /* create if nonexistant */ + TRUNC, /* truncate to zero length */ + EXCL, /* error if already exists */ + SHLOCK, /* open with shared file lock */ + EXLOCK, /* open with exclusive file lock */ + DIRECTORY, /* restrict open to only directories */ + NOFOLLOW, /* don't follow symlinks */ + SYMLINK, /* allow open of a symlink */ + EVTONLY, /* descriptor requested for event notifications only */ + CLOEXEC, /* causes the descriptor to be closed if you use any of the exec like functions */ + NOFOLLOW_ANY, /* no symlinks allowed in path */ +} +Open_Flags :: bit_set[Open_Flags_Enum; u16] + +Permission_Enum :: enum u8 { + /* For owner */ + PERMISSION_OWNER_READ, /* R for owner */ + PERMISSION_OWNER_WRITE, /* W for owner */ + PERMISSION_OWNER_EXECUTE, /* X for owner */ + //IRWXU, /* RWX mask for owner */ + + /* For group */ + PERMISSION_GROUP_READ, /* R for group */ + PERMISSION_GROUP_WRITE, /* W for group */ + PERMISSION_GROUP_EXECUTE, /* X for group */ + //IRWXG, /* RWX mask for group */ + + /* For other */ + PERMISSION_OTHER_READ, /* R for other */ + PERMISSION_OTHER_WRITE, /* W for other */ + PERMISSION_OTHER_EXECUTE, /* X for other */ + //IRWXO, /* RWX mask for other */ + + /* Special */ + PERMISSION_SET_USER_ON_EXECUTION, /* set user id on execution */ + PERMISSION_SET_GROUP_ON_EXECUTION, /* set group id on execution */ + + /* ?? */ + PERMISSION_ISVTX, /* save swapped text even after use */ +} +Permission :: bit_set[Permission_Enum; u16] + +PERMISSION_NONE_NONE :: Permission{} +PERMISSION_OWNER_ALL :: Permission{.PERMISSION_OWNER_READ, .PERMISSION_OWNER_WRITE, .PERMISSION_OWNER_EXECUTE} +PERMISSION_GROUP_ALL :: Permission{.PERMISSION_GROUP_READ, .PERMISSION_GROUP_WRITE, .PERMISSION_GROUP_EXECUTE} +PERMISSION_OTHER_ALL :: Permission{.PERMISSION_OTHER_READ, .PERMISSION_OTHER_WRITE, .PERMISSION_OTHER_EXECUTE} +PERMISSION_ALL_ALL :: PERMISSION_OWNER_ALL | PERMISSION_GROUP_ALL | PERMISSION_OTHER_ALL + +_sys_permission_mode :: #force_inline proc (mode: Permission) -> u32 { + cflags: u32 = 0 + + cflags |= PERMISSION_MASK_IRUSR * u32(Permission.PERMISSION_OWNER_READ in mode) + cflags |= PERMISSION_MASK_IWUSR * u32(Permission.PERMISSION_OWNER_WRITE in mode) + cflags |= PERMISSION_MASK_IXUSR * u32(Permission.PERMISSION_OWNER_WRITE in mode) + cflags |= PERMISSION_MASK_IRGRP * u32(Permission.PERMISSION_GROUP_READ in mode) + cflags |= PERMISSION_MASK_IWGRP * u32(Permission.PERMISSION_GROUP_WRITE in mode) + cflags |= PERMISSION_MASK_IXGRP * u32(Permission.PERMISSION_GROUP_WRITE in mode) + cflags |= PERMISSION_MASK_IROTH * u32(Permission.PERMISSION_OTHER_READ in mode) + cflags |= PERMISSION_MASK_IWOTH * u32(Permission.PERMISSION_OTHER_WRITE in mode) + cflags |= PERMISSION_MASK_IXOTH * u32(Permission.PERMISSION_OTHER_WRITE in mode) + + return cflags +} + +sys_open :: proc(path: string, oflag: Open_Flags, mode: Permission) -> (c.int, bool) { + + cmode: u32 = 0 + cflags: u32 = 0 + cpath: cstring = strings.clone_to_cstring(path, context.temp_allocator) + + cflags = _sys_permission_mode(mode) + + cmode |= OPEN_FLAG_RDONLY * u32(Open_Flags.RDONLY in oflag) + cmode |= OPEN_FLAG_WRONLY * u32(Open_Flags.WRONLY in oflag) + cmode |= OPEN_FLAG_RDWR * u32(Open_Flags.RDWR in oflag) + cmode |= OPEN_FLAG_NONBLOCK * u32(Open_Flags.NONBLOCK in oflag) + cmode |= OPEN_FLAG_CREAT * u32(Open_Flags.CREAT in oflag) + cmode |= OPEN_FLAG_APPEND * u32(Open_Flags.APPEND in oflag) + cmode |= OPEN_FLAG_TRUNC * u32(Open_Flags.TRUNC in oflag) + cmode |= OPEN_FLAG_EXCL * u32(Open_Flags.EXCL in oflag) + cmode |= OPEN_FLAG_SHLOCK * u32(Open_Flags.SHLOCK in oflag) + cmode |= OPEN_FLAG_EXLOCK * u32(Open_Flags.EXLOCK in oflag) + cmode |= OPEN_FLAG_DIRECTORY * u32(Open_Flags.DIRECTORY in oflag) + cmode |= OPEN_FLAG_NOFOLLOW * u32(Open_Flags.NOFOLLOW in oflag) + cmode |= OPEN_FLAG_SYMLINK * u32(Open_Flags.SYMLINK in oflag) + cmode |= OPEN_FLAG_EVTONLY * u32(Open_Flags.EVTONLY in oflag) + cmode |= OPEN_FLAG_CLOEXEC * u32(Open_Flags.CLOEXEC in oflag) + cmode |= OPEN_FLAG_NOFOLLOW_ANY * u32(Open_Flags.NOFOLLOW_ANY in oflag) + + result := syscall_open(cpath, cmode, cflags) + state := result != -1 + + if state && cflags != 0 { + state = (syscall_fchmod(result, cflags) != -1) + } + + return result * cast(c.int)state, state +} + +sys_mkdir :: proc(path: string, mode: Permission) -> bool { + cpath: cstring = strings.clone_to_cstring(path, context.temp_allocator) + cflags := _sys_permission_mode(mode) + return syscall_mkdir(cpath, cflags) != -1 +} + +sys_mkdir_at :: proc(fd: c.int, path: string, mode: Permission) -> bool { + cpath: cstring = strings.clone_to_cstring(path, context.temp_allocator) + cflags := _sys_permission_mode(mode) + return syscall_mkdir_at(fd, cpath, cflags) != -1 +} + +sys_rmdir :: proc(path: string, mode: Permission) -> bool { + cpath: cstring = strings.clone_to_cstring(path, context.temp_allocator) + cflags := _sys_permission_mode(mode) + return syscall_rmdir(cpath, cflags) != -1 +} + +sys_rename :: proc(path: string, new_path: string) -> bool { + cpath: cstring = strings.clone_to_cstring(path, context.temp_allocator) + cnpath: cstring = strings.clone_to_cstring(new_path, context.temp_allocator) + return syscall_rename(cpath, cnpath) != -1 +} + +sys_rename_at :: proc(fd: c.int, path: string, to_fd: c.int, new_path: string) -> bool { + cpath: cstring = strings.clone_to_cstring(path, context.temp_allocator) + cnpath: cstring = strings.clone_to_cstring(new_path, context.temp_allocator) + return syscall_rename_at(fd, cpath, to_fd, cnpath) != -1 +} + +sys_lseek :: proc(fd: c.int, offset: i64, whence: Offset_From) -> i64 { + return syscall_lseek(fd, offset, cast(c.int)whence) +} + +sys_chmod :: proc(path: string, mode: Permission) -> bool { + cpath: cstring = strings.clone_to_cstring(path, context.temp_allocator) + cmode := _sys_permission_mode(mode) + return syscall_chmod(cpath, cmode) != -1 +} + +sys_lstat :: proc(path: string, status: ^stat) -> bool { + cpath: cstring = strings.clone_to_cstring(path, context.temp_allocator) + return syscall_lstat(cpath, status) != -1 +} diff --git a/core/sys/darwin/xnu_system_call_numbers.odin b/core/sys/darwin/xnu_system_call_numbers.odin new file mode 100644 index 000000000..b90373fdc --- /dev/null +++ b/core/sys/darwin/xnu_system_call_numbers.odin @@ -0,0 +1,558 @@ +package darwin + +unix_offset_syscall :: proc(number: System_Call_Number) -> uintptr { + return uintptr(number) + uintptr(0x2000000) +} + +System_Call_Number :: enum uintptr { + /* 0 syscall */ + exit = 1, + fork = 2, + read = 3, + write = 4, + open = 5, + close = 6, + wait4 = 7, + /* 8 old creat */ + link = 9, + unlink = 10, + /* 11 old execv */ + chdir = 12, + fchdir = 13, + mknod = 14, + chmod = 15, + chown = 16, + /* 17 old break */ + getfsstat = 18, + /* 19 old lseek */ + getpid = 20, + /* 21 old mount */ + /* 22 old umount */ + setuid = 23, + getuid = 24, + geteuid = 25, + ptrace = 26, + recvmsg = 27, + sendmsg = 28, + recvfrom = 29, + accept = 30, + getpeername = 31, + getsockname = 32, + access = 33, + chflags = 34, + fchflags = 35, + sync = 36, + kill = 37, + /* 38 old stat */ + getppid = 39, + /* 40 old lstat */ + dup = 41, + pipe = 42, + getegid = 43, + /* 44 old profil */ + /* 45 old ktrace */ + sigaction = 46, + getgid = 47, + sigprocmask = 48, + getlogin = 49, + setlogin = 50, + acct = 51, + sigpending = 52, + sigaltstack = 53, + ioctl = 54, + reboot = 55, + revoke = 56, + symlink = 57, + readlink = 58, + execve = 59, + umask = 60, + chroot = 61, + /* 62 old fstat */ + /* 63 used internally and reserved */ + /* getpagesize = 64, invalid */ + msync = 65, + vfork = 66, + /* 67 old vread */ + /* 68 old vwrite */ + /* 69 old sbrk */ + /* 70 old sstk */ + /* 71 old mmap */ + /* 72 old vadvise */ + munmap = 73, + mprotect = 74, + madvise = 75, + /* 76 old vhangup */ + /* 77 old vlimit */ + mincore = 78, + getgroups = 79, + setgroups = 80, + getpgrp = 81, + setpgid = 82, + setitimer = 83, + /* 84 old wait */ + swapon = 85, + getitimer = 86, + /* 87 old gethostname */ + /* 88 old sethostname */ + getdtablesize = 89, + dup2 = 90, + /* 91 old getdopt */ + fcntl = 92, + select = 93, + /* 94 old setdopt */ + fsync = 95, + setpriority = 96, + socket = 97, + connect = 98, + /* 99 old accept */ + getpriority = 100, + /* 101 old send */ + /* 102 old recv */ + /* 103 old sigreturn */ + bind = 104, + setsockopt = 105, + listen = 106, + /* 107 old vtimes */ + /* 108 old sigvec */ + /* 109 old sigblock */ + /* 110 old sigsetmask */ + sigsuspend = 111, + /* 112 old sigstack */ + /* 113 old recvmsg */ + /* 114 old sendmsg */ + /* 115 old vtrace */ + gettimeofday = 116, + getrusage = 117, + getsockopt = 118, + /* 119 old resuba */ + readv = 120, + writev = 121, + settimeofday = 122, + fchown = 123, + fchmod = 124, + /* 125 old recvfrom */ + setreuid = 126, + setregid = 127, + rename = 128, + /* 129 old truncate */ + /* 130 old ftruncate */ + flock = 131, + mkfifo = 132, + sendto = 133, + shutdown = 134, + socketpair = 135, + mkdir = 136, + rmdir = 137, + utimes = 138, + futimes = 139, + adjtime = 140, + /* 141 old getpeername */ + gethostuuid = 142, + /* 143 old sethostid */ + /* 144 old getrlimit */ + /* 145 old setrlimit */ + /* 146 old killpg */ + setsid = 147, + /* 148 old setquota */ + /* 149 old qquota */ + /* 150 old getsockname */ + getpgid = 151, + setprivexec = 152, + pread = 153, + pwrite = 154, + nfssvc = 155, + /* 156 old getdirentries */ + statfs = 157, + fstatfs = 158, + unmount = 159, + /* 160 old async_daemon */ + getfh = 161, + /* 162 old getdomainname */ + /* 163 old setdomainname */ + /* 164 */ + quotactl = 165, + /* 166 old exportfs */ + mount = 167, + /* 168 old ustat */ + csops = 169, + csops_audittoken = 170, + /* 171 old wait3 */ + /* 172 old rpause */ + waitid = 173, + /* 174 old getdents */ + /* 175 old gc_control */ + /* 176 old add_profil */ + kdebug_typefilter = 177, + kdebug_trace_string = 178, + kdebug_trace64 = 179, + kdebug_trace = 180, + setgid = 181, + setegid = 182, + seteuid = 183, + sigreturn = 184, + /* 185 old chud */ + thread_selfcounts = 186, + fdatasync = 187, + stat = 188, + fstat = 189, + lstat = 190, + pathconf = 191, + fpathconf = 192, + /* 193 old getfsstat */ + getrlimit = 194, + setrlimit = 195, + getdirentries = 196, + mmap = 197, + /* 198 old __syscall */ + lseek = 199, + truncate = 200, + ftruncate = 201, + sysctl = 202, + mlock = 203, + munlock = 204, + undelete = 205, + /* 206 old ATsocket */ + /* 207 old ATgetmsg */ + /* 208 old ATputmsg */ + /* 209 old ATsndreq */ + /* 210 old ATsndrsp */ + /* 211 old ATgetreq */ + /* 212 old ATgetrsp */ + /* 213 Reserved for AppleTalk */ + /* 214 */ + /* 215 */ + open_dprotected_np = 216, + fsgetpath_ext = 217, + /* 218 old lstatv */ + /* 219 old fstatv */ + getattrlist = 220, + setattrlist = 221, + getdirentriesattr = 222, + exchangedata = 223, + /* 224 old checkuseraccess or fsgetpath */ + searchfs = 225, + delete = 226, + copyfile = 227, + fgetattrlist = 228, + fsetattrlist = 229, + poll = 230, + /* 231 old watchevent */ + /* 232 old waitevent */ + /* 233 old modwatch */ + getxattr = 234, + fgetxattr = 235, + setxattr = 236, + fsetxattr = 237, + removexattr = 238, + fremovexattr = 239, + listxattr = 240, + flistxattr = 241, + fsctl = 242, + initgroups = 243, + posix_spawn = 244, + ffsctl = 245, + /* 246 */ + nfsclnt = 247, + fhopen = 248, + /* 249 */ + minherit = 250, + semsys = 251, + msgsys = 252, + shmsys = 253, + semctl = 254, + semget = 255, + semop = 256, + /* 257 old semconfig */ + msgctl = 258, + msgget = 259, + msgsnd = 260, + msgrcv = 261, + shmat = 262, + shmctl = 263, + shmdt = 264, + shmget = 265, + shm_open = 266, + shm_unlink = 267, + sem_open = 268, + sem_close = 269, + sem_unlink = 270, + sem_wait = 271, + sem_trywait = 272, + sem_post = 273, + sysctlbyname = 274, + /* 275 old sem_init */ + /* 276 old sem_destroy */ + open_extended = 277, + umask_extended = 278, + stat_extended = 279, + lstat_extended = 280, + fstat_extended = 281, + chmod_extended = 282, + fchmod_extended = 283, + access_extended = 284, + settid = 285, + gettid = 286, + setsgroups = 287, + getsgroups = 288, + setwgroups = 289, + getwgroups = 290, + mkfifo_extended = 291, + mkdir_extended = 292, + identitysvc = 293, + shared_region_check_np = 294, + /* 295 old shared_region_map_np */ + vm_pressure_monitor = 296, + psynch_rw_longrdlock = 297, + psynch_rw_yieldwrlock = 298, + psynch_rw_downgrade = 299, + psynch_rw_upgrade = 300, + psynch_mutexwait = 301, + psynch_mutexdrop = 302, + psynch_cvbroad = 303, + psynch_cvsignal = 304, + psynch_cvwait = 305, + psynch_rw_rdlock = 306, + psynch_rw_wrlock = 307, + psynch_rw_unlock = 308, + psynch_rw_unlock2 = 309, + getsid = 310, + settid_with_pid = 311, + psynch_cvclrprepost = 312, + aio_fsync = 313, + aio_return = 314, + aio_suspend = 315, + aio_cancel = 316, + aio_error = 317, + aio_read = 318, + aio_write = 319, + lio_listio = 320, + /* 321 old __pthread_cond_wait */ + iopolicysys = 322, + process_policy = 323, + mlockall = 324, + munlockall = 325, + /* 326 */ + issetugid = 327, + __pthread_kill = 328, + __pthread_sigmask = 329, + __sigwait = 330, + __disable_threadsignal = 331, + __pthread_markcancel = 332, + __pthread_canceled = 333, + __semwait_signal = 334, + /* 335 old utrace */ + proc_info = 336, + sendfile = 337, + stat64 = 338, + fstat64 = 339, + lstat64 = 340, + stat64_extended = 341, + lstat64_extended = 342, + fstat64_extended = 343, + getdirentries64 = 344, + statfs64 = 345, + fstatfs64 = 346, + getfsstat64 = 347, + __pthread_chdir = 348, + __pthread_fchdir = 349, + audit = 350, + auditon = 351, + /* 352 */ + getauid = 353, + setauid = 354, + /* 355 old getaudit */ + /* 356 old setaudit */ + getaudit_addr = 357, + setaudit_addr = 358, + auditctl = 359, + bsdthread_create = 360, + bsdthread_terminate = 361, + kqueue = 362, + kevent = 363, + lchown = 364, + /* 365 old stack_snapshot */ + bsdthread_register = 366, + workq_open = 367, + workq_kernreturn = 368, + kevent64 = 369, + __old_semwait_signal = 370, + __old_semwait_signal_nocancel = 371, + thread_selfid = 372, + ledger = 373, + kevent_qos = 374, + kevent_id = 375, + /* 376 */ + /* 377 */ + /* 378 */ + /* 379 */ + __mac_execve = 380, + __mac_syscall = 381, + __mac_get_file = 382, + __mac_set_file = 383, + __mac_get_link = 384, + __mac_set_link = 385, + __mac_get_proc = 386, + __mac_set_proc = 387, + __mac_get_fd = 388, + __mac_set_fd = 389, + __mac_get_pid = 390, + /* 391 */ + /* 392 */ + /* 393 */ + pselect = 394, + pselect_nocancel = 395, + read_nocancel = 396, + write_nocancel = 397, + open_nocancel = 398, + close_nocancel = 399, + wait4_nocancel = 400, + recvmsg_nocancel = 401, + sendmsg_nocancel = 402, + recvfrom_nocancel = 403, + accept_nocancel = 404, + msync_nocancel = 405, + fcntl_nocancel = 406, + select_nocancel = 407, + fsync_nocancel = 408, + connect_nocancel = 409, + sigsuspend_nocancel = 410, + readv_nocancel = 411, + writev_nocancel = 412, + sendto_nocancel = 413, + pread_nocancel = 414, + pwrite_nocancel = 415, + waitid_nocancel = 416, + poll_nocancel = 417, + msgsnd_nocancel = 418, + msgrcv_nocancel = 419, + sem_wait_nocancel = 420, + aio_suspend_nocancel = 421, + __sigwait_nocancel = 422, + __semwait_signal_nocancel = 423, + __mac_mount = 424, + __mac_get_mount = 425, + __mac_getfsstat = 426, + fsgetpath = 427, + audit_session_self = 428, + audit_session_join = 429, + fileport_makeport = 430, + fileport_makefd = 431, + audit_session_port = 432, + pid_suspend = 433, + pid_resume = 434, + pid_hibernate = 435, + pid_shutdown_sockets = 436, + /* 437 old shared_region_slide_np */ + shared_region_map_and_slide_np = 438, + kas_info = 439, + memorystatus_control = 440, + guarded_open_np = 441, + guarded_close_np = 442, + guarded_kqueue_np = 443, + change_fdguard_np = 444, + usrctl = 445, + proc_rlimit_control = 446, + connectx = 447, + disconnectx = 448, + peeloff = 449, + socket_delegate = 450, + telemetry = 451, + proc_uuid_policy = 452, + memorystatus_get_level = 453, + system_override = 454, + vfs_purge = 455, + sfi_ctl = 456, + sfi_pidctl = 457, + coalition = 458, + coalition_info = 459, + necp_match_policy = 460, + getattrlistbulk = 461, + clonefileat = 462, + openat = 463, + openat_nocancel = 464, + renameat = 465, + faccessat = 466, + fchmodat = 467, + fchownat = 468, + fstatat = 469, + fstatat64 = 470, + linkat = 471, + unlinkat = 472, + readlinkat = 473, + symlinkat = 474, + mkdirat = 475, + getattrlistat = 476, + proc_trace_log = 477, + bsdthread_ctl = 478, + openbyid_np = 479, + recvmsg_x = 480, + sendmsg_x = 481, + thread_selfusage = 482, + csrctl = 483, + guarded_open_dprotected_np = 484, + guarded_write_np = 485, + guarded_pwrite_np = 486, + guarded_writev_np = 487, + renameatx_np = 488, + mremap_encrypted = 489, + netagent_trigger = 490, + stack_snapshot_with_config = 491, + microstackshot = 492, + grab_pgo_data = 493, + persona = 494, + /* 495 */ + mach_eventlink_signal = 496, + mach_eventlink_wait_until = 497, + mach_eventlink_signal_wait_until = 498, + work_interval_ctl = 499, + getentropy = 500, + necp_open = 501, + necp_client_action = 502, + nexus_open = 503, // for those who are intressted http://newosxbook.com/bonus/vol1ch16.html + nexus_register = 504, + nexus_deregister = 505, + nexus_create = 506, + nexus_destroy = 507, + nexus_get_opt = 508, + nexus_set_opt = 509, + channel_open = 510, + channel_get_info = 511, + channel_sync = 512, + channel_get_opt = 513, + channel_set_opt = 514, + ulock_wait = 515, + ulock_wake = 516, + fclonefileat = 517, + fs_snapshot = 518, + register_uexc_handler = 519, + terminate_with_payload = 520, + abort_with_payload = 521, + necp_session_open = 522, + necp_session_action = 523, + setattrlistat = 524, + net_qos_guideline = 525, + fmount = 526, + ntp_adjtime = 527, + ntp_gettime = 528, + os_fault_with_payload = 529, + kqueue_workloop_ctl = 530, + mach_bridge_remote_time = 531, + coalition_ledger = 532, + log_data = 533, + memorystatus_available_memory = 534, + objc_bp_assist_cfg_np = 535, + shared_region_map_and_slide_2_np = 536, + pivot_root = 537, + task_inspect_for_pid = 538, + task_read_for_pid = 539, + preadv = 540, + pwritev = 541, + preadv_nocancel = 542, + pwritev_nocancel = 543, + ulock_wait2 = 544, + proc_info_extended_id = 545, + tracker_action = 546, + debug_syscall_reject = 547, + MAXSYSCALL = 548, + /* invalid = 63, */ +} diff --git a/core/sys/darwin/xnu_system_call_wrappers.odin b/core/sys/darwin/xnu_system_call_wrappers.odin new file mode 100644 index 000000000..4e4227f1f --- /dev/null +++ b/core/sys/darwin/xnu_system_call_wrappers.odin @@ -0,0 +1,419 @@ +package darwin + +import "core:c" +import "core:intrinsics" + +/* flock */ +LOCK_SH :: 1 /* shared lock */ +LOCK_EX :: 2 /* exclusive lock */ +LOCK_NB :: 4 /* don't block when locking */ +LOCK_UN :: 8 /* unlock */ + +/* sys/unistd.h for access */ +F_OK :: c.int(0) /* test for existence of file */ +X_OK :: c.int((1 << 0)) /* test for execute or search permission */ +W_OK :: c.int((1 << 1)) /* test for write permission */ +R_OK :: c.int((1 << 2)) /* test for read permission */ + +/* copyfile flags */ +COPYFILE_ACL :: (1 << 0) +COPYFILE_STAT :: (1 << 1) +COPYFILE_XATTR :: (1 << 2) +COPYFILE_DATA :: (1 << 3) + +COPYFILE_SECURITY :: (COPYFILE_STAT | COPYFILE_ACL) +COPYFILE_METADATA :: (COPYFILE_SECURITY | COPYFILE_XATTR) +COPYFILE_ALL :: (COPYFILE_METADATA | COPYFILE_DATA) + +/* syslimits.h */ +PATH_MAX :: 1024 /* max bytes in pathname */ + +/* param.h */ +MAXPATHLEN :: PATH_MAX + +/* proc_info.h */ +DARWIN_PROC_PIDPATHINFO_SIZE :: MAXPATHLEN +DARWIN_PROC_PIDPATHINFO :: 11 + +DARWIN_PROC_ALL_PIDS :: c.int(1) +DARWIN_PROC_PGRP_ONLY :: c.int(2) +DARWIN_PROC_TTY_ONLY :: c.int(3) +DARWIN_PROC_UID_ONLY :: c.int(4) +DARWIN_PROC_RUID_ONLY :: c.int(5) +DARWIN_PROC_PPID_ONLY :: c.int(6) +DARWIN_PROC_KDBG_ONLY :: c.int(7) + +DARWIN_PROC_INFO_CALL_LISTPIDS :: c.int(0x1) +DARWIN_PROC_INFO_CALL_PIDINFO :: c.int(0x2) +DARWIN_PROC_INFO_CALL_PIDFDINFO :: c.int(0x3) +DARWIN_PROC_INFO_CALL_KERNMSGBUF :: c.int(0x4) +DARWIN_PROC_INFO_CALL_SETCONTROL :: c.int(0x5) +DARWIN_PROC_INFO_CALL_PIDFILEPORTINFO :: c.int(0x6) +DARWIN_PROC_INFO_CALL_TERMINATE :: c.int(0x7) +DARWIN_PROC_INFO_CALL_DIRTYCONTROL :: c.int(0x8) +DARWIN_PROC_INFO_CALL_PIDRUSAGE :: c.int(0x9) +DARWIN_PROC_INFO_CALL_PIDORIGINATORINFO :: c.int(0xa) +DARWIN_PROC_INFO_CALL_LISTCOALITIONS :: c.int(0xb) +DARWIN_PROC_INFO_CALL_CANUSEFGHW :: c.int(0xc) +DARWIN_PROC_INFO_CALL_PIDDYNKQUEUEINFO :: c.int(0xd) +DARWIN_PROC_INFO_CALL_UDATA_INFO :: c.int(0xe) + +/* mmap flags */ +MAP_ANONYMOUS :: 0x1000 /* allocated from memory, swap space */ +MAP_FILE :: 0x0000 /* map from file (default) */ +MAP_FIXED :: 0x0010 /* [MF|SHM] interpret addr exactly */ +MAP_HASSEMAPHORE :: 0x0200 /* region may contain semaphores */ +MAP_PRIVATE :: 0x0002 /* [MF|SHM] changes are private */ +MAP_SHARED :: 0x0001 /* [MF|SHM] share changes */ +MAP_NOCACHE :: 0x0400 /* don't cache pages for this mapping */ +MAP_JIT :: 0x0800 /* Allocate a region that will be used for JIT purposes */ +MAP_32BIT :: 0x8000 /* Return virtual addresses <4G only */ + +/* mmap prot flags */ +PROT_NONE :: 0x00 /* [MC2] no permissions */ +PROT_READ :: 0x01 /* [MC2] pages can be read */ +PROT_WRITE :: 0x02 /* [MC2] pages can be written */ +PROT_EXEC :: 0x04 /* [MC2] pages can be executed */ + +/* For owner Mode/Permission Flags for Open etc. */ +PERMISSION_MASK_IRWXU :: 0o000700 /* RWX mask for owner */ +PERMISSION_MASK_IRUSR :: 0o000400 /* R for owner */ +PERMISSION_MASK_IWUSR :: 0o000200 /* W for owner */ +PERMISSION_MASK_IXUSR :: 0o000100 /* X for owner */ + +/* For group Mode/Permission Flags for Open etc. */ +PERMISSION_MASK_IRWXG :: 0o000070 /* RWX mask for group */ +PERMISSION_MASK_IRGRP :: 0o000040 /* R for group */ +PERMISSION_MASK_IWGRP :: 0o000020 /* W for group */ +PERMISSION_MASK_IXGRP :: 0o000010 /* X for group */ + +/* For other Mode/Permission Flags for Open etc. */ +PERMISSION_MASK_IRWXO :: 0o000007 /* RWX mask for other */ +PERMISSION_MASK_IROTH :: 0o000004 /* R for other */ +PERMISSION_MASK_IWOTH :: 0o000002 /* W for other */ +PERMISSION_MASK_IXOTH :: 0o000001 /* X for other */ + +/* Special Mode/Permission Flags for Open etc. */ +PERMISSION_MASK_ISUID :: 0o004000 /* set user id on execution */ +PERMISSION_MASK_ISGID :: 0o002000 /* set group id on execution */ +PERMISSION_MASK_ISVTX :: 0o001000 /* save swapped text even after use */ + +OPEN_FLAG_RDONLY :: 0x0000 /* open for reading only */ +OPEN_FLAG_WRONLY :: 0x0001 /* open for writing only */ +OPEN_FLAG_RDWR :: 0x0002 /* open for reading and writing */ + +/* mask for above rd/wr/rdwr flags */ +MASK_ACCMODE :: 0x0003 + +OPEN_FLAG_NONBLOCK :: 0x00000004 /* no delay */ +OPEN_FLAG_APPEND :: 0x00000008 /* set append mode */ +OPEN_FLAG_CREAT :: 0x00000200 /* create if nonexistant */ +OPEN_FLAG_TRUNC :: 0x00000400 /* truncate to zero length */ +OPEN_FLAG_EXCL :: 0x00000800 /* error if already exists */ +OPEN_FLAG_SHLOCK :: 0x00000010 /* open with shared file lock */ +OPEN_FLAG_EXLOCK :: 0x00000020 /* open with exclusive file lock */ +OPEN_FLAG_DIRECTORY :: 0x00100000 /* restrict open to only directories */ +OPEN_FLAG_NOFOLLOW :: 0x00000100 /* don't follow symlinks */ +OPEN_FLAG_SYMLINK :: 0x00200000 /* allow open of a symlink */ +OPEN_FLAG_EVTONLY :: 0x00008000 /* descriptor requested for event notifications only */ +OPEN_FLAG_CLOEXEC :: 0x01000000 /* causes the descriptor to be closed if you use any of the exec like functions */ +OPEN_FLAG_NOFOLLOW_ANY :: 0x20000000 /* no symlinks allowed in path */ + +/* bsd/sys/param.h */ +DARWIN_MAXCOMLEN :: 16 + +/*--==========================================================================--*/ + +__darwin_ino64_t :: u64 +__darwin_time_t :: u32 +__darwin_dev_t :: i32 +__darwin_mode_t :: u16 +__darwin_off_t :: i64 +__darwin_blkcnt_t :: i64 +__darwin_blksize_t :: i32 +__darwin_pid_t :: i32 +__darwin_suseconds_t :: i32 + +time_t :: __darwin_time_t +dev_t :: __darwin_dev_t +mode_t :: u16 +nlink_t :: u16 +uid_t :: u16 +gid_t :: u16 +off_t :: __darwin_off_t +blkcnt_t :: __darwin_blkcnt_t +blksize_t :: __darwin_blksize_t +pid_t :: __darwin_pid_t + +stat :: __DARWIN_STRUCT_STAT64 +timeval :: _STRUCT_TIMEVAL + +/*--==========================================================================--*/ + +/* sys/stat.h */ +__DARWIN_STRUCT_STAT64 :: struct { + st_dev: dev_t, /* [XSI] ID of device containing file */ + st_mode: mode_t, /* [XSI] Mode of file (see below) */ + st_nlink: nlink_t, /* [XSI] Number of hard links */ + st_ino: __darwin_ino64_t, /* [XSI] File serial number */ + st_uid_t: uid_t, /* [XSI] User ID of the file */ + st_gid_t: gid_t, /* [XSI] Group ID of the file */ + st_rdev: dev_t, /* [XSI] Device ID */ + + // __DARWIN_STRUCT_STAT64_TIMES + st_atime: time_t, /* [XSI] Time of last access */ + st_atimensec: i32, /* nsec of last access */ + st_mtime: time_t, /* [XSI] Last data modification time */ + st_mtimensec: i32, /* last data modification nsec */ + st_ctime: time_t, /* [XSI] Time of last status change */ + st_ctimensec: u32, /* nsec of last status change */ + st_birthtime: time_t, /* File creation time(birth) */ + st_birthtimensec: i32, /* nsec of File creation time */ + // end __DARWIN_STRUCT_STAT64_TIMES + + st_size: off_t, /* [XSI] file size, in bytes */ + st_blocks: blkcnt_t, /* [XSI] blocks allocated for file */ + st_blksize: blksize_t, /* [XSI] optimal blocksize for I/O */ + st_flags: u32, /* user defined flags for file */ + st_gen: u32, /* file generation number */ + st_lspare: i32, /* RESERVED: DO NOT USE! */ + st_qspare: [2]i64, /* RESERVED: DO NOT USE! */ +} + +/* sys/_types/_timeval.h */ +_STRUCT_TIMEVAL :: struct { + tv_sec: __darwin_time_t, /* seconds */ + tv_usec: __darwin_suseconds_t, /* microseconds */ +} + +/* pwd.h */ +_Password_Entry :: struct { + pw_name: cstring, /* username */ + pw_passwd: cstring, /* user password */ + pw_uid: i32, /* user ID */ + pw_gid: i32, /* group ID */ + pw_change: u64, /* password change time */ + pw_class: cstring, /* user access class */ + pw_gecos: cstring, /* full user name */ + pw_dir: cstring, /* home directory */ + pw_shell: cstring, /* shell program */ + pw_expire: u64, /* account expiration */ + pw_fields: i32, /* filled fields */ +} + +/* processinfo.h */ +_Proc_Bsdinfo :: struct { + pbi_flags: u32, /* if is 64bit; emulated etc */ + pbi_status: u32, + pbi_xstatus: u32, + pbi_pid: u32, + pbi_ppid: u32, + pbi_uid: u32, + pbi_gid: u32, + pbi_ruid: u32, + pbi_rgid: u32, + pbi_svuid: u32, + pbi_svgid: u32, + res: u32, + pbi_comm: [DARWIN_MAXCOMLEN]u8, + pbi_name: [2 * DARWIN_MAXCOMLEN]u8, /* empty if no name is registered */ + pbi_nfiles: u32, + pbi_pgid: u32, + pbi_pjobc: u32, + e_tdev: u32, /* controlling tty dev */ + e_tpgid: u32, /* tty process group id */ + pbi_nice: i32, + pbi_start_tvsec: u64, + pbi_start_tvusec: u64, +} + +/*--==========================================================================--*/ + +syscall_fsync :: #force_inline proc(fildes: c.int) -> bool { + return !(cast(bool)intrinsics.syscall(unix_offset_syscall(.fsync), uintptr(fildes))) +} + +syscall_write :: #force_inline proc (fildes: c.int, buf: ^byte, nbyte: u64) -> bool { + return !(cast(bool)intrinsics.syscall(unix_offset_syscall(.write), uintptr(fildes), uintptr(buf), uintptr(nbyte))) +} + +syscall_read :: #force_inline proc(fildes: c.int, buf: ^byte, nbyte: u64) -> i64 { + return cast(i64)intrinsics.syscall(unix_offset_syscall(.read), uintptr(fildes), uintptr(buf), uintptr(nbyte)) +} + +syscall_open :: #force_inline proc(path: cstring, oflag: u32, mode: u32) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.open), transmute(uintptr)path, uintptr(oflag), uintptr(mode)) +} + +syscall_close :: #force_inline proc(fd: c.int) -> bool { + return !(cast(bool)intrinsics.syscall(unix_offset_syscall(.close), uintptr(fd))) +} + +syscall_fchmod :: #force_inline proc(fildes: c.int, mode: u32) -> c.int { + return (cast(c.int)intrinsics.syscall(unix_offset_syscall(.fchmod), uintptr(fildes), uintptr(mode))) +} + +syscall_chmod :: #force_inline proc(path: cstring, mode: u32) -> c.int { + return (cast(c.int)intrinsics.syscall(unix_offset_syscall(.chmod), transmute(uintptr)path, uintptr(mode))) +} + +syscall_mkdir :: #force_inline proc(path: cstring, mode: u32) -> c.int { + return (cast(c.int)intrinsics.syscall(unix_offset_syscall(.mkdir), transmute(uintptr)path, uintptr(mode))) +} + +syscall_mkdir_at :: #force_inline proc(fd: c.int, path: cstring, mode: u32) -> c.int { + return (cast(c.int)intrinsics.syscall(unix_offset_syscall(.mkdir), uintptr(fd), transmute(uintptr)path, uintptr(mode))) +} + +syscall_rmdir :: #force_inline proc(path: cstring, mode: u32) -> c.int { + return (cast(c.int)intrinsics.syscall(unix_offset_syscall(.rmdir), transmute(uintptr)path, uintptr(mode))) +} + +syscall_rename :: #force_inline proc(path_old: cstring, path_new: cstring) -> c.int { + return (cast(c.int)intrinsics.syscall(unix_offset_syscall(.rename), transmute(uintptr)path_old, transmute(uintptr)path_new)) +} + +syscall_rename_at :: #force_inline proc(from_fd: c.int, from: cstring, to_fd: c.int, to: cstring) -> c.int { + return (cast(c.int)intrinsics.syscall(unix_offset_syscall(.renameat), uintptr(from_fd), transmute(uintptr)from, uintptr(to_fd), transmute(uintptr)to)) +} + +syscall_lseek :: #force_inline proc(fd: c.int, offset: i64, whence: c.int) -> i64 { + return cast(i64)intrinsics.syscall(unix_offset_syscall(.lseek), uintptr(fd), uintptr(offset), uintptr(whence)) +} + +syscall_gettid :: #force_inline proc() -> u64 { + return cast(u64)intrinsics.syscall(unix_offset_syscall(.gettid)) +} + +syscall_fstat :: #force_inline proc(fd: c.int, status: ^stat) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.fstat), uintptr(fd), uintptr(status)) +} + +syscall_lstat :: #force_inline proc(path: cstring, status: ^stat) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.lstat), transmute(uintptr)path, uintptr(status)) +} + +syscall_stat :: #force_inline proc(path: cstring, status: ^stat) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.stat), transmute(uintptr)path, uintptr(status)) +} + +syscall_fstatat :: #force_inline proc(fd: c.int, path: cstring, status: ^stat) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.fstatat), uintptr(fd), transmute(uintptr)path, uintptr(status)) +} + +syscall_link :: #force_inline proc(path: cstring, to_link: cstring) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.link), transmute(uintptr)path, transmute(uintptr)to_link) +} + +syscall_linkat :: #force_inline proc(fd: c.int, path: cstring, fd2: c.int, to_link: cstring) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.linkat), uintptr(fd), transmute(uintptr)path, uintptr(fd2), transmute(uintptr)to_link) +} + +syscall_readlink :: #force_inline proc(path: cstring, buf: ^u8, buf_size: u64) -> i64 { + return cast(i64)intrinsics.syscall(unix_offset_syscall(.readlink), transmute(uintptr)path, uintptr(buf), uintptr(buf_size)) +} + +syscall_readlinkat :: #force_inline proc(fd: c.int, path: cstring, buf: ^u8, buf_size: u64) -> i64 { + return cast(i64)intrinsics.syscall(unix_offset_syscall(.readlinkat), uintptr(fd), transmute(uintptr)path, uintptr(buf), uintptr(buf_size)) +} + +syscall_access :: #force_inline proc(path: cstring, mode: c.int) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.access), transmute(uintptr)path, uintptr(mode)) +} + +syscall_faccessat :: #force_inline proc(fd: c.int, path: cstring, mode: c.int, flag: c.int) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.faccessat), uintptr(fd), transmute(uintptr)path, uintptr(mode), uintptr(flag)) +} + +syscall_getdirentries :: #force_inline proc(fd: c.int, buf: ^u8, nbytes: c.int, base_pointer: ^u32) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.getdirentries), uintptr(fd), uintptr(buf), uintptr(nbytes), uintptr(base_pointer)) +} + +syscall_truncate :: #force_inline proc (path: cstring, length: off_t) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.truncate), transmute(uintptr)path, uintptr(length)) +} + +syscall_ftruncate :: #force_inline proc (fd: c.int, length: off_t) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.ftruncate), uintptr(fd), uintptr(length)) +} + +syscall_sysctl :: #force_inline proc (name: ^c.int, namelen: c.uint, oldp: rawptr, oldlenp: ^i64, newp: ^i8, newlen: i64) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.sysctl), uintptr(name), uintptr(namelen), uintptr(oldp), uintptr(oldlenp), uintptr(newp), uintptr(newlen)) +} + +syscall_copyfile :: #force_inline proc(from: cstring, to: cstring, state: rawptr, flags: u32) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.copyfile), transmute(uintptr)from, transmute(uintptr)to, uintptr(state), uintptr(flags)) +} + +// think about this? last arg should be more than one +syscall_fcntl :: #force_inline proc(fd: c.int, cmd: c.int, other: rawptr) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.fsctl), uintptr(fd), uintptr(cmd), uintptr(other)) +} + +syscall_exit :: #force_inline proc(code: c.int) { + intrinsics.syscall(unix_offset_syscall(.exit), uintptr(code)) +} + +syscall_kill :: #force_inline proc(pid: pid_t, sig: c.int) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.kill), uintptr(pid), uintptr(sig)) +} + +syscall_dup :: #force_inline proc(fd: c.int) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.dup), uintptr(fd)) +} + +syscall_execve :: #force_inline proc(path: cstring, argv: [^]cstring, env: [^]cstring) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.execve), transmute(uintptr)path, transmute(uintptr)argv, transmute(uintptr)env) +} + +syscall_munmap :: #force_inline proc(addr: rawptr, len: u64) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.mmap), uintptr(addr), uintptr(len)) +} + +syscall_mmap :: #force_inline proc(addr: ^u8, len: u64, port: c.int, flags: c.int, fd: int, offset: off_t) -> ^u8 { + return cast(^u8)intrinsics.syscall(unix_offset_syscall(.mmap), uintptr(addr), uintptr(len), uintptr(port), uintptr(flags), uintptr(fd), uintptr(offset)) +} + +syscall_flock :: #force_inline proc(fd: c.int, operation: c.int) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.flock), uintptr(fd), uintptr(operation)) +} + +syscall_utimes :: #force_inline proc(path: cstring, times: ^timeval) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.utimes), transmute(uintptr)path, uintptr(times)) +} + +syscall_futimes :: #force_inline proc(fd: c.int, times: ^timeval) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.futimes), uintptr(fd), uintptr(times)) +} + +syscall_adjtime :: #force_inline proc(delta: ^timeval, old_delta: ^timeval) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.adjtime), uintptr(delta), uintptr(old_delta)) +} + +syscall_sysctlbyname :: #force_inline proc(name: cstring, oldp: rawptr, oldlenp: ^i64, newp: rawptr, newlen: i64) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.sysctlbyname), transmute(uintptr)name, uintptr(oldp), uintptr(oldlenp), uintptr(newp), uintptr(newlen)) +} + +syscall_proc_info :: #force_inline proc(num: c.int, pid: u32, flavor: c.int, arg: u64, buffer: rawptr, buffer_size: c.int) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.proc_info), uintptr(num), uintptr(pid), uintptr(flavor), uintptr(arg), uintptr(buffer), uintptr(buffer_size)) +} + +syscall_openat :: #force_inline proc(fd: int, path: cstring, oflag: u32, mode: u32) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.openat), uintptr(fd), transmute(uintptr)path, uintptr(oflag), uintptr(mode)) +} + +syscall_getentropy :: #force_inline proc(buf: ^u8, buflen: u64) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.getentropy), uintptr(buf), uintptr(buflen)) +} + +syscall_pipe :: #force_inline proc(fds: [^]c.int) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.getentropy), uintptr(&fds[0]), uintptr(&fds[1])) +} + +syscall_chdir :: #force_inline proc(path: cstring) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.getentropy), transmute(uintptr)path) +} + +syscall_fchdir :: #force_inline proc(fd: c.int, path: cstring) -> c.int { + return cast(c.int)intrinsics.syscall(unix_offset_syscall(.getentropy), uintptr(fd), transmute(uintptr)path) +} \ No newline at end of file diff --git a/core/sys/unix/pthread_freebsd.odin b/core/sys/unix/pthread_freebsd.odin index e5b0087b1..dd5306417 100644 --- a/core/sys/unix/pthread_freebsd.odin +++ b/core/sys/unix/pthread_freebsd.odin @@ -1,76 +1,76 @@ //+build freebsd package unix -import "core:c"; +import "core:c" -pthread_t :: distinct u64; -// pthread_t :: struct #align 16 { x: u64 }; +pthread_t :: distinct u64 +// pthread_t :: struct #align 16 { x: u64 } -PTHREAD_COND_T_SIZE :: 8; +PTHREAD_COND_T_SIZE :: 8 -PTHREAD_MUTEXATTR_T_SIZE :: 8; -PTHREAD_CONDATTR_T_SIZE :: 8; -PTHREAD_RWLOCKATTR_T_SIZE :: 8; -PTHREAD_BARRIERATTR_T_SIZE :: 8; +PTHREAD_MUTEXATTR_T_SIZE :: 8 +PTHREAD_CONDATTR_T_SIZE :: 8 +PTHREAD_RWLOCKATTR_T_SIZE :: 8 +PTHREAD_BARRIERATTR_T_SIZE :: 8 // WARNING: The sizes of these things are different yet again // on non-X86! when size_of(int) == 8 { - PTHREAD_ATTR_T_SIZE :: 8; - PTHREAD_MUTEX_T_SIZE :: 8; - PTHREAD_RWLOCK_T_SIZE :: 8; - PTHREAD_BARRIER_T_SIZE :: 8; + PTHREAD_ATTR_T_SIZE :: 8 + PTHREAD_MUTEX_T_SIZE :: 8 + PTHREAD_RWLOCK_T_SIZE :: 8 + PTHREAD_BARRIER_T_SIZE :: 8 } else when size_of(int) == 4 { // TODO - PTHREAD_ATTR_T_SIZE :: 32; - PTHREAD_MUTEX_T_SIZE :: 32; - PTHREAD_RWLOCK_T_SIZE :: 44; - PTHREAD_BARRIER_T_SIZE :: 20; + PTHREAD_ATTR_T_SIZE :: 32 + PTHREAD_MUTEX_T_SIZE :: 32 + PTHREAD_RWLOCK_T_SIZE :: 44 + PTHREAD_BARRIER_T_SIZE :: 20 } pthread_cond_t :: struct #align 16 { _: [PTHREAD_COND_T_SIZE] c.char, -}; +} pthread_mutex_t :: struct #align 16 { _: [PTHREAD_MUTEX_T_SIZE] c.char, -}; +} pthread_rwlock_t :: struct #align 16 { _: [PTHREAD_RWLOCK_T_SIZE] c.char, -}; +} pthread_barrier_t :: struct #align 16 { _: [PTHREAD_BARRIER_T_SIZE] c.char, -}; +} pthread_attr_t :: struct #align 16 { _: [PTHREAD_ATTR_T_SIZE] c.char, -}; +} pthread_condattr_t :: struct #align 16 { _: [PTHREAD_CONDATTR_T_SIZE] c.char, -}; +} pthread_mutexattr_t :: struct #align 16 { _: [PTHREAD_MUTEXATTR_T_SIZE] c.char, -}; +} pthread_rwlockattr_t :: struct #align 16 { _: [PTHREAD_RWLOCKATTR_T_SIZE] c.char, -}; +} pthread_barrierattr_t :: struct #align 16 { _: [PTHREAD_BARRIERATTR_T_SIZE] c.char, -}; +} -PTHREAD_MUTEX_ERRORCHECK :: 1; -PTHREAD_MUTEX_RECURSIVE :: 2; -PTHREAD_MUTEX_NORMAL :: 3; +PTHREAD_MUTEX_ERRORCHECK :: 1 +PTHREAD_MUTEX_RECURSIVE :: 2 +PTHREAD_MUTEX_NORMAL :: 3 -PTHREAD_CREATE_JOINABLE :: 0; -PTHREAD_CREATE_DETACHED :: 1; -PTHREAD_INHERIT_SCHED :: 4; -PTHREAD_EXPLICIT_SCHED :: 0; -PTHREAD_PROCESS_PRIVATE :: 0; -PTHREAD_PROCESS_SHARED :: 1; +PTHREAD_CREATE_JOINABLE :: 0 +PTHREAD_CREATE_DETACHED :: 1 +PTHREAD_INHERIT_SCHED :: 4 +PTHREAD_EXPLICIT_SCHED :: 0 +PTHREAD_PROCESS_PRIVATE :: 0 +PTHREAD_PROCESS_SHARED :: 1 -SCHED_FIFO :: 1; -SCHED_OTHER :: 2; -SCHED_RR :: 3; // Round robin. +SCHED_FIFO :: 1 +SCHED_OTHER :: 2 +SCHED_RR :: 3 // Round robin. sched_param :: struct { @@ -98,17 +98,17 @@ foreign import "system:pthread" foreign pthread { // create named semaphore. // used in process-shared semaphores. - sem_open :: proc(name: cstring, flags: c.int) -> ^sem_t ---; + sem_open :: proc(name: cstring, flags: c.int) -> ^sem_t --- - sem_init :: proc(sem: ^sem_t, pshared: c.int, initial_value: c.uint) -> c.int ---; - sem_destroy :: proc(sem: ^sem_t) -> c.int ---; - sem_post :: proc(sem: ^sem_t) -> c.int ---; - sem_wait :: proc(sem: ^sem_t) -> c.int ---; - sem_trywait :: proc(sem: ^sem_t) -> c.int ---; - // sem_timedwait :: proc(sem: ^sem_t, timeout: time.TimeSpec) -> c.int ---; + sem_init :: proc(sem: ^sem_t, pshared: c.int, initial_value: c.uint) -> c.int --- + sem_destroy :: proc(sem: ^sem_t) -> c.int --- + sem_post :: proc(sem: ^sem_t) -> c.int --- + sem_wait :: proc(sem: ^sem_t) -> c.int --- + sem_trywait :: proc(sem: ^sem_t) -> c.int --- + // sem_timedwait :: proc(sem: ^sem_t, timeout: time.TimeSpec) -> c.int --- // NOTE: unclear whether pthread_yield is well-supported on Linux systems, // see https://linux.die.net/man/3/pthread_yield - pthread_yield :: proc() ---; + pthread_yield :: proc() --- } diff --git a/core/sys/unix/pthread_openbsd.odin b/core/sys/unix/pthread_openbsd.odin new file mode 100644 index 000000000..c855f95c0 --- /dev/null +++ b/core/sys/unix/pthread_openbsd.odin @@ -0,0 +1,65 @@ +//+build openbsd +package unix + +import "core:c" + +pthread_t :: distinct rawptr +pthread_attr_t :: distinct rawptr +pthread_mutex_t :: distinct rawptr +pthread_mutexattr_t :: distinct rawptr +pthread_cond_t :: distinct rawptr +pthread_condattr_t :: distinct rawptr +pthread_rwlock_t :: distinct rawptr +pthread_rwlockattr_t :: distinct rawptr +pthread_barrier_t :: distinct rawptr +pthread_barrierattr_t :: distinct rawptr +pthread_spinlock_t :: distinct rawptr + +pthread_key_t :: distinct c.int +pthread_once_t :: struct { + state: c.int, + mutex: pthread_mutex_t, +} + +PTHREAD_MUTEX_ERRORCHECK :: 1 +PTHREAD_MUTEX_RECURSIVE :: 2 +PTHREAD_MUTEX_NORMAL :: 3 +PTHREAD_MUTEX_STRICT_NP :: 4 + +PTHREAD_DETACHED :: 0x1 +PTHREAD_SCOPE_SYSTEM :: 0x2 +PTHREAD_INHERIT_SCHED :: 0x4 +PTHREAD_NOFLOAT :: 0x8 + +PTHREAD_CREATE_DETACHED :: PTHREAD_DETACHED +PTHREAD_CREATE_JOINABLE :: 0 +PTHREAD_SCOPE_PROCESS :: 0 +PTHREAD_EXPLICIT_SCHED :: 0 + +SCHED_FIFO :: 1 +SCHED_OTHER :: 2 +SCHED_RR :: 3 + +sched_param :: struct { + sched_priority: c.int, +} + +sem_t :: distinct rawptr + +foreign import libc "system:c" + +@(default_calling_convention="c") +foreign libc { + sem_open :: proc(name: cstring, flags: c.int) -> ^sem_t --- + + sem_init :: proc(sem: ^sem_t, pshared: c.int, initial_value: c.uint) -> c.int --- + sem_destroy :: proc(sem: ^sem_t) -> c.int --- + sem_post :: proc(sem: ^sem_t) -> c.int --- + sem_wait :: proc(sem: ^sem_t) -> c.int --- + sem_trywait :: proc(sem: ^sem_t) -> c.int --- + //sem_timedwait :: proc(sem: ^sem_t, timeout: time.TimeSpec) -> c.int --- + + // NOTE: unclear whether pthread_yield is well-supported on Linux systems, + // see https://linux.die.net/man/3/pthread_yield + pthread_yield :: proc() --- +} diff --git a/core/sys/unix/pthread_unix.odin b/core/sys/unix/pthread_unix.odin index ccd8f7844..62e3701ab 100644 --- a/core/sys/unix/pthread_unix.odin +++ b/core/sys/unix/pthread_unix.odin @@ -1,4 +1,4 @@ -//+build linux, darwin, freebsd +//+build linux, darwin, freebsd, openbsd package unix foreign import "system:pthread" diff --git a/core/sys/unix/syscalls_linux.odin b/core/sys/unix/syscalls_linux.odin index 659eedfbb..3d06d42d4 100644 --- a/core/sys/unix/syscalls_linux.odin +++ b/core/sys/unix/syscalls_linux.odin @@ -15,38 +15,1505 @@ import "core:intrinsics" // 386: arch/x86/entry/syscalls/sycall_32.tbl // arm: arch/arm/tools/syscall.tbl -when ODIN_ARCH == "amd64" { +when ODIN_ARCH == .amd64 { + SYS_read : uintptr : 0 + SYS_write : uintptr : 1 + SYS_open : uintptr : 2 + SYS_close : uintptr : 3 + SYS_stat : uintptr : 4 + SYS_fstat : uintptr : 5 + SYS_lstat : uintptr : 6 + SYS_poll : uintptr : 7 + SYS_lseek : uintptr : 8 SYS_mmap : uintptr : 9 SYS_mprotect : uintptr : 10 SYS_munmap : uintptr : 11 + SYS_brk : uintptr : 12 + SYS_rt_sigaction : uintptr : 13 + SYS_rt_sigprocmask : uintptr : 14 + SYS_rt_sigreturn : uintptr : 15 + SYS_ioctl : uintptr : 16 + SYS_pread : uintptr : 17 + SYS_pwrite : uintptr : 18 + SYS_readv : uintptr : 19 + SYS_writev : uintptr : 20 + SYS_access : uintptr : 21 + SYS_pipe : uintptr : 22 + SYS_select : uintptr : 23 + SYS_sched_yield : uintptr : 24 + SYS_mremap : uintptr : 25 + SYS_msync : uintptr : 26 + SYS_mincore : uintptr : 27 SYS_madvise : uintptr : 28 - SYS_futex : uintptr : 202 + SYS_shmget : uintptr : 29 + SYS_shmat : uintptr : 30 + SYS_shmctl : uintptr : 31 + SYS_dup : uintptr : 32 + SYS_dup2 : uintptr : 33 + SYS_pause : uintptr : 34 + SYS_nanosleep : uintptr : 35 + SYS_getitimer : uintptr : 36 + SYS_alarm : uintptr : 37 + SYS_setitimer : uintptr : 38 + SYS_getpid : uintptr : 39 + SYS_sendfile : uintptr : 40 + SYS_socket : uintptr : 41 + SYS_connect : uintptr : 42 + SYS_accept : uintptr : 43 + SYS_sendto : uintptr : 44 + SYS_recvfrom : uintptr : 45 + SYS_sendmsg : uintptr : 46 + SYS_recvmsg : uintptr : 47 + SYS_shutdown : uintptr : 48 + SYS_bind : uintptr : 49 + SYS_listen : uintptr : 50 + SYS_getsockname : uintptr : 51 + SYS_getpeername : uintptr : 52 + SYS_socketpair : uintptr : 53 + SYS_setsockopt : uintptr : 54 + SYS_getsockopt : uintptr : 55 + SYS_clone : uintptr : 56 + SYS_fork : uintptr : 57 + SYS_vfork : uintptr : 58 + SYS_execve : uintptr : 59 + SYS_exit : uintptr : 60 + SYS_wait4 : uintptr : 61 + SYS_kill : uintptr : 62 + SYS_uname : uintptr : 63 + SYS_semget : uintptr : 64 + SYS_semop : uintptr : 65 + SYS_semctl : uintptr : 66 + SYS_shmdt : uintptr : 67 + SYS_msgget : uintptr : 68 + SYS_msgsnd : uintptr : 69 + SYS_msgrcv : uintptr : 70 + SYS_msgctl : uintptr : 71 + SYS_fcntl : uintptr : 72 + SYS_flock : uintptr : 73 + SYS_fsync : uintptr : 74 + SYS_fdatasync : uintptr : 75 + SYS_truncate : uintptr : 76 + SYS_ftruncate : uintptr : 77 + SYS_getdents : uintptr : 78 + SYS_getcwd : uintptr : 79 + SYS_chdir : uintptr : 80 + SYS_fchdir : uintptr : 81 + SYS_rename : uintptr : 82 + SYS_mkdir : uintptr : 83 + SYS_rmdir : uintptr : 84 + SYS_creat : uintptr : 85 + SYS_link : uintptr : 86 + SYS_unlink : uintptr : 87 + SYS_symlink : uintptr : 88 + SYS_readlink : uintptr : 89 + SYS_chmod : uintptr : 90 + SYS_fchmod : uintptr : 91 + SYS_chown : uintptr : 92 + SYS_fchown : uintptr : 93 + SYS_lchown : uintptr : 94 + SYS_umask : uintptr : 95 + SYS_gettimeofday : uintptr : 96 + SYS_getrlimit : uintptr : 97 + SYS_getrusage : uintptr : 98 + SYS_sysinfo : uintptr : 99 + SYS_times : uintptr : 100 + SYS_ptrace : uintptr : 101 + SYS_getuid : uintptr : 102 + SYS_syslog : uintptr : 103 + SYS_getgid : uintptr : 104 + SYS_setuid : uintptr : 105 + SYS_setgid : uintptr : 106 + SYS_geteuid : uintptr : 107 + SYS_getegid : uintptr : 108 + SYS_setpgid : uintptr : 109 + SYS_getppid : uintptr : 110 + SYS_getpgrp : uintptr : 111 + SYS_setsid : uintptr : 112 + SYS_setreuid : uintptr : 113 + SYS_setregid : uintptr : 114 + SYS_getgroups : uintptr : 115 + SYS_setgroups : uintptr : 116 + SYS_setresuid : uintptr : 117 + SYS_getresuid : uintptr : 118 + SYS_setresgid : uintptr : 119 + SYS_getresgid : uintptr : 120 + SYS_getpgid : uintptr : 121 + SYS_setfsuid : uintptr : 122 + SYS_setfsgid : uintptr : 123 + SYS_getsid : uintptr : 124 + SYS_capget : uintptr : 125 + SYS_capset : uintptr : 126 + SYS_rt_sigpending : uintptr : 127 + SYS_rt_sigtimedwait : uintptr : 128 + SYS_rt_sigqueueinfo : uintptr : 129 + SYS_rt_sigsuspend : uintptr : 130 + SYS_sigaltstack : uintptr : 131 + SYS_utime : uintptr : 132 + SYS_mknod : uintptr : 133 + SYS_uselib : uintptr : 134 + SYS_personality : uintptr : 135 + SYS_ustat : uintptr : 136 + SYS_statfs : uintptr : 137 + SYS_fstatfs : uintptr : 138 + SYS_sysfs : uintptr : 139 + SYS_getpriority : uintptr : 140 + SYS_setpriority : uintptr : 141 + SYS_sched_setparam : uintptr : 142 + SYS_sched_getparam : uintptr : 143 + SYS_sched_setscheduler : uintptr : 144 + SYS_sched_getscheduler : uintptr : 145 + SYS_sched_get_priority_max : uintptr : 146 + SYS_sched_get_priority_min : uintptr : 147 + SYS_sched_rr_get_interval : uintptr : 148 + SYS_mlock : uintptr : 149 + SYS_munlock : uintptr : 150 + SYS_mlockall : uintptr : 151 + SYS_munlockall : uintptr : 152 + SYS_vhangup : uintptr : 153 + SYS_modify_ldt : uintptr : 154 + SYS_pivot_root : uintptr : 155 + SYS__sysctl : uintptr : 156 + SYS_prctl : uintptr : 157 + SYS_arch_prctl : uintptr : 158 + SYS_adjtimex : uintptr : 159 + SYS_setrlimit : uintptr : 160 + SYS_chroot : uintptr : 161 + SYS_sync : uintptr : 162 + SYS_acct : uintptr : 163 + SYS_settimeofday : uintptr : 164 + SYS_mount : uintptr : 165 + SYS_umount2 : uintptr : 166 + SYS_swapon : uintptr : 167 + SYS_swapoff : uintptr : 168 + SYS_reboot : uintptr : 169 + SYS_sethostname : uintptr : 170 + SYS_setdomainname : uintptr : 171 + SYS_iopl : uintptr : 172 + SYS_ioperm : uintptr : 173 + SYS_create_module : uintptr : 174 + SYS_init_module : uintptr : 175 + SYS_delete_module : uintptr : 176 + SYS_get_kernel_syms : uintptr : 177 + SYS_query_module : uintptr : 178 + SYS_quotactl : uintptr : 179 + SYS_nfsservctl : uintptr : 180 + SYS_getpmsg : uintptr : 181 + SYS_putpmsg : uintptr : 182 + SYS_afs_syscall : uintptr : 183 + SYS_tuxcall : uintptr : 184 + SYS_security : uintptr : 185 SYS_gettid : uintptr : 186 + SYS_readahead : uintptr : 187 + SYS_setxattr : uintptr : 188 + SYS_lsetxattr : uintptr : 189 + SYS_fsetxattr : uintptr : 190 + SYS_getxattr : uintptr : 191 + SYS_lgetxattr : uintptr : 192 + SYS_fgetxattr : uintptr : 193 + SYS_listxattr : uintptr : 194 + SYS_llistxattr : uintptr : 195 + SYS_flistxattr : uintptr : 196 + SYS_removexattr : uintptr : 197 + SYS_lremovexattr : uintptr : 198 + SYS_fremovexattr : uintptr : 199 + SYS_tkill : uintptr : 200 + SYS_time : uintptr : 201 + SYS_futex : uintptr : 202 + SYS_sched_setaffinity : uintptr : 203 + SYS_sched_getaffinity : uintptr : 204 + SYS_set_thread_area : uintptr : 205 + SYS_io_setup : uintptr : 206 + SYS_io_destroy : uintptr : 207 + SYS_io_getevents : uintptr : 208 + SYS_io_submit : uintptr : 209 + SYS_io_cancel : uintptr : 210 + SYS_get_thread_area : uintptr : 211 + SYS_lookup_dcookie : uintptr : 212 + SYS_epoll_create : uintptr : 213 + SYS_epoll_ctl_old : uintptr : 214 + SYS_epoll_wait_old : uintptr : 215 + SYS_remap_file_pages : uintptr : 216 + SYS_getdents64 : uintptr : 217 + SYS_set_tid_address : uintptr : 218 + SYS_restart_syscall : uintptr : 219 + SYS_semtimedop : uintptr : 220 + SYS_fadvise64 : uintptr : 221 + SYS_timer_create : uintptr : 222 + SYS_timer_settime : uintptr : 223 + SYS_timer_gettime : uintptr : 224 + SYS_timer_getoverrun : uintptr : 225 + SYS_timer_delete : uintptr : 226 + SYS_clock_settime : uintptr : 227 + SYS_clock_gettime : uintptr : 228 + SYS_clock_getres : uintptr : 229 + SYS_clock_nanosleep : uintptr : 230 + SYS_exit_group : uintptr : 231 + SYS_epoll_wait : uintptr : 232 + SYS_epoll_ctl : uintptr : 233 + SYS_tgkill : uintptr : 234 + SYS_utimes : uintptr : 235 + SYS_vserver : uintptr : 236 + SYS_mbind : uintptr : 237 + SYS_set_mempolicy : uintptr : 238 + SYS_get_mempolicy : uintptr : 239 + SYS_mq_open : uintptr : 240 + SYS_mq_unlink : uintptr : 241 + SYS_mq_timedsend : uintptr : 242 + SYS_mq_timedreceive : uintptr : 243 + SYS_mq_notify : uintptr : 244 + SYS_mq_getsetattr : uintptr : 245 + SYS_kexec_load : uintptr : 246 + SYS_waitid : uintptr : 247 + SYS_add_key : uintptr : 248 + SYS_request_key : uintptr : 249 + SYS_keyctl : uintptr : 250 + SYS_ioprio_set : uintptr : 251 + SYS_ioprio_get : uintptr : 252 + SYS_inotify_init : uintptr : 253 + SYS_inotify_add_watch : uintptr : 254 + SYS_inotify_rm_watch : uintptr : 255 + SYS_migrate_pages : uintptr : 256 + SYS_openat : uintptr : 257 + SYS_mkdirat : uintptr : 258 + SYS_mknodat : uintptr : 259 + SYS_fchownat : uintptr : 260 + SYS_futimesat : uintptr : 261 + SYS_fstatat : uintptr : 262 + SYS_unlinkat : uintptr : 263 + SYS_renameat : uintptr : 264 + SYS_linkat : uintptr : 265 + SYS_symlinkat : uintptr : 266 + SYS_readlinkat : uintptr : 267 + SYS_fchmodat : uintptr : 268 + SYS_faccessat : uintptr : 269 + SYS_pselect6 : uintptr : 270 + SYS_ppoll : uintptr : 271 + SYS_unshare : uintptr : 272 + SYS_set_robust_list : uintptr : 273 + SYS_get_robust_list : uintptr : 274 + SYS_splice : uintptr : 275 + SYS_tee : uintptr : 276 + SYS_sync_file_range : uintptr : 277 + SYS_vmsplice : uintptr : 278 + SYS_move_pages : uintptr : 279 + SYS_utimensat : uintptr : 280 + SYS_epoll_pwait : uintptr : 281 + SYS_signalfd : uintptr : 282 + SYS_timerfd_create : uintptr : 283 + SYS_eventfd : uintptr : 284 + SYS_fallocate : uintptr : 285 + SYS_timerfd_settime : uintptr : 286 + SYS_timerfd_gettime : uintptr : 287 + SYS_accept4 : uintptr : 288 + SYS_signalfd4 : uintptr : 289 + SYS_eventfd2 : uintptr : 290 + SYS_epoll_create1 : uintptr : 291 + SYS_dup3 : uintptr : 292 + SYS_pipe2 : uintptr : 293 + SYS_inotify_init1 : uintptr : 294 + SYS_preadv : uintptr : 295 + SYS_pwritev : uintptr : 296 + SYS_rt_tgsigqueueinfo : uintptr : 297 + SYS_perf_event_open : uintptr : 298 + SYS_recvmmsg : uintptr : 299 + SYS_fanotify_init : uintptr : 300 + SYS_fanotify_mark : uintptr : 301 + SYS_prlimit64 : uintptr : 302 + SYS_name_to_handle_at : uintptr : 303 + SYS_open_by_handle_at : uintptr : 304 + SYS_clock_adjtime : uintptr : 305 + SYS_syncfs : uintptr : 306 + SYS_sendmmsg : uintptr : 307 + SYS_setns : uintptr : 308 + SYS_getcpu : uintptr : 309 + SYS_process_vm_readv : uintptr : 310 + SYS_process_vm_writev : uintptr : 311 + SYS_kcmp : uintptr : 312 + SYS_finit_module : uintptr : 313 + SYS_sched_setattr : uintptr : 314 + SYS_sched_getattr : uintptr : 315 + SYS_renameat2 : uintptr : 316 + SYS_seccomp : uintptr : 317 SYS_getrandom : uintptr : 318 -} else when ODIN_ARCH == "arm64" { - SYS_mmap : uintptr : 222 - SYS_mprotect : uintptr : 226 - SYS_munmap : uintptr : 215 - SYS_madvise : uintptr : 233 + SYS_memfd_create : uintptr : 319 + SYS_kexec_file_load : uintptr : 320 + SYS_bpf : uintptr : 321 + SYS_execveat : uintptr : 322 + SYS_userfaultfd : uintptr : 323 + SYS_membarrier : uintptr : 324 + SYS_mlock2 : uintptr : 325 + SYS_copy_file_range : uintptr : 326 + SYS_preadv2 : uintptr : 327 + SYS_pwritev2 : uintptr : 328 + SYS_pkey_mprotect : uintptr : 329 + SYS_pkey_alloc : uintptr : 330 + SYS_pkey_free : uintptr : 331 + SYS_statx : uintptr : 332 + SYS_io_pgetevents : uintptr : 333 + SYS_rseq : uintptr : 334 + SYS_pidfd_send_signal : uintptr : 424 + SYS_io_uring_setup : uintptr : 425 + SYS_io_uring_enter : uintptr : 426 + SYS_io_uring_register : uintptr : 427 + SYS_open_tree : uintptr : 428 + SYS_move_mount : uintptr : 429 + SYS_fsopen : uintptr : 430 + SYS_fsconfig : uintptr : 431 + SYS_fsmount : uintptr : 432 + SYS_fspick : uintptr : 433 + SYS_pidfd_open : uintptr : 434 + SYS_clone3 : uintptr : 435 + SYS_close_range : uintptr : 436 + SYS_openat2 : uintptr : 437 + SYS_pidfd_getfd : uintptr : 438 + SYS_faccessat2 : uintptr : 439 + SYS_process_madvise : uintptr : 440 + SYS_epoll_pwait2 : uintptr : 441 + SYS_mount_setattr : uintptr : 442 + SYS_landlock_create_ruleset : uintptr : 444 + SYS_landlock_add_rule : uintptr : 445 + SYS_landlock_restrict_self : uintptr : 446 + SYS_memfd_secret : uintptr : 447 +} else when ODIN_ARCH == .arm64 { + SYS_io_setup : uintptr : 0 + SYS_io_destroy : uintptr : 1 + SYS_io_submit : uintptr : 2 + SYS_io_cancel : uintptr : 3 + SYS_io_getevents : uintptr : 4 + SYS_setxattr : uintptr : 5 + SYS_lsetxattr : uintptr : 6 + SYS_fsetxattr : uintptr : 7 + SYS_getxattr : uintptr : 8 + SYS_lgetxattr : uintptr : 9 + SYS_fgetxattr : uintptr : 10 + SYS_listxattr : uintptr : 11 + SYS_llistxattr : uintptr : 12 + SYS_flistxattr : uintptr : 13 + SYS_removexattr : uintptr : 14 + SYS_lremovexattr : uintptr : 15 + SYS_fremovexattr : uintptr : 16 + SYS_getcwd : uintptr : 17 + SYS_lookup_dcookie : uintptr : 18 + SYS_eventfd2 : uintptr : 19 + SYS_epoll_create1 : uintptr : 20 + SYS_epoll_ctl : uintptr : 21 + SYS_epoll_pwait : uintptr : 22 + SYS_dup : uintptr : 23 + SYS_dup3 : uintptr : 24 + SYS_fcntl : uintptr : 25 + SYS_inotify_init1 : uintptr : 26 + SYS_inotify_add_watch : uintptr : 27 + SYS_inotify_rm_watch : uintptr : 28 + SYS_ioctl : uintptr : 29 + SYS_ioprio_set : uintptr : 30 + SYS_ioprio_get : uintptr : 31 + SYS_flock : uintptr : 32 + SYS_mknodat : uintptr : 33 + SYS_mkdirat : uintptr : 34 + SYS_unlinkat : uintptr : 35 + SYS_symlinkat : uintptr : 36 + SYS_linkat : uintptr : 37 + SYS_renameat : uintptr : 38 + SYS_umount2 : uintptr : 39 + SYS_mount : uintptr : 40 + SYS_pivot_root : uintptr : 41 + SYS_nfsservctl : uintptr : 42 + SYS_statfs : uintptr : 43 + SYS_fstatfs : uintptr : 44 + SYS_truncate : uintptr : 45 + SYS_ftruncate : uintptr : 46 + SYS_fallocate : uintptr : 47 + SYS_faccessat : uintptr : 48 + SYS_chdir : uintptr : 49 + SYS_fchdir : uintptr : 50 + SYS_chroot : uintptr : 51 + SYS_fchmod : uintptr : 52 + SYS_fchmodat : uintptr : 53 + SYS_fchownat : uintptr : 54 + SYS_fchown : uintptr : 55 + SYS_openat : uintptr : 56 + SYS_close : uintptr : 57 + SYS_vhangup : uintptr : 58 + SYS_pipe2 : uintptr : 59 + SYS_quotactl : uintptr : 60 + SYS_getdents64 : uintptr : 61 + SYS_lseek : uintptr : 62 + SYS_read : uintptr : 63 + SYS_write : uintptr : 64 + SYS_readv : uintptr : 65 + SYS_writev : uintptr : 66 + SYS_pread64 : uintptr : 67 + SYS_pwrite64 : uintptr : 68 + SYS_preadv : uintptr : 69 + SYS_pwritev : uintptr : 70 + SYS_sendfile : uintptr : 71 + SYS_pselect6 : uintptr : 72 + SYS_ppoll : uintptr : 73 + SYS_signalfd4 : uintptr : 74 + SYS_vmsplice : uintptr : 75 + SYS_splice : uintptr : 76 + SYS_tee : uintptr : 77 + SYS_readlinkat : uintptr : 78 + SYS_fstatat : uintptr : 79 + SYS_fstat : uintptr : 80 + SYS_sync : uintptr : 81 + SYS_fsync : uintptr : 82 + SYS_fdatasync : uintptr : 83 + SYS_sync_file_range : uintptr : 84 + SYS_timerfd_create : uintptr : 85 + SYS_timerfd_settime : uintptr : 86 + SYS_timerfd_gettime : uintptr : 87 + SYS_utimensat : uintptr : 88 + SYS_acct : uintptr : 89 + SYS_capget : uintptr : 90 + SYS_capset : uintptr : 91 + SYS_personality : uintptr : 92 + SYS_exit : uintptr : 93 + SYS_exit_group : uintptr : 94 + SYS_waitid : uintptr : 95 + SYS_set_tid_address : uintptr : 96 + SYS_unshare : uintptr : 97 SYS_futex : uintptr : 98 + SYS_set_robust_list : uintptr : 99 + SYS_get_robust_list : uintptr : 100 + SYS_nanosleep : uintptr : 101 + SYS_getitimer : uintptr : 102 + SYS_setitimer : uintptr : 103 + SYS_kexec_load : uintptr : 104 + SYS_init_module : uintptr : 105 + SYS_delete_module : uintptr : 106 + SYS_timer_create : uintptr : 107 + SYS_timer_gettime : uintptr : 108 + SYS_timer_getoverrun : uintptr : 109 + SYS_timer_settime : uintptr : 110 + SYS_timer_delete : uintptr : 111 + SYS_clock_settime : uintptr : 112 + SYS_clock_gettime : uintptr : 113 + SYS_clock_getres : uintptr : 114 + SYS_clock_nanosleep : uintptr : 115 + SYS_syslog : uintptr : 116 + SYS_ptrace : uintptr : 117 + SYS_sched_setparam : uintptr : 118 + SYS_sched_setscheduler : uintptr : 119 + SYS_sched_getscheduler : uintptr : 120 + SYS_sched_getparam : uintptr : 121 + SYS_sched_setaffinity : uintptr : 122 + SYS_sched_getaffinity : uintptr : 123 + SYS_sched_yield : uintptr : 124 + SYS_sched_get_priority_max : uintptr : 125 + SYS_sched_get_priority_min : uintptr : 126 + SYS_sched_rr_get_interval : uintptr : 127 + SYS_restart_syscall : uintptr : 128 + SYS_kill : uintptr : 129 + SYS_tkill : uintptr : 130 + SYS_tgkill : uintptr : 131 + SYS_sigaltstack : uintptr : 132 + SYS_rt_sigsuspend : uintptr : 133 + SYS_rt_sigaction : uintptr : 134 + SYS_rt_sigprocmask : uintptr : 135 + SYS_rt_sigpending : uintptr : 136 + SYS_rt_sigtimedwait : uintptr : 137 + SYS_rt_sigqueueinfo : uintptr : 138 + SYS_rt_sigreturn : uintptr : 139 + SYS_setpriority : uintptr : 140 + SYS_getpriority : uintptr : 141 + SYS_reboot : uintptr : 142 + SYS_setregid : uintptr : 143 + SYS_setgid : uintptr : 144 + SYS_setreuid : uintptr : 145 + SYS_setuid : uintptr : 146 + SYS_setresuid : uintptr : 147 + SYS_getresuid : uintptr : 148 + SYS_setresgid : uintptr : 149 + SYS_getresgid : uintptr : 150 + SYS_setfsuid : uintptr : 151 + SYS_setfsgid : uintptr : 152 + SYS_times : uintptr : 153 + SYS_setpgid : uintptr : 154 + SYS_getpgid : uintptr : 155 + SYS_getsid : uintptr : 156 + SYS_setsid : uintptr : 157 + SYS_getgroups : uintptr : 158 + SYS_setgroups : uintptr : 159 + SYS_uname : uintptr : 160 + SYS_sethostname : uintptr : 161 + SYS_setdomainname : uintptr : 162 + SYS_getrlimit : uintptr : 163 + SYS_setrlimit : uintptr : 164 + SYS_getrusage : uintptr : 165 + SYS_umask : uintptr : 166 + SYS_prctl : uintptr : 167 + SYS_getcpu : uintptr : 168 + SYS_gettimeofday : uintptr : 169 + SYS_settimeofday : uintptr : 170 + SYS_adjtimex : uintptr : 171 + SYS_getpid : uintptr : 172 + SYS_getppid : uintptr : 173 + SYS_getuid : uintptr : 174 + SYS_geteuid : uintptr : 175 + SYS_getgid : uintptr : 176 + SYS_getegid : uintptr : 177 SYS_gettid : uintptr : 178 + SYS_sysinfo : uintptr : 179 + SYS_mq_open : uintptr : 180 + SYS_mq_unlink : uintptr : 181 + SYS_mq_timedsend : uintptr : 182 + SYS_mq_timedreceive : uintptr : 183 + SYS_mq_notify : uintptr : 184 + SYS_mq_getsetattr : uintptr : 185 + SYS_msgget : uintptr : 186 + SYS_msgctl : uintptr : 187 + SYS_msgrcv : uintptr : 188 + SYS_msgsnd : uintptr : 189 + SYS_semget : uintptr : 190 + SYS_semctl : uintptr : 191 + SYS_semtimedop : uintptr : 192 + SYS_semop : uintptr : 193 + SYS_shmget : uintptr : 194 + SYS_shmctl : uintptr : 195 + SYS_shmat : uintptr : 196 + SYS_shmdt : uintptr : 197 + SYS_socket : uintptr : 198 + SYS_socketpair : uintptr : 199 + SYS_bind : uintptr : 200 + SYS_listen : uintptr : 201 + SYS_accept : uintptr : 202 + SYS_connect : uintptr : 203 + SYS_getsockname : uintptr : 204 + SYS_getpeername : uintptr : 205 + SYS_sendto : uintptr : 206 + SYS_recvfrom : uintptr : 207 + SYS_setsockopt : uintptr : 208 + SYS_getsockopt : uintptr : 209 + SYS_shutdown : uintptr : 210 + SYS_sendmsg : uintptr : 211 + SYS_recvmsg : uintptr : 212 + SYS_readahead : uintptr : 213 + SYS_brk : uintptr : 214 + SYS_munmap : uintptr : 215 + SYS_mremap : uintptr : 216 + SYS_add_key : uintptr : 217 + SYS_request_key : uintptr : 218 + SYS_keyctl : uintptr : 219 + SYS_clone : uintptr : 220 + SYS_execve : uintptr : 221 + SYS_mmap : uintptr : 222 + SYS_fadvise64 : uintptr : 223 + SYS_swapon : uintptr : 224 + SYS_swapoff : uintptr : 225 + SYS_mprotect : uintptr : 226 + SYS_msync : uintptr : 227 + SYS_mlock : uintptr : 228 + SYS_munlock : uintptr : 229 + SYS_mlockall : uintptr : 230 + SYS_munlockall : uintptr : 231 + SYS_mincore : uintptr : 232 + SYS_madvise : uintptr : 233 + SYS_remap_file_pages : uintptr : 234 + SYS_mbind : uintptr : 235 + SYS_get_mempolicy : uintptr : 236 + SYS_set_mempolicy : uintptr : 237 + SYS_migrate_pages : uintptr : 238 + SYS_move_pages : uintptr : 239 + SYS_rt_tgsigqueueinfo : uintptr : 240 + SYS_perf_event_open : uintptr : 241 + SYS_accept4 : uintptr : 242 + SYS_recvmmsg : uintptr : 243 + SYS_arch_specific_syscall : uintptr : 244 + SYS_wait4 : uintptr : 260 + SYS_prlimit64 : uintptr : 261 + SYS_fanotify_init : uintptr : 262 + SYS_fanotify_mark : uintptr : 263 + SYS_clock_adjtime : uintptr : 266 + SYS_syncfs : uintptr : 267 + SYS_setns : uintptr : 268 + SYS_sendmmsg : uintptr : 269 + SYS_process_vm_readv : uintptr : 270 + SYS_process_vm_writev : uintptr : 271 + SYS_kcmp : uintptr : 272 + SYS_finit_module : uintptr : 273 + SYS_sched_setattr : uintptr : 274 + SYS_sched_getattr : uintptr : 275 + SYS_renameat2 : uintptr : 276 + SYS_seccomp : uintptr : 277 SYS_getrandom : uintptr : 278 -} else when ODIN_ARCH == "386" { - SYS_mmap : uintptr : 192 // 90 is "sys_old_mmap", we want mmap2 - SYS_mprotect : uintptr : 125 + SYS_memfd_create : uintptr : 279 + SYS_bpf : uintptr : 280 + SYS_execveat : uintptr : 281 + SYS_userfaultfd : uintptr : 282 + SYS_membarrier : uintptr : 283 + SYS_mlock2 : uintptr : 284 + SYS_copy_file_range : uintptr : 285 + SYS_preadv2 : uintptr : 286 + SYS_pwritev2 : uintptr : 287 + SYS_pkey_mprotect : uintptr : 288 + SYS_pkey_alloc : uintptr : 289 + SYS_pkey_free : uintptr : 290 + SYS_statx : uintptr : 291 + SYS_io_pgetevents : uintptr : 292 + SYS_rseq : uintptr : 293 + SYS_kexec_file_load : uintptr : 294 + SYS_pidfd_send_signal : uintptr : 424 + SYS_io_uring_setup : uintptr : 425 + SYS_io_uring_enter : uintptr : 426 + SYS_io_uring_register : uintptr : 427 + SYS_open_tree : uintptr : 428 + SYS_move_mount : uintptr : 429 + SYS_fsopen : uintptr : 430 + SYS_fsconfig : uintptr : 431 + SYS_fsmount : uintptr : 432 + SYS_fspick : uintptr : 433 + SYS_pidfd_open : uintptr : 434 + SYS_clone3 : uintptr : 435 + SYS_close_range : uintptr : 436 + SYS_openat2 : uintptr : 437 + SYS_pidfd_getfd : uintptr : 438 + SYS_faccessat2 : uintptr : 439 + SYS_process_madvise : uintptr : 440 + SYS_epoll_pwait2 : uintptr : 441 + SYS_mount_setattr : uintptr : 442 + SYS_landlock_create_ruleset : uintptr : 444 + SYS_landlock_add_rule : uintptr : 445 + SYS_landlock_restrict_self : uintptr : 446 + + SIGCHLD :: 17 +} else when ODIN_ARCH == .i386 { + SYS_restart_syscall : uintptr : 0 + SYS_exit : uintptr : 1 + SYS_fork : uintptr : 2 + SYS_read : uintptr : 3 + SYS_write : uintptr : 4 + SYS_open : uintptr : 5 + SYS_close : uintptr : 6 + SYS_waitpid : uintptr : 7 + SYS_creat : uintptr : 8 + SYS_link : uintptr : 9 + SYS_unlink : uintptr : 10 + SYS_execve : uintptr : 11 + SYS_chdir : uintptr : 12 + SYS_time : uintptr : 13 + SYS_mknod : uintptr : 14 + SYS_chmod : uintptr : 15 + SYS_lchown : uintptr : 16 + SYS_break : uintptr : 17 + SYS_oldstat : uintptr : 18 + SYS_lseek : uintptr : 19 + SYS_getpid : uintptr : 20 + SYS_mount : uintptr : 21 + SYS_umount : uintptr : 22 + SYS_setuid : uintptr : 23 + SYS_getuid : uintptr : 24 + SYS_stime : uintptr : 25 + SYS_ptrace : uintptr : 26 + SYS_alarm : uintptr : 27 + SYS_oldfstat : uintptr : 28 + SYS_pause : uintptr : 29 + SYS_utime : uintptr : 30 + SYS_stty : uintptr : 31 + SYS_gtty : uintptr : 32 + SYS_access : uintptr : 33 + SYS_nice : uintptr : 34 + SYS_ftime : uintptr : 35 + SYS_sync : uintptr : 36 + SYS_kill : uintptr : 37 + SYS_rename : uintptr : 38 + SYS_mkdir : uintptr : 39 + SYS_rmdir : uintptr : 40 + SYS_dup : uintptr : 41 + SYS_pipe : uintptr : 42 + SYS_times : uintptr : 43 + SYS_prof : uintptr : 44 + SYS_brk : uintptr : 45 + SYS_setgid : uintptr : 46 + SYS_getgid : uintptr : 47 + SYS_signal : uintptr : 48 + SYS_geteuid : uintptr : 49 + SYS_getegid : uintptr : 50 + SYS_acct : uintptr : 51 + SYS_umount2 : uintptr : 52 + SYS_lock : uintptr : 53 + SYS_ioctl : uintptr : 54 + SYS_fcntl : uintptr : 55 + SYS_mpx : uintptr : 56 + SYS_setpgid : uintptr : 57 + SYS_ulimit : uintptr : 58 + SYS_oldolduname : uintptr : 59 + SYS_umask : uintptr : 60 + SYS_chroot : uintptr : 61 + SYS_ustat : uintptr : 62 + SYS_dup2 : uintptr : 63 + SYS_getppid : uintptr : 64 + SYS_getpgrp : uintptr : 65 + SYS_setsid : uintptr : 66 + SYS_sigaction : uintptr : 67 + SYS_sgetmask : uintptr : 68 + SYS_ssetmask : uintptr : 69 + SYS_setreuid : uintptr : 70 + SYS_setregid : uintptr : 71 + SYS_sigsuspend : uintptr : 72 + SYS_sigpending : uintptr : 73 + SYS_sethostname : uintptr : 74 + SYS_setrlimit : uintptr : 75 + SYS_getrlimit : uintptr : 76 + SYS_getrusage : uintptr : 77 + SYS_gettimeofday : uintptr : 78 + SYS_settimeofday : uintptr : 79 + SYS_getgroups : uintptr : 80 + SYS_setgroups : uintptr : 81 + SYS_select : uintptr : 82 + SYS_symlink : uintptr : 83 + SYS_oldlstat : uintptr : 84 + SYS_readlink : uintptr : 85 + SYS_uselib : uintptr : 86 + SYS_swapon : uintptr : 87 + SYS_reboot : uintptr : 88 + SYS_readdir : uintptr : 89 + SYS_old_mmap : uintptr : 90 // 90 is "sys_old_mmap", we want mmap2 SYS_munmap : uintptr : 91 - SYS_madvise : uintptr : 219 - SYS_futex : uintptr : 240 - SYS_gettid : uintptr : 224 - SYS_getrandom : uintptr : 355 -} else when ODIN_ARCH == "arm" { - SYS_mmap : uintptr : 192 // 90 is "sys_old_mmap", we want mmap2 + SYS_truncate : uintptr : 92 + SYS_ftruncate : uintptr : 93 + SYS_fchmod : uintptr : 94 + SYS_fchown : uintptr : 95 + SYS_getpriority : uintptr : 96 + SYS_setpriority : uintptr : 97 + SYS_profil : uintptr : 98 + SYS_statfs : uintptr : 99 + SYS_fstatfs : uintptr : 100 + SYS_ioperm : uintptr : 101 + SYS_socketcall : uintptr : 102 + SYS_syslog : uintptr : 103 + SYS_setitimer : uintptr : 104 + SYS_getitimer : uintptr : 105 + SYS_stat : uintptr : 106 + SYS_lstat : uintptr : 107 + SYS_fstat : uintptr : 108 + SYS_olduname : uintptr : 109 + SYS_iopl : uintptr : 110 + SYS_vhangup : uintptr : 111 + SYS_idle : uintptr : 112 + SYS_vm86old : uintptr : 113 + SYS_wait4 : uintptr : 114 + SYS_swapoff : uintptr : 115 + SYS_sysinfo : uintptr : 116 + SYS_ipc : uintptr : 117 + SYS_fsync : uintptr : 118 + SYS_sigreturn : uintptr : 119 + SYS_clone : uintptr : 120 + SYS_setdomainname : uintptr : 121 + SYS_uname : uintptr : 122 + SYS_modify_ldt : uintptr : 123 + SYS_adjtimex : uintptr : 124 SYS_mprotect : uintptr : 125 - SYS_munmap: uintptr : 91 - SYS_madvise: uintptr : 220 + SYS_sigprocmask : uintptr : 126 + SYS_create_module : uintptr : 127 + SYS_init_module : uintptr : 128 + SYS_delete_module : uintptr : 129 + SYS_get_kernel_syms : uintptr : 130 + SYS_quotactl : uintptr : 131 + SYS_getpgid : uintptr : 132 + SYS_fchdir : uintptr : 133 + SYS_bdflush : uintptr : 134 + SYS_sysfs : uintptr : 135 + SYS_personality : uintptr : 136 + SYS_afs_syscall : uintptr : 137 + SYS_setfsuid : uintptr : 138 + SYS_setfsgid : uintptr : 139 + SYS__llseek : uintptr : 140 + SYS_getdents : uintptr : 141 + SYS__newselect : uintptr : 142 + SYS_flock : uintptr : 143 + SYS_msync : uintptr : 144 + SYS_readv : uintptr : 145 + SYS_writev : uintptr : 146 + SYS_getsid : uintptr : 147 + SYS_fdatasync : uintptr : 148 + SYS__sysctl : uintptr : 149 + SYS_mlock : uintptr : 150 + SYS_munlock : uintptr : 151 + SYS_mlockall : uintptr : 152 + SYS_munlockall : uintptr : 153 + SYS_sched_setparam : uintptr : 154 + SYS_sched_getparam : uintptr : 155 + SYS_sched_setscheduler : uintptr : 156 + SYS_sched_getscheduler : uintptr : 157 + SYS_sched_yield : uintptr : 158 + SYS_sched_get_priority_max : uintptr : 159 + SYS_sched_get_priority_min : uintptr : 160 + SYS_sched_rr_get_interval : uintptr : 161 + SYS_nanosleep : uintptr : 162 + SYS_mremap : uintptr : 163 + SYS_setresuid : uintptr : 164 + SYS_getresuid : uintptr : 165 + SYS_vm86 : uintptr : 166 + SYS_query_module : uintptr : 167 + SYS_poll : uintptr : 168 + SYS_nfsservctl : uintptr : 169 + SYS_setresgid : uintptr : 170 + SYS_getresgid : uintptr : 171 + SYS_prctl : uintptr : 172 + SYS_rt_sigreturn : uintptr : 173 + SYS_rt_sigaction : uintptr : 174 + SYS_rt_sigprocmask : uintptr : 175 + SYS_rt_sigpending : uintptr : 176 + SYS_rt_sigtimedwait : uintptr : 177 + SYS_rt_sigqueueinfo : uintptr : 178 + SYS_rt_sigsuspend : uintptr : 179 + SYS_pread64 : uintptr : 180 + SYS_pwrite64 : uintptr : 181 + SYS_chown : uintptr : 182 + SYS_getcwd : uintptr : 183 + SYS_capget : uintptr : 184 + SYS_capset : uintptr : 185 + SYS_sigaltstack : uintptr : 186 + SYS_sendfile : uintptr : 187 + SYS_getpmsg : uintptr : 188 + SYS_putpmsg : uintptr : 189 + SYS_vfork : uintptr : 190 + SYS_ugetrlimit : uintptr : 191 + SYS_mmap : uintptr : 192 // actually mmap2 + SYS_truncate64 : uintptr : 193 + SYS_ftruncate64 : uintptr : 194 + SYS_stat64 : uintptr : 195 + SYS_lstat64 : uintptr : 196 + SYS_fstat64 : uintptr : 197 + SYS_lchown32 : uintptr : 198 + SYS_getuid32 : uintptr : 199 + SYS_getgid32 : uintptr : 200 + SYS_geteuid32 : uintptr : 201 + SYS_getegid32 : uintptr : 202 + SYS_setreuid32 : uintptr : 203 + SYS_setregid32 : uintptr : 204 + SYS_getgroups32 : uintptr : 205 + SYS_setgroups32 : uintptr : 206 + SYS_fchown32 : uintptr : 207 + SYS_setresuid32 : uintptr : 208 + SYS_getresuid32 : uintptr : 209 + SYS_setresgid32 : uintptr : 210 + SYS_getresgid32 : uintptr : 211 + SYS_chown32 : uintptr : 212 + SYS_setuid32 : uintptr : 213 + SYS_setgid32 : uintptr : 214 + SYS_setfsuid32 : uintptr : 215 + SYS_setfsgid32 : uintptr : 216 + SYS_pivot_root : uintptr : 217 + SYS_mincore : uintptr : 218 + SYS_madvise : uintptr : 219 + SYS_getdents64 : uintptr : 220 + SYS_fcntl64 : uintptr : 221 + SYS_gettid : uintptr : 224 + SYS_readahead : uintptr : 225 + SYS_setxattr : uintptr : 226 + SYS_lsetxattr : uintptr : 227 + SYS_fsetxattr : uintptr : 228 + SYS_getxattr : uintptr : 229 + SYS_lgetxattr : uintptr : 230 + SYS_fgetxattr : uintptr : 231 + SYS_listxattr : uintptr : 232 + SYS_llistxattr : uintptr : 233 + SYS_flistxattr : uintptr : 234 + SYS_removexattr : uintptr : 235 + SYS_lremovexattr : uintptr : 236 + SYS_fremovexattr : uintptr : 237 + SYS_tkill : uintptr : 238 + SYS_sendfile64 : uintptr : 239 SYS_futex : uintptr : 240 - SYS_gettid : uintptr: 224 + SYS_sched_setaffinity : uintptr : 241 + SYS_sched_getaffinity : uintptr : 242 + SYS_set_thread_area : uintptr : 243 + SYS_get_thread_area : uintptr : 244 + SYS_io_setup : uintptr : 245 + SYS_io_destroy : uintptr : 246 + SYS_io_getevents : uintptr : 247 + SYS_io_submit : uintptr : 248 + SYS_io_cancel : uintptr : 249 + SYS_fadvise64 : uintptr : 250 + SYS_exit_group : uintptr : 252 + SYS_lookup_dcookie : uintptr : 253 + SYS_epoll_create : uintptr : 254 + SYS_epoll_ctl : uintptr : 255 + SYS_epoll_wait : uintptr : 256 + SYS_remap_file_pages : uintptr : 257 + SYS_set_tid_address : uintptr : 258 + SYS_timer_create : uintptr : 259 + SYS_timer_settime : uintptr : 260 + SYS_timer_gettime : uintptr : 261 + SYS_timer_getoverrun : uintptr : 262 + SYS_timer_delete : uintptr : 263 + SYS_clock_settime : uintptr : 264 + SYS_clock_gettime : uintptr : 265 + SYS_clock_getres : uintptr : 266 + SYS_clock_nanosleep : uintptr : 267 + SYS_statfs64 : uintptr : 268 + SYS_fstatfs64 : uintptr : 269 + SYS_tgkill : uintptr : 270 + SYS_utimes : uintptr : 271 + SYS_fadvise64_64 : uintptr : 272 + SYS_vserver : uintptr : 273 + SYS_mbind : uintptr : 274 + SYS_get_mempolicy : uintptr : 275 + SYS_set_mempolicy : uintptr : 276 + SYS_mq_open : uintptr : 277 + SYS_mq_unlink : uintptr : 278 + SYS_mq_timedsend : uintptr : 279 + SYS_mq_timedreceive : uintptr : 280 + SYS_mq_notify : uintptr : 281 + SYS_mq_getsetattr : uintptr : 282 + SYS_kexec_load : uintptr : 283 + SYS_waitid : uintptr : 284 + SYS_add_key : uintptr : 286 + SYS_request_key : uintptr : 287 + SYS_keyctl : uintptr : 288 + SYS_ioprio_set : uintptr : 289 + SYS_ioprio_get : uintptr : 290 + SYS_inotify_init : uintptr : 291 + SYS_inotify_add_watch : uintptr : 292 + SYS_inotify_rm_watch : uintptr : 293 + SYS_migrate_pages : uintptr : 294 + SYS_openat : uintptr : 295 + SYS_mkdirat : uintptr : 296 + SYS_mknodat : uintptr : 297 + SYS_fchownat : uintptr : 298 + SYS_futimesat : uintptr : 299 + SYS_fstatat64 : uintptr : 300 + SYS_unlinkat : uintptr : 301 + SYS_renameat : uintptr : 302 + SYS_linkat : uintptr : 303 + SYS_symlinkat : uintptr : 304 + SYS_readlinkat : uintptr : 305 + SYS_fchmodat : uintptr : 306 + SYS_faccessat : uintptr : 307 + SYS_pselect6 : uintptr : 308 + SYS_ppoll : uintptr : 309 + SYS_unshare : uintptr : 310 + SYS_set_robust_list : uintptr : 311 + SYS_get_robust_list : uintptr : 312 + SYS_splice : uintptr : 313 + SYS_sync_file_range : uintptr : 314 + SYS_tee : uintptr : 315 + SYS_vmsplice : uintptr : 316 + SYS_move_pages : uintptr : 317 + SYS_getcpu : uintptr : 318 + SYS_epoll_pwait : uintptr : 319 + SYS_utimensat : uintptr : 320 + SYS_signalfd : uintptr : 321 + SYS_timerfd_create : uintptr : 322 + SYS_eventfd : uintptr : 323 + SYS_fallocate : uintptr : 324 + SYS_timerfd_settime : uintptr : 325 + SYS_timerfd_gettime : uintptr : 326 + SYS_signalfd4 : uintptr : 327 + SYS_eventfd2 : uintptr : 328 + SYS_epoll_create1 : uintptr : 329 + SYS_dup3 : uintptr : 330 + SYS_pipe2 : uintptr : 331 + SYS_inotify_init1 : uintptr : 332 + SYS_preadv : uintptr : 333 + SYS_pwritev : uintptr : 334 + SYS_rt_tgsigqueueinfo : uintptr : 335 + SYS_perf_event_open : uintptr : 336 + SYS_recvmmsg : uintptr : 337 + SYS_fanotify_init : uintptr : 338 + SYS_fanotify_mark : uintptr : 339 + SYS_prlimit64 : uintptr : 340 + SYS_name_to_handle_at : uintptr : 341 + SYS_open_by_handle_at : uintptr : 342 + SYS_clock_adjtime : uintptr : 343 + SYS_syncfs : uintptr : 344 + SYS_sendmmsg : uintptr : 345 + SYS_setns : uintptr : 346 + SYS_process_vm_readv : uintptr : 347 + SYS_process_vm_writev : uintptr : 348 + SYS_kcmp : uintptr : 349 + SYS_finit_module : uintptr : 350 + SYS_sched_setattr : uintptr : 351 + SYS_sched_getattr : uintptr : 352 + SYS_renameat2 : uintptr : 353 + SYS_seccomp : uintptr : 354 + SYS_getrandom : uintptr : 355 + SYS_memfd_create : uintptr : 356 + SYS_bpf : uintptr : 357 + SYS_execveat : uintptr : 358 + SYS_socket : uintptr : 359 + SYS_socketpair : uintptr : 360 + SYS_bind : uintptr : 361 + SYS_connect : uintptr : 362 + SYS_listen : uintptr : 363 + SYS_accept4 : uintptr : 364 + SYS_getsockopt : uintptr : 365 + SYS_setsockopt : uintptr : 366 + SYS_getsockname : uintptr : 367 + SYS_getpeername : uintptr : 368 + SYS_sendto : uintptr : 369 + SYS_sendmsg : uintptr : 370 + SYS_recvfrom : uintptr : 371 + SYS_recvmsg : uintptr : 372 + SYS_shutdown : uintptr : 373 + SYS_userfaultfd : uintptr : 374 + SYS_membarrier : uintptr : 375 + SYS_mlock2 : uintptr : 376 + SYS_copy_file_range : uintptr : 377 + SYS_preadv2 : uintptr : 378 + SYS_pwritev2 : uintptr : 379 + SYS_pkey_mprotect : uintptr : 380 + SYS_pkey_alloc : uintptr : 381 + SYS_pkey_free : uintptr : 382 + SYS_statx : uintptr : 383 + SYS_arch_prctl : uintptr : 384 + SYS_io_pgetevents : uintptr : 385 + SYS_rseq : uintptr : 386 + SYS_semget : uintptr : 393 + SYS_semctl : uintptr : 394 + SYS_shmget : uintptr : 395 + SYS_shmctl : uintptr : 396 + SYS_shmat : uintptr : 397 + SYS_shmdt : uintptr : 398 + SYS_msgget : uintptr : 399 + SYS_msgsnd : uintptr : 400 + SYS_msgrcv : uintptr : 401 + SYS_msgctl : uintptr : 402 + SYS_clock_gettime64 : uintptr : 403 + SYS_clock_settime64 : uintptr : 404 + SYS_clock_adjtime64 : uintptr : 405 + SYS_clock_getres_time64 : uintptr : 406 + SYS_clock_nanosleep_time64 : uintptr : 407 + SYS_timer_gettime64 : uintptr : 408 + SYS_timer_settime64 : uintptr : 409 + SYS_timerfd_gettime64 : uintptr : 410 + SYS_timerfd_settime64 : uintptr : 411 + SYS_utimensat_time64 : uintptr : 412 + SYS_pselect6_time64 : uintptr : 413 + SYS_ppoll_time64 : uintptr : 414 + SYS_io_pgetevents_time64 : uintptr : 416 + SYS_recvmmsg_time64 : uintptr : 417 + SYS_mq_timedsend_time64 : uintptr : 418 + SYS_mq_timedreceive_time64 : uintptr : 419 + SYS_semtimedop_time64 : uintptr : 420 + SYS_rt_sigtimedwait_time64 : uintptr : 421 + SYS_futex_time64 : uintptr : 422 + SYS_sched_rr_get_interval_time64 : uintptr : 423 + SYS_pidfd_send_signal : uintptr : 424 + SYS_io_uring_setup : uintptr : 425 + SYS_io_uring_enter : uintptr : 426 + SYS_io_uring_register : uintptr : 427 + SYS_open_tree : uintptr : 428 + SYS_move_mount : uintptr : 429 + SYS_fsopen : uintptr : 430 + SYS_fsconfig : uintptr : 431 + SYS_fsmount : uintptr : 432 + SYS_fspick : uintptr : 433 + SYS_pidfd_open : uintptr : 434 + SYS_clone3 : uintptr : 435 + SYS_close_range : uintptr : 436 + SYS_openat2 : uintptr : 437 + SYS_pidfd_getfd : uintptr : 438 + SYS_faccessat2 : uintptr : 439 + SYS_process_madvise : uintptr : 440 + SYS_epoll_pwait2 : uintptr : 441 + SYS_mount_setattr : uintptr : 442 + SYS_landlock_create_ruleset : uintptr : 444 + SYS_landlock_add_rule : uintptr : 445 + SYS_landlock_restrict_self : uintptr : 446 + SYS_memfd_secret : uintptr : 447 +} else when false /*ODIN_ARCH == .arm*/ { // TODO + SYS_restart_syscall : uintptr : 0 + SYS_exit : uintptr : 1 + SYS_fork : uintptr : 2 + SYS_read : uintptr : 3 + SYS_write : uintptr : 4 + SYS_open : uintptr : 5 + SYS_close : uintptr : 6 + SYS_creat : uintptr : 8 + SYS_link : uintptr : 9 + SYS_unlink : uintptr : 10 + SYS_execve : uintptr : 11 + SYS_chdir : uintptr : 12 + SYS_mknod : uintptr : 14 + SYS_chmod : uintptr : 15 + SYS_lchown : uintptr : 16 + SYS_lseek : uintptr : 19 + SYS_getpid : uintptr : 20 + SYS_mount : uintptr : 21 + SYS_setuid : uintptr : 23 + SYS_getuid : uintptr : 24 + SYS_ptrace : uintptr : 26 + SYS_pause : uintptr : 29 + SYS_access : uintptr : 33 + SYS_nice : uintptr : 34 + SYS_sync : uintptr : 36 + SYS_kill : uintptr : 37 + SYS_rename : uintptr : 38 + SYS_mkdir : uintptr : 39 + SYS_rmdir : uintptr : 40 + SYS_dup : uintptr : 41 + SYS_pipe : uintptr : 42 + SYS_times : uintptr : 43 + SYS_brk : uintptr : 45 + SYS_setgid : uintptr : 46 + SYS_getgid : uintptr : 47 + SYS_geteuid : uintptr : 49 + SYS_getegid : uintptr : 50 + SYS_acct : uintptr : 51 + SYS_umount2 : uintptr : 52 + SYS_ioctl : uintptr : 54 + SYS_fcntl : uintptr : 55 + SYS_setpgid : uintptr : 57 + SYS_umask : uintptr : 60 + SYS_chroot : uintptr : 61 + SYS_ustat : uintptr : 62 + SYS_dup2 : uintptr : 63 + SYS_getppid : uintptr : 64 + SYS_getpgrp : uintptr : 65 + SYS_setsid : uintptr : 66 + SYS_sigaction : uintptr : 67 + SYS_setreuid : uintptr : 70 + SYS_setregid : uintptr : 71 + SYS_sigsuspend : uintptr : 72 + SYS_sigpending : uintptr : 73 + SYS_sethostname : uintptr : 74 + SYS_setrlimit : uintptr : 75 + SYS_getrusage : uintptr : 77 + SYS_gettimeofday : uintptr : 78 + SYS_settimeofday : uintptr : 79 + SYS_getgroups : uintptr : 80 + SYS_setgroups : uintptr : 81 + SYS_symlink : uintptr : 83 + SYS_readlink : uintptr : 85 + SYS_uselib : uintptr : 86 + SYS_swapon : uintptr : 87 + SYS_reboot : uintptr : 88 + SYS_munmap : uintptr : 91 + SYS_truncate : uintptr : 92 + SYS_ftruncate : uintptr : 93 + SYS_fchmod : uintptr : 94 + SYS_fchown : uintptr : 95 + SYS_getpriority : uintptr : 96 + SYS_setpriority : uintptr : 97 + SYS_statfs : uintptr : 99 + SYS_fstatfs : uintptr : 100 + SYS_syslog : uintptr : 103 + SYS_setitimer : uintptr : 104 + SYS_getitimer : uintptr : 105 + SYS_stat : uintptr : 106 + SYS_lstat : uintptr : 107 + SYS_fstat : uintptr : 108 + SYS_vhangup : uintptr : 111 + SYS_wait4 : uintptr : 114 + SYS_swapoff : uintptr : 115 + SYS_sysinfo : uintptr : 116 + SYS_fsync : uintptr : 118 + SYS_sigreturn : uintptr : 119 + SYS_clone : uintptr : 120 + SYS_setdomainname : uintptr : 121 + SYS_uname : uintptr : 122 + SYS_adjtimex : uintptr : 124 + SYS_mprotect : uintptr : 125 + SYS_sigprocmask : uintptr : 126 + SYS_init_module : uintptr : 128 + SYS_delete_module : uintptr : 129 + SYS_quotactl : uintptr : 131 + SYS_getpgid : uintptr : 132 + SYS_fchdir : uintptr : 133 + SYS_bdflush : uintptr : 134 + SYS_sysfs : uintptr : 135 + SYS_personality : uintptr : 136 + SYS_setfsuid : uintptr : 138 + SYS_setfsgid : uintptr : 139 + SYS__llseek : uintptr : 140 + SYS_getdents : uintptr : 141 + SYS__newselect : uintptr : 142 + SYS_flock : uintptr : 143 + SYS_msync : uintptr : 144 + SYS_readv : uintptr : 145 + SYS_writev : uintptr : 146 + SYS_getsid : uintptr : 147 + SYS_fdatasync : uintptr : 148 + SYS__sysctl : uintptr : 149 + SYS_mlock : uintptr : 150 + SYS_munlock : uintptr : 151 + SYS_mlockall : uintptr : 152 + SYS_munlockall : uintptr : 153 + SYS_sched_setparam : uintptr : 154 + SYS_sched_getparam : uintptr : 155 + SYS_sched_setscheduler : uintptr : 156 + SYS_sched_getscheduler : uintptr : 157 + SYS_sched_yield : uintptr : 158 + SYS_sched_get_priority_max : uintptr : 159 + SYS_sched_get_priority_min : uintptr : 160 + SYS_sched_rr_get_interval : uintptr : 161 + SYS_nanosleep : uintptr : 162 + SYS_mremap : uintptr : 163 + SYS_setresuid : uintptr : 164 + SYS_getresuid : uintptr : 165 + SYS_poll : uintptr : 168 + SYS_nfsservctl : uintptr : 169 + SYS_setresgid : uintptr : 170 + SYS_getresgid : uintptr : 171 + SYS_prctl : uintptr : 172 + SYS_rt_sigreturn : uintptr : 173 + SYS_rt_sigaction : uintptr : 174 + SYS_rt_sigprocmask : uintptr : 175 + SYS_rt_sigpending : uintptr : 176 + SYS_rt_sigtimedwait : uintptr : 177 + SYS_rt_sigqueueinfo : uintptr : 178 + SYS_rt_sigsuspend : uintptr : 179 + SYS_pread64 : uintptr : 180 + SYS_pwrite64 : uintptr : 181 + SYS_chown : uintptr : 182 + SYS_getcwd : uintptr : 183 + SYS_capget : uintptr : 184 + SYS_capset : uintptr : 185 + SYS_sigaltstack : uintptr : 186 + SYS_sendfile : uintptr : 187 + SYS_vfork : uintptr : 190 + SYS_ugetrlimit : uintptr : 191 + SYS_mmap : uintptr : 192 // actually mmap2 + SYS_truncate64 : uintptr : 193 + SYS_ftruncate64 : uintptr : 194 + SYS_stat64 : uintptr : 195 + SYS_lstat64 : uintptr : 196 + SYS_fstat64 : uintptr : 197 + SYS_lchown32 : uintptr : 198 + SYS_getuid32 : uintptr : 199 + SYS_getgid32 : uintptr : 200 + SYS_geteuid32 : uintptr : 201 + SYS_getegid32 : uintptr : 202 + SYS_setreuid32 : uintptr : 203 + SYS_setregid32 : uintptr : 204 + SYS_getgroups32 : uintptr : 205 + SYS_setgroups32 : uintptr : 206 + SYS_fchown32 : uintptr : 207 + SYS_setresuid32 : uintptr : 208 + SYS_getresuid32 : uintptr : 209 + SYS_setresgid32 : uintptr : 210 + SYS_getresgid32 : uintptr : 211 + SYS_chown32 : uintptr : 212 + SYS_setuid32 : uintptr : 213 + SYS_setgid32 : uintptr : 214 + SYS_setfsuid32 : uintptr : 215 + SYS_setfsgid32 : uintptr : 216 + SYS_getdents64 : uintptr : 217 + SYS_pivot_root : uintptr : 218 + SYS_mincore : uintptr : 219 + SYS_madvise : uintptr : 220 + SYS_fcntl64 : uintptr : 221 + SYS_gettid : uintptr : 224 + SYS_readahead : uintptr : 225 + SYS_setxattr : uintptr : 226 + SYS_lsetxattr : uintptr : 227 + SYS_fsetxattr : uintptr : 228 + SYS_getxattr : uintptr : 229 + SYS_lgetxattr : uintptr : 230 + SYS_fgetxattr : uintptr : 231 + SYS_listxattr : uintptr : 232 + SYS_llistxattr : uintptr : 233 + SYS_flistxattr : uintptr : 234 + SYS_removexattr : uintptr : 235 + SYS_lremovexattr : uintptr : 236 + SYS_fremovexattr : uintptr : 237 + SYS_tkill : uintptr : 238 + SYS_sendfile64 : uintptr : 239 + SYS_futex : uintptr : 240 + SYS_sched_setaffinity : uintptr : 241 + SYS_sched_getaffinity : uintptr : 242 + SYS_io_setup : uintptr : 243 + SYS_io_destroy : uintptr : 244 + SYS_io_getevents : uintptr : 245 + SYS_io_submit : uintptr : 246 + SYS_io_cancel : uintptr : 247 + SYS_exit_group : uintptr : 248 + SYS_lookup_dcookie : uintptr : 249 + SYS_epoll_create : uintptr : 250 + SYS_epoll_ctl : uintptr : 251 + SYS_epoll_wait : uintptr : 252 + SYS_remap_file_pages : uintptr : 253 + SYS_set_tid_address : uintptr : 256 + SYS_timer_create : uintptr : 257 + SYS_timer_settime : uintptr : 258 + SYS_timer_gettime : uintptr : 259 + SYS_timer_getoverrun : uintptr : 260 + SYS_timer_delete : uintptr : 261 + SYS_clock_settime : uintptr : 262 + SYS_clock_gettime : uintptr : 263 + SYS_clock_getres : uintptr : 264 + SYS_clock_nanosleep : uintptr : 265 + SYS_statfs64 : uintptr : 266 + SYS_fstatfs64 : uintptr : 267 + SYS_tgkill : uintptr : 268 + SYS_utimes : uintptr : 269 + SYS_fadvise64_64 : uintptr : 270 + SYS_pciconfig_iobase : uintptr : 271 + SYS_pciconfig_read : uintptr : 272 + SYS_pciconfig_write : uintptr : 273 + SYS_mq_open : uintptr : 274 + SYS_mq_unlink : uintptr : 275 + SYS_mq_timedsend : uintptr : 276 + SYS_mq_timedreceive : uintptr : 277 + SYS_mq_notify : uintptr : 278 + SYS_mq_getsetattr : uintptr : 279 + SYS_waitid : uintptr : 280 + SYS_socket : uintptr : 281 + SYS_bind : uintptr : 282 + SYS_connect : uintptr : 283 + SYS_listen : uintptr : 284 + SYS_accept : uintptr : 285 + SYS_getsockname : uintptr : 286 + SYS_getpeername : uintptr : 287 + SYS_socketpair : uintptr : 288 + SYS_send : uintptr : 289 + SYS_sendto : uintptr : 290 + SYS_recv : uintptr : 291 + SYS_recvfrom : uintptr : 292 + SYS_shutdown : uintptr : 293 + SYS_setsockopt : uintptr : 294 + SYS_getsockopt : uintptr : 295 + SYS_sendmsg : uintptr : 296 + SYS_recvmsg : uintptr : 297 + SYS_semop : uintptr : 298 + SYS_semget : uintptr : 299 + SYS_semctl : uintptr : 300 + SYS_msgsnd : uintptr : 301 + SYS_msgrcv : uintptr : 302 + SYS_msgget : uintptr : 303 + SYS_msgctl : uintptr : 304 + SYS_shmat : uintptr : 305 + SYS_shmdt : uintptr : 306 + SYS_shmget : uintptr : 307 + SYS_shmctl : uintptr : 308 + SYS_add_key : uintptr : 309 + SYS_request_key : uintptr : 310 + SYS_keyctl : uintptr : 311 + SYS_semtimedop : uintptr : 312 + SYS_vserver : uintptr : 313 + SYS_ioprio_set : uintptr : 314 + SYS_ioprio_get : uintptr : 315 + SYS_inotify_init : uintptr : 316 + SYS_inotify_add_watch : uintptr : 317 + SYS_inotify_rm_watch : uintptr : 318 + SYS_mbind : uintptr : 319 + SYS_get_mempolicy : uintptr : 320 + SYS_set_mempolicy : uintptr : 321 + SYS_openat : uintptr : 322 + SYS_mkdirat : uintptr : 323 + SYS_mknodat : uintptr : 324 + SYS_fchownat : uintptr : 325 + SYS_futimesat : uintptr : 326 + SYS_fstatat64 : uintptr : 327 + SYS_unlinkat : uintptr : 328 + SYS_renameat : uintptr : 329 + SYS_linkat : uintptr : 330 + SYS_symlinkat : uintptr : 331 + SYS_readlinkat : uintptr : 332 + SYS_fchmodat : uintptr : 333 + SYS_faccessat : uintptr : 334 + SYS_pselect6 : uintptr : 335 + SYS_ppoll : uintptr : 336 + SYS_unshare : uintptr : 337 + SYS_set_robust_list : uintptr : 338 + SYS_get_robust_list : uintptr : 339 + SYS_splice : uintptr : 340 + SYS_sync_file_range : uintptr : 341 + SYS_tee : uintptr : 342 + SYS_vmsplice : uintptr : 343 + SYS_move_pages : uintptr : 344 + SYS_getcpu : uintptr : 345 + SYS_epoll_pwait : uintptr : 346 + SYS_kexec_load : uintptr : 347 + SYS_utimensat : uintptr : 348 + SYS_signalfd : uintptr : 349 + SYS_timerfd_create : uintptr : 350 + SYS_eventfd : uintptr : 351 + SYS_fallocate : uintptr : 352 + SYS_timerfd_settime : uintptr : 353 + SYS_timerfd_gettime : uintptr : 354 + SYS_signalfd4 : uintptr : 355 + SYS_eventfd2 : uintptr : 356 + SYS_epoll_create1 : uintptr : 357 + SYS_dup3 : uintptr : 358 + SYS_pipe2 : uintptr : 359 + SYS_inotify_init1 : uintptr : 360 + SYS_preadv : uintptr : 361 + SYS_pwritev : uintptr : 362 + SYS_rt_tgsigqueueinfo : uintptr : 363 + SYS_perf_event_open : uintptr : 364 + SYS_recvmmsg : uintptr : 365 + SYS_accept4 : uintptr : 366 + SYS_fanotify_init : uintptr : 367 + SYS_fanotify_mark : uintptr : 368 + SYS_prlimit64 : uintptr : 369 + SYS_name_to_handle_at : uintptr : 370 + SYS_open_by_handle_at : uintptr : 371 + SYS_clock_adjtime : uintptr : 372 + SYS_syncfs : uintptr : 373 + SYS_sendmmsg : uintptr : 374 + SYS_setns : uintptr : 375 + SYS_process_vm_readv : uintptr : 376 + SYS_process_vm_writev : uintptr : 377 + SYS_kcmp : uintptr : 378 + SYS_finit_module : uintptr : 379 + SYS_sched_setattr : uintptr : 380 + SYS_sched_getattr : uintptr : 381 + SYS_renameat2 : uintptr : 382 + SYS_seccomp : uintptr : 383 SYS_getrandom : uintptr : 384 + SYS_memfd_create : uintptr : 385 + SYS_bpf : uintptr : 386 + SYS_execveat : uintptr : 387 + SYS_userfaultfd : uintptr : 388 + SYS_membarrier : uintptr : 389 + SYS_mlock2 : uintptr : 390 + SYS_copy_file_range : uintptr : 391 + SYS_preadv2 : uintptr : 392 + SYS_pwritev2 : uintptr : 393 + SYS_pkey_mprotect : uintptr : 394 + SYS_pkey_alloc : uintptr : 395 + SYS_pkey_free : uintptr : 396 + SYS_statx : uintptr : 397 + SYS_rseq : uintptr : 398 + SYS_io_pgetevents : uintptr : 399 + SYS_migrate_pages : uintptr : 400 + SYS_kexec_file_load : uintptr : 401 + SYS_clock_gettime64 : uintptr : 403 + SYS_clock_settime64 : uintptr : 404 + SYS_clock_adjtime64 : uintptr : 405 + SYS_clock_getres_time64 : uintptr : 406 + SYS_clock_nanosleep_time64 : uintptr : 407 + SYS_timer_gettime64 : uintptr : 408 + SYS_timer_settime64 : uintptr : 409 + SYS_timerfd_gettime64 : uintptr : 410 + SYS_timerfd_settime64 : uintptr : 411 + SYS_utimensat_time64 : uintptr : 412 + SYS_pselect6_time64 : uintptr : 413 + SYS_ppoll_time64 : uintptr : 414 + SYS_io_pgetevents_time64 : uintptr : 416 + SYS_recvmmsg_time64 : uintptr : 417 + SYS_mq_timedsend_time64 : uintptr : 418 + SYS_mq_timedreceive_time64 : uintptr : 419 + SYS_semtimedop_time64 : uintptr : 420 + SYS_rt_sigtimedwait_time64 : uintptr : 421 + SYS_futex_time64 : uintptr : 422 + SYS_sched_rr_get_interval_time64 : uintptr : 423 + SYS_pidfd_send_signal : uintptr : 424 + SYS_io_uring_setup : uintptr : 425 + SYS_io_uring_enter : uintptr : 426 + SYS_io_uring_register : uintptr : 427 + SYS_open_tree : uintptr : 428 + SYS_move_mount : uintptr : 429 + SYS_fsopen : uintptr : 430 + SYS_fsconfig : uintptr : 431 + SYS_fsmount : uintptr : 432 + SYS_fspick : uintptr : 433 + SYS_pidfd_open : uintptr : 434 + SYS_clone3 : uintptr : 435 + SYS_close_range : uintptr : 436 + SYS_openat2 : uintptr : 437 + SYS_pidfd_getfd : uintptr : 438 + SYS_faccessat2 : uintptr : 439 + SYS_process_madvise : uintptr : 440 + SYS_epoll_pwait2 : uintptr : 441 + SYS_mount_setattr : uintptr : 442 + SYS_landlock_create_ruleset : uintptr : 444 + SYS_landlock_add_rule : uintptr : 445 + SYS_landlock_restrict_self : uintptr : 446 } else { #panic("Unsupported architecture") } diff --git a/core/sys/win32/user32.odin b/core/sys/win32/user32.odin index 593fdbb8e..44d1f7004 100644 --- a/core/sys/win32/user32.odin +++ b/core/sys/win32/user32.odin @@ -101,6 +101,9 @@ foreign user32 { } @(link_name="GetCursorPos") get_cursor_pos :: proc(p: ^Point) -> Bool --- @(link_name="SetCursorPos") set_cursor_pos :: proc(x, y: i32) -> Bool --- + @(link_name="GetCapure") get_capture :: proc(hwnd: Hwnd) -> Hwnd --- + @(link_name="SetCapture") set_capture :: proc(hwnd: Hwnd) -> Hwnd --- + @(link_name="ReleaseCapture") release_capture :: proc() -> Bool --- @(link_name="ScreenToClient") screen_to_client :: proc(h: Hwnd, p: ^Point) -> Bool --- @(link_name="ClientToScreen") client_to_screen :: proc(h: Hwnd, p: ^Point) -> Bool --- @(link_name="PostQuitMessage") post_quit_message :: proc(exit_code: i32) --- @@ -108,6 +111,8 @@ foreign user32 { @(link_name="SetWindowTextW") set_window_text_w :: proc(hwnd: Hwnd, c_string: Wstring) -> Bool --- @(link_name="RegisterClassA") register_class_a :: proc(wc: ^Wnd_Class_A) -> i16 --- @(link_name="RegisterClassW") register_class_w :: proc(wc: ^Wnd_Class_W) -> i16 --- + @(link_name="UnregisterClassA") unregister_class_a :: proc(class_name: cstring, instance: Hinstance) -> Bool --- + @(link_name="UnregisterClassW") unregister_class_w :: proc(class_name: Wstring, instance: Hinstance) -> Bool --- @(link_name="RegisterClassExA") register_class_ex_a :: proc(wc: ^Wnd_Class_Ex_A) -> i16 --- @(link_name="RegisterClassExW") register_class_ex_w :: proc(wc: ^Wnd_Class_Ex_W) -> i16 --- diff --git a/core/sys/windows/dwmapi.odin b/core/sys/windows/dwmapi.odin new file mode 100644 index 000000000..468b5bb87 --- /dev/null +++ b/core/sys/windows/dwmapi.odin @@ -0,0 +1,9 @@ +// +build windows +package sys_windows + +foreign import dwmapi "system:Dwmapi.lib" + +@(default_calling_convention="stdcall") +foreign dwmapi { + DwmFlush :: proc() -> HRESULT --- +} diff --git a/core/sys/windows/gdi32.odin b/core/sys/windows/gdi32.odin new file mode 100644 index 000000000..15d5567c7 --- /dev/null +++ b/core/sys/windows/gdi32.odin @@ -0,0 +1,66 @@ +// +build windows +package sys_windows + +foreign import gdi32 "system:Gdi32.lib" + +@(default_calling_convention="stdcall") +foreign gdi32 { + GetStockObject :: proc(i: c_int) -> HGDIOBJ --- + SelectObject :: proc(hdc: HDC, h: HGDIOBJ) -> HGDIOBJ --- + + CreateDIBPatternBrush :: proc(h: HGLOBAL, iUsage: UINT) -> HBRUSH --- + + CreateDIBitmap :: proc( + hdc: HDC, + pbmih: ^BITMAPINFOHEADER, + flInit: DWORD, + pjBits: VOID, + pbmi: ^BITMAPINFO, + iUsage: UINT, + ) -> HBITMAP --- + + CreateDIBSection :: proc( + hdc: HDC, + pbmi: ^BITMAPINFO, + usage: UINT, + ppvBits: VOID, + hSection: HANDLE, + offset: DWORD, + ) -> HBITMAP --- + + StretchDIBits :: proc( + hdc: HDC, + xDest: c_int, + yDest: c_int, + DestWidth: c_int, + DestHeight: c_int, + xSrc: c_int, + ySrc: c_int, + SrcWidth: c_int, + SrcHeight: c_int, + lpBits: VOID, + lpbmi: ^BITMAPINFO, + iUsage: UINT, + rop: DWORD, + ) -> c_int --- + + StretchBlt :: proc( + hdcDest: HDC, + xDest: c_int, + yDest: c_int, + wDest: c_int, + hDest: c_int, + hdcSrc: HDC, + xSrc: c_int, + ySrc: c_int, + wSrc: c_int, + hSrc: c_int, + rop: DWORD, + ) -> BOOL --- + + SetPixelFormat :: proc(hdc: HDC, format: c_int, ppfd: ^PIXELFORMATDESCRIPTOR) -> BOOL --- + ChoosePixelFormat :: proc(hdc: HDC, ppfd: ^PIXELFORMATDESCRIPTOR) -> c_int --- + SwapBuffers :: proc(HDC) -> BOOL --- + + PatBlt :: proc(hdc: HDC, x, y, w, h: c_int, rop: DWORD) -> BOOL --- +} diff --git a/core/sys/windows/kernel32.odin b/core/sys/windows/kernel32.odin index 8c58fbd52..cb90f71da 100644 --- a/core/sys/windows/kernel32.odin +++ b/core/sys/windows/kernel32.odin @@ -62,6 +62,13 @@ foreign kernel32 { GetCurrentProcessId :: proc() -> DWORD --- GetCurrentThread :: proc() -> HANDLE --- GetCurrentThreadId :: proc() -> DWORD --- + GetProcessTimes :: proc( + hProcess: HANDLE, + lpCreationTime: LPFILETIME, + lpExitTime: LPFILETIME, + lpKernelTime: LPFILETIME, + lpUserTime: LPFILETIME, + ) -> BOOL --- GetStdHandle :: proc(which: DWORD) -> HANDLE --- ExitProcess :: proc(uExitCode: c_uint) -> ! --- DeviceIoControl :: proc( @@ -92,6 +99,20 @@ foreign kernel32 { CreateSemaphoreW :: proc(attributes: LPSECURITY_ATTRIBUTES, initial_count, maximum_count: LONG, name: LPCSTR) -> HANDLE --- ReleaseSemaphore :: proc(semaphore: HANDLE, release_count: LONG, previous_count: ^LONG) -> BOOL --- + CreateWaitableTimerW :: proc( + lpTimerAttributes: LPSECURITY_ATTRIBUTES, + bManualReset: BOOL, + lpTimerName: LPCWSTR, + ) -> HANDLE --- + SetWaitableTimerEx :: proc( + hTimer: HANDLE, + lpDueTime: ^LARGE_INTEGER, + lPeriod: LONG, + pfnCompletionRoutine: PTIMERAPCROUTINE, + lpArgToCompletionRoutine: LPVOID, + WakeContext: PREASON_CONTEXT, + TolerableDelay: ULONG, + ) -> BOOL --- WaitForSingleObject :: proc(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD --- Sleep :: proc(dwMilliseconds: DWORD) --- GetProcessId :: proc(handle: HANDLE) -> DWORD --- @@ -341,6 +362,7 @@ MEM_TOP_DOWN :: 0x100000 MEM_LARGE_PAGES :: 0x20000000 MEM_4MB_PAGES :: 0x80000000 +@(default_calling_convention="stdcall") foreign kernel32 { VirtualAlloc :: proc( lpAddress: LPVOID, @@ -483,6 +505,7 @@ LowMemoryResourceNotification :: MEMORY_RESOURCE_NOTIFICATION_TYPE.LowMemoryRes HighMemoryResourceNotification :: MEMORY_RESOURCE_NOTIFICATION_TYPE.HighMemoryResourceNotification +@(default_calling_convention="stdcall") foreign kernel32 { CreateMemoryResourceNotification :: proc( NotificationType: MEMORY_RESOURCE_NOTIFICATION_TYPE, @@ -498,6 +521,7 @@ FILE_CACHE_MAX_HARD_DISABLE :: DWORD(0x00000002) FILE_CACHE_MIN_HARD_ENABLE :: DWORD(0x00000004) FILE_CACHE_MIN_HARD_DISABLE :: DWORD(0x00000008) +@(default_calling_convention="stdcall") foreign kernel32 { GetSystemFileCacheSize :: proc( lpMinimumFileCacheSize: PSIZE_T, @@ -527,6 +551,7 @@ WIN32_MEMORY_RANGE_ENTRY :: struct { PWIN32_MEMORY_RANGE_ENTRY :: ^WIN32_MEMORY_RANGE_ENTRY +@(default_calling_convention="stdcall") foreign kernel32 { PrefetchVirtualMemory :: proc( hProcess: HANDLE, @@ -584,6 +609,7 @@ foreign kernel32 { MEHC_PATROL_SCRUBBER_PRESENT :: ULONG(0x1) +@(default_calling_convention="stdcall") foreign kernel32 { GetMemoryErrorHandlingCapabilities :: proc( Capabilities: PULONG, @@ -592,6 +618,7 @@ foreign kernel32 { PBAD_MEMORY_CALLBACK_ROUTINE :: #type proc "stdcall" () +@(default_calling_convention="stdcall") foreign kernel32 { RegisterBadMemoryNotification :: proc( Callback: PBAD_MEMORY_CALLBACK_ROUTINE, @@ -612,6 +639,7 @@ VmOfferPriorityLow :: OFFER_PRIORITY.VmOfferPriorityLow VmOfferPriorityBelowNormal :: OFFER_PRIORITY.VmOfferPriorityBelowNormal VmOfferPriorityNormal :: OFFER_PRIORITY.VmOfferPriorityNormal +@(default_calling_convention="stdcall") foreign kernel32 { OfferVirtualMemory :: proc( VirtualAddress: PVOID, @@ -676,6 +704,7 @@ WIN32_MEMORY_REGION_INFORMATION_u_s_Bitfield :: distinct ULONG Reserved : 32-6, }*/ +@(default_calling_convention="stdcall") foreign kernel32 { QueryVirtualMemoryInformation :: proc( Process: HANDLE, @@ -700,7 +729,7 @@ foreign kernel32 { NUMA_NO_PREFERRED_NODE :: 0xffffffff -MapViewOfFile2 :: #force_inline proc( +MapViewOfFile2 :: #force_inline proc "stdcall" ( FileMappingHandle: HANDLE, ProcessHandle: HANDLE, Offset: ULONG64, @@ -721,6 +750,7 @@ MapViewOfFile2 :: #force_inline proc( ) } +@(default_calling_convention="stdcall") foreign kernel32 { UnmapViewOfFile2 :: proc( ProcessHandle: HANDLE, diff --git a/core/sys/windows/key_codes.odin b/core/sys/windows/key_codes.odin new file mode 100644 index 000000000..2f6e01116 --- /dev/null +++ b/core/sys/windows/key_codes.odin @@ -0,0 +1,252 @@ +// +build windows +package sys_windows + +// https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes +// Virtual Keys, Standard Set +VK_LBUTTON :: 0x01 +VK_RBUTTON :: 0x02 +VK_CANCEL :: 0x03 +VK_MBUTTON :: 0x04 // NOT contiguous with L & RBUTTON +VK_XBUTTON1 :: 0x05 // NOT contiguous with L & RBUTTON +VK_XBUTTON2 :: 0x06 // NOT contiguous with L & RBUTTON + +// 0x07 : reserved + +VK_BACK :: 0x08 +VK_TAB :: 0x09 + +// 0x0A - 0x0B : reserved + +VK_CLEAR :: 0x0C +VK_RETURN :: 0x0D + +// 0x0E - 0x0F : unassigned + +VK_SHIFT :: 0x10 +VK_CONTROL :: 0x11 +VK_MENU :: 0x12 +VK_PAUSE :: 0x13 +VK_CAPITAL :: 0x14 +VK_KANA :: 0x15 +VK_HANGEUL :: 0x15 // old name - should be here for compatibility +VK_HANGUL :: 0x15 +VK_IME_ON :: 0x16 +VK_JUNJA :: 0x17 +VK_FINAL :: 0x18 +VK_HANJA :: 0x19 +VK_KANJI :: 0x19 +VK_IME_OFF :: 0x1A +VK_ESCAPE :: 0x1B +VK_CONVERT :: 0x1C +VK_NONCONVERT :: 0x1D +VK_ACCEPT :: 0x1E +VK_MODECHANGE :: 0x1F +VK_SPACE :: 0x20 +VK_PRIOR :: 0x21 +VK_NEXT :: 0x22 +VK_END :: 0x23 +VK_HOME :: 0x24 +VK_LEFT :: 0x25 +VK_UP :: 0x26 +VK_RIGHT :: 0x27 +VK_DOWN :: 0x28 +VK_SELECT :: 0x29 +VK_PRINT :: 0x2A +VK_EXECUTE :: 0x2B +VK_SNAPSHOT :: 0x2C +VK_INSERT :: 0x2D +VK_DELETE :: 0x2E +VK_HELP :: 0x2F + +VK_0 :: '0' +VK_1 :: '1' +VK_2 :: '2' +VK_3 :: '3' +VK_4 :: '4' +VK_5 :: '5' +VK_6 :: '6' +VK_7 :: '7' +VK_8 :: '8' +VK_9 :: '9' + +// 0x3A - 0x40 : unassigned + +VK_A :: 'A' +VK_B :: 'B' +VK_C :: 'C' +VK_D :: 'D' +VK_E :: 'E' +VK_F :: 'F' +VK_G :: 'G' +VK_H :: 'H' +VK_I :: 'I' +VK_J :: 'J' +VK_K :: 'K' +VK_L :: 'L' +VK_M :: 'M' +VK_N :: 'N' +VK_O :: 'O' +VK_P :: 'P' +VK_Q :: 'Q' +VK_R :: 'R' +VK_S :: 'S' +VK_T :: 'T' +VK_U :: 'U' +VK_V :: 'V' +VK_W :: 'W' +VK_X :: 'X' +VK_Y :: 'Y' +VK_Z :: 'Z' + +VK_LWIN :: 0x5B +VK_RWIN :: 0x5C +VK_APPS :: 0x5D + +// 0x5E : reserved + +VK_SLEEP :: 0x5F +VK_NUMPAD0 :: 0x60 +VK_NUMPAD1 :: 0x61 +VK_NUMPAD2 :: 0x62 +VK_NUMPAD3 :: 0x63 +VK_NUMPAD4 :: 0x64 +VK_NUMPAD5 :: 0x65 +VK_NUMPAD6 :: 0x66 +VK_NUMPAD7 :: 0x67 +VK_NUMPAD8 :: 0x68 +VK_NUMPAD9 :: 0x69 +VK_MULTIPLY :: 0x6A +VK_ADD :: 0x6B +VK_SEPARATOR :: 0x6C +VK_SUBTRACT :: 0x6D +VK_DECIMAL :: 0x6E +VK_DIVIDE :: 0x6F +VK_F1 :: 0x70 +VK_F2 :: 0x71 +VK_F3 :: 0x72 +VK_F4 :: 0x73 +VK_F5 :: 0x74 +VK_F6 :: 0x75 +VK_F7 :: 0x76 +VK_F8 :: 0x77 +VK_F9 :: 0x78 +VK_F10 :: 0x79 +VK_F11 :: 0x7A +VK_F12 :: 0x7B +VK_F13 :: 0x7C +VK_F14 :: 0x7D +VK_F15 :: 0x7E +VK_F16 :: 0x7F +VK_F17 :: 0x80 +VK_F18 :: 0x81 +VK_F19 :: 0x82 +VK_F20 :: 0x83 +VK_F21 :: 0x84 +VK_F22 :: 0x85 +VK_F23 :: 0x86 +VK_F24 :: 0x87 + +// 0x88 - 0x8F : reserved + +VK_NUMLOCK :: 0x90 +VK_SCROLL :: 0x91 + +// NEC PC-9800 kbd definitions +VK_OEM_NEC_EQUAL :: 0x92 // '=' key on numpad + +// Fujitsu/OASYS kbd definitions +VK_OEM_FJ_JISHO :: 0x92 // 'Dictionary' key +VK_OEM_FJ_MASSHOU :: 0x93 // 'Unregister word' key +VK_OEM_FJ_TOUROKU :: 0x94 // 'Register word' key +VK_OEM_FJ_LOYA :: 0x95 // 'Left OYAYUBI' key +VK_OEM_FJ_ROYA :: 0x96 // 'Right OYAYUBI' key + +// 0x97 - 0x9F : unassigned + +// VK_L* & VK_R* - left and right Alt, Ctrl and Shift virtual keys. +// Used only as parameters to GetAsyncKeyState() and GetKeyState(). +// No other API or message will distinguish left and right keys in this way. +VK_LSHIFT :: 0xA0 +VK_RSHIFT :: 0xA1 +VK_LCONTROL :: 0xA2 +VK_RCONTROL :: 0xA3 +VK_LMENU :: 0xA4 +VK_RMENU :: 0xA5 + +VK_BROWSER_BACK :: 0xA6 +VK_BROWSER_FORWARD :: 0xA7 +VK_BROWSER_REFRESH :: 0xA8 +VK_BROWSER_STOP :: 0xA9 +VK_BROWSER_SEARCH :: 0xAA +VK_BROWSER_FAVORITES :: 0xAB +VK_BROWSER_HOME :: 0xAC +VK_VOLUME_MUTE :: 0xAD +VK_VOLUME_DOWN :: 0xAE +VK_VOLUME_UP :: 0xAF +VK_MEDIA_NEXT_TRACK :: 0xB0 +VK_MEDIA_PREV_TRACK :: 0xB1 +VK_MEDIA_STOP :: 0xB2 +VK_MEDIA_PLAY_PAUSE :: 0xB3 +VK_LAUNCH_MAIL :: 0xB4 +VK_LAUNCH_MEDIA_SELECT :: 0xB5 +VK_LAUNCH_APP1 :: 0xB6 +VK_LAUNCH_APP2 :: 0xB7 + +// 0xB8 - 0xB9 : reserved + +VK_OEM_1 :: 0xBA // ';:' for US +VK_OEM_PLUS :: 0xBB // '+' any country +VK_OEM_COMMA :: 0xBC // ',' any country +VK_OEM_MINUS :: 0xBD // '-' any country +VK_OEM_PERIOD :: 0xBE // '.' any country +VK_OEM_2 :: 0xBF // '/?' for US +VK_OEM_3 :: 0xC0 // '`~' for US + +// 0xC1 - 0xDA : reserved + +VK_OEM_4 :: 0xDB // '[{' for US +VK_OEM_5 :: 0xDC // '\|' for US +VK_OEM_6 :: 0xDD // ']}' for US +VK_OEM_7 :: 0xDE // ''"' for US +VK_OEM_8 :: 0xDF + +// 0xE0 : reserved + +// Various extended or enhanced keyboards +VK_OEM_AX :: 0xE1 // 'AX' key on Japanese AX kbd +VK_OEM_102 :: 0xE2 // "<>" or "\|" on RT 102-key kbd. +VK_ICO_HELP :: 0xE3 // Help key on ICO +VK_ICO_00 :: 0xE4 // 00 key on ICO + +VK_PROCESSKEY :: 0xE5 +VK_ICO_CLEAR :: 0xE6 +VK_PACKET :: 0xE7 + +// 0xE8 : unassigned + +// Nokia/Ericsson definitions +VK_OEM_RESET :: 0xE9 +VK_OEM_JUMP :: 0xEA +VK_OEM_PA1 :: 0xEB +VK_OEM_PA2 :: 0xEC +VK_OEM_PA3 :: 0xED +VK_OEM_WSCTRL :: 0xEE +VK_OEM_CUSEL :: 0xEF +VK_OEM_ATTN :: 0xF0 +VK_OEM_FINISH :: 0xF1 +VK_OEM_COPY :: 0xF2 +VK_OEM_AUTO :: 0xF3 +VK_OEM_ENLW :: 0xF4 +VK_OEM_BACKTAB :: 0xF5 + +VK_ATTN :: 0xF6 +VK_CRSEL :: 0xF7 +VK_EXSEL :: 0xF8 +VK_EREOF :: 0xF9 +VK_PLAY :: 0xFA +VK_ZOOM :: 0xFB +VK_NONAME :: 0xFC +VK_PA1 :: 0xFD +VK_OEM_CLEAR :: 0xFE + +// 0xFF : reserved diff --git a/core/sys/windows/types.odin b/core/sys/windows/types.odin index 3e25a4c18..6bded29e1 100644 --- a/core/sys/windows/types.odin +++ b/core/sys/windows/types.odin @@ -21,7 +21,16 @@ HINSTANCE :: HANDLE HMODULE :: distinct HINSTANCE HRESULT :: distinct LONG HWND :: distinct HANDLE +HDC :: distinct HANDLE HMONITOR :: distinct HANDLE +HICON :: distinct HANDLE +HCURSOR :: distinct HANDLE +HMENU :: distinct HANDLE +HBRUSH :: distinct HANDLE +HGDIOBJ :: distinct HANDLE +HBITMAP :: distinct HANDLE +HGLOBAL :: distinct HANDLE +HHOOK :: distinct HANDLE BOOL :: distinct b32 BYTE :: distinct u8 BOOLEAN :: distinct b8 @@ -42,9 +51,15 @@ PULONG_PTR :: ^ULONG_PTR LPULONG_PTR :: ^ULONG_PTR DWORD_PTR :: ULONG_PTR LONG_PTR :: int +UINT_PTR :: uintptr ULONG :: c_ulong UCHAR :: BYTE NTSTATUS :: c.long +LPARAM :: LONG_PTR +WPARAM :: UINT_PTR +LRESULT :: LONG_PTR +LPRECT :: ^RECT +LPPOINT :: ^POINT UINT8 :: u8 UINT16 :: u16 @@ -71,6 +86,7 @@ PBOOL :: ^BOOL LPBOOL :: ^BOOL LPCSTR :: cstring LPCWSTR :: wstring +LPCTSTR :: wstring LPDWORD :: ^DWORD PCSTR :: cstring PCWSTR :: wstring @@ -81,7 +97,9 @@ LPPROCESS_INFORMATION :: ^PROCESS_INFORMATION PSECURITY_ATTRIBUTES :: ^SECURITY_ATTRIBUTES LPSECURITY_ATTRIBUTES :: ^SECURITY_ATTRIBUTES LPSTARTUPINFO :: ^STARTUPINFO -PVOID :: rawptr +LPTRACKMOUSEEVENT :: ^TRACKMOUSEEVENT +VOID :: rawptr +PVOID :: rawptr LPVOID :: rawptr PINT :: ^INT LPINT :: ^INT @@ -105,6 +123,8 @@ PCONDITION_VARIABLE :: ^CONDITION_VARIABLE PLARGE_INTEGER :: ^LARGE_INTEGER PSRWLOCK :: ^SRWLOCK +MMRESULT :: UINT + SOCKET :: distinct uintptr // TODO socklen_t :: c_int ADDRESS_FAMILY :: USHORT @@ -177,6 +197,159 @@ GET_FILEEX_INFO_LEVELS :: distinct i32 GetFileExInfoStandard: GET_FILEEX_INFO_LEVELS : 0 GetFileExMaxInfoLevel: GET_FILEEX_INFO_LEVELS : 1 +// String resource number bases (internal use) + +MMSYSERR_BASE :: 0 +WAVERR_BASE :: 32 +MIDIERR_BASE :: 64 +TIMERR_BASE :: 96 +JOYERR_BASE :: 160 +MCIERR_BASE :: 256 +MIXERR_BASE :: 1024 + +MCI_STRING_OFFSET :: 512 +MCI_VD_OFFSET :: 1024 +MCI_CD_OFFSET :: 1088 +MCI_WAVE_OFFSET :: 1152 +MCI_SEQ_OFFSET :: 1216 + +// timer error return values +TIMERR_NOERROR :: 0 // no error +TIMERR_NOCANDO :: TIMERR_BASE + 1 // request not completed +TIMERR_STRUCT :: TIMERR_BASE + 33 // time struct size + +DIAGNOSTIC_REASON_VERSION :: 0 + +DIAGNOSTIC_REASON_SIMPLE_STRING :: 0x00000001 +DIAGNOSTIC_REASON_DETAILED_STRING :: 0x00000002 +DIAGNOSTIC_REASON_NOT_SPECIFIED :: 0x80000000 + +// Defines for power request APIs + +POWER_REQUEST_CONTEXT_VERSION :: DIAGNOSTIC_REASON_VERSION + +POWER_REQUEST_CONTEXT_SIMPLE_STRING :: DIAGNOSTIC_REASON_SIMPLE_STRING +POWER_REQUEST_CONTEXT_DETAILED_STRING :: DIAGNOSTIC_REASON_DETAILED_STRING + +REASON_CONTEXT :: struct { + Version: ULONG, + Flags: DWORD, + Reason: struct #raw_union { + Detailed: struct { + LocalizedReasonModule: HMODULE, + LocalizedReasonId: ULONG, + ReasonStringCount: ULONG, + ReasonStrings: ^LPWSTR, + }, + SimpleReasonString: LPWSTR, + }, +} +PREASON_CONTEXT :: ^REASON_CONTEXT + +PTIMERAPCROUTINE :: #type proc "stdcall" (lpArgToCompletionRoutine: LPVOID, dwTimerLowValue, dwTimerHighValue: DWORD) + +TIMERPROC :: #type proc "stdcall" (HWND, UINT, UINT_PTR, DWORD) + +WNDPROC :: #type proc "stdcall" (HWND, UINT, WPARAM, LPARAM) -> LRESULT + +HOOKPROC :: #type proc "stdcall" (code: c_int, wParam: WPARAM, lParam: LPARAM) -> LRESULT + +CWPRETSTRUCT :: struct { + lResult: LRESULT, + lParam: LPARAM, + wParam: WPARAM, + message: UINT, + hwnd: HWND, +} + +KBDLLHOOKSTRUCT :: struct { + vkCode: DWORD, + scanCode: DWORD, + flags: DWORD, + time: DWORD, + dwExtraInfo: ULONG_PTR, +} + +WNDCLASSA :: struct { + style: UINT, + lpfnWndProc: WNDPROC, + cbClsExtra: c_int, + cbWndExtra: c_int, + hInstance: HINSTANCE, + hIcon: HICON, + hCursor: HCURSOR, + hbrBackground: HBRUSH, + lpszMenuName: LPCSTR, + lpszClassName: LPCSTR, +} + +WNDCLASSW :: struct { + style: UINT, + lpfnWndProc: WNDPROC, + cbClsExtra: c_int, + cbWndExtra: c_int, + hInstance: HINSTANCE, + hIcon: HICON, + hCursor: HCURSOR, + hbrBackground: HBRUSH, + lpszMenuName: LPCWSTR, + lpszClassName: LPCWSTR, +} + +WNDCLASSEXA :: struct { + cbSize: UINT, + style: UINT, + lpfnWndProc: WNDPROC, + cbClsExtra: c_int, + cbWndExtra: c_int, + hInstance: HINSTANCE, + hIcon: HICON, + hCursor: HCURSOR, + hbrBackground: HBRUSH, + lpszMenuName: LPCSTR, + lpszClassName: LPCSTR, + hIconSm: HICON, +} + +WNDCLASSEXW :: struct { + cbSize: UINT, + style: UINT, + lpfnWndProc: WNDPROC, + cbClsExtra: c_int, + cbWndExtra: c_int, + hInstance: HINSTANCE, + hIcon: HICON, + hCursor: HCURSOR, + hbrBackground: HBRUSH, + lpszMenuName: LPCWSTR, + lpszClassName: LPCWSTR, + hIconSm: HICON, +} + +MSG :: struct { + hwnd: HWND, + message: UINT, + wParam: WPARAM, + lParam: LPARAM, + time: DWORD, + pt: POINT, +} + +PAINTSTRUCT :: struct { + hdc: HDC, + fErase: BOOL, + rcPaint: RECT, + fRestore: BOOL, + fIncUpdate: BOOL, + rgbReserved: [32]BYTE, +} + +TRACKMOUSEEVENT :: struct { + cbSize: DWORD, + dwFlags: DWORD, + hwndTrack: HWND, + dwHoverTime: DWORD, +} WIN32_FIND_DATAW :: struct { dwFileAttributes: DWORD, @@ -191,6 +364,709 @@ WIN32_FIND_DATAW :: struct { cAlternateFileName: [14]wchar_t, } +CREATESTRUCTA :: struct { + lpCreateParams: LPVOID, + hInstance: HINSTANCE, + hMenu: HMENU, + hwndParent: HWND, + cy: c_int, + cx: c_int, + y: c_int, + x: c_int, + style: LONG, + lpszName: LPCSTR, + lpszClass: LPCSTR, + dwExStyle: DWORD, +} + +CREATESTRUCTW:: struct { + lpCreateParams: LPVOID, + hInstance: HINSTANCE, + hMenu: HMENU, + hwndParent: HWND, + cy: c_int, + cx: c_int, + y: c_int, + x: c_int, + style: LONG, + lpszName: LPCWSTR, + lpszClass: LPCWSTR, + dwExStyle: DWORD, +} + +// MessageBox() Flags +MB_OK :: 0x00000000 +MB_OKCANCEL :: 0x00000001 +MB_ABORTRETRYIGNORE :: 0x00000002 +MB_YESNOCANCEL :: 0x00000003 +MB_YESNO :: 0x00000004 +MB_RETRYCANCEL :: 0x00000005 +MB_CANCELTRYCONTINUE :: 0x00000006 + +MB_ICONHAND :: 0x00000010 +MB_ICONQUESTION :: 0x00000020 +MB_ICONEXCLAMATION :: 0x00000030 +MB_ICONASTERISK :: 0x00000040 +MB_USERICON :: 0x00000080 +MB_ICONWARNING :: MB_ICONEXCLAMATION +MB_ICONERROR :: MB_ICONHAND +MB_ICONINFORMATION :: MB_ICONASTERISK +MB_ICONSTOP :: MB_ICONHAND + +MB_DEFBUTTON1 :: 0x00000000 +MB_DEFBUTTON2 :: 0x00000100 +MB_DEFBUTTON3 :: 0x00000200 +MB_DEFBUTTON4 :: 0x00000300 + +MB_APPLMODAL :: 0x00000000 +MB_SYSTEMMODAL :: 0x00001000 +MB_TASKMODAL :: 0x00002000 +MB_HELP :: 0x00004000 // Help Button + +MB_NOFOCUS :: 0x00008000 +MB_SETFOREGROUND :: 0x00010000 +MB_DEFAULT_DESKTOP_ONLY :: 0x00020000 +MB_TOPMOST :: 0x00040000 +MB_RIGHT :: 0x00080000 +MB_RTLREADING :: 0x00100000 + +MB_SERVICE_NOTIFICATION :: 0x00200000 +MB_SERVICE_NOTIFICATION_NT3X :: 0x00040000 + +MB_TYPEMASK :: 0x0000000F +MB_ICONMASK :: 0x000000F0 +MB_DEFMASK :: 0x00000F00 +MB_MODEMASK :: 0x00003000 +MB_MISCMASK :: 0x0000C000 + +// Dialog Box Command IDs +IDOK :: 1 +IDCANCEL :: 2 +IDABORT :: 3 +IDRETRY :: 4 +IDIGNORE :: 5 +IDYES :: 6 +IDNO :: 7 +IDCLOSE :: 8 +IDHELP :: 9 +IDTRYAGAIN :: 10 +IDCONTINUE :: 11 +IDTIMEOUT :: 32000 + +CS_VREDRAW : UINT : 0x0001 +CS_HREDRAW : UINT : 0x0002 +CS_DBLCLKS : UINT : 0x0008 +CS_OWNDC : UINT : 0x0020 +CS_CLASSDC : UINT : 0x0040 +CS_PARENTDC : UINT : 0x0080 +CS_NOCLOSE : UINT : 0x0200 +CS_SAVEBITS : UINT : 0x0800 +CS_BYTEALIGNCLIENT : UINT : 0x1000 +CS_BYTEALIGNWINDOW : UINT : 0x2000 +CS_GLOBALCLASS : UINT : 0x4000 +CS_DROPSHADOW : UINT : 0x0002_0000 + +WS_BORDER : UINT : 0x0080_0000 +WS_CAPTION : UINT : 0x00C0_0000 +WS_CHILD : UINT : 0x4000_0000 +WS_CHILDWINDOW : UINT : WS_CHILD +WS_CLIPCHILDREN : UINT : 0x0200_0000 +WS_CLIPSIBLINGS : UINT : 0x0400_0000 +WS_DISABLED : UINT : 0x0800_0000 +WS_DLGFRAME : UINT : 0x0040_0000 +WS_GROUP : UINT : 0x0002_0000 +WS_HSCROLL : UINT : 0x0010_0000 +WS_ICONIC : UINT : 0x2000_0000 +WS_MAXIMIZE : UINT : 0x0100_0000 +WS_MAXIMIZEBOX : UINT : 0x0001_0000 +WS_MINIMIZE : UINT : 0x2000_0000 +WS_MINIMIZEBOX : UINT : 0x0002_0000 +WS_OVERLAPPED : UINT : 0x0000_0000 +WS_OVERLAPPEDWINDOW : UINT : WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX +WS_POPUP : UINT : 0x8000_0000 +WS_POPUPWINDOW : UINT : WS_POPUP | WS_BORDER | WS_SYSMENU +WS_SIZEBOX : UINT : 0x0004_0000 +WS_SYSMENU : UINT : 0x0008_0000 +WS_TABSTOP : UINT : 0x0001_0000 +WS_THICKFRAME : UINT : 0x0004_0000 +WS_TILED : UINT : 0x0000_0000 +WS_TILEDWINDOW : UINT : WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE +WS_VISIBLE : UINT : 0x1000_0000 +WS_VSCROLL : UINT : 0x0020_0000 + +QS_ALLEVENTS : UINT : QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY +QS_ALLINPUT : UINT : QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY | QS_SENDMESSAGE +QS_ALLPOSTMESSAGE : UINT : 0x0100 +QS_HOTKEY : UINT : 0x0080 +QS_INPUT : UINT : QS_MOUSE | QS_KEY | QS_RAWINPUT +QS_KEY : UINT : 0x0001 +QS_MOUSE : UINT : QS_MOUSEMOVE | QS_MOUSEBUTTON +QS_MOUSEBUTTON : UINT : 0x0004 +QS_MOUSEMOVE : UINT : 0x0002 +QS_PAINT : UINT : 0x0020 +QS_POSTMESSAGE : UINT : 0x0008 +QS_RAWINPUT : UINT : 0x0400 +QS_SENDMESSAGE : UINT : 0x0040 +QS_TIMER : UINT : 0x0010 + +PM_NOREMOVE : UINT : 0x0000 +PM_REMOVE : UINT : 0x0001 +PM_NOYIELD : UINT : 0x0002 + +PM_QS_INPUT : UINT : QS_INPUT << 16 +PM_QS_PAINT : UINT : QS_PAINT << 16 +PM_QS_POSTMESSAGE : UINT : (QS_POSTMESSAGE | QS_HOTKEY | QS_TIMER) << 16 +PM_QS_SENDMESSAGE : UINT : QS_SENDMESSAGE << 16 + +SW_HIDE : c_int : 0 +SW_SHOWNORMAL : c_int : SW_NORMAL +SW_NORMAL : c_int : 1 +SW_SHOWMINIMIZED : c_int : 2 +SW_SHOWMAXIMIZED : c_int : SW_MAXIMIZE +SW_MAXIMIZE : c_int : 3 +SW_SHOWNOACTIVATE : c_int : 4 +SW_SHOW : c_int : 5 +SW_MINIMIZE : c_int : 6 +SW_SHOWMINNOACTIVE : c_int : 7 +SW_SHOWNA : c_int : 8 +SW_RESTORE : c_int : 9 +SW_SHOWDEFAULT : c_int : 10 +SW_FORCEMINIMIZE : c_int : 11 + +// SetWindowPos Flags +SWP_NOSIZE :: 0x0001 +SWP_NOMOVE :: 0x0002 +SWP_NOZORDER :: 0x0004 +SWP_NOREDRAW :: 0x0008 +SWP_NOACTIVATE :: 0x0010 +SWP_FRAMECHANGED :: 0x0020 // The frame changed: send WM_NCCALCSIZE +SWP_SHOWWINDOW :: 0x0040 +SWP_HIDEWINDOW :: 0x0080 +SWP_NOCOPYBITS :: 0x0100 +SWP_NOOWNERZORDER :: 0x0200 // Don't do owner Z ordering +SWP_NOSENDCHANGING :: 0x0400 // Don't send WM_WINDOWPOSCHANGING + +SWP_DRAWFRAME :: SWP_FRAMECHANGED +SWP_NOREPOSITION :: SWP_NOOWNERZORDER + +SWP_DEFERERASE :: 0x2000 // same as SWP_DEFERDRAWING +SWP_ASYNCWINDOWPOS :: 0x4000 // same as SWP_CREATESPB + +HWND_TOP :: HWND( uintptr(0)) // 0 +HWND_BOTTOM :: HWND( uintptr(1)) // 1 +HWND_TOPMOST :: HWND(~uintptr(0)) // -1 +HWND_NOTOPMOST :: HWND(~uintptr(0) - 1) // -2 + +// Window field offsets for GetWindowLong() +GWL_STYLE :: -16 +GWL_EXSTYLE :: -20 +GWL_ID :: -12 + +when ODIN_ARCH == .i386 { + GWL_WNDPROC :: -4 + GWL_HINSTANCE :: -6 + GWL_HWNDPARENT :: -8 + GWL_USERDATA :: -21 +} + +GWLP_WNDPROC :: -4 +GWLP_HINSTANCE :: -6 +GWLP_HWNDPARENT :: -8 +GWLP_USERDATA :: -21 +GWLP_ID :: -12 + +// Class field offsets for GetClassLong() +GCL_CBWNDEXTRA :: -18 +GCL_CBCLSEXTRA :: -20 +GCL_STYLE :: -26 +GCW_ATOM :: -32 + +when ODIN_ARCH == .i386 { + GCL_MENUNAME :: -8 + GCL_HBRBACKGROUND :: -10 + GCL_HCURSOR :: -12 + GCL_HICON :: -14 + GCL_HMODULE :: -16 + GCL_WNDPROC :: -24 + GCL_HICONSM :: -34 +} + +GCLP_MENUNAME :: -8 +GCLP_HBRBACKGROUND :: -10 +GCLP_HCURSOR :: -12 +GCLP_HICON :: -14 +GCLP_HMODULE :: -16 +GCLP_WNDPROC :: -24 +GCLP_HICONSM :: -34 + +// GetSystemMetrics() codes +SM_CXSCREEN :: 0 +SM_CYSCREEN :: 1 +SM_CXVSCROLL :: 2 +SM_CYHSCROLL :: 3 +SM_CYCAPTION :: 4 +SM_CXBORDER :: 5 +SM_CYBORDER :: 6 +SM_CXDLGFRAME :: 7 +SM_CYDLGFRAME :: 8 +SM_CYVTHUMB :: 9 +SM_CXHTHUMB :: 10 +SM_CXICON :: 11 +SM_CYICON :: 12 +SM_CXCURSOR :: 13 +SM_CYCURSOR :: 14 +SM_CYMENU :: 15 +SM_CXFULLSCREEN :: 16 +SM_CYFULLSCREEN :: 17 +SM_CYKANJIWINDOW :: 18 +SM_MOUSEPRESENT :: 19 +SM_CYVSCROLL :: 20 +SM_CXHSCROLL :: 21 +SM_DEBUG :: 22 +SM_SWAPBUTTON :: 23 +SM_RESERVED1 :: 24 +SM_RESERVED2 :: 25 +SM_RESERVED3 :: 26 +SM_RESERVED4 :: 27 +SM_CXMIN :: 28 +SM_CYMIN :: 29 +SM_CXSIZE :: 30 +SM_CYSIZE :: 31 +SM_CXFRAME :: 32 +SM_CYFRAME :: 33 +SM_CXMINTRACK :: 34 +SM_CYMINTRACK :: 35 +SM_CXDOUBLECLK :: 36 +SM_CYDOUBLECLK :: 37 +SM_CXICONSPACING :: 38 +SM_CYICONSPACING :: 39 +SM_MENUDROPALIGNMENT :: 40 +SM_PENWINDOWS :: 41 +SM_DBCSENABLED :: 42 +SM_CMOUSEBUTTONS :: 43 + +SM_CXFIXEDFRAME :: SM_CXDLGFRAME // ;win40 name change +SM_CYFIXEDFRAME :: SM_CYDLGFRAME // ;win40 name change +SM_CXSIZEFRAME :: SM_CXFRAME // ;win40 name change +SM_CYSIZEFRAME :: SM_CYFRAME // ;win40 name change + +SM_SECURE :: 44 +SM_CXEDGE :: 45 +SM_CYEDGE :: 46 +SM_CXMINSPACING :: 47 +SM_CYMINSPACING :: 48 +SM_CXSMICON :: 49 +SM_CYSMICON :: 50 +SM_CYSMCAPTION :: 51 +SM_CXSMSIZE :: 52 +SM_CYSMSIZE :: 53 +SM_CXMENUSIZE :: 54 +SM_CYMENUSIZE :: 55 +SM_ARRANGE :: 56 +SM_CXMINIMIZED :: 57 +SM_CYMINIMIZED :: 58 +SM_CXMAXTRACK :: 59 +SM_CYMAXTRACK :: 60 +SM_CXMAXIMIZED :: 61 +SM_CYMAXIMIZED :: 62 +SM_NETWORK :: 63 +SM_CLEANBOOT :: 67 +SM_CXDRAG :: 68 +SM_CYDRAG :: 69 + +SM_SHOWSOUNDS :: 70 +SM_CXMENUCHECK :: 71 // Use instead of GetMenuCheckMarkDimensions()! +SM_CYMENUCHECK :: 72 +SM_SLOWMACHINE :: 73 +SM_MIDEASTENABLED :: 74 +SM_MOUSEWHEELPRESENT :: 75 +SM_XVIRTUALSCREEN :: 76 +SM_YVIRTUALSCREEN :: 77 +SM_CXVIRTUALSCREEN :: 78 +SM_CYVIRTUALSCREEN :: 79 +SM_CMONITORS :: 80 +SM_SAMEDISPLAYFORMAT :: 81 +SM_IMMENABLED :: 82 +SM_CXFOCUSBORDER :: 83 +SM_CYFOCUSBORDER :: 84 +SM_TABLETPC :: 86 +SM_MEDIACENTER :: 87 +SM_STARTER :: 88 +SM_SERVERR2 :: 89 + +SM_MOUSEHORIZONTALWHEELPRESENT :: 91 + +SM_CXPADDEDBORDER :: 92 +SM_DIGITIZER :: 94 +SM_MAXIMUMTOUCHES :: 95 +SM_CMETRICS :: 97 + +SM_REMOTESESSION :: 0x1000 +SM_SHUTTINGDOWN :: 0x2000 +SM_REMOTECONTROL :: 0x2001 +SM_CARETBLINKINGENABLED :: 0x2002 +SM_CONVERTIBLESLATEMODE :: 0x2003 +SM_SYSTEMDOCKED :: 0x2004 + +// System Menu Command Values +SC_SIZE :: 0xF000 +SC_MOVE :: 0xF010 +SC_MINIMIZE :: 0xF020 +SC_MAXIMIZE :: 0xF030 +SC_NEXTWINDOW :: 0xF040 +SC_PREVWINDOW :: 0xF050 +SC_CLOSE :: 0xF060 +SC_VSCROLL :: 0xF070 +SC_HSCROLL :: 0xF080 +SC_MOUSEMENU :: 0xF090 +SC_KEYMENU :: 0xF100 +SC_ARRANGE :: 0xF110 +SC_RESTORE :: 0xF120 +SC_TASKLIST :: 0xF130 +SC_SCREENSAVE :: 0xF140 +SC_HOTKEY :: 0xF150 +SC_DEFAULT :: 0xF160 +SC_MONITORPOWER :: 0xF170 +SC_CONTEXTHELP :: 0xF180 +SC_SEPARATOR :: 0xF00F +SCF_ISSECURE :: 0x00000001 +SC_ICON :: SC_MINIMIZE +SC_ZOOM :: SC_MAXIMIZE + +CW_USEDEFAULT : c_int : -2147483648 + +SIZE_RESTORED :: 0 +SIZE_MINIMIZED :: 1 +SIZE_MAXIMIZED :: 2 +SIZE_MAXSHOW :: 3 +SIZE_MAXHIDE :: 4 + +WMSZ_LEFT :: 1 +WMSZ_RIGHT :: 2 +WMSZ_TOP :: 3 +WMSZ_TOPLEFT :: 4 +WMSZ_TOPRIGHT :: 5 +WMSZ_BOTTOM :: 6 +WMSZ_BOTTOMLEFT :: 7 +WMSZ_BOTTOMRIGHT :: 8 + +// Key State Masks for Mouse Messages +MK_LBUTTON :: 0x0001 +MK_RBUTTON :: 0x0002 +MK_SHIFT :: 0x0004 +MK_CONTROL :: 0x0008 +MK_MBUTTON :: 0x0010 +MK_XBUTTON1 :: 0x0020 +MK_XBUTTON2 :: 0x0040 + +// Value for rolling one detent +WHEEL_DELTA :: 120 + +// Setting to scroll one page for SPI_GET/SETWHEELSCROLLLINES +WHEEL_PAGESCROLL :: max(UINT) + +// XButton values are WORD flags +XBUTTON1 :: 0x0001 +XBUTTON2 :: 0x0002 +// Were there to be an XBUTTON3, its value would be 0x0004 + +MAPVK_VK_TO_VSC :: 0 +MAPVK_VSC_TO_VK :: 1 +MAPVK_VK_TO_CHAR :: 2 +MAPVK_VSC_TO_VK_EX :: 3 +MAPVK_VK_TO_VSC_EX :: 4 + +TME_HOVER :: 0x00000001 +TME_LEAVE :: 0x00000002 +TME_NONCLIENT :: 0x00000010 +TME_QUERY :: 0x40000000 +TME_CANCEL :: 0x80000000 +HOVER_DEFAULT :: 0xFFFFFFFF + +USER_TIMER_MAXIMUM :: 0x7FFFFFFF +USER_TIMER_MINIMUM :: 0x0000000A + +// WM_ACTIVATE state values +WA_INACTIVE :: 0 +WA_ACTIVE :: 1 +WA_CLICKACTIVE :: 2 + +// SetWindowsHook() codes +WH_MIN :: -1 +WH_MSGFILTER :: -1 +WH_JOURNALRECORD :: 0 +WH_JOURNALPLAYBACK :: 1 +WH_KEYBOARD :: 2 +WH_GETMESSAGE :: 3 +WH_CALLWNDPROC :: 4 +WH_CBT :: 5 +WH_SYSMSGFILTER :: 6 +WH_MOUSE :: 7 +WH_HARDWARE :: 8 +WH_DEBUG :: 9 +WH_SHELL :: 10 +WH_FOREGROUNDIDLE :: 11 +WH_CALLWNDPROCRET :: 12 +WH_KEYBOARD_LL :: 13 +WH_MOUSE_LL :: 14 +WH_MAX :: 14 +WH_MINHOOK :: WH_MIN +WH_MAXHOOK :: WH_MAX + +// Hook Codes +HC_ACTION :: 0 +HC_GETNEXT :: 1 +HC_SKIP :: 2 +HC_NOREMOVE :: 3 +HC_NOREM :: HC_NOREMOVE +HC_SYSMODALON :: 4 +HC_SYSMODALOFF :: 5 + +// CBT Hook Codes +HCBT_MOVESIZE :: 0 +HCBT_MINMAX :: 1 +HCBT_QS :: 2 +HCBT_CREATEWND :: 3 +HCBT_DESTROYWND :: 4 +HCBT_ACTIVATE :: 5 +HCBT_CLICKSKIPPED :: 6 +HCBT_KEYSKIPPED :: 7 +HCBT_SYSCOMMAND :: 8 +HCBT_SETFOCUS :: 9 + +_IDC_APPSTARTING := rawptr(uintptr(32650)) +_IDC_ARROW := rawptr(uintptr(32512)) +_IDC_CROSS := rawptr(uintptr(32515)) +_IDC_HAND := rawptr(uintptr(32649)) +_IDC_HELP := rawptr(uintptr(32651)) +_IDC_IBEAM := rawptr(uintptr(32513)) +_IDC_ICON := rawptr(uintptr(32641)) +_IDC_NO := rawptr(uintptr(32648)) +_IDC_SIZE := rawptr(uintptr(32640)) +_IDC_SIZEALL := rawptr(uintptr(32646)) +_IDC_SIZENESW := rawptr(uintptr(32643)) +_IDC_SIZENS := rawptr(uintptr(32645)) +_IDC_SIZENWSE := rawptr(uintptr(32642)) +_IDC_SIZEWE := rawptr(uintptr(32644)) +_IDC_UPARROW := rawptr(uintptr(32516)) +_IDC_WAIT := rawptr(uintptr(32514)) + +IDC_APPSTARTING := cstring(_IDC_APPSTARTING) +IDC_ARROW := cstring(_IDC_ARROW) +IDC_CROSS := cstring(_IDC_CROSS) +IDC_HAND := cstring(_IDC_HAND) +IDC_HELP := cstring(_IDC_HELP) +IDC_IBEAM := cstring(_IDC_IBEAM) +IDC_ICON := cstring(_IDC_ICON) +IDC_NO := cstring(_IDC_NO) +IDC_SIZE := cstring(_IDC_SIZE) +IDC_SIZEALL := cstring(_IDC_SIZEALL) +IDC_SIZENESW := cstring(_IDC_SIZENESW) +IDC_SIZENS := cstring(_IDC_SIZENS) +IDC_SIZENWSE := cstring(_IDC_SIZENWSE) +IDC_SIZEWE := cstring(_IDC_SIZEWE) +IDC_UPARROW := cstring(_IDC_UPARROW) +IDC_WAIT := cstring(_IDC_WAIT) + + +_IDI_APPLICATION := rawptr(uintptr(32512)) +_IDI_HAND := rawptr(uintptr(32513)) +_IDI_QUESTION := rawptr(uintptr(32514)) +_IDI_EXCLAMATION := rawptr(uintptr(32515)) +_IDI_ASTERISK := rawptr(uintptr(32516)) +_IDI_WINLOGO := rawptr(uintptr(32517)) +_IDI_SHIELD := rawptr(uintptr(32518)) +IDI_APPLICATION := cstring(_IDI_APPLICATION) +IDI_HAND := cstring(_IDI_HAND) +IDI_QUESTION := cstring(_IDI_QUESTION) +IDI_EXCLAMATION := cstring(_IDI_EXCLAMATION) +IDI_ASTERISK := cstring(_IDI_ASTERISK) +IDI_WINLOGO := cstring(_IDI_WINLOGO) +IDI_SHIELD := cstring(_IDI_SHIELD) +IDI_WARNING := IDI_EXCLAMATION +IDI_ERROR := IDI_HAND +IDI_INFORMATION := IDI_ASTERISK + + +// DIB color table identifiers +DIB_RGB_COLORS :: 0 +DIB_PAL_COLORS :: 1 + +// constants for CreateDIBitmap +CBM_INIT :: 0x04 // initialize bitmap + +// Region Flags +ERROR :: 0 +NULLREGION :: 1 +SIMPLEREGION :: 2 +COMPLEXREGION :: 3 +RGN_ERROR :: ERROR + +// StretchBlt() Modes +BLACKONWHITE :: 1 +WHITEONBLACK :: 2 +COLORONCOLOR :: 3 +HALFTONE :: 4 +MAXSTRETCHBLTMODE :: 4 + +// Binary raster ops +R2_BLACK :: 1 // 0 +R2_NOTMERGEPEN :: 2 // DPon +R2_MASKNOTPEN :: 3 // DPna +R2_NOTCOPYPEN :: 4 // PN +R2_MASKPENNOT :: 5 // PDna +R2_NOT :: 6 // Dn +R2_XORPEN :: 7 // DPx +R2_NOTMASKPEN :: 8 // DPan +R2_MASKPEN :: 9 // DPa +R2_NOTXORPEN :: 10 // DPxn +R2_NOP :: 11 // D +R2_MERGENOTPEN :: 12 // DPno +R2_COPYPEN :: 13 // P +R2_MERGEPENNOT :: 14 // PDno +R2_MERGEPEN :: 15 // DPo +R2_WHITE :: 16 // 1 +R2_LAST :: 16 + +// Ternary raster operations +SRCCOPY : DWORD : 0x00CC0020 // dest = source +SRCPAINT : DWORD : 0x00EE0086 // dest = source OR dest +SRCAND : DWORD : 0x008800C6 // dest = source AND dest +SRCINVERT : DWORD : 0x00660046 // dest = source XOR dest +SRCERASE : DWORD : 0x00440328 // dest = source AND (NOT dest) +NOTSRCCOPY : DWORD : 0x00330008 // dest = (NOT source) +NOTSRCERASE : DWORD : 0x001100A6 // dest = (NOT src) AND (NOT dest) +MERGECOPY : DWORD : 0x00C000CA // dest = (source AND pattern +MERGEPAINT : DWORD : 0x00BB0226 // dest = (NOT source) OR dest +PATCOPY : DWORD : 0x00F00021 // dest = pattern +PATPAINT : DWORD : 0x00FB0A09 // dest = DPSnoo +PATINVERT : DWORD : 0x005A0049 // dest = pattern XOR dest +DSTINVERT : DWORD : 0x00550009 // dest = (NOT dest) +BLACKNESS : DWORD : 0x00000042 // dest = BLACK +WHITENESS : DWORD : 0x00FF0062 // dest = WHITE +NOMIRRORBITMAP : DWORD : 0x80000000 // Do not Mirror the bitmap in this call +CAPTUREBLT : DWORD : 0x40000000 // Include layered windows + +// Stock Logical Objects +WHITE_BRUSH :: 0 +LTGRAY_BRUSH :: 1 +GRAY_BRUSH :: 2 +DKGRAY_BRUSH :: 3 +BLACK_BRUSH :: 4 +NULL_BRUSH :: 5 +HOLLOW_BRUSH :: NULL_BRUSH +WHITE_PEN :: 6 +BLACK_PEN :: 7 +NULL_PEN :: 8 +OEM_FIXED_FONT :: 10 +ANSI_FIXED_FONT :: 11 +ANSI_VAR_FONT :: 12 +SYSTEM_FONT :: 13 +DEVICE_DEFAULT_FONT :: 14 +DEFAULT_PALETTE :: 15 +SYSTEM_FIXED_FONT :: 16 +DEFAULT_GUI_FONT :: 17 +DC_BRUSH :: 18 +DC_PEN :: 19 +STOCK_LAST :: 19 + +CLR_INVALID :: 0xFFFFFFFF + +RGBQUAD :: struct { + rgbBlue: BYTE, + rgbGreen: BYTE, + rgbRed: BYTE, + rgbReserved: BYTE, +} + +PIXELFORMATDESCRIPTOR :: struct { + nSize: WORD, + nVersion: WORD, + dwFlags: DWORD, + iPixelType: BYTE, + cColorBits: BYTE, + cRedBits: BYTE, + cRedShift: BYTE, + cGreenBits: BYTE, + cGreenShift: BYTE, + cBlueBits: BYTE, + cBlueShift: BYTE, + cAlphaBits: BYTE, + cAlphaShift: BYTE, + cAccumBits: BYTE, + cAccumRedBits: BYTE, + cAccumGreenBits: BYTE, + cAccumBlueBits: BYTE, + cAccumAlphaBits: BYTE, + cDepthBits: BYTE, + cStencilBits: BYTE, + cAuxBuffers: BYTE, + iLayerType: BYTE, + bReserved: BYTE, + dwLayerMask: DWORD, + dwVisibleMask: DWORD, + dwDamageMask: DWORD, +} + +BITMAPINFOHEADER :: struct { + biSize: DWORD, + biWidth: LONG, + biHeight: LONG, + biPlanes: WORD, + biBitCount: WORD, + biCompression: DWORD, + biSizeImage: DWORD, + biXPelsPerMeter: LONG, + biYPelsPerMeter: LONG, + biClrUsed: DWORD, + biClrImportant: DWORD, +} + +BITMAPINFO :: struct { + bmiHeader: BITMAPINFOHEADER, + bmiColors: [1]RGBQUAD, +} + +// pixel types +PFD_TYPE_RGBA :: 0 +PFD_TYPE_COLORINDEX :: 1 + +// layer types +PFD_MAIN_PLANE :: 0 +PFD_OVERLAY_PLANE :: 1 +PFD_UNDERLAY_PLANE :: -1 + +// PIXELFORMATDESCRIPTOR flags +PFD_DOUBLEBUFFER :: 0x00000001 +PFD_STEREO :: 0x00000002 +PFD_DRAW_TO_WINDOW :: 0x00000004 +PFD_DRAW_TO_BITMAP :: 0x00000008 +PFD_SUPPORT_GDI :: 0x00000010 +PFD_SUPPORT_OPENGL :: 0x00000020 +PFD_GENERIC_FORMAT :: 0x00000040 +PFD_NEED_PALETTE :: 0x00000080 +PFD_NEED_SYSTEM_PALETTE :: 0x00000100 +PFD_SWAP_EXCHANGE :: 0x00000200 +PFD_SWAP_COPY :: 0x00000400 +PFD_SWAP_LAYER_BUFFERS :: 0x00000800 +PFD_GENERIC_ACCELERATED :: 0x00001000 +PFD_SUPPORT_DIRECTDRAW :: 0x00002000 +PFD_DIRECT3D_ACCELERATED :: 0x00004000 +PFD_SUPPORT_COMPOSITION :: 0x00008000 + +// PIXELFORMATDESCRIPTOR flags for use in ChoosePixelFormat only +PFD_DEPTH_DONTCARE :: 0x20000000 +PFD_DOUBLEBUFFER_DONTCARE :: 0x40000000 +PFD_STEREO_DONTCARE :: 0x80000000 + +// constants for the biCompression field +BI_RGB :: 0 +BI_RLE8 :: 1 +BI_RLE4 :: 2 +BI_BITFIELDS :: 3 +BI_JPEG :: 4 +BI_PNG :: 5 + WSA_FLAG_OVERLAPPED: DWORD : 0x01 WSA_FLAG_NO_HANDLE_INHERIT: DWORD : 0x80 @@ -376,6 +1252,18 @@ FILE_TYPE_DISK :: 0x0001 FILE_TYPE_CHAR :: 0x0002 FILE_TYPE_PIPE :: 0x0003 +RECT :: struct {left, top, right, bottom: LONG} +POINT :: struct {x, y: LONG} + +WINDOWPOS :: struct { + hwnd: HWND, + hwndInsertAfter: HWND, + x: c_int, + y: c_int, + cx: c_int, + cy: c_int, + flags: UINT, +} when size_of(uintptr) == 4 { WSADATA :: struct { @@ -575,7 +1463,7 @@ PROCESS_INFORMATION :: struct { } // FYI: This is STARTUPINFOW, not STARTUPINFOA -STARTUPINFO :: struct #packed { +STARTUPINFO :: struct { cb: DWORD, lpReserved: LPWSTR, lpDesktop: LPWSTR, @@ -781,17 +1669,17 @@ SYSTEM_INFO :: struct { // https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_osversioninfoexw OSVERSIONINFOEXW :: struct { - dwOSVersionInfoSize: ULONG, - dwMajorVersion: ULONG, - dwMinorVersion: ULONG, - dwBuildNumber: ULONG, - dwPlatformId: ULONG, - szCSDVersion: [128]WCHAR, - wServicePackMajor: USHORT, - wServicePackMinor: USHORT, - wSuiteMask: USHORT, - wProductType: UCHAR, - wReserved: UCHAR, + dwOSVersionInfoSize: ULONG, + dwMajorVersion: ULONG, + dwMinorVersion: ULONG, + dwBuildNumber: ULONG, + dwPlatformId: ULONG, + szCSDVersion: [128]WCHAR, + wServicePackMajor: USHORT, + wServicePackMinor: USHORT, + wSuiteMask: USHORT, + wProductType: UCHAR, + wReserved: UCHAR, } // https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-quota_limits @@ -834,24 +1722,24 @@ PROFILEINFOW :: struct { lpDefaultPath: LPWSTR, lpServerName: LPWSTR, lpPolicyPath: LPWSTR, - hProfile: HANDLE, + hProfile: HANDLE, } // Used in LookupAccountNameW SID_NAME_USE :: distinct DWORD SID_TYPE :: enum SID_NAME_USE { - User = 1, - Group, - Domain, - Alias, - WellKnownGroup, - DeletedAccount, - Invalid, - Unknown, - Computer, - Label, - LogonSession, + User = 1, + Group, + Domain, + Alias, + WellKnownGroup, + DeletedAccount, + Invalid, + Unknown, + Computer, + Label, + LogonSession, } SECURITY_MAX_SID_SIZE :: 68 @@ -866,7 +1754,7 @@ SID :: struct #packed { #assert(size_of(SID) == SECURITY_MAX_SID_SIZE) SID_IDENTIFIER_AUTHORITY :: struct #packed { - Value: [6]u8, + Value: [6]u8, } // For NetAPI32 @@ -898,11 +1786,11 @@ USER_INFO_FLAG :: enum DWORD { Passwd_Cant_Change = 6, // 1 << 6: 0x0040, Encrypted_Text_Password_Allowed = 7, // 1 << 7: 0x0080, - Temp_Duplicate_Account = 8, // 1 << 8: 0x0100, - Normal_Account = 9, // 1 << 9: 0x0200, - InterDomain_Trust_Account = 11, // 1 << 11: 0x0800, - Workstation_Trust_Account = 12, // 1 << 12: 0x1000, - Server_Trust_Account = 13, // 1 << 13: 0x2000, + Temp_Duplicate_Account = 8, // 1 << 8: 0x0100, + Normal_Account = 9, // 1 << 9: 0x0200, + InterDomain_Trust_Account = 11, // 1 << 11: 0x0800, + Workstation_Trust_Account = 12, // 1 << 12: 0x1000, + Server_Trust_Account = 13, // 1 << 13: 0x2000, } USER_INFO_FLAGS :: distinct bit_set[USER_INFO_FLAG] @@ -1249,4 +2137,4 @@ SYSTEMTIME :: struct { minute: WORD, second: WORD, milliseconds: WORD, -} \ No newline at end of file +} diff --git a/core/sys/windows/user32.odin b/core/sys/windows/user32.odin new file mode 100644 index 000000000..dd45df42a --- /dev/null +++ b/core/sys/windows/user32.odin @@ -0,0 +1,258 @@ +// +build windows +package sys_windows + +foreign import user32 "system:User32.lib" + +@(default_calling_convention="stdcall") +foreign user32 { + GetClassInfoA :: proc(hInstance: HINSTANCE, lpClassNAme: LPCSTR, lpWndClass: ^WNDCLASSA) -> BOOL --- + GetClassInfoW :: proc(hInstance: HINSTANCE, lpClassNAme: LPCWSTR, lpWndClass: ^WNDCLASSW) -> BOOL --- + GetClassInfoExA :: proc(hInsatnce: HINSTANCE, lpszClass: LPCSTR, lpwcx: ^WNDCLASSEXA) -> BOOL --- + GetClassInfoExW :: proc(hInsatnce: HINSTANCE, lpszClass: LPCWSTR, lpwcx: ^WNDCLASSEXW) -> BOOL --- + + GetClassLongA :: proc(hWnd: HWND, nIndex: c_int) -> DWORD --- + GetClassLongW :: proc(hWnd: HWND, nIndex: c_int) -> DWORD --- + SetClassLongA :: proc(hWnd: HWND, nIndex: c_int, dwNewLong: LONG) -> DWORD --- + SetClassLongW :: proc(hWnd: HWND, nIndex: c_int, dwNewLong: LONG) -> DWORD --- + + GetWindowLongA :: proc(hWnd: HWND, nIndex: c_int) -> LONG --- + GetWindowLongW :: proc(hWnd: HWND, nIndex: c_int) -> LONG --- + SetWindowLongA :: proc(hWnd: HWND, nIndex: c_int, dwNewLong: LONG) -> LONG --- + SetWindowLongW :: proc(hWnd: HWND, nIndex: c_int, dwNewLong: LONG) -> LONG --- + + GetClassNameA :: proc(hWnd: HWND, lpClassName: LPSTR, nMaxCount: c_int) -> c_int --- + GetClassNameW :: proc(hWnd: HWND, lpClassName: LPWSTR, nMaxCount: c_int) -> c_int --- + + RegisterClassA :: proc(lpWndClass: ^WNDCLASSA) -> ATOM --- + RegisterClassW :: proc(lpWndClass: ^WNDCLASSW) -> ATOM --- + RegisterClassExA :: proc(^WNDCLASSEXA) -> ATOM --- + RegisterClassExW :: proc(^WNDCLASSEXW) -> ATOM --- + + CreateWindowExA :: proc( + dwExStyle: DWORD, + lpClassName: LPCSTR, + lpWindowName: LPCSTR, + dwStyle: DWORD, + X: c_int, + Y: c_int, + nWidth: c_int, + nHeight: c_int, + hWndParent: HWND, + hMenu: HMENU, + hInstance: HINSTANCE, + lpParam: LPVOID, + ) -> HWND --- + CreateWindowExW :: proc( + dwExStyle: DWORD, + lpClassName: LPCWSTR, + lpWindowName: LPCWSTR, + dwStyle: DWORD, + X: c_int, + Y: c_int, + nWidth: c_int, + nHeight: c_int, + hWndParent: HWND, + hMenu: HMENU, + hInstance: HINSTANCE, + lpParam: LPVOID, + ) -> HWND --- + + DestroyWindow :: proc(hWnd: HWND) -> BOOL --- + + ShowWindow :: proc(hWnd: HWND, nCmdShow: c_int) -> BOOL --- + BringWindowToTop :: proc(hWnd: HWND) -> BOOL --- + GetTopWindow :: proc(hWnd: HWND) -> HWND --- + SetForegroundWindow :: proc(hWnd: HWND) -> BOOL --- + GetForegroundWindow :: proc() -> HWND --- + SetActiveWindow :: proc(hWnd: HWND) -> HWND --- + GetActiveWindow :: proc() -> HWND --- + + GetMessageA :: proc(lpMsg: ^MSG, hWnd: HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT) -> BOOL --- + GetMessageW :: proc(lpMsg: ^MSG, hWnd: HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT) -> BOOL --- + + TranslateMessage :: proc(lpMsg: ^MSG) -> BOOL --- + DispatchMessageA :: proc(lpMsg: ^MSG) -> LRESULT --- + DispatchMessageW :: proc(lpMsg: ^MSG) -> LRESULT --- + + PeekMessageA :: proc(lpMsg: ^MSG, hWnd: HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT, wRemoveMsg: UINT) -> BOOL --- + PeekMessageW :: proc(lpMsg: ^MSG, hWnd: HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT, wRemoveMsg: UINT) -> BOOL --- + + PostMessageA :: proc(hWnd: HWND, Msg: UINT, wParam: WPARAM, lParam: LPARAM) -> BOOL --- + PostMessageW :: proc(hWnd: HWND, Msg: UINT, wParam: WPARAM, lParam: LPARAM) -> BOOL --- + SendMessageA :: proc(hWnd: HWND, Msg: UINT, wParam: WPARAM, lParam: LPARAM) -> LRESULT --- + SendMessageW :: proc(hWnd: HWND, Msg: UINT, wParam: WPARAM, lParam: LPARAM) -> LRESULT --- + + PostThreadMessageA :: proc(idThread: DWORD, Msg: UINT, wParam: WPARAM, lParam: LPARAM) -> BOOL --- + PostThreadMessageW :: proc(idThread: DWORD, Msg: UINT, wParam: WPARAM, lParam: LPARAM) -> BOOL --- + + PostQuitMessage :: proc(nExitCode: c_int) --- + + GetQueueStatus :: proc(flags: UINT) -> DWORD --- + + DefWindowProcA :: proc(hWnd: HWND, Msg: UINT, wParam: WPARAM, lParam: LPARAM) -> LRESULT --- + DefWindowProcW :: proc(hWnd: HWND, Msg: UINT, wParam: WPARAM, lParam: LPARAM) -> LRESULT --- + + FindWindowA :: proc(lpClassName: LPCSTR, lpWindowName: LPCSTR) -> HWND --- + FindWindowW :: proc(lpClassName: LPCWSTR, lpWindowName: LPCWSTR) -> HWND --- + FindWindowExA :: proc(hWndParent: HWND, hWndChildAfter: HWND, lpszClass: LPCSTR, lpszWindow: LPCSTR) -> HWND --- + FindWindowExW :: proc(hWndParent: HWND, hWndChildAfter: HWND, lpszClass: LPCWSTR, lpszWindow: LPCWSTR) -> HWND --- + + LoadIconA :: proc(hInstance: HINSTANCE, lpIconName: LPCSTR) -> HICON --- + LoadIconW :: proc(hInstance: HINSTANCE, lpIconName: LPCWSTR) -> HICON --- + LoadCursorA :: proc(hInstance: HINSTANCE, lpCursorName: LPCSTR) -> HCURSOR --- + LoadCursorW :: proc(hInstance: HINSTANCE, lpCursorName: LPCWSTR) -> HCURSOR --- + + GetWindowRect :: proc(hWnd: HWND, lpRect: LPRECT) -> BOOL --- + GetClientRect :: proc(hWnd: HWND, lpRect: LPRECT) -> BOOL --- + ClientToScreen :: proc(hWnd: HWND, lpPoint: LPPOINT) -> BOOL --- + SetWindowPos :: proc( + hWnd: HWND, + hWndInsertAfter: HWND, + X: c_int, + Y: c_int, + cx: c_int, + cy: c_int, + uFlags: UINT, + ) -> BOOL --- + GetSystemMetrics :: proc(nIndex: c_int) -> c_int --- + AdjustWindowRect :: proc(lpRect: LPRECT, dwStyle: DWORD, bMenu: BOOL) -> BOOL --- + AdjustWindowRectEx :: proc(lpRect: LPRECT, dwStyle: DWORD, bMenu: BOOL, dwExStyle: DWORD) -> BOOL --- + + GetWindowDC :: proc(hWnd: HWND) -> HDC --- + GetDC :: proc(hWnd: HWND) -> HDC --- + ReleaseDC :: proc(hWnd: HWND, hDC: HDC) -> c_int --- + + GetUpdateRect :: proc(hWnd: HWND, lpRect: LPRECT, bErase: BOOL) -> BOOL --- + ValidateRect :: proc(hWnd: HWND, lpRect: ^RECT) -> BOOL --- + InvalidateRect :: proc(hWnd: HWND, lpRect: ^RECT, bErase: BOOL) -> BOOL --- + + BeginPaint :: proc(hWnd: HWND, lpPaint: ^PAINTSTRUCT) -> HDC --- + EndPaint :: proc(hWnd: HWND, lpPaint: ^PAINTSTRUCT) -> BOOL --- + + GetCapture :: proc() -> HWND --- + SetCapture :: proc(hWnd: HWND) -> HWND --- + ReleaseCapture :: proc() -> BOOL --- + TrackMouseEvent :: proc(lpEventTrack: LPTRACKMOUSEEVENT) -> BOOL --- + + GetKeyState :: proc(nVirtKey: c_int) -> SHORT --- + GetAsyncKeyState :: proc(vKey: c_int) -> SHORT --- + + MapVirtualKeyA :: proc(uCode: UINT, uMapType: UINT) -> UINT --- + MapVirtualKeyW :: proc(uCode: UINT, uMapType: UINT) -> UINT --- + + SetWindowsHookExA :: proc(idHook: c_int, lpfn: HOOKPROC, hmod: HINSTANCE, dwThreadId: DWORD) -> HHOOK --- + SetWindowsHookExW :: proc(idHook: c_int, lpfn: HOOKPROC, hmod: HINSTANCE, dwThreadId: DWORD) -> HHOOK --- + UnhookWindowsHookEx :: proc(hhk: HHOOK) -> BOOL --- + CallNextHookEx :: proc(hhk: HHOOK, nCode: c_int, wParam: WPARAM, lParam: LPARAM) -> LRESULT --- + + SetTimer :: proc(hWnd: HWND, nIDEvent: UINT_PTR, uElapse: UINT, lpTimerFunc: TIMERPROC) -> UINT_PTR --- + KillTimer :: proc(hWnd: HWND, uIDEvent: UINT_PTR) -> BOOL --- + + MessageBoxA :: proc(hWnd: HWND, lpText: LPCSTR, lpCaption: LPCSTR, uType: UINT) -> c_int --- + MessageBoxW :: proc(hWnd: HWND, lpText: LPCWSTR, lpCaption: LPCWSTR, uType: UINT) -> c_int --- + MessageBoxExA :: proc(hWnd: HWND, lpText: LPCSTR, lpCaption: LPCSTR, uType: UINT, wLanguageId: WORD) -> c_int --- + MessageBoxExW :: proc(hWnd: HWND, lpText: LPCWSTR, lpCaption: LPCWSTR, uType: UINT, wLanguageId: WORD) -> c_int --- +} + +CreateWindowA :: #force_inline proc "stdcall" ( + lpClassName: LPCSTR, + lpWindowName: LPCSTR, + dwStyle: DWORD, + X: c_int, + Y: c_int, + nWidth: c_int, + nHeight: c_int, + hWndParent: HWND, + hMenu: HMENU, + hInstance: HINSTANCE, + lpParam: LPVOID, +) -> HWND { + return CreateWindowExA( + 0, + lpClassName, + lpWindowName, + dwStyle, + X, + Y, + nWidth, + nHeight, + hWndParent, + hMenu, + hInstance, + lpParam, + ) +} + +CreateWindowW :: #force_inline proc "stdcall" ( + lpClassName: LPCTSTR, + lpWindowName: LPCTSTR, + dwStyle: DWORD, + X: c_int, + Y: c_int, + nWidth: c_int, + nHeight: c_int, + hWndParent: HWND, + hMenu: HMENU, + hInstance: HINSTANCE, + lpParam: LPVOID, +) -> HWND { + return CreateWindowExW( + 0, + lpClassName, + lpWindowName, + dwStyle, + X, + Y, + nWidth, + nHeight, + hWndParent, + hMenu, + hInstance, + lpParam, + ) +} + +when ODIN_ARCH == .amd64 { + @(default_calling_convention="stdcall") + foreign user32 { + GetClassLongPtrA :: proc(hWnd: HWND, nIndex: c_int) -> ULONG_PTR --- + GetClassLongPtrW :: proc(hWnd: HWND, nIndex: c_int) -> ULONG_PTR --- + SetClassLongPtrA :: proc(hWnd: HWND, nIndex: c_int, dwNewLong: LONG_PTR) -> ULONG_PTR --- + SetClassLongPtrW :: proc(hWnd: HWND, nIndex: c_int, dwNewLong: LONG_PTR) -> ULONG_PTR --- + + GetWindowLongPtrA :: proc(hWnd: HWND, nIndex: c_int) -> LONG_PTR --- + GetWindowLongPtrW :: proc(hWnd: HWND, nIndex: c_int) -> LONG_PTR --- + SetWindowLongPtrA :: proc(hWnd: HWND, nIndex: c_int, dwNewLong: LONG_PTR) -> LONG_PTR --- + SetWindowLongPtrW :: proc(hWnd: HWND, nIndex: c_int, dwNewLong: LONG_PTR) -> LONG_PTR --- + } +} else when ODIN_ARCH == .i386 { + GetClassLongPtrA :: GetClassLongA + GetClassLongPtrW :: GetClassLongW + SetClassLongPtrA :: SetClassLongA + SetClassLongPtrW :: SetClassLongW + + GetWindowLongPtrA :: GetWindowLongA + GetWindowLongPtrW :: GetWindowLongW + SetWindowLongPtrA :: GetWindowLongA + SetWindowLongPtrW :: GetWindowLongW +} + +GET_SC_WPARAM :: #force_inline proc "contextless" (wParam: WPARAM) -> c_int { + return c_int(wParam) & 0xFFF0 +} + +GET_WHEEL_DELTA_WPARAM :: #force_inline proc "contextless" (wParam: WPARAM) -> c_short { + return cast(c_short)HIWORD(cast(DWORD)wParam) +} + +GET_KEYSTATE_WPARAM :: #force_inline proc "contextless" (wParam: WPARAM) -> WORD { + return LOWORD(cast(DWORD)wParam) +} + +GET_NCHITTEST_WPARAM :: #force_inline proc "contextless" (wParam: WPARAM) -> c_short { + return cast(c_short)LOWORD(cast(DWORD)wParam) +} + +GET_XBUTTON_WPARAM :: #force_inline proc "contextless" (wParam: WPARAM) -> WORD { + return HIWORD(cast(DWORD)wParam) +} diff --git a/core/sys/windows/util.odin b/core/sys/windows/util.odin index efb37dbc0..f448f6bc5 100644 --- a/core/sys/windows/util.odin +++ b/core/sys/windows/util.odin @@ -3,6 +3,9 @@ package sys_windows import "core:strings" import "core:sys/win32" +import "core:intrinsics" + +L :: intrinsics.constant_utf16_cstring LOWORD :: #force_inline proc "contextless" (x: DWORD) -> WORD { return WORD(x & 0xffff) @@ -12,6 +15,14 @@ HIWORD :: #force_inline proc "contextless" (x: DWORD) -> WORD { return WORD(x >> 16) } +GET_X_LPARAM :: #force_inline proc "contextless" (lp: LPARAM) -> c_int { + return cast(c_int)cast(c_short)LOWORD(cast(DWORD)lp) +} + +GET_Y_LPARAM :: #force_inline proc "contextless" (lp: LPARAM) -> c_int { + return cast(c_int)cast(c_short)HIWORD(cast(DWORD)lp) +} + utf8_to_utf16 :: proc(s: string, allocator := context.temp_allocator) -> []u16 { if len(s) < 1 { return nil @@ -45,7 +56,9 @@ utf8_to_wstring :: proc(s: string, allocator := context.temp_allocator) -> wstri return nil } -wstring_to_utf8 :: proc(s: wstring, N: int, allocator := context.temp_allocator) -> string { +wstring_to_utf8 :: proc(s: wstring, N: int, allocator := context.temp_allocator) -> (res: string) { + context.allocator = allocator + if N <= 0 { return "" } @@ -60,7 +73,7 @@ wstring_to_utf8 :: proc(s: wstring, N: int, allocator := context.temp_allocator) // also null terminated. // If N != -1 it assumes the wide string is not null terminated and the resulting string // will not be null terminated, we therefore have to force it to be null terminated manually. - text := make([]byte, n+1 if N != -1 else n, allocator) + text := make([]byte, n+1 if N != -1 else n) n1 := WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, s, i32(N), raw_data(text), n, nil, nil) if n1 == 0 { @@ -74,7 +87,6 @@ wstring_to_utf8 :: proc(s: wstring, N: int, allocator := context.temp_allocator) break } } - return string(text[:n]) } @@ -455,4 +467,4 @@ run_as_user :: proc(username, password, application, commandline: string, pi: ^P } else { return false } -} \ No newline at end of file +} diff --git a/core/sys/windows/window_messages.odin b/core/sys/windows/window_messages.odin new file mode 100644 index 000000000..9c3a30088 --- /dev/null +++ b/core/sys/windows/window_messages.odin @@ -0,0 +1,1048 @@ +// +build windows +package sys_windows + +WM_NULL :: 0x0000 +WM_CREATE :: 0x0001 +WM_DESTROY :: 0x0002 +WM_MOVE :: 0x0003 +WM_SIZE :: 0x0005 +WM_ACTIVATE :: 0x0006 +WM_SETFOCUS :: 0x0007 +WM_KILLFOCUS :: 0x0008 +WM_ENABLE :: 0x000a +WM_SETREDRAW :: 0x000b +WM_SETTEXT :: 0x000c +WM_GETTEXT :: 0x000d +WM_GETTEXTLENGTH :: 0x000e +WM_PAINT :: 0x000f +WM_CLOSE :: 0x0010 +WM_QUERYENDSESSION :: 0x0011 +WM_QUIT :: 0x0012 +WM_QUERYOPEN :: 0x0013 +WM_ERASEBKGND :: 0x0014 +WM_SYSCOLORCHANGE :: 0x0015 +WM_ENDSESSION :: 0x0016 +WM_SHOWWINDOW :: 0x0018 +WM_CTLCOLOR :: 0x0019 +WM_WININICHANGE :: 0x001a +WM_DEVMODECHANGE :: 0x001b +WM_ACTIVATEAPP :: 0x001c +WM_FONTCHANGE :: 0x001d +WM_TIMECHANGE :: 0x001e +WM_CANCELMODE :: 0x001f +WM_SETCURSOR :: 0x0020 +WM_MOUSEACTIVATE :: 0x0021 +WM_CHILDACTIVATE :: 0x0022 +WM_QUEUESYNC :: 0x0023 +WM_GETMINMAXINFO :: 0x0024 +WM_PAINTICON :: 0x0026 +WM_ICONERASEBKGND :: 0x0027 +WM_NEXTDLGCTL :: 0x0028 +WM_SPOOLERSTATUS :: 0x002a +WM_DRAWITEM :: 0x002b +WM_MEASUREITEM :: 0x002c +WM_DELETEITEM :: 0x002d +WM_VKEYTOITEM :: 0x002e +WM_CHARTOITEM :: 0x002f +WM_SETFONT :: 0x0030 +WM_GETFONT :: 0x0031 +WM_SETHOTKEY :: 0x0032 +WM_GETHOTKEY :: 0x0033 +WM_QUERYDRAGICON :: 0x0037 +WM_COMPAREITEM :: 0x0039 +WM_GETOBJECT :: 0x003d +WM_COMPACTING :: 0x0041 +WM_COMMNOTIFY :: 0x0044 +WM_WINDOWPOSCHANGING :: 0x0046 +WM_WINDOWPOSCHANGED :: 0x0047 +WM_POWER :: 0x0048 +WM_COPYGLOBALDATA :: 0x0049 +WM_COPYDATA :: 0x004a +WM_CANCELJOURNAL :: 0x004b +WM_NOTIFY :: 0x004e +WM_INPUTLANGCHANGEREQUEST :: 0x0050 +WM_INPUTLANGCHANGE :: 0x0051 +WM_TCARD :: 0x0052 +WM_HELP :: 0x0053 +WM_USERCHANGED :: 0x0054 +WM_NOTIFYFORMAT :: 0x0055 +WM_CONTEXTMENU :: 0x007b +WM_STYLECHANGING :: 0x007c +WM_STYLECHANGED :: 0x007d +WM_DISPLAYCHANGE :: 0x007e +WM_GETICON :: 0x007f +WM_SETICON :: 0x0080 +WM_NCCREATE :: 0x0081 +WM_NCDESTROY :: 0x0082 +WM_NCCALCSIZE :: 0x0083 +WM_NCHITTEST :: 0x0084 +WM_NCPAINT :: 0x0085 +WM_NCACTIVATE :: 0x0086 +WM_GETDLGCODE :: 0x0087 +WM_SYNCPAINT :: 0x0088 +WM_NCMOUSEMOVE :: 0x00a0 +WM_NCLBUTTONDOWN :: 0x00a1 +WM_NCLBUTTONUP :: 0x00a2 +WM_NCLBUTTONDBLCLK :: 0x00a3 +WM_NCRBUTTONDOWN :: 0x00a4 +WM_NCRBUTTONUP :: 0x00a5 +WM_NCRBUTTONDBLCLK :: 0x00a6 +WM_NCMBUTTONDOWN :: 0x00a7 +WM_NCMBUTTONUP :: 0x00a8 +WM_NCMBUTTONDBLCLK :: 0x00a9 +WM_NCXBUTTONDOWN :: 0x00ab +WM_NCXBUTTONUP :: 0x00ac +WM_NCXBUTTONDBLCLK :: 0x00ad +EM_GETSEL :: 0x00b0 +EM_SETSEL :: 0x00b1 +EM_GETRECT :: 0x00b2 +EM_SETRECT :: 0x00b3 +EM_SETRECTNP :: 0x00b4 +EM_SCROLL :: 0x00b5 +EM_LINESCROLL :: 0x00b6 +EM_SCROLLCARET :: 0x00b7 +EM_GETMODIFY :: 0x00b8 +EM_SETMODIFY :: 0x00b9 +EM_GETLINECOUNT :: 0x00ba +EM_LINEINDEX :: 0x00bb +EM_SETHANDLE :: 0x00bc +EM_GETHANDLE :: 0x00bd +EM_GETTHUMB :: 0x00be +EM_LINELENGTH :: 0x00c1 +EM_REPLACESEL :: 0x00c2 +EM_SETFONT :: 0x00c3 +EM_GETLINE :: 0x00c4 +EM_LIMITTEXT :: 0x00c5 +EM_SETLIMITTEXT :: 0x00c5 +EM_CANUNDO :: 0x00c6 +EM_UNDO :: 0x00c7 +EM_FMTLINES :: 0x00c8 +EM_LINEFROMCHAR :: 0x00c9 +EM_SETWORDBREAK :: 0x00ca +EM_SETTABSTOPS :: 0x00cb +EM_SETPASSWORDCHAR :: 0x00cc +EM_EMPTYUNDOBUFFER :: 0x00cd +EM_GETFIRSTVISIBLELINE :: 0x00ce +EM_SETREADONLY :: 0x00cf +EM_SETWORDBREAKPROC :: 0x00d0 +EM_GETWORDBREAKPROC :: 0x00d1 +EM_GETPASSWORDCHAR :: 0x00d2 +EM_SETMARGINS :: 0x00d3 +EM_GETMARGINS :: 0x00d4 +EM_GETLIMITTEXT :: 0x00d5 +EM_POSFROMCHAR :: 0x00d6 +EM_CHARFROMPOS :: 0x00d7 +EM_SETIMESTATUS :: 0x00d8 +EM_GETIMESTATUS :: 0x00d9 +SBM_SETPOS :: 0x00e0 +SBM_GETPOS :: 0x00e1 +SBM_SETRANGE :: 0x00e2 +SBM_GETRANGE :: 0x00e3 +SBM_ENABLE_ARROWS :: 0x00e4 +SBM_SETRANGEREDRAW :: 0x00e6 +SBM_SETSCROLLINFO :: 0x00e9 +SBM_GETSCROLLINFO :: 0x00ea +SBM_GETSCROLLBARINFO :: 0x00eb +BM_GETCHECK :: 0x00f0 +BM_SETCHECK :: 0x00f1 +BM_GETSTATE :: 0x00f2 +BM_SETSTATE :: 0x00f3 +BM_SETSTYLE :: 0x00f4 +BM_CLICK :: 0x00f5 +BM_GETIMAGE :: 0x00f6 +BM_SETIMAGE :: 0x00f7 +BM_SETDONTCLICK :: 0x00f8 +WM_INPUT :: 0x00ff +WM_KEYDOWN :: 0x0100 +WM_KEYFIRST :: 0x0100 +WM_KEYUP :: 0x0101 +WM_CHAR :: 0x0102 +WM_DEADCHAR :: 0x0103 +WM_SYSKEYDOWN :: 0x0104 +WM_SYSKEYUP :: 0x0105 +WM_SYSCHAR :: 0x0106 +WM_SYSDEADCHAR :: 0x0107 +WM_UNICHAR :: 0x0109 +WM_KEYLAST :: 0x0109 +WM_WNT_CONVERTREQUESTEX :: 0x0109 +WM_CONVERTREQUEST :: 0x010a +WM_CONVERTRESULT :: 0x010b +WM_INTERIM :: 0x010c +WM_IME_STARTCOMPOSITION :: 0x010d +WM_IME_ENDCOMPOSITION :: 0x010e +WM_IME_COMPOSITION :: 0x010f +WM_IME_KEYLAST :: 0x010f +WM_INITDIALOG :: 0x0110 +WM_COMMAND :: 0x0111 +WM_SYSCOMMAND :: 0x0112 +WM_TIMER :: 0x0113 +WM_HSCROLL :: 0x0114 +WM_VSCROLL :: 0x0115 +WM_INITMENU :: 0x0116 +WM_INITMENUPOPUP :: 0x0117 +WM_SYSTIMER :: 0x0118 +WM_MENUSELECT :: 0x011f +WM_MENUCHAR :: 0x0120 +WM_ENTERIDLE :: 0x0121 +WM_MENURBUTTONUP :: 0x0122 +WM_MENUDRAG :: 0x0123 +WM_MENUGETOBJECT :: 0x0124 +WM_UNINITMENUPOPUP :: 0x0125 +WM_MENUCOMMAND :: 0x0126 +WM_CHANGEUISTATE :: 0x0127 +WM_UPDATEUISTATE :: 0x0128 +WM_QUERYUISTATE :: 0x0129 +WM_LBTRACKPOINT :: 0x0131 +WM_CTLCOLORMSGBOX :: 0x0132 +WM_CTLCOLOREDIT :: 0x0133 +WM_CTLCOLORLISTBOX :: 0x0134 +WM_CTLCOLORBTN :: 0x0135 +WM_CTLCOLORDLG :: 0x0136 +WM_CTLCOLORSCROLLBAR :: 0x0137 +WM_CTLCOLORSTATIC :: 0x0138 +CB_GETEDITSEL :: 0x0140 +CB_LIMITTEXT :: 0x0141 +CB_SETEDITSEL :: 0x0142 +CB_ADDSTRING :: 0x0143 +CB_DELETESTRING :: 0x0144 +CB_DIR :: 0x0145 +CB_GETCOUNT :: 0x0146 +CB_GETCURSEL :: 0x0147 +CB_GETLBTEXT :: 0x0148 +CB_GETLBTEXTLEN :: 0x0149 +CB_INSERTSTRING :: 0x014a +CB_RESETCONTENT :: 0x014b +CB_FINDSTRING :: 0x014c +CB_SELECTSTRING :: 0x014d +CB_SETCURSEL :: 0x014e +CB_SHOWDROPDOWN :: 0x014f +CB_GETITEMDATA :: 0x0150 +CB_SETITEMDATA :: 0x0151 +CB_GETDROPPEDCONTROLRECT :: 0x0152 +CB_SETITEMHEIGHT :: 0x0153 +CB_GETITEMHEIGHT :: 0x0154 +CB_SETEXTENDEDUI :: 0x0155 +CB_GETEXTENDEDUI :: 0x0156 +CB_GETDROPPEDSTATE :: 0x0157 +CB_FINDSTRINGEXACT :: 0x0158 +CB_SETLOCALE :: 0x0159 +CB_GETLOCALE :: 0x015a +CB_GETTOPINDEX :: 0x015b +CB_SETTOPINDEX :: 0x015c +CB_GETHORIZONTALEXTENT :: 0x015d +CB_SETHORIZONTALEXTENT :: 0x015e +CB_GETDROPPEDWIDTH :: 0x015f +CB_SETDROPPEDWIDTH :: 0x0160 +CB_INITSTORAGE :: 0x0161 +CB_MULTIPLEADDSTRING :: 0x0163 +CB_GETCOMBOBOXINFO :: 0x0164 +CB_MSGMAX :: 0x0165 +WM_MOUSEFIRST :: 0x0200 +WM_MOUSEMOVE :: 0x0200 +WM_LBUTTONDOWN :: 0x0201 +WM_LBUTTONUP :: 0x0202 +WM_LBUTTONDBLCLK :: 0x0203 +WM_RBUTTONDOWN :: 0x0204 +WM_RBUTTONUP :: 0x0205 +WM_RBUTTONDBLCLK :: 0x0206 +WM_MBUTTONDOWN :: 0x0207 +WM_MBUTTONUP :: 0x0208 +WM_MBUTTONDBLCLK :: 0x0209 +WM_MOUSELAST :: 0x0209 +WM_MOUSEWHEEL :: 0x020a +WM_XBUTTONDOWN :: 0x020b +WM_XBUTTONUP :: 0x020c +WM_XBUTTONDBLCLK :: 0x020d +WM_MOUSEHWHEEL :: 0x020e +WM_PARENTNOTIFY :: 0x0210 +WM_ENTERMENULOOP :: 0x0211 +WM_EXITMENULOOP :: 0x0212 +WM_NEXTMENU :: 0x0213 +WM_SIZING :: 0x0214 +WM_CAPTURECHANGED :: 0x0215 +WM_MOVING :: 0x0216 +WM_POWERBROADCAST :: 0x0218 +WM_DEVICECHANGE :: 0x0219 +WM_MDICREATE :: 0x0220 +WM_MDIDESTROY :: 0x0221 +WM_MDIACTIVATE :: 0x0222 +WM_MDIRESTORE :: 0x0223 +WM_MDINEXT :: 0x0224 +WM_MDIMAXIMIZE :: 0x0225 +WM_MDITILE :: 0x0226 +WM_MDICASCADE :: 0x0227 +WM_MDIICONARRANGE :: 0x0228 +WM_MDIGETACTIVE :: 0x0229 +WM_MDISETMENU :: 0x0230 +WM_ENTERSIZEMOVE :: 0x0231 +WM_EXITSIZEMOVE :: 0x0232 +WM_DROPFILES :: 0x0233 +WM_MDIREFRESHMENU :: 0x0234 +WM_IME_REPORT :: 0x0280 +WM_IME_SETCONTEXT :: 0x0281 +WM_IME_NOTIFY :: 0x0282 +WM_IME_CONTROL :: 0x0283 +WM_IME_COMPOSITIONFULL :: 0x0284 +WM_IME_SELECT :: 0x0285 +WM_IME_CHAR :: 0x0286 +WM_IME_REQUEST :: 0x0288 +WM_IMEKEYDOWN :: 0x0290 +WM_IME_KEYDOWN :: 0x0290 +WM_IMEKEYUP :: 0x0291 +WM_IME_KEYUP :: 0x0291 +WM_NCMOUSEHOVER :: 0x02a0 +WM_MOUSEHOVER :: 0x02a1 +WM_NCMOUSELEAVE :: 0x02a2 +WM_MOUSELEAVE :: 0x02a3 +WM_CUT :: 0x0300 +WM_COPY :: 0x0301 +WM_PASTE :: 0x0302 +WM_CLEAR :: 0x0303 +WM_UNDO :: 0x0304 +WM_RENDERFORMAT :: 0x0305 +WM_RENDERALLFORMATS :: 0x0306 +WM_DESTROYCLIPBOARD :: 0x0307 +WM_DRAWCLIPBOARD :: 0x0308 +WM_PAINTCLIPBOARD :: 0x0309 +WM_VSCROLLCLIPBOARD :: 0x030a +WM_SIZECLIPBOARD :: 0x030b +WM_ASKCBFORMATNAME :: 0x030c +WM_CHANGECBCHAIN :: 0x030d +WM_HSCROLLCLIPBOARD :: 0x030e +WM_QUERYNEWPALETTE :: 0x030f +WM_PALETTEISCHANGING :: 0x0310 +WM_PALETTECHANGED :: 0x0311 +WM_HOTKEY :: 0x0312 +WM_PRINT :: 0x0317 +WM_PRINTCLIENT :: 0x0318 +WM_APPCOMMAND :: 0x0319 +WM_HANDHELDFIRST :: 0x0358 +WM_HANDHELDLAST :: 0x035f +WM_AFXFIRST :: 0x0360 +WM_AFXLAST :: 0x037f +WM_PENWINFIRST :: 0x0380 +WM_RCRESULT :: 0x0381 +WM_HOOKRCRESULT :: 0x0382 +WM_GLOBALRCCHANGE :: 0x0383 +WM_PENMISCINFO :: 0x0383 +WM_SKB :: 0x0384 +WM_HEDITCTL :: 0x0385 +WM_PENCTL :: 0x0385 +WM_PENMISC :: 0x0386 +WM_CTLINIT :: 0x0387 +WM_PENEVENT :: 0x0388 +WM_PENWINLAST :: 0x038f +DDM_SETFMT :: 0x0400 +DM_GETDEFID :: 0x0400 +NIN_SELECT :: 0x0400 +TBM_GETPOS :: 0x0400 +WM_PSD_PAGESETUPDLG :: 0x0400 +WM_USER :: 0x0400 +CBEM_INSERTITEMA :: 0x0401 +DDM_DRAW :: 0x0401 +DM_SETDEFID :: 0x0401 +HKM_SETHOTKEY :: 0x0401 +PBM_SETRANGE :: 0x0401 +RB_INSERTBANDA :: 0x0401 +SB_SETTEXTA :: 0x0401 +TB_ENABLEBUTTON :: 0x0401 +TBM_GETRANGEMIN :: 0x0401 +TTM_ACTIVATE :: 0x0401 +WM_CHOOSEFONT_GETLOGFONT :: 0x0401 +WM_PSD_FULLPAGERECT :: 0x0401 +CBEM_SETIMAGELIST :: 0x0402 +DDM_CLOSE :: 0x0402 +DM_REPOSITION :: 0x0402 +HKM_GETHOTKEY :: 0x0402 +PBM_SETPOS :: 0x0402 +RB_DELETEBAND :: 0x0402 +SB_GETTEXTA :: 0x0402 +TB_CHECKBUTTON :: 0x0402 +TBM_GETRANGEMAX :: 0x0402 +WM_PSD_MINMARGINRECT :: 0x0402 +CBEM_GETIMAGELIST :: 0x0403 +DDM_BEGIN :: 0x0403 +HKM_SETRULES :: 0x0403 +PBM_DELTAPOS :: 0x0403 +RB_GETBARINFO :: 0x0403 +SB_GETTEXTLENGTHA :: 0x0403 +TBM_GETTIC :: 0x0403 +TB_PRESSBUTTON :: 0x0403 +TTM_SETDELAYTIME :: 0x0403 +WM_PSD_MARGINRECT :: 0x0403 +CBEM_GETITEMA :: 0x0404 +DDM_END :: 0x0404 +PBM_SETSTEP :: 0x0404 +RB_SETBARINFO :: 0x0404 +SB_SETPARTS :: 0x0404 +TB_HIDEBUTTON :: 0x0404 +TBM_SETTIC :: 0x0404 +TTM_ADDTOOLA :: 0x0404 +WM_PSD_GREEKTEXTRECT :: 0x0404 +CBEM_SETITEMA :: 0x0405 +PBM_STEPIT :: 0x0405 +TB_INDETERMINATE :: 0x0405 +TBM_SETPOS :: 0x0405 +TTM_DELTOOLA :: 0x0405 +WM_PSD_ENVSTAMPRECT :: 0x0405 +CBEM_GETCOMBOCONTROL :: 0x0406 +PBM_SETRANGE32 :: 0x0406 +RB_SETBANDINFOA :: 0x0406 +SB_GETPARTS :: 0x0406 +TB_MARKBUTTON :: 0x0406 +TBM_SETRANGE :: 0x0406 +TTM_NEWTOOLRECTA :: 0x0406 +WM_PSD_YAFULLPAGERECT :: 0x0406 +CBEM_GETEDITCONTROL :: 0x0407 +PBM_GETRANGE :: 0x0407 +RB_SETPARENT :: 0x0407 +SB_GETBORDERS :: 0x0407 +TBM_SETRANGEMIN :: 0x0407 +TTM_RELAYEVENT :: 0x0407 +CBEM_SETEXSTYLE :: 0x0408 +PBM_GETPOS :: 0x0408 +RB_HITTEST :: 0x0408 +SB_SETMINHEIGHT :: 0x0408 +TBM_SETRANGEMAX :: 0x0408 +TTM_GETTOOLINFOA :: 0x0408 +CBEM_GETEXSTYLE :: 0x0409 +CBEM_GETEXTENDEDSTYLE :: 0x0409 +PBM_SETBARCOLOR :: 0x0409 +RB_GETRECT :: 0x0409 +SB_SIMPLE :: 0x0409 +TB_ISBUTTONENABLED :: 0x0409 +TBM_CLEARTICS :: 0x0409 +TTM_SETTOOLINFOA :: 0x0409 +CBEM_HASEDITCHANGED :: 0x040a +RB_INSERTBANDW :: 0x040a +SB_GETRECT :: 0x040a +TB_ISBUTTONCHECKED :: 0x040a +TBM_SETSEL :: 0x040a +TTM_HITTESTA :: 0x040a +WIZ_QUERYNUMPAGES :: 0x040a +CBEM_INSERTITEMW :: 0x040b +RB_SETBANDINFOW :: 0x040b +SB_SETTEXTW :: 0x040b +TB_ISBUTTONPRESSED :: 0x040b +TBM_SETSELSTART :: 0x040b +TTM_GETTEXTA :: 0x040b +WIZ_NEXT :: 0x040b +CBEM_SETITEMW :: 0x040c +RB_GETBANDCOUNT :: 0x040c +SB_GETTEXTLENGTHW :: 0x040c +TB_ISBUTTONHIDDEN :: 0x040c +TBM_SETSELEND :: 0x040c +TTM_UPDATETIPTEXTA :: 0x040c +WIZ_PREV :: 0x040c +CBEM_GETITEMW :: 0x040d +RB_GETROWCOUNT :: 0x040d +SB_GETTEXTW :: 0x040d +TB_ISBUTTONINDETERMINATE :: 0x040d +TTM_GETTOOLCOUNT :: 0x040d +CBEM_SETEXTENDEDSTYLE :: 0x040e +RB_GETROWHEIGHT :: 0x040e +SB_ISSIMPLE :: 0x040e +TB_ISBUTTONHIGHLIGHTED :: 0x040e +TBM_GETPTICS :: 0x040e +TTM_ENUMTOOLSA :: 0x040e +SB_SETICON :: 0x040f +TBM_GETTICPOS :: 0x040f +TTM_GETCURRENTTOOLA :: 0x040f +RB_IDTOINDEX :: 0x0410 +SB_SETTIPTEXTA :: 0x0410 +TBM_GETNUMTICS :: 0x0410 +TTM_WINDOWFROMPOINT :: 0x0410 +RB_GETTOOLTIPS :: 0x0411 +SB_SETTIPTEXTW :: 0x0411 +TBM_GETSELSTART :: 0x0411 +TB_SETSTATE :: 0x0411 +TTM_TRACKACTIVATE :: 0x0411 +RB_SETTOOLTIPS :: 0x0412 +SB_GETTIPTEXTA :: 0x0412 +TB_GETSTATE :: 0x0412 +TBM_GETSELEND :: 0x0412 +TTM_TRACKPOSITION :: 0x0412 +RB_SETBKCOLOR :: 0x0413 +SB_GETTIPTEXTW :: 0x0413 +TB_ADDBITMAP :: 0x0413 +TBM_CLEARSEL :: 0x0413 +TTM_SETTIPBKCOLOR :: 0x0413 +RB_GETBKCOLOR :: 0x0414 +SB_GETICON :: 0x0414 +TB_ADDBUTTONSA :: 0x0414 +TBM_SETTICFREQ :: 0x0414 +TTM_SETTIPTEXTCOLOR :: 0x0414 +RB_SETTEXTCOLOR :: 0x0415 +TB_INSERTBUTTONA :: 0x0415 +TBM_SETPAGESIZE :: 0x0415 +TTM_GETDELAYTIME :: 0x0415 +RB_GETTEXTCOLOR :: 0x0416 +TB_DELETEBUTTON :: 0x0416 +TBM_GETPAGESIZE :: 0x0416 +TTM_GETTIPBKCOLOR :: 0x0416 +RB_SIZETORECT :: 0x0417 +TB_GETBUTTON :: 0x0417 +TBM_SETLINESIZE :: 0x0417 +TTM_GETTIPTEXTCOLOR :: 0x0417 +RB_BEGINDRAG :: 0x0418 +TB_BUTTONCOUNT :: 0x0418 +TBM_GETLINESIZE :: 0x0418 +TTM_SETMAXTIPWIDTH :: 0x0418 +RB_ENDDRAG :: 0x0419 +TB_COMMANDTOINDEX :: 0x0419 +TBM_GETTHUMBRECT :: 0x0419 +TTM_GETMAXTIPWIDTH :: 0x0419 +RB_DRAGMOVE :: 0x041a +TBM_GETCHANNELRECT :: 0x041a +TB_SAVERESTOREA :: 0x041a +TTM_SETMARGIN :: 0x041a +RB_GETBARHEIGHT :: 0x041b +TB_CUSTOMIZE :: 0x041b +TBM_SETTHUMBLENGTH :: 0x041b +TTM_GETMARGIN :: 0x041b +RB_GETBANDINFOW :: 0x041c +TB_ADDSTRINGA :: 0x041c +TBM_GETTHUMBLENGTH :: 0x041c +TTM_POP :: 0x041c +RB_GETBANDINFOA :: 0x041d +TB_GETITEMRECT :: 0x041d +TBM_SETTOOLTIPS :: 0x041d +TTM_UPDATE :: 0x041d +RB_MINIMIZEBAND :: 0x041e +TB_BUTTONSTRUCTSIZE :: 0x041e +TBM_GETTOOLTIPS :: 0x041e +TTM_GETBUBBLESIZE :: 0x041e +RB_MAXIMIZEBAND :: 0x041f +TBM_SETTIPSIDE :: 0x041f +TB_SETBUTTONSIZE :: 0x041f +TTM_ADJUSTRECT :: 0x041f +TBM_SETBUDDY :: 0x0420 +TB_SETBITMAPSIZE :: 0x0420 +TTM_SETTITLEA :: 0x0420 +MSG_FTS_JUMP_VA :: 0x0421 +TB_AUTOSIZE :: 0x0421 +TBM_GETBUDDY :: 0x0421 +TTM_SETTITLEW :: 0x0421 +RB_GETBANDBORDERS :: 0x0422 +MSG_FTS_JUMP_QWORD :: 0x0423 +RB_SHOWBAND :: 0x0423 +TB_GETTOOLTIPS :: 0x0423 +MSG_REINDEX_REQUEST :: 0x0424 +TB_SETTOOLTIPS :: 0x0424 +MSG_FTS_WHERE_IS_IT :: 0x0425 +RB_SETPALETTE :: 0x0425 +TB_SETPARENT :: 0x0425 +RB_GETPALETTE :: 0x0426 +RB_MOVEBAND :: 0x0427 +TB_SETROWS :: 0x0427 +TB_GETROWS :: 0x0428 +TB_GETBITMAPFLAGS :: 0x0429 +TB_SETCMDID :: 0x042a +RB_PUSHCHEVRON :: 0x042b +TB_CHANGEBITMAP :: 0x042b +TB_GETBITMAP :: 0x042c +MSG_GET_DEFFONT :: 0x042d +TB_GETBUTTONTEXTA :: 0x042d +TB_REPLACEBITMAP :: 0x042e +TB_SETINDENT :: 0x042f +TB_SETIMAGELIST :: 0x0430 +TB_GETIMAGELIST :: 0x0431 +TB_LOADIMAGES :: 0x0432 +EM_CANPASTE :: 0x0432 +TTM_ADDTOOLW :: 0x0432 +EM_DISPLAYBAND :: 0x0433 +TB_GETRECT :: 0x0433 +TTM_DELTOOLW :: 0x0433 +EM_EXGETSEL :: 0x0434 +TB_SETHOTIMAGELIST :: 0x0434 +TTM_NEWTOOLRECTW :: 0x0434 +EM_EXLIMITTEXT :: 0x0435 +TB_GETHOTIMAGELIST :: 0x0435 +TTM_GETTOOLINFOW :: 0x0435 +EM_EXLINEFROMCHAR :: 0x0436 +TB_SETDISABLEDIMAGELIST :: 0x0436 +TTM_SETTOOLINFOW :: 0x0436 +EM_EXSETSEL :: 0x0437 +TB_GETDISABLEDIMAGELIST :: 0x0437 +TTM_HITTESTW :: 0x0437 +EM_FINDTEXT :: 0x0438 +TB_SETSTYLE :: 0x0438 +TTM_GETTEXTW :: 0x0438 +EM_FORMATRANGE :: 0x0439 +TB_GETSTYLE :: 0x0439 +TTM_UPDATETIPTEXTW :: 0x0439 +EM_GETCHARFORMAT :: 0x043a +TB_GETBUTTONSIZE :: 0x043a +TTM_ENUMTOOLSW :: 0x043a +EM_GETEVENTMASK :: 0x043b +TB_SETBUTTONWIDTH :: 0x043b +TTM_GETCURRENTTOOLW :: 0x043b +EM_GETOLEINTERFACE :: 0x043c +TB_SETMAXTEXTROWS :: 0x043c +EM_GETPARAFORMAT :: 0x043d +TB_GETTEXTROWS :: 0x043d +EM_GETSELTEXT :: 0x043e +TB_GETOBJECT :: 0x043e +EM_HIDESELECTION :: 0x043f +TB_GETBUTTONINFOW :: 0x043f +EM_PASTESPECIAL :: 0x0440 +TB_SETBUTTONINFOW :: 0x0440 +EM_REQUESTRESIZE :: 0x0441 +TB_GETBUTTONINFOA :: 0x0441 +EM_SELECTIONTYPE :: 0x0442 +TB_SETBUTTONINFOA :: 0x0442 +EM_SETBKGNDCOLOR :: 0x0443 +TB_INSERTBUTTONW :: 0x0443 +EM_SETCHARFORMAT :: 0x0444 +TB_ADDBUTTONSW :: 0x0444 +EM_SETEVENTMASK :: 0x0445 +TB_HITTEST :: 0x0445 +EM_SETOLECALLBACK :: 0x0446 +TB_SETDRAWTEXTFLAGS :: 0x0446 +EM_SETPARAFORMAT :: 0x0447 +TB_GETHOTITEM :: 0x0447 +EM_SETTARGETDEVICE :: 0x0448 +TB_SETHOTITEM :: 0x0448 +EM_STREAMIN :: 0x0449 +TB_SETANCHORHIGHLIGHT :: 0x0449 +EM_STREAMOUT :: 0x044a +TB_GETANCHORHIGHLIGHT :: 0x044a +EM_GETTEXTRANGE :: 0x044b +TB_GETBUTTONTEXTW :: 0x044b +EM_FINDWORDBREAK :: 0x044c +TB_SAVERESTOREW :: 0x044c +EM_SETOPTIONS :: 0x044d +TB_ADDSTRINGW :: 0x044d +EM_GETOPTIONS :: 0x044e +TB_MAPACCELERATORA :: 0x044e +EM_FINDTEXTEX :: 0x044f +TB_GETINSERTMARK :: 0x044f +EM_GETWORDBREAKPROCEX :: 0x0450 +TB_SETINSERTMARK :: 0x0450 +EM_SETWORDBREAKPROCEX :: 0x0451 +TB_INSERTMARKHITTEST :: 0x0451 +EM_SETUNDOLIMIT :: 0x0452 +TB_MOVEBUTTON :: 0x0452 +TB_GETMAXSIZE :: 0x0453 +EM_REDO :: 0x0454 +TB_SETEXTENDEDSTYLE :: 0x0454 +EM_CANREDO :: 0x0455 +TB_GETEXTENDEDSTYLE :: 0x0455 +EM_GETUNDONAME :: 0x0456 +TB_GETPADDING :: 0x0456 +EM_GETREDONAME :: 0x0457 +TB_SETPADDING :: 0x0457 +EM_STOPGROUPTYPING :: 0x0458 +TB_SETINSERTMARKCOLOR :: 0x0458 +EM_SETTEXTMODE :: 0x0459 +TB_GETINSERTMARKCOLOR :: 0x0459 +EM_GETTEXTMODE :: 0x045a +TB_MAPACCELERATORW :: 0x045a +EM_AUTOURLDETECT :: 0x045b +TB_GETSTRINGW :: 0x045b +EM_GETAUTOURLDETECT :: 0x045c +TB_GETSTRINGA :: 0x045c +EM_SETPALETTE :: 0x045d +EM_GETTEXTEX :: 0x045e +EM_GETTEXTLENGTHEX :: 0x045f +EM_SHOWSCROLLBAR :: 0x0460 +EM_SETTEXTEX :: 0x0461 +TAPI_REPLY :: 0x0463 +ACM_OPENA :: 0x0464 +BFFM_SETSTATUSTEXTA :: 0x0464 +CDM_FIRST :: 0x0464 +CDM_GETSPEC :: 0x0464 +EM_SETPUNCTUATION :: 0x0464 +IPM_CLEARADDRESS :: 0x0464 +WM_CAP_UNICODE_START :: 0x0464 +ACM_PLAY :: 0x0465 +BFFM_ENABLEOK :: 0x0465 +CDM_GETFILEPATH :: 0x0465 +EM_GETPUNCTUATION :: 0x0465 +IPM_SETADDRESS :: 0x0465 +PSM_SETCURSEL :: 0x0465 +UDM_SETRANGE :: 0x0465 +WM_CHOOSEFONT_SETLOGFONT :: 0x0465 +ACM_STOP :: 0x0466 +BFFM_SETSELECTIONA :: 0x0466 +CDM_GETFOLDERPATH :: 0x0466 +EM_SETWORDWRAPMODE :: 0x0466 +IPM_GETADDRESS :: 0x0466 +PSM_REMOVEPAGE :: 0x0466 +UDM_GETRANGE :: 0x0466 +WM_CAP_SET_CALLBACK_ERRORW :: 0x0466 +WM_CHOOSEFONT_SETFLAGS :: 0x0466 +ACM_OPENW :: 0x0467 +BFFM_SETSELECTIONW :: 0x0467 +CDM_GETFOLDERIDLIST :: 0x0467 +EM_GETWORDWRAPMODE :: 0x0467 +IPM_SETRANGE :: 0x0467 +PSM_ADDPAGE :: 0x0467 +UDM_SETPOS :: 0x0467 +WM_CAP_SET_CALLBACK_STATUSW :: 0x0467 +BFFM_SETSTATUSTEXTW :: 0x0468 +CDM_SETCONTROLTEXT :: 0x0468 +EM_SETIMECOLOR :: 0x0468 +IPM_SETFOCUS :: 0x0468 +PSM_CHANGED :: 0x0468 +UDM_GETPOS :: 0x0468 +CDM_HIDECONTROL :: 0x0469 +EM_GETIMECOLOR :: 0x0469 +IPM_ISBLANK :: 0x0469 +PSM_RESTARTWINDOWS :: 0x0469 +UDM_SETBUDDY :: 0x0469 +CDM_SETDEFEXT :: 0x046a +EM_SETIMEOPTIONS :: 0x046a +PSM_REBOOTSYSTEM :: 0x046a +UDM_GETBUDDY :: 0x046a +EM_GETIMEOPTIONS :: 0x046b +PSM_CANCELTOCLOSE :: 0x046b +UDM_SETACCEL :: 0x046b +EM_CONVPOSITION :: 0x046c +PSM_QUERYSIBLINGS :: 0x046c +UDM_GETACCEL :: 0x046c +MCIWNDM_GETZOOM :: 0x046d +PSM_UNCHANGED :: 0x046d +UDM_SETBASE :: 0x046d +PSM_APPLY :: 0x046e +UDM_GETBASE :: 0x046e +PSM_SETTITLEA :: 0x046f +UDM_SETRANGE32 :: 0x046f +PSM_SETWIZBUTTONS :: 0x0470 +UDM_GETRANGE32 :: 0x0470 +WM_CAP_DRIVER_GET_NAMEW :: 0x0470 +PSM_PRESSBUTTON :: 0x0471 +UDM_SETPOS32 :: 0x0471 +WM_CAP_DRIVER_GET_VERSIONW :: 0x0471 +PSM_SETCURSELID :: 0x0472 +UDM_GETPOS32 :: 0x0472 +PSM_SETFINISHTEXTA :: 0x0473 +PSM_GETTABCONTROL :: 0x0474 +PSM_ISDIALOGMESSAGE :: 0x0475 +MCIWNDM_REALIZE :: 0x0476 +PSM_GETCURRENTPAGEHWND :: 0x0476 +MCIWNDM_SETTIMEFORMATA :: 0x0477 +PSM_INSERTPAGE :: 0x0477 +EM_SETLANGOPTIONS :: 0x0478 +MCIWNDM_GETTIMEFORMATA :: 0x0478 +PSM_SETTITLEW :: 0x0478 +WM_CAP_FILE_SET_CAPTURE_FILEW :: 0x0478 +EM_GETLANGOPTIONS :: 0x0479 +MCIWNDM_VALIDATEMEDIA :: 0x0479 +PSM_SETFINISHTEXTW :: 0x0479 +WM_CAP_FILE_GET_CAPTURE_FILEW :: 0x0479 +EM_GETIMECOMPMODE :: 0x047a +EM_FINDTEXTW :: 0x047b +MCIWNDM_PLAYTO :: 0x047b +WM_CAP_FILE_SAVEASW :: 0x047b +EM_FINDTEXTEXW :: 0x047c +MCIWNDM_GETFILENAMEA :: 0x047c +EM_RECONVERSION :: 0x047d +MCIWNDM_GETDEVICEA :: 0x047d +PSM_SETHEADERTITLEA :: 0x047d +WM_CAP_FILE_SAVEDIBW :: 0x047d +EM_SETIMEMODEBIAS :: 0x047e +MCIWNDM_GETPALETTE :: 0x047e +PSM_SETHEADERTITLEW :: 0x047e +EM_GETIMEMODEBIAS :: 0x047f +MCIWNDM_SETPALETTE :: 0x047f +PSM_SETHEADERSUBTITLEA :: 0x047f +MCIWNDM_GETERRORA :: 0x0480 +PSM_SETHEADERSUBTITLEW :: 0x0480 +PSM_HWNDTOINDEX :: 0x0481 +PSM_INDEXTOHWND :: 0x0482 +MCIWNDM_SETINACTIVETIMER :: 0x0483 +PSM_PAGETOINDEX :: 0x0483 +PSM_INDEXTOPAGE :: 0x0484 +DL_BEGINDRAG :: 0x0485 +MCIWNDM_GETINACTIVETIMER :: 0x0485 +PSM_IDTOINDEX :: 0x0485 +DL_DRAGGING :: 0x0486 +PSM_INDEXTOID :: 0x0486 +DL_DROPPED :: 0x0487 +PSM_GETRESULT :: 0x0487 +DL_CANCELDRAG :: 0x0488 +PSM_RECALCPAGESIZES :: 0x0488 +MCIWNDM_GET_SOURCE :: 0x048c +MCIWNDM_PUT_SOURCE :: 0x048d +MCIWNDM_GET_DEST :: 0x048e +MCIWNDM_PUT_DEST :: 0x048f +MCIWNDM_CAN_PLAY :: 0x0490 +MCIWNDM_CAN_WINDOW :: 0x0491 +MCIWNDM_CAN_RECORD :: 0x0492 +MCIWNDM_CAN_SAVE :: 0x0493 +MCIWNDM_CAN_EJECT :: 0x0494 +MCIWNDM_CAN_CONFIG :: 0x0495 +IE_GETINK :: 0x0496 +IE_MSGFIRST :: 0x0496 +MCIWNDM_PALETTEKICK :: 0x0496 +IE_SETINK :: 0x0497 +IE_GETPENTIP :: 0x0498 +IE_SETPENTIP :: 0x0499 +IE_GETERASERTIP :: 0x049a +IE_SETERASERTIP :: 0x049b +IE_GETBKGND :: 0x049c +IE_SETBKGND :: 0x049d +IE_GETGRIDORIGIN :: 0x049e +IE_SETGRIDORIGIN :: 0x049f +IE_GETGRIDPEN :: 0x04a0 +IE_SETGRIDPEN :: 0x04a1 +IE_GETGRIDSIZE :: 0x04a2 +IE_SETGRIDSIZE :: 0x04a3 +IE_GETMODE :: 0x04a4 +IE_SETMODE :: 0x04a5 +IE_GETINKRECT :: 0x04a6 +WM_CAP_SET_MCI_DEVICEW :: 0x04a6 +WM_CAP_GET_MCI_DEVICEW :: 0x04a7 +WM_CAP_PAL_OPENW :: 0x04b4 +WM_CAP_PAL_SAVEW :: 0x04b5 +IE_GETAPPDATA :: 0x04b8 +IE_SETAPPDATA :: 0x04b9 +IE_GETDRAWOPTS :: 0x04ba +IE_SETDRAWOPTS :: 0x04bb +IE_GETFORMAT :: 0x04bc +IE_SETFORMAT :: 0x04bd +IE_GETINKINPUT :: 0x04be +IE_SETINKINPUT :: 0x04bf +IE_GETNOTIFY :: 0x04c0 +IE_SETNOTIFY :: 0x04c1 +IE_GETRECOG :: 0x04c2 +IE_SETRECOG :: 0x04c3 +IE_GETSECURITY :: 0x04c4 +IE_SETSECURITY :: 0x04c5 +IE_GETSEL :: 0x04c6 +IE_SETSEL :: 0x04c7 +CDM_LAST :: 0x04c8 +EM_SETBIDIOPTIONS :: 0x04c8 +IE_DOCOMMAND :: 0x04c8 +MCIWNDM_NOTIFYMODE :: 0x04c8 +EM_GETBIDIOPTIONS :: 0x04c9 +IE_GETCOMMAND :: 0x04c9 +EM_SETTYPOGRAPHYOPTIONS :: 0x04ca +IE_GETCOUNT :: 0x04ca +EM_GETTYPOGRAPHYOPTIONS :: 0x04cb +IE_GETGESTURE :: 0x04cb +MCIWNDM_NOTIFYMEDIA :: 0x04cb +EM_SETEDITSTYLE :: 0x04cc +IE_GETMENU :: 0x04cc +EM_GETEDITSTYLE :: 0x04cd +IE_GETPAINTDC :: 0x04cd +MCIWNDM_NOTIFYERROR :: 0x04cd +IE_GETPDEVENT :: 0x04ce +IE_GETSELCOUNT :: 0x04cf +IE_GETSELITEMS :: 0x04d0 +IE_GETSTYLE :: 0x04d1 +MCIWNDM_SETTIMEFORMATW :: 0x04db +EM_OUTLINE :: 0x04dc +MCIWNDM_GETTIMEFORMATW :: 0x04dc +EM_GETSCROLLPOS :: 0x04dd +EM_SETSCROLLPOS :: 0x04de +EM_SETFONTSIZE :: 0x04df +EM_GETZOOM :: 0x04e0 +MCIWNDM_GETFILENAMEW :: 0x04e0 +EM_SETZOOM :: 0x04e1 +MCIWNDM_GETDEVICEW :: 0x04e1 +EM_GETVIEWKIND :: 0x04e2 +EM_SETVIEWKIND :: 0x04e3 +EM_GETPAGE :: 0x04e4 +MCIWNDM_GETERRORW :: 0x04e4 +EM_SETPAGE :: 0x04e5 +EM_GETHYPHENATEINFO :: 0x04e6 +EM_SETHYPHENATEINFO :: 0x04e7 +EM_GETPAGEROTATE :: 0x04eb +EM_SETPAGEROTATE :: 0x04ec +EM_GETCTFMODEBIAS :: 0x04ed +EM_SETCTFMODEBIAS :: 0x04ee +EM_GETCTFOPENSTATUS :: 0x04f0 +EM_SETCTFOPENSTATUS :: 0x04f1 +EM_GETIMECOMPTEXT :: 0x04f2 +EM_ISIME :: 0x04f3 +EM_GETIMEPROPERTY :: 0x04f4 +EM_GETQUERYRTFOBJ :: 0x050d +EM_SETQUERYRTFOBJ :: 0x050e +FM_GETFOCUS :: 0x0600 +FM_GETDRIVEINFOA :: 0x0601 +FM_GETSELCOUNT :: 0x0602 +FM_GETSELCOUNTLFN :: 0x0603 +FM_GETFILESELA :: 0x0604 +FM_GETFILESELLFNA :: 0x0605 +FM_REFRESH_WINDOWS :: 0x0606 +FM_RELOAD_EXTENSIONS :: 0x0607 +FM_GETDRIVEINFOW :: 0x0611 +FM_GETFILESELW :: 0x0614 +FM_GETFILESELLFNW :: 0x0615 +WLX_WM_SAS :: 0x0659 +SM_GETSELCOUNT :: 0x07e8 +UM_GETSELCOUNT :: 0x07e8 +WM_CPL_LAUNCH :: 0x07e8 +SM_GETSERVERSELA :: 0x07e9 +UM_GETUSERSELA :: 0x07e9 +WM_CPL_LAUNCHED :: 0x07e9 +SM_GETSERVERSELW :: 0x07ea +UM_GETUSERSELW :: 0x07ea +SM_GETCURFOCUSA :: 0x07eb +UM_GETGROUPSELA :: 0x07eb +SM_GETCURFOCUSW :: 0x07ec +UM_GETGROUPSELW :: 0x07ec +SM_GETOPTIONS :: 0x07ed +UM_GETCURFOCUSA :: 0x07ed +UM_GETCURFOCUSW :: 0x07ee +UM_GETOPTIONS :: 0x07ef +UM_GETOPTIONS2 :: 0x07f0 +LVM_FIRST :: 0x1000 +LVM_GETBKCOLOR :: 0x1000 +LVM_SETBKCOLOR :: 0x1001 +LVM_GETIMAGELIST :: 0x1002 +LVM_SETIMAGELIST :: 0x1003 +LVM_GETITEMCOUNT :: 0x1004 +LVM_GETITEMA :: 0x1005 +LVM_SETITEMA :: 0x1006 +LVM_INSERTITEMA :: 0x1007 +LVM_DELETEITEM :: 0x1008 +LVM_DELETEALLITEMS :: 0x1009 +LVM_GETCALLBACKMASK :: 0x100a +LVM_SETCALLBACKMASK :: 0x100b +LVM_GETNEXTITEM :: 0x100c +LVM_FINDITEMA :: 0x100d +LVM_GETITEMRECT :: 0x100e +LVM_SETITEMPOSITION :: 0x100f +LVM_GETITEMPOSITION :: 0x1010 +LVM_GETSTRINGWIDTHA :: 0x1011 +LVM_HITTEST :: 0x1012 +LVM_ENSUREVISIBLE :: 0x1013 +LVM_SCROLL :: 0x1014 +LVM_REDRAWITEMS :: 0x1015 +LVM_ARRANGE :: 0x1016 +LVM_EDITLABELA :: 0x1017 +LVM_GETEDITCONTROL :: 0x1018 +LVM_GETCOLUMNA :: 0x1019 +LVM_SETCOLUMNA :: 0x101a +LVM_INSERTCOLUMNA :: 0x101b +LVM_DELETECOLUMN :: 0x101c +LVM_GETCOLUMNWIDTH :: 0x101d +LVM_SETCOLUMNWIDTH :: 0x101e +LVM_GETHEADER :: 0x101f +LVM_CREATEDRAGIMAGE :: 0x1021 +LVM_GETVIEWRECT :: 0x1022 +LVM_GETTEXTCOLOR :: 0x1023 +LVM_SETTEXTCOLOR :: 0x1024 +LVM_GETTEXTBKCOLOR :: 0x1025 +LVM_SETTEXTBKCOLOR :: 0x1026 +LVM_GETTOPINDEX :: 0x1027 +LVM_GETCOUNTPERPAGE :: 0x1028 +LVM_GETORIGIN :: 0x1029 +LVM_UPDATE :: 0x102a +LVM_SETITEMSTATE :: 0x102b +LVM_GETITEMSTATE :: 0x102c +LVM_GETITEMTEXTA :: 0x102d +LVM_SETITEMTEXTA :: 0x102e +LVM_SETITEMCOUNT :: 0x102f +LVM_SORTITEMS :: 0x1030 +LVM_SETITEMPOSITION32 :: 0x1031 +LVM_GETSELECTEDCOUNT :: 0x1032 +LVM_GETITEMSPACING :: 0x1033 +LVM_GETISEARCHSTRINGA :: 0x1034 +LVM_SETICONSPACING :: 0x1035 +LVM_SETEXTENDEDLISTVIEWSTYLE :: 0x1036 +LVM_GETEXTENDEDLISTVIEWSTYLE :: 0x1037 +LVM_GETSUBITEMRECT :: 0x1038 +LVM_SUBITEMHITTEST :: 0x1039 +LVM_SETCOLUMNORDERARRAY :: 0x103a +LVM_GETCOLUMNORDERARRAY :: 0x103b +LVM_SETHOTITEM :: 0x103c +LVM_GETHOTITEM :: 0x103d +LVM_SETHOTCURSOR :: 0x103e +LVM_GETHOTCURSOR :: 0x103f +LVM_APPROXIMATEVIEWRECT :: 0x1040 +LVM_SETWORKAREAS :: 0x1041 +LVM_GETSELECTIONMARK :: 0x1042 +LVM_SETSELECTIONMARK :: 0x1043 +LVM_SETBKIMAGEA :: 0x1044 +LVM_GETBKIMAGEA :: 0x1045 +LVM_GETWORKAREAS :: 0x1046 +LVM_SETHOVERTIME :: 0x1047 +LVM_GETHOVERTIME :: 0x1048 +LVM_GETNUMBEROFWORKAREAS :: 0x1049 +LVM_SETTOOLTIPS :: 0x104a +LVM_GETITEMW :: 0x104b +LVM_SETITEMW :: 0x104c +LVM_INSERTITEMW :: 0x104d +LVM_GETTOOLTIPS :: 0x104e +LVM_FINDITEMW :: 0x1053 +LVM_GETSTRINGWIDTHW :: 0x1057 +LVM_GETCOLUMNW :: 0x105f +LVM_SETCOLUMNW :: 0x1060 +LVM_INSERTCOLUMNW :: 0x1061 +LVM_GETITEMTEXTW :: 0x1073 +LVM_SETITEMTEXTW :: 0x1074 +LVM_GETISEARCHSTRINGW :: 0x1075 +LVM_EDITLABELW :: 0x1076 +LVM_GETBKIMAGEW :: 0x108b +LVM_SETSELECTEDCOLUMN :: 0x108c +LVM_SETTILEWIDTH :: 0x108d +LVM_SETVIEW :: 0x108e +LVM_GETVIEW :: 0x108f +LVM_INSERTGROUP :: 0x1091 +LVM_SETGROUPINFO :: 0x1093 +LVM_GETGROUPINFO :: 0x1095 +LVM_REMOVEGROUP :: 0x1096 +LVM_MOVEGROUP :: 0x1097 +LVM_MOVEITEMTOGROUP :: 0x109a +LVM_SETGROUPMETRICS :: 0x109b +LVM_GETGROUPMETRICS :: 0x109c +LVM_ENABLEGROUPVIEW :: 0x109d +LVM_SORTGROUPS :: 0x109e +LVM_INSERTGROUPSORTED :: 0x109f +LVM_REMOVEALLGROUPS :: 0x10a0 +LVM_HASGROUP :: 0x10a1 +LVM_SETTILEVIEWINFO :: 0x10a2 +LVM_GETTILEVIEWINFO :: 0x10a3 +LVM_SETTILEINFO :: 0x10a4 +LVM_GETTILEINFO :: 0x10a5 +LVM_SETINSERTMARK :: 0x10a6 +LVM_GETINSERTMARK :: 0x10a7 +LVM_INSERTMARKHITTEST :: 0x10a8 +LVM_GETINSERTMARKRECT :: 0x10a9 +LVM_SETINSERTMARKCOLOR :: 0x10aa +LVM_GETINSERTMARKCOLOR :: 0x10ab +LVM_SETINFOTIP :: 0x10ad +LVM_GETSELECTEDCOLUMN :: 0x10ae +LVM_ISGROUPVIEWENABLED :: 0x10af +LVM_GETOUTLINECOLOR :: 0x10b0 +LVM_SETOUTLINECOLOR :: 0x10b1 +LVM_CANCELEDITLABEL :: 0x10b3 +LVM_MAPINDEXTOID :: 0x10b4 +LVM_MAPIDTOINDEX :: 0x10b5 +LVM_ISITEMVISIBLE :: 0x10b6 +LVM_GETEMPTYTEXT :: 0x10cc +LVM_GETFOOTERRECT :: 0x10cd +LVM_GETFOOTERINFO :: 0x10ce +LVM_GETFOOTERITEMRECT :: 0x10cf +LVM_GETFOOTERITEM :: 0x10d0 +LVM_GETITEMINDEXRECT :: 0x10d1 +LVM_SETITEMINDEXSTATE :: 0x10d2 +LVM_GETNEXTITEMINDEX :: 0x10d3 +OCM__BASE :: 0x2000 +LVM_SETUNICODEFORMAT :: 0x2005 +LVM_GETUNICODEFORMAT :: 0x2006 +OCM_CTLCOLOR :: 0x2019 +OCM_DRAWITEM :: 0x202b +OCM_MEASUREITEM :: 0x202c +OCM_DELETEITEM :: 0x202d +OCM_VKEYTOITEM :: 0x202e +OCM_CHARTOITEM :: 0x202f +OCM_COMPAREITEM :: 0x2039 +OCM_NOTIFY :: 0x204e +OCM_COMMAND :: 0x2111 +OCM_HSCROLL :: 0x2114 +OCM_VSCROLL :: 0x2115 +OCM_CTLCOLORMSGBOX :: 0x2132 +OCM_CTLCOLOREDIT :: 0x2133 +OCM_CTLCOLORLISTBOX :: 0x2134 +OCM_CTLCOLORBTN :: 0x2135 +OCM_CTLCOLORDLG :: 0x2136 +OCM_CTLCOLORSCROLLBAR :: 0x2137 +OCM_CTLCOLORSTATIC :: 0x2138 +OCM_PARENTNOTIFY :: 0x2210 +WM_APP :: 0x8000 +WM_RASDIALEVENT :: 0xcccd diff --git a/core/sys/windows/winmm.odin b/core/sys/windows/winmm.odin new file mode 100644 index 000000000..9edd56acc --- /dev/null +++ b/core/sys/windows/winmm.odin @@ -0,0 +1,10 @@ +// +build windows +package sys_windows + +foreign import winmm "system:Winmm.lib" + +@(default_calling_convention="stdcall") +foreign winmm { + timeBeginPeriod :: proc(uPeriod: UINT) -> MMRESULT --- + timeEndPeriod :: proc(uPeriod: UINT) -> MMRESULT --- +} diff --git a/core/testing/runner_other.odin b/core/testing/runner_other.odin index 3978a3c83..f3271d209 100644 --- a/core/testing/runner_other.odin +++ b/core/testing/runner_other.odin @@ -6,7 +6,7 @@ import "core:time" run_internal_test :: proc(t: ^T, it: Internal_Test) { // TODO(bill): Catch panics on other platforms - it.p(t); + it.p(t) } _fail_timeout :: proc(t: ^T, duration: time.Duration, loc := #caller_location) { diff --git a/core/testing/runner_windows.odin b/core/testing/runner_windows.odin index 560f23956..e812c410a 100644 --- a/core/testing/runner_windows.odin +++ b/core/testing/runner_windows.odin @@ -21,7 +21,7 @@ sema_wait :: proc "contextless" (s: ^Sema) { win32.WaitOnAddress(&s.count, &original_count, size_of(original_count), win32.INFINITE) original_count = s.count } - if original_count == intrinsics.atomic_cxchg(&s.count, original_count-1, original_count) { + if original_count == intrinsics.atomic_compare_exchange_strong(&s.count, original_count-1, original_count) { return } } @@ -46,7 +46,7 @@ sema_wait_with_timeout :: proc "contextless" (s: ^Sema, duration: time.Duration) } original_count = s.count } - if original_count == intrinsics.atomic_cxchg(&s.count, original_count-1, original_count) { + if original_count == intrinsics.atomic_compare_exchange_strong(&s.count, original_count-1, original_count) { return true } } diff --git a/core/thread/thread_pool.odin b/core/thread/thread_pool.odin index 37ee4fa98..af80da9aa 100644 --- a/core/thread/thread_pool.odin +++ b/core/thread/thread_pool.odin @@ -1,67 +1,75 @@ package thread +/* + thread.Pool + Copyright 2022 eisbehr + Made available under Odin's BSD-3 license. +*/ + import "core:intrinsics" import "core:sync" import "core:mem" -Task_Status :: enum i32 { - Ready, - Busy, - Waiting, - Term, -} - -Task_Proc :: #type proc(task: ^Task) +Task_Proc :: #type proc(task: Task) Task :: struct { - procedure: Task_Proc, - data: rawptr, + procedure: Task_Proc, + data: rawptr, user_index: int, + allocator: mem.Allocator, } -Task_Id :: distinct i32 -INVALID_TASK_ID :: Task_Id(-1) - - +// Do not access the pool's members directly while the pool threads are running, +// since they use different kinds of locking and mutual exclusion devices. +// Careless access can and will lead to nasty bugs. Once initialized, the +// pool's memory address is not allowed to change until it is destroyed. Pool :: struct { - allocator: mem.Allocator, - mutex: sync.Mutex, - sem_available: sync.Semaphore, - processing_task_count: int, // atomic - is_running: bool, + allocator: mem.Allocator, + mutex: sync.Mutex, + sem_available: sync.Sema, + + // the following values are atomic + num_waiting: int, + num_in_processing: int, + num_outstanding: int, // num_waiting + num_in_processing + num_done: int, + // end of atomics + + is_running: bool, threads: []^Thread, - tasks: [dynamic]Task, + tasks: [dynamic]Task, + tasks_done: [dynamic]Task, } -pool_init :: proc(pool: ^Pool, thread_count: int, allocator := context.allocator) { - worker_thread_internal :: proc(t: ^Thread) { - pool := (^Pool)(t.data) - - for pool.is_running { - sync.semaphore_wait_for(&pool.sem_available) - - if task, ok := pool_try_and_pop_task(pool); ok { - pool_do_work(pool, &task) - } - } - - sync.semaphore_post(&pool.sem_available, 1) - } - - +// Once initialized, the pool's memory address is not allowed to change until +// it is destroyed. +// +// The thread pool requires an allocator which it either owns, or which is thread safe. +pool_init :: proc(pool: ^Pool, allocator: mem.Allocator, thread_count: int) { context.allocator = allocator pool.allocator = allocator - pool.tasks = make([dynamic]Task) - pool.threads = make([]^Thread, thread_count) + pool.tasks = make([dynamic]Task) + pool.tasks_done = make([dynamic]Task) + pool.threads = make([]^Thread, max(thread_count, 1)) - sync.mutex_init(&pool.mutex) - sync.semaphore_init(&pool.sem_available) pool.is_running = true for _, i in pool.threads { - t := create(worker_thread_internal) + t := create(proc(t: ^Thread) { + pool := (^Pool)(t.data) + + for intrinsics.atomic_load(&pool.is_running) { + sync.wait(&pool.sem_available) + + if task, ok := pool_pop_waiting(pool); ok { + pool_do_work(pool, task) + } + } + + sync.post(&pool.sem_available, 1) + }) t.user_index = i t.data = pool pool.threads[i] = t @@ -70,15 +78,13 @@ pool_init :: proc(pool: ^Pool, thread_count: int, allocator := context.allocator pool_destroy :: proc(pool: ^Pool) { delete(pool.tasks) + delete(pool.tasks_done) - for thread in &pool.threads { - destroy(thread) + for t in &pool.threads { + destroy(t) } delete(pool.threads, pool.allocator) - - sync.mutex_destroy(&pool.mutex) - sync.semaphore_destroy(&pool.sem_available) } pool_start :: proc(pool: ^Pool) { @@ -87,10 +93,12 @@ pool_start :: proc(pool: ^Pool) { } } +// Finish tasks that have already started processing, then shut down all pool +// threads. Might leave over waiting tasks, any memory allocated for the +// user data of those tasks will not be freed. pool_join :: proc(pool: ^Pool) { - pool.is_running = false - - sync.semaphore_post(&pool.sem_available, len(pool.threads)) + intrinsics.atomic_store(&pool.is_running, false) + sync.post(&pool.sem_available, len(pool.threads)) yield() @@ -99,53 +107,111 @@ pool_join :: proc(pool: ^Pool) { } } -pool_add_task :: proc(pool: ^Pool, procedure: Task_Proc, data: rawptr, user_index: int = 0) { - sync.mutex_lock(&pool.mutex) - defer sync.mutex_unlock(&pool.mutex) +// Add a task to the thread pool. +// +// Tasks can be added from any thread, not just the thread that created +// the thread pool. You can even add tasks from inside other tasks. +// +// Each task also needs an allocator which it either owns, or which is thread +// safe. +pool_add_task :: proc(pool: ^Pool, allocator: mem.Allocator, procedure: Task_Proc, data: rawptr, user_index: int = 0) { + sync.guard(&pool.mutex) - task: Task - task.procedure = procedure - task.data = data - task.user_index = user_index - - append(&pool.tasks, task) - sync.semaphore_post(&pool.sem_available, 1) + append(&pool.tasks, Task{ + procedure = procedure, + data = data, + user_index = user_index, + allocator = allocator, + }) + intrinsics.atomic_add(&pool.num_waiting, 1) + intrinsics.atomic_add(&pool.num_outstanding, 1) + sync.post(&pool.sem_available, 1) } -pool_try_and_pop_task :: proc(pool: ^Pool) -> (task: Task, got_task: bool = false) { - if sync.mutex_try_lock(&pool.mutex) { - if len(pool.tasks) != 0 { - intrinsics.atomic_add(&pool.processing_task_count, 1) - task = pop_front(&pool.tasks) - got_task = true - } - sync.mutex_unlock(&pool.mutex) +// Number of tasks waiting to be processed. Only informational, mostly for +// debugging. Don't rely on this value being consistent with other num_* +// values. +pool_num_waiting :: #force_inline proc(pool: ^Pool) -> int { + return intrinsics.atomic_load(&pool.num_waiting) +} + +// Number of tasks currently being processed. Only informational, mostly for +// debugging. Don't rely on this value being consistent with other num_* +// values. +pool_num_in_processing :: #force_inline proc(pool: ^Pool) -> int { + return intrinsics.atomic_load(&pool.num_in_processing) +} + +// Outstanding tasks are all tasks that are not done, that is, tasks that are +// waiting, as well as tasks that are currently being processed. Only +// informational, mostly for debugging. Don't rely on this value being +// consistent with other num_* values. +pool_num_outstanding :: #force_inline proc(pool: ^Pool) -> int { + return intrinsics.atomic_load(&pool.num_outstanding) +} + +// Number of tasks which are done processing. Only informational, mostly for +// debugging. Don't rely on this value being consistent with other num_* +// values. +pool_num_done :: #force_inline proc(pool: ^Pool) -> int { + return intrinsics.atomic_load(&pool.num_done) +} + +// If tasks are only being added from one thread, and this procedure is being +// called from that same thread, it will reliably tell if the thread pool is +// empty or not. Empty in this case means there are no tasks waiting, being +// processed, or _done_. +pool_is_empty :: #force_inline proc(pool: ^Pool) -> bool { + return pool_num_outstanding(pool) == 0 && pool_num_done(pool) == 0 +} + +// Mostly for internal use. +pool_pop_waiting :: proc(pool: ^Pool) -> (task: Task, got_task: bool) { + sync.guard(&pool.mutex) + + if len(pool.tasks) != 0 { + intrinsics.atomic_sub(&pool.num_waiting, 1) + intrinsics.atomic_add(&pool.num_in_processing, 1) + task = pop_front(&pool.tasks) + got_task = true } + return } +// Use this to take out finished tasks. +pool_pop_done :: proc(pool: ^Pool) -> (task: Task, got_task: bool) { + sync.guard(&pool.mutex) -pool_do_work :: proc(pool: ^Pool, task: ^Task) { - task.procedure(task) - intrinsics.atomic_sub(&pool.processing_task_count, 1) -} - - -pool_wait_and_process :: proc(pool: ^Pool) { - for len(pool.tasks) != 0 || intrinsics.atomic_load(&pool.processing_task_count) != 0 { - if task, ok := pool_try_and_pop_task(pool); ok { - pool_do_work(pool, &task) - } - - // Safety kick - if len(pool.tasks) != 0 && intrinsics.atomic_load(&pool.processing_task_count) == 0 { - sync.mutex_lock(&pool.mutex) - sync.semaphore_post(&pool.sem_available, len(pool.tasks)) - sync.mutex_unlock(&pool.mutex) - } - - yield() + if len(pool.tasks_done) != 0 { + task = pop_front(&pool.tasks_done) + got_task = true + intrinsics.atomic_sub(&pool.num_done, 1) } + return +} + +// Mostly for internal use. +pool_do_work :: proc(pool: ^Pool, task: Task) { + { + context.allocator = task.allocator + task.procedure(task) + } + + sync.guard(&pool.mutex) + + append(&pool.tasks_done, task) + intrinsics.atomic_add(&pool.num_done, 1) + intrinsics.atomic_sub(&pool.num_outstanding, 1) + intrinsics.atomic_sub(&pool.num_in_processing, 1) +} + +// Process the rest of the tasks, also use this thread for processing, then join +// all the pool threads. +pool_finish :: proc(pool: ^Pool) { + for task in pool_pop_waiting(pool) { + pool_do_work(pool, task) + } pool_join(pool) } diff --git a/core/thread/thread_unix.odin b/core/thread/thread_unix.odin index cee278c7a..8452df112 100644 --- a/core/thread/thread_unix.odin +++ b/core/thread/thread_unix.odin @@ -1,4 +1,4 @@ -// +build linux, darwin, freebsd +// +build linux, darwin, freebsd, openbsd // +private package thread @@ -7,30 +7,19 @@ import "core:intrinsics" import "core:sync" import "core:sys/unix" +Thread_State :: enum u8 { + Started, + Joined, + Done, +} + // NOTE(tetra): Aligned here because of core/unix/pthread_linux.odin/pthread_t. // Also see core/sys/darwin/mach_darwin.odin/semaphore_t. Thread_Os_Specific :: struct #align 16 { unix_thread: unix.pthread_t, // NOTE: very large on Darwin, small on Linux. - - // NOTE: pthread has a proc to query this, but it is marked - // as non-portable ("np") so we do this instead. - done: bool, - - // since libpthread doesn't seem to have a way to create a thread - // in a suspended state, we have it wait on this gate, which we - // signal to start it. - // destroyed after thread is started. - start_gate: sync.Condition, - start_mutex: sync.Mutex, - - // if true, the thread has been started and the start_gate has been destroyed. - started: bool, - - // NOTE: with pthreads, it is undefined behavior for multiple threads - // to call join on the same thread at the same time. - // this value is atomically updated to detect this. - // See the comment in `join`. - already_joined: bool, + cond: sync.Cond, + mutex: sync.Mutex, + flags: bit_set[Thread_State; u8], } // // Creates a thread which will run the given procedure. @@ -38,26 +27,31 @@ Thread_Os_Specific :: struct #align 16 { // _create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^Thread { __linux_thread_entry_proc :: proc "c" (t: rawptr) -> rawptr { - context = runtime.default_context() t := (^Thread)(t) - sync.condition_wait_for(&t.start_gate) - sync.condition_destroy(&t.start_gate) - sync.mutex_destroy(&t.start_mutex) - t.start_gate = {} - t.start_mutex = {} - context = t.init_context.? or_else runtime.default_context() - + context = runtime.default_context() + + sync.lock(&t.mutex) + t.id = sync.current_thread_id() - t.procedure(t) - if t.init_context == nil { - if context.temp_allocator.data == &runtime.global_default_temp_allocator_data { - runtime.default_temp_allocator_destroy(auto_cast context.temp_allocator.data) - } + for (.Started not_in t.flags) { + sync.wait(&t.cond, &t.mutex) + } + + init_context := t.init_context + context = init_context.? or_else runtime.default_context() + + t.procedure(t) + + intrinsics.atomic_store(&t.flags, t.flags + { .Done }) + + sync.unlock(&t.mutex) + + if init_context == nil && context.temp_allocator.data == &runtime.global_default_temp_allocator_data { + runtime.default_temp_allocator_destroy(auto_cast context.temp_allocator.data) } - intrinsics.atomic_store(&t.done, true) return nil } @@ -76,9 +70,6 @@ _create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^ return nil } thread.creation_allocator = context.allocator - - sync.mutex_init(&thread.start_mutex) - sync.condition_init(&thread.start_gate, &thread.start_mutex) // Set thread priority. policy: i32 @@ -97,65 +88,35 @@ _create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^ res = unix.pthread_attr_setschedparam(&attrs, ¶ms) assert(res == 0) + thread.procedure = procedure if unix.pthread_create(&thread.unix_thread, &attrs, __linux_thread_entry_proc, thread) != 0 { free(thread, thread.creation_allocator) - - sync.condition_destroy(&thread.start_gate) - sync.mutex_destroy(&thread.start_mutex) return nil } - thread.procedure = procedure - return thread } _start :: proc(t: ^Thread) { - if intrinsics.atomic_xchg(&t.started, true) { - return - } - sync.condition_signal(&t.start_gate) + sync.guard(&t.mutex) + t.flags += { .Started } + sync.signal(&t.cond) } _is_done :: proc(t: ^Thread) -> bool { - return intrinsics.atomic_load(&t.done) + return .Done in intrinsics.atomic_load(&t.flags) } _join :: proc(t: ^Thread) { - if unix.pthread_equal(unix.pthread_self(), t.unix_thread) { - return - } - // if unix.pthread_self().x == t.unix_thread.x do return; + sync.guard(&t.mutex) - // NOTE(tetra): It's apparently UB for multiple threads to join the same thread - // at the same time. - // If someone else already did, spin until the thread dies. - // See note on `already_joined` field. - // TODO(tetra): I'm not sure if we should do this, or panic, since I'm not - // sure it makes sense to need to join from multiple threads? - if intrinsics.atomic_xchg(&t.already_joined, true) { - for { - if intrinsics.atomic_load(&t.done) { - return - } - intrinsics.cpu_relax() - } - } - - // NOTE(tetra): If we're already dead, don't bother calling to pthread_join as that - // will just return 3 (ESRCH). - // We do this instead because I don't know if there is a danger - // that you may join a different thread from the one you called join on, - // if the thread handle is reused. - if intrinsics.atomic_load(&t.done) { + if .Joined in t.flags || unix.pthread_equal(unix.pthread_self(), t.unix_thread) { return } - ret_val: rawptr - _ = unix.pthread_join(t.unix_thread, &ret_val) - if !intrinsics.atomic_load(&t.done) { - panic("thread not done after join") - } + unix.pthread_join(t.unix_thread, nil) + + t.flags += { .Joined } } _join_multiple :: proc(threads: ..^Thread) { @@ -164,16 +125,12 @@ _join_multiple :: proc(threads: ..^Thread) { } } - _destroy :: proc(t: ^Thread) { _join(t) - sync.condition_destroy(&t.start_gate) - sync.mutex_destroy(&t.start_mutex) t.unix_thread = {} free(t, t.creation_allocator) } - _terminate :: proc(t: ^Thread, exit_code: int) { // TODO(bill) } diff --git a/core/thread/thread_windows.odin b/core/thread/thread_windows.odin index 428e241d0..68382444c 100644 --- a/core/thread/thread_windows.odin +++ b/core/thread/thread_windows.odin @@ -3,13 +3,21 @@ package thread import "core:runtime" -import sync "core:sync/sync2" +import "core:intrinsics" +import "core:sync" import win32 "core:sys/windows" +Thread_State :: enum u8 { + Started, + Joined, + Done, +} + Thread_Os_Specific :: struct { win32_thread: win32.HANDLE, win32_thread_id: win32.DWORD, - done: bool, // see note in `is_done` + mutex: sync.Mutex, + flags: bit_set[Thread_State; u8], } _thread_priority_map := [Thread_Priority]i32{ @@ -26,15 +34,16 @@ _create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^ context = t.init_context.? or_else runtime.default_context() t.id = sync.current_thread_id() + t.procedure(t) + intrinsics.atomic_store(&t.flags, t.flags + {.Done}) + if t.init_context == nil { if context.temp_allocator.data == &runtime.global_default_temp_allocator_data { runtime.default_temp_allocator_destroy(auto_cast context.temp_allocator.data) } } - - sync.atomic_store(&t.done, true) return 0 } @@ -61,23 +70,31 @@ _create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^ return thread } -_start :: proc(thread: ^Thread) { - win32.ResumeThread(thread.win32_thread) +_start :: proc(t: ^Thread) { + sync.guard(&t.mutex) + t.flags += {.Started} + win32.ResumeThread(t.win32_thread) } -_is_done :: proc(using thread: ^Thread) -> bool { +_is_done :: proc(t: ^Thread) -> bool { // NOTE(tetra, 2019-10-31): Apparently using wait_for_single_object and // checking if it didn't time out immediately, is not good enough, // so we do it this way instead. - return sync.atomic_load(&done) + return .Done in sync.atomic_load(&t.flags) } -_join :: proc(using thread: ^Thread) { - if win32_thread != win32.INVALID_HANDLE { - win32.WaitForSingleObject(win32_thread, win32.INFINITE) - win32.CloseHandle(win32_thread) - win32_thread = win32.INVALID_HANDLE +_join :: proc(t: ^Thread) { + sync.guard(&t.mutex) + + if .Joined in t.flags || t.win32_thread == win32.INVALID_HANDLE { + return } + + win32.WaitForSingleObject(t.win32_thread, win32.INFINITE) + win32.CloseHandle(t.win32_thread) + t.win32_thread = win32.INVALID_HANDLE + + t.flags += {.Joined} } _join_multiple :: proc(threads: ..^Thread) { diff --git a/core/time/time.odin b/core/time/time.odin index fddb09d85..1f778a8de 100644 --- a/core/time/time.odin +++ b/core/time/time.odin @@ -213,6 +213,44 @@ time_add :: proc(t: Time, d: Duration) -> Time { return Time{t._nsec + i64(d)} } +// Accurate sleep borrowed from: https://blat-blatnik.github.io/computerBear/making-accurate-sleep-function/ +// +// Accuracy seems to be pretty good out of the box on Linux, to within around 4µs worst case. +// On Windows it depends but is comparable with regular sleep in the worst case. +// To get the same kind of accuracy as on Linux, have your program call `win32.time_begin_period(1)` to +// tell Windows to use a more accurate timer for your process. +accurate_sleep :: proc(d: Duration) { + to_sleep, estimate, mean, m2, count: Duration + + to_sleep = d + estimate = 5 * Millisecond + mean = 5 * Millisecond + count = 1 + + for to_sleep > estimate { + start := tick_now() + sleep(1 * Millisecond) + + observed := tick_since(start) + to_sleep -= observed + + count += 1 + + delta := observed - mean + mean += delta / count + m2 += delta * (observed - mean) + stddev := intrinsics.sqrt(f64(m2) / f64(count - 1)) + estimate = mean + Duration(stddev) + } + + start := tick_now() + for to_sleep > tick_since(start) { + // prevent the spinlock from taking the thread hostage, still accurate enough + _yield() + // NOTE: it might be possible that it yields for too long, in that case it should spinlock freely for a while + // TODO: needs actual testing done to check if that's the case + } +} ABSOLUTE_ZERO_YEAR :: i64(-292277022399) // Day is chosen so that 2001-01-01 is Monday in the calculations ABSOLUTE_TO_INTERNAL :: i64(-9223371966579724800) // i64((ABSOLUTE_ZERO_YEAR - 1) * 365.2425 * SECONDS_PER_DAY); diff --git a/core/time/time_unix.odin b/core/time/time_unix.odin index 0d765b72d..0cfa196a2 100644 --- a/core/time/time_unix.odin +++ b/core/time/time_unix.odin @@ -1,9 +1,9 @@ -//+build linux, darwin, freebsd +//+build linux, darwin, freebsd, openbsd package time IS_SUPPORTED :: true // NOTE: Times on Darwin are UTC. -when ODIN_OS == "darwin" { +when ODIN_OS == .Darwin { foreign import libc "System.framework" } else { foreign import libc "system:c" @@ -17,21 +17,47 @@ foreign libc { @(link_name="nanosleep") _unix_nanosleep :: proc(requested: ^TimeSpec, remaining: ^TimeSpec) -> i32 --- } +foreign import "system:pthread" + +import "core:c" + +@(private="file") +@(default_calling_convention="c") +foreign pthread { + sched_yield :: proc() -> c.int --- +} + +_yield :: proc "contextless" () { + sched_yield() +} + TimeSpec :: struct { tv_sec : i64, /* seconds */ tv_nsec : i64, /* nanoseconds */ } -CLOCK_REALTIME :: 0 // NOTE(tetra): May jump in time, when user changes the system time. -CLOCK_MONOTONIC :: 1 // NOTE(tetra): May stand still while system is asleep. -CLOCK_PROCESS_CPUTIME_ID :: 2 -CLOCK_THREAD_CPUTIME_ID :: 3 -CLOCK_MONOTONIC_RAW :: 4 // NOTE(tetra): "RAW" means: Not adjusted by NTP. -CLOCK_REALTIME_COARSE :: 5 // NOTE(tetra): "COARSE" clocks are apparently much faster, but not "fine-grained." -CLOCK_MONOTONIC_COARSE :: 6 -CLOCK_BOOTTIME :: 7 // NOTE(tetra): Same as MONOTONIC, except also including time system was asleep. -CLOCK_REALTIME_ALARM :: 8 -CLOCK_BOOTTIME_ALARM :: 9 +when ODIN_OS == .OpenBSD { + CLOCK_REALTIME :: 0 + CLOCK_PROCESS_CPUTIME_ID :: 2 + CLOCK_MONOTONIC :: 3 + CLOCK_THREAD_CPUTIME_ID :: 4 + CLOCK_UPTIME :: 5 + CLOCK_BOOTTIME :: 6 + + // CLOCK_MONOTONIC_RAW doesn't exist, use CLOCK_MONOTONIC + CLOCK_MONOTONIC_RAW :: CLOCK_MONOTONIC +} else { + CLOCK_REALTIME :: 0 // NOTE(tetra): May jump in time, when user changes the system time. + CLOCK_MONOTONIC :: 1 // NOTE(tetra): May stand still while system is asleep. + CLOCK_PROCESS_CPUTIME_ID :: 2 + CLOCK_THREAD_CPUTIME_ID :: 3 + CLOCK_MONOTONIC_RAW :: 4 // NOTE(tetra): "RAW" means: Not adjusted by NTP. + CLOCK_REALTIME_COARSE :: 5 // NOTE(tetra): "COARSE" clocks are apparently much faster, but not "fine-grained." + CLOCK_MONOTONIC_COARSE :: 6 + CLOCK_BOOTTIME :: 7 // NOTE(tetra): Same as MONOTONIC, except also including time system was asleep. + CLOCK_REALTIME_ALARM :: 8 + CLOCK_BOOTTIME_ALARM :: 9 +} // TODO(tetra, 2019-11-05): The original implementation of this package for Darwin used this constants. // I do not know if Darwin programmers are used to the existance of these constants or not, so diff --git a/core/time/time_windows.odin b/core/time/time_windows.odin index 0fb9eaa0f..397741126 100644 --- a/core/time/time_windows.odin +++ b/core/time/time_windows.odin @@ -35,3 +35,7 @@ _tick_now :: proc "contextless" () -> Tick { _nsec := mul_div_u64(i64(now), 1e9, i64(qpc_frequency)) return Tick{_nsec = _nsec} } + +_yield :: proc "contextless" () { + win32.SwitchToThread() +} diff --git a/core/unicode/utf16/utf16.odin b/core/unicode/utf16/utf16.odin index 2e349640e..6bdd6558a 100644 --- a/core/unicode/utf16/utf16.odin +++ b/core/unicode/utf16/utf16.odin @@ -117,9 +117,9 @@ decode_to_utf8 :: proc(d: []byte, s: []u16) -> (n: int) { switch c := s[i]; { case c < _surr1, _surr3 <= c: r = rune(c) - case _surr1 <= r && r < _surr2 && i+1 < len(s) && + case _surr1 <= c && c < _surr2 && i+1 < len(s) && _surr2 <= s[i+1] && s[i+1] < _surr3: - r = decode_surrogate_pair(rune(r), rune(s[i+1])) + r = decode_surrogate_pair(rune(c), rune(s[i+1])) i += 1 } diff --git a/core/unicode/utf8/utf8string/string.odin b/core/unicode/utf8/utf8string/string.odin index 23e2eefc6..86267defb 100644 --- a/core/unicode/utf8/utf8string/string.odin +++ b/core/unicode/utf8/utf8string/string.odin @@ -16,140 +16,140 @@ String :: struct { } @(private) -_len :: builtin.len; // helper procedure +_len :: builtin.len // helper procedure init :: proc(s: ^String, contents: string) -> ^String { - s.contents = contents; - s.byte_pos = 0; - s.rune_pos = 0; + s.contents = contents + s.byte_pos = 0 + s.rune_pos = 0 for i in 0..<_len(contents) { if contents[i] >= utf8.RUNE_SELF { - s.rune_count = utf8.rune_count_in_string(contents); - _, s.width = utf8.decode_rune_in_string(contents); - s.non_ascii = i; - return s; + s.rune_count = utf8.rune_count_in_string(contents) + _, s.width = utf8.decode_rune_in_string(contents) + s.non_ascii = i + return s } } - s.rune_count = _len(contents); - s.width = 0; - s.non_ascii = _len(contents); - return s; + s.rune_count = _len(contents) + s.width = 0 + s.non_ascii = _len(contents) + return s } to_string :: proc(s: ^String) -> string { - return s.contents; + return s.contents } len :: proc(s: ^String) -> int { - return s.rune_count; + return s.rune_count } is_ascii :: proc(s: ^String) -> bool { - return s.width == 0; + return s.width == 0 } at :: proc(s: ^String, i: int, loc := #caller_location) -> (r: rune) { - runtime.bounds_check_error_loc(loc, i, s.rune_count); + runtime.bounds_check_error_loc(loc, i, s.rune_count) if i < s.non_ascii { - return rune(s.contents[i]); + return rune(s.contents[i]) } switch i { case 0: - r, s.width = utf8.decode_rune_in_string(s.contents); - s.rune_pos = 0; - s.byte_pos = 0; - return; + r, s.width = utf8.decode_rune_in_string(s.contents) + s.rune_pos = 0 + s.byte_pos = 0 + return case s.rune_count-1: - r, s.width = utf8.decode_rune_in_string(s.contents); - s.rune_pos = i; - s.byte_pos = _len(s.contents) - s.width; - return; + r, s.width = utf8.decode_rune_in_string(s.contents) + s.rune_pos = i + s.byte_pos = _len(s.contents) - s.width + return case s.rune_pos-1: - r, s.width = utf8.decode_rune_in_string(s.contents[0:s.byte_pos]); - s.rune_pos = i; - s.byte_pos -= s.width; - return; + r, s.width = utf8.decode_rune_in_string(s.contents[0:s.byte_pos]) + s.rune_pos = i + s.byte_pos -= s.width + return case s.rune_pos+1: - s.rune_pos = i; - s.byte_pos += s.width; - fallthrough; + s.rune_pos = i + s.byte_pos += s.width + fallthrough case s.rune_pos: - r, s.width = utf8.decode_rune_in_string(s.contents[s.byte_pos:]); - return; + r, s.width = utf8.decode_rune_in_string(s.contents[s.byte_pos:]) + return } // Linear scan - scan_forward := true; + scan_forward := true if i < s.rune_pos { if i < (s.rune_pos-s.non_ascii)/2 { - s.byte_pos, s.rune_pos = s.non_ascii, s.non_ascii; + s.byte_pos, s.rune_pos = s.non_ascii, s.non_ascii } else { - scan_forward = false; + scan_forward = false } } else if i-s.rune_pos < (s.rune_count-s.rune_pos)/2 { - // scan_forward = true; + // scan_forward = true } else { - s.byte_pos, s.rune_pos = _len(s.contents), s.rune_count; - scan_forward = false; + s.byte_pos, s.rune_pos = _len(s.contents), s.rune_count + scan_forward = false } if scan_forward { for { - r, s.width = utf8.decode_rune_in_string(s.contents[s.byte_pos:]); + r, s.width = utf8.decode_rune_in_string(s.contents[s.byte_pos:]) if s.rune_pos == i { - return; + return } - s.rune_pos += 1; - s.byte_pos += s.width; + s.rune_pos += 1 + s.byte_pos += s.width } } else { for { - r, s.width = utf8.decode_last_rune_in_string(s.contents[:s.byte_pos]); - s.rune_pos -= 1; - s.byte_pos -= s.width; + r, s.width = utf8.decode_last_rune_in_string(s.contents[:s.byte_pos]) + s.rune_pos -= 1 + s.byte_pos -= s.width if s.rune_pos == i { - return; + return } } } } slice :: proc(s: ^String, i, j: int, loc := #caller_location) -> string { - runtime.slice_expr_error_lo_hi_loc(loc, i, j, s.rune_count); + runtime.slice_expr_error_lo_hi_loc(loc, i, j, s.rune_count) if j < s.non_ascii { - return s.contents[i:j]; + return s.contents[i:j] } if i == j { - return ""; + return "" } - lo, hi: int; + lo, hi: int if i < s.non_ascii { - lo = i; + lo = i } else if i == s.rune_count { - lo = _len(s.contents); + lo = _len(s.contents) } else { - at(s, i, loc); - lo = s.byte_pos; + at(s, i, loc) + lo = s.byte_pos } if j == s.rune_count { - hi = _len(s.contents); + hi = _len(s.contents) } else { - at(s, j, loc); - hi = s.byte_pos; + at(s, j, loc) + hi = s.byte_pos } - return s.contents[lo:hi]; + return s.contents[lo:hi] } diff --git a/examples/all/all_main.odin b/examples/all/all_main.odin index a88cc273e..27f199062 100644 --- a/examples/all/all_main.odin +++ b/examples/all/all_main.odin @@ -5,25 +5,68 @@ package all import bufio "core:bufio" import bytes "core:bytes" + import c "core:c" import libc "core:c/libc" + import compress "core:compress" +import shoco "core:compress/shoco" import gzip "core:compress/gzip" import zlib "core:compress/zlib" -import container "core:container" + +import bit_array "core:container/bit_array" +import priority_queue "core:container/priority_queue" +import queue "core:container/queue" +import small_array "core:container/small_array" +import lru "core:container/lru" + +import crypto "core:crypto" +import blake "core:crypto/blake" +import blake2b "core:crypto/blake2b" +import blake2s "core:crypto/blake2s" +import chacha20 "core:crypto/chacha20" +import chacha20poly1305 "core:crypto/chacha20poly1305" +import gost "core:crypto/gost" +import groestl "core:crypto/groestl" +import haval "core:crypto/haval" +import jh "core:crypto/jh" +import keccak "core:crypto/keccak" +import md2 "core:crypto/md2" +import md4 "core:crypto/md4" +import md5 "core:crypto/md5" +import poly1305 "core:crypto/poly1305" +import ripemd "core:crypto/ripemd" +import sha1 "core:crypto/sha1" +import sha2 "core:crypto/sha2" +import sha3 "core:crypto/sha3" +import shake "core:crypto/shake" +import sm3 "core:crypto/sm3" +import streebog "core:crypto/streebog" +import tiger "core:crypto/tiger" +import tiger2 "core:crypto/tiger2" +import crypto_util "core:crypto/util" +import whirlpool "core:crypto/whirlpool" +import x25519 "core:crypto/x25519" + import dynlib "core:dynlib" -import encoding "core:encoding" + import base32 "core:encoding/base32" import base64 "core:encoding/base64" import csv "core:encoding/csv" import hxa "core:encoding/hxa" import json "core:encoding/json" +import varint "core:encoding/varint" + import fmt "core:fmt" import hash "core:hash" + import image "core:image" import png "core:image/png" +import qoi "core:image/qoi" + import io "core:io" import log "core:log" + import math "core:math" import big "core:math/big" import bits "core:math/bits" @@ -32,16 +75,22 @@ import linalg "core:math/linalg" import glm "core:math/linalg/glsl" import hlm "core:math/linalg/hlsl" import rand "core:math/rand" + import mem "core:mem" +// import virtual "core:mem/virtual" + import ast "core:odin/ast" import doc_format "core:odin/doc-format" import odin_format "core:odin/format" import odin_parser "core:odin/parser" import odin_printer "core:odin/printer" import odin_tokenizer "core:odin/tokenizer" + import os "core:os" -import path "core:path" + +import slashpath "core:path/slashpath" import filepath "core:path/filepath" + import reflect "core:reflect" import runtime "core:runtime" import slice "core:slice" @@ -49,12 +98,14 @@ import sort "core:sort" import strconv "core:strconv" import strings "core:strings" import sync "core:sync" -import sync2 "core:sync/sync2" +import testing "core:testing" import scanner "core:text/scanner" import thread "core:thread" import time "core:time" + import unicode "core:unicode" import utf8 "core:unicode/utf8" +import utf8string "core:unicode/utf8/utf8string" import utf16 "core:unicode/utf16" main :: proc(){} @@ -65,20 +116,53 @@ _ :: bytes _ :: c _ :: libc _ :: compress +_ :: shoco _ :: gzip _ :: zlib -_ :: container +_ :: bit_array +_ :: priority_queue +_ :: queue +_ :: small_array +_ :: lru +_ :: crypto +_ :: blake +_ :: blake2b +_ :: blake2s +_ :: chacha20 +_ :: chacha20poly1305 +_ :: gost +_ :: groestl +_ :: haval +_ :: jh +_ :: keccak +_ :: md2 +_ :: md4 +_ :: md5 +_ :: poly1305 +_ :: ripemd +_ :: sha1 +_ :: sha2 +_ :: sha3 +_ :: shake +_ :: sm3 +_ :: streebog +_ :: tiger +_ :: tiger2 +_ :: crypto_util +_ :: whirlpool +_ :: x25519 _ :: dynlib -_ :: encoding _ :: base32 _ :: base64 _ :: csv _ :: hxa _ :: json +_ :: varint _ :: fmt _ :: hash _ :: image _ :: png +_ :: qoi _ :: io _ :: log _ :: math @@ -97,7 +181,7 @@ _ :: odin_parser _ :: odin_printer _ :: odin_tokenizer _ :: os -_ :: path +_ :: slashpath _ :: filepath _ :: reflect _ :: runtime @@ -106,10 +190,11 @@ _ :: sort _ :: strconv _ :: strings _ :: sync -_ :: sync2 +_ :: testing _ :: scanner _ :: thread _ :: time _ :: unicode _ :: utf8 +_ :: utf8string _ :: utf16 \ No newline at end of file diff --git a/examples/all/all_vendor.odin b/examples/all/all_vendor.odin index 777c184f9..f83e906a2 100644 --- a/examples/all/all_vendor.odin +++ b/examples/all/all_vendor.odin @@ -1,26 +1,40 @@ -//+build windows package all -import glfw "vendor:glfw" -import gl "vendor:OpenGL" -import rl "vendor:raylib" -import PM "vendor:portmidi" +import botan "vendor:botan" +import ENet "vendor:ENet" +import gl "vendor:OpenGL" +import glfw "vendor:glfw" +import microui "vendor:microui" +import miniaudio "vendor:miniaudio" +import PM "vendor:portmidi" +import rl "vendor:raylib" + import SDL "vendor:sdl2" -import IMG "vendor:sdl2/image" import SDLNet "vendor:sdl2/net" +import IMG "vendor:sdl2/image" import MIX "vendor:sdl2/mixer" import TTF "vendor:sdl2/ttf" -import vk "vendor:vulkan" -import ENet "vendor:ENet" -_ :: glfw +import vk "vendor:vulkan" + +import NS "vendor:darwin/Foundation" +import MTL "vendor:darwin/Metal" +import CA "vendor:darwin/QuartzCore" + +_ :: botan +_ :: ENet _ :: gl -_ :: rl +_ :: glfw +_ :: microui +_ :: miniaudio _ :: PM +_ :: rl _ :: SDL -_ :: IMG _ :: SDLNet +_ :: IMG _ :: MIX _ :: TTF _ :: vk -_ :: ENet \ No newline at end of file +_ :: NS +_ :: MTL +_ :: CA diff --git a/examples/all/all_vendor_directx.odin b/examples/all/all_vendor_directx.odin new file mode 100644 index 000000000..2f10d92f8 --- /dev/null +++ b/examples/all/all_vendor_directx.odin @@ -0,0 +1,10 @@ +//+build windows +package all + +import D3D11 "vendor:directx/d3d11" +import D3D12 "vendor:directx/d3d12" +import DXGI "vendor:directx/dxgi" + +_ :: D3D11 +_ :: D3D12 +_ :: DXGI diff --git a/examples/all/all_vendor_stl.odin b/examples/all/all_vendor_stl.odin new file mode 100644 index 000000000..9faf53c63 --- /dev/null +++ b/examples/all/all_vendor_stl.odin @@ -0,0 +1,15 @@ +//+build windows, linux +package all + +import stb_easy_font "vendor:stb/easy_font" +import stbi "vendor:stb/image" +import stbrp "vendor:stb/rect_pack" +import stbtt "vendor:stb/truetype" +import stb_vorbis "vendor:stb/vorbis" + +_ :: stb_easy_font +_ :: stbi +_ :: stbrp +_ :: stbtt +_ :: stb_vorbis + diff --git a/examples/demo/demo.odin b/examples/demo/demo.odin index 3e34e3d49..a36acdf18 100644 --- a/examples/demo/demo.odin +++ b/examples/demo/demo.odin @@ -11,22 +11,32 @@ import "core:intrinsics" import "core:math/big" /* - The Odin programming language is fast, concise, readable, pragmatic and open sourced. - It is designed with the intent of replacing C with the following goals: - * simplicity - * high performance - * built for modern systems - * joy of programming + Odin is a general-purpose programming language with distinct typing built + for high performance, modern systems and data-oriented programming. + + Odin is the C alternative for the Joy of Programming. # Installing Odin Getting Started - https://odin-lang.org/docs/install/ Instructions for downloading and install the Odin compiler and libraries. # Learning Odin + Getting Started - https://odin-lang.org/docs/install/ + Getting Started with Odin. Downloading, installing, and getting your + first program to compile and run. Overview of Odin - https://odin-lang.org/docs/overview/ - An overview of the Odin programming language. + An overview of the Odin programming language and its features. Frequently Asked Questions (FAQ) - https://odin-lang.org/docs/faq/ Answers to common questions about Odin. + Packages - https://pkg.odin-lang.org/ + Documentation for all the official packages part of the + core and vendor library collections. + Nightly Builds - https://odin-lang.org/docs/nightly/ + Get the latest nightly builds of Odin. + More Odin Examples - https://github.com/odin-lang/examples + This repository contains examples of how certain things can be accomplished + in idiomatic Odin, allowing you learn its semantics, as well as how to use + parts of the core and vendor package collections. */ the_basics :: proc() { @@ -88,6 +98,7 @@ the_basics :: proc() { z: f64 // `z` is typed of type `f64` (64-bit floating point number) z = 1 // `1` is an untyped integer literal which can be implicitly converted to `f64` // No need for any suffixes or decimal places like in other languages + // (with the exception of negative zero, which must be given as `-0.0`) // CONSTANTS JUST WORK!!! @@ -244,10 +255,10 @@ control_flow :: proc() { // A switch statement is another way to write a sequence of if-else statements. // In Odin, the default case is denoted as a case without any expression. - switch arch := ODIN_ARCH; arch { - case "386": + #partial switch arch := ODIN_ARCH; arch { + case .i386: fmt.println("32-bit") - case "amd64": + case .amd64: fmt.println("64-bit") case: // default fmt.println("Unsupported architecture") @@ -363,12 +374,12 @@ control_flow :: proc() { */ // Example - when ODIN_ARCH == "386" { + when ODIN_ARCH == .i386 { fmt.println("32 bit") - } else when ODIN_ARCH == "amd64" { + } else when ODIN_ARCH == .amd64 { fmt.println("64 bit") } else { - fmt.println("Unsupported architecture") + fmt.println("Unknown architecture") } // The when statement is very useful for writing platform specific code. // This is akin to the #if construct in C’s preprocessor however, in Odin, @@ -1100,11 +1111,6 @@ prefix_table := [?]string{ } threading_example :: proc() { - if ODIN_OS == "darwin" { - // TODO: Fix threads on darwin/macOS - return - } - fmt.println("\n# threading_example") { // Basic Threads @@ -1145,7 +1151,7 @@ threading_example :: proc() { { // Thread Pool fmt.println("\n## Thread Pool") - task_proc :: proc(t: ^thread.Task) { + task_proc :: proc(t: thread.Task) { index := t.user_index % len(prefix_table) for iteration in 1..=5 { fmt.printf("Worker Task %d is on iteration %d\n", t.user_index, iteration) @@ -1155,16 +1161,17 @@ threading_example :: proc() { } pool: thread.Pool - thread.pool_init(pool=&pool, thread_count=3) + thread.pool_init(pool=&pool, thread_count=3, allocator=context.allocator) defer thread.pool_destroy(&pool) for i in 0..<30 { - thread.pool_add_task(pool=&pool, procedure=task_proc, data=nil, user_index=i) + // be mindful of the allocator used for tasks. The allocator needs to be thread safe, or be owned by the task for exclusive use + thread.pool_add_task(pool=&pool, procedure=task_proc, data=nil, user_index=i, allocator=context.allocator) } thread.pool_start(&pool) - thread.pool_wait_and_process(&pool) + thread.pool_finish(&pool) } } @@ -1606,13 +1613,13 @@ where_clauses :: proc() { } -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import kernel32 "system:kernel32.lib" } foreign_system :: proc() { fmt.println("\n#foreign system") - when ODIN_OS == "windows" { + when ODIN_OS == .Windows { // It is sometimes necessarily to interface with foreign code, // such as a C library. In Odin, this is achieved through the // foreign system. You can “import” a library into the code @@ -1708,7 +1715,6 @@ deprecated_attribute :: proc() { } range_statements_with_multiple_return_values :: proc() { - // IMPORTANT NOTE(bill, 2019-11-02): This feature is subject to be changed/removed fmt.println("\n#range statements with multiple return values") My_Iterator :: struct { index: int, @@ -1921,14 +1927,14 @@ constant_literal_expressions :: proc() { fmt.println("-------") - Partial_Baz :: enum{A=5, B, C, D=16} - #assert(len(Partial_Baz) < len(#partial [Partial_Baz]int)) - PARTIAL_ENUM_ARRAY_CONST :: #partial [Partial_Baz]int{.A ..= .C = 1, .D = 16} + Sparse_Baz :: enum{A=5, B, C, D=16} + #assert(len(Sparse_Baz) < len(#sparse[Sparse_Baz]int)) + SPARSE_ENUM_ARRAY_CONST :: #sparse[Sparse_Baz]int{.A ..= .C = 1, .D = 16} - fmt.println(PARTIAL_ENUM_ARRAY_CONST[.A]) - fmt.println(PARTIAL_ENUM_ARRAY_CONST[.B]) - fmt.println(PARTIAL_ENUM_ARRAY_CONST[.C]) - fmt.println(PARTIAL_ENUM_ARRAY_CONST[.D]) + fmt.println(SPARSE_ENUM_ARRAY_CONST[.A]) + fmt.println(SPARSE_ENUM_ARRAY_CONST[.B]) + fmt.println(SPARSE_ENUM_ARRAY_CONST[.C]) + fmt.println(SPARSE_ENUM_ARRAY_CONST[.D]) fmt.println("-------") @@ -1998,7 +2004,6 @@ relative_data_types :: proc() { or_else_operator :: proc() { fmt.println("\n#'or_else'") - // IMPORTANT NOTE: 'or_else' is an experimental feature and subject to change/removal { m: map[string]int i: int @@ -2029,8 +2034,6 @@ or_else_operator :: proc() { or_return_operator :: proc() { fmt.println("\n#'or_return'") - // IMPORTANT NOTE: 'or_return' is an experimental feature and subject to change/removal - // // The concept of 'or_return' will work by popping off the end value in a multiple // valued expression and checking whether it was not 'nil' or 'false', and if so, // set the end return value to value if possible. If the procedure only has one @@ -2421,6 +2424,13 @@ matrix_type :: proc() { } main :: proc() { + /* + For More Odin Examples - https://github.com/odin-lang/examples + This repository contains examples of how certain things can be accomplished + in idiomatic Odin, allowing you learn its semantics, as well as how to use + parts of the core and vendor package collections. + */ + when true { the_basics() control_flow() diff --git a/examples/hms2019/basic.odin b/examples/hms2019/basic.odin deleted file mode 100644 index 4c4a4eff0..000000000 --- a/examples/hms2019/basic.odin +++ /dev/null @@ -1,7 +0,0 @@ -package basic - -import "core:fmt" - -main :: proc() { - fmt.println("Hellope!"); -} \ No newline at end of file diff --git a/examples/hms2019/eca.odin b/examples/hms2019/eca.odin deleted file mode 100644 index eaefeeb9b..000000000 --- a/examples/hms2019/eca.odin +++ /dev/null @@ -1,67 +0,0 @@ -package eca - -import "core:fmt" -import "core:math/rand" -import "core:time" -import "intrinsics" - -elementary_cellular_automata :: proc(state: $T, rule: u8, generations: int, pause: time.Duration = 0) - where intrinsics.type_is_integer(T), - intrinsics.type_is_unsigned(T) { - N :: 8*size_of(state); - - output :: proc(state: T) { - buf: [N]byte; - for i in 0.. T { - return (x >> i) & 0x1; - } - set :: proc(x: ^T, cell, k: T, rule: u8) { - x^ &~= 1<>k&1 != 0 { - x^ |= 1< 0 do time.sleep(pause); - - - k := bit(a, last) | bit(a, 0)<<1 | bit(a, 1)<<2; - set(&a1, 0, k, rule); - a1 |= (1<<0) * T(rule>>k&1); - for c in 1..>1 | bit(a, c+1)<<2; - set(&a1, c, k, rule); - } - set(&a1, last, k>>1|bit(a, 0)<<2, rule); - a, a1 = a1, a; - output(a); - if a == a1 { - return; - } - } -} - -main :: proc() { - elementary_cellular_automata( - state=rand.uint128(), - rule=30, - generations=5000, - pause=100*time.Millisecond, - ); -} \ No newline at end of file diff --git a/examples/hms2019/hms2019.odin b/examples/hms2019/hms2019.odin deleted file mode 100644 index 5c2e836f8..000000000 --- a/examples/hms2019/hms2019.odin +++ /dev/null @@ -1,1754 +0,0 @@ -package hms2019 - -import "core:fmt" -import "core:mem" -import "core:os" -import "core:reflect" -import "intrinsics" - -/* - Welcome to Handmade Seattle 2019! - - The Odin programming language is fast, concise, readable, pragmatic and open sourced. - It is designed with the intent of replacing C with the following goals: - * simplicity - * high performance - * built for modern systems - * joy of programming - - # Installing Odin - Getting Started - https://odin-lang.org/docs/install/ - Instructions for downloading and install the Odin compiler and libraries. - - # Learning Odin - Overview of Odin - https://odin-lang.org/docs/overview/ - An overview of the Odin programming language. - Frequently Asked Questions (FAQ) - https://odin-lang.org/docs/faq/ - Answers to common questions about Odin. -*/ - -the_basics :: proc() { - fmt.println("\n# the basics"); - - { // The Basics - fmt.println("Hellope"); - - // Lexical elements and literals - // A comment - - my_integer_variable: int; // A comment for documentaton - - // Multi-line comments begin with /* and end with */. Multi-line comments can - // also be nested (unlike in C): - /* - You can have any text or code here and - have it be commented. - /* - NOTE: comments can be nested! - */ - */ - - // String literals are enclosed in double quotes and character literals in single quotes. - // Special characters are escaped with a backslash \ - - some_string := "This is a string"; - _ = 'A'; // unicode codepoint literal - _ = '\n'; - _ = "C:\\Windows\\notepad.exe"; - // Raw string literals are enclosed with single back ticks - _ = `C:\Windows\notepad.exe`; - - // The length of a string in bytes can be found using the built-in `len` procedure: - _ = len("Foo"); - _ = len(some_string); - - - // Numbers - - // Numerical literals are written similar to most other programming languages. - // A useful feature in Odin is that underscores are allowed for better - // readability: 1_000_000_000 (one billion). A number that contains a dot is a - // floating point literal: 1.0e9 (one billion). If a number literal is suffixed - // with i, is an imaginary number literal: 2i (2 multiply the square root of -1). - - // Binary literals are prefixed with 0b, octal literals with 0o, and hexadecimal - // literals 0x. A leading zero does not produce an octal constant (unlike C). - - // In Odin, if a number constant is possible to be represented by a type without - // precision loss, it will automatically convert to that type. - - x: int = 1.0; // A float literal but it can be represented by an integer without precision loss - // Constant literals are “untyped” which means that they can implicitly convert to a type. - - y: int; // `y` is typed of type `int` - y = 1; // `1` is an untyped integer literal which can implicitly convert to `int` - - z: f64; // `z` is typed of type `f64` (64-bit floating point number) - z = 1; // `1` is an untyped integer literals which can be implicity conver to `f64` - // No need for any suffixes or decimal places like in other languages - // CONSTANTS JUST WORK!!! - - - // Assignment statements - h: int = 123; // declares a new variable `h` with type `int` and assigns a value to it - h = 637; // assigns a new value to `h` - - // `=` is the assignment operator - - // You can assign multiple variables with it: - a, b := 1, "hello"; // declares `a` and `b` and infers the types from the assignments - b, a = "byte", 0; - - // Note: `:=` is two tokens, `:` and `=`. The follow are equivalent - /* - i: int = 123; - i: = 123; - i := 123 - */ - - // Constant declarations - // Constants are entities (symbols) which have an assigned value. - // The constant’s value cannot be changed. - // The constant’s value must be able to be evaluated at compile time: - X :: "what"; // constant `X` has the untyped string value "what" - - // Constants can be explicitly typed like a variable declaration: - Y : int : 123; - Z :: Y + 7; // constant computations are possible - } -} - -control_flow :: proc() { - fmt.println("\n# control flow"); - { // Control flow - // For loop - // Odin has only one loop statement, the `for` loop - - // Basic for loop - for i := 0; i < 10; i += 1 { - fmt.println(i); - } - - // NOTE: Unlike other languages like C, there are no parentheses `( )` surrounding the three components. - // Braces `{ }` or a `do` are always required> - for i := 0; i < 10; i += 1 { } - for i := 0; i < 10; i += 1 do fmt.print(); - - // The initial and post statements are optional - i := 0; - for ; i < 10; { - i += 1; - } - - // These semicolons can be dropped. This `for` loop is equivalent to C's `while` loop - i = 0; - for i < 10 { - i += 1; - } - - // If the condition is omitted, this produces an infinite loop: - for { - break; - } - - // Range-based for loop - // The basic for loop - for i := 0; i < 10; i += 1 { - fmt.println(i); - } - // can also be written - for i in 0..<10 { - fmt.println(i); - } - for i in 0..9 { - fmt.println(i); - } - - // Certain built-in types can be iterated over - some_string := "Hello, 世界"; - for character in some_string { // Strings are assumed to be UTF-8 - fmt.println(character); - } - - some_array := [3]int{1, 4, 9}; - for value in some_array { - fmt.println(value); - } - - some_slice := []int{1, 4, 9}; - for value in some_slice { - fmt.println(value); - } - - some_dynamic_array := [dynamic]int{1, 4, 9}; - defer delete(some_dynamic_array); - for value in some_dynamic_array { - fmt.println(value); - } - - - some_map := map[string]int{"A" = 1, "C" = 9, "B" = 4}; - defer delete(some_map); - for key in some_map { - fmt.println(key); - } - - // Alternatively a second index value can be added - for character, index in some_string { - fmt.println(index, character); - } - for value, index in some_array { - fmt.println(index, value); - } - for value, index in some_slice { - fmt.println(index, value); - } - for value, index in some_dynamic_array { - fmt.println(index, value); - } - for key, value in some_map { - fmt.println(key, value); - } - - // The iterated values are copies and cannot be written to. - // The following idiom is useful for iterating over a container in a by-reference manner: - for _, i in some_slice { - some_slice[i] = (i+1)*(i+1); - } - - - // If statements - x := 123; - if x >= 0 { - fmt.println("x is positive"); - } - - if y := -34; y < 0 { - fmt.println("y is negative"); - } - - if y := 123; y < 0 { - fmt.println("y is negative"); - } else if y == 0 { - fmt.println("y is zero"); - } else { - fmt.println("y is positive"); - } - - // Switch statement - // A switch statement is another way to write a sequence of if-else statements. - // In Odin, the default case is denoted as a case without any expression. - - switch arch := ODIN_ARCH; arch { - case "386": - fmt.println("32-bit"); - case "amd64": - fmt.println("64-bit"); - case: // default - fmt.println("Unsupported architecture"); - } - - // Odin’s `switch` is like one in C or C++, except that Odin only runs the selected case. - // This means that a `break` statement is not needed at the end of each case. - // Another important difference is that the case values need not be integers nor constants. - - // To achieve a C-like fall through into the next case block, the keyword `fallthrough` can be used. - one_angry_dwarf :: proc() -> int { - fmt.println("one_angry_dwarf was called"); - return 1; - } - - switch i := 0; i { - case 0: - case one_angry_dwarf(): - } - - // A switch statement without a condition is the same as `switch true`. - // This can be used to write a clean and long if-else chain and have the - // ability to break if needed - - switch { - case x < 0: - fmt.println("x is negative"); - case x == 0: - fmt.println("x is zero"); - case: - fmt.println("x is positive"); - } - - // A `switch` statement can also use ranges like a range-based loop: - switch c := 'j'; c { - case 'A'..'Z', 'a'..'z', '0'..'9': - fmt.println("c is alphanumeric"); - } - - switch x { - case 0..<10: - fmt.println("units"); - case 10..<13: - fmt.println("pre-teens"); - case 13..<20: - fmt.println("teens"); - case 20..<30: - fmt.println("twenties"); - } - } - - { // Defer statement - // A defer statement defers the execution of a statement until the end of - // the scope it is in. - - // The following will print 4 then 234: - { - x := 123; - defer fmt.println(x); - { - defer x = 4; - x = 2; - } - fmt.println(x); - - x = 234; - } - - // You can defer an entire block too: - { - bar :: proc() {} - - defer { - fmt.println("1"); - fmt.println("2"); - } - - cond := false; - defer if cond { - bar(); - } - } - - // Defer statements are executed in the reverse order that they were declared: - { - defer fmt.println("1"); - defer fmt.println("2"); - defer fmt.println("3"); - } - // Will print 3, 2, and then 1. - - if false { - f, err := os.open("my_file.txt"); - if err != 0 { - // handle error - } - defer os.close(f); - // rest of code - } - } - - { // When statement - /* - The when statement is almost identical to the if statement but with some differences: - - * Each condition must be a constant expression as a when - statement is evaluated at compile time. - * The statements within a branch do not create a new scope - * The compiler checks the semantics and code only for statements - that belong to the first condition that is true - * An initial statement is not allowed in a when statement - * when statements are allowed at file scope - */ - - // Example - when ODIN_ARCH == "386" { - fmt.println("32 bit"); - } else when ODIN_ARCH == "amd64" { - fmt.println("64 bit"); - } else { - fmt.println("Unsupported architecture"); - } - // The when statement is very useful for writing platform specific code. - // This is akin to the #if construct in C’s preprocessor however, in Odin, - // it is type checked. - } - - { // Branch statements - cond, cond1, cond2 := false, false, false; - one_step :: proc() { fmt.println("one_step"); } - beyond :: proc() { fmt.println("beyond"); } - - // Break statement - for cond { - switch { - case: - if cond { - break; // break out of the `switch` statement - } - } - - break; // break out of the `for` statement - } - - loop: for cond1 { - for cond2 { - break loop; // leaves both loops - } - } - - // Continue statement - for cond { - if cond2 { - continue; - } - fmt.println("Hellope"); - } - - // Fallthrough statement - - // Odin’s switch is like one in C or C++, except that Odin only runs the selected - // case. This means that a break statement is not needed at the end of each case. - // Another important difference is that the case values need not be integers nor - // constants. - - // fallthrough can be used to explicitly fall through into the next case block: - - switch i := 0; i { - case 0: - one_step(); - fallthrough; - case 1: - beyond(); - } - } -} - - -named_proc_return_parameters :: proc() { - fmt.println("\n# named proc return parameters"); - - foo0 :: proc() -> int { - return 123; - } - foo1 :: proc() -> (a: int) { - a = 123; - return; - } - foo2 :: proc() -> (a, b: int) { - // Named return values act like variables within the scope - a = 321; - b = 567; - return b, a; - } - fmt.println("foo0 =", foo0()); // 123 - fmt.println("foo1 =", foo1()); // 123 - fmt.println("foo2 =", foo2()); // 567 321 -} - - -explicit_procedure_overloading :: proc() { - fmt.println("\n# explicit procedure overloading"); - - add_ints :: proc(a, b: int) -> int { - x := a + b; - fmt.println("add_ints", x); - return x; - } - add_floats :: proc(a, b: f32) -> f32 { - x := a + b; - fmt.println("add_floats", x); - return x; - } - add_numbers :: proc(a: int, b: f32, c: u8) -> int { - x := int(a) + int(b) + int(c); - fmt.println("add_numbers", x); - return x; - } - - add :: proc{add_ints, add_floats, add_numbers}; - - add(int(1), int(2)); - add(f32(1), f32(2)); - add(int(1), f32(2), u8(3)); - - add(1, 2); // untyped ints coerce to int tighter than f32 - add(1.0, 2.0); // untyped floats coerce to f32 tighter than int - add(1, 2, 3); // three parameters - - // Ambiguous answers - // add(1.0, 2); - // add(1, 2.0); -} - -struct_type :: proc() { - fmt.println("\n# struct type"); - // A struct is a record type in Odin. It is a collection of fields. - // Struct fields are accessed by using a dot: - { - Vector2 :: struct { - x: f32, - y: f32, - }; - v := Vector2{1, 2}; - v.x = 4; - fmt.println(v.x); - - // Struct fields can be accessed through a struct pointer: - - v = Vector2{1, 2}; - p := &v; - p.x = 1335; - fmt.println(v); - - // We could write p^.x, however, it is to nice abstract the ability - // to not explicitly dereference the pointer. This is very useful when - // refactoring code to use a pointer rather than a value, and vice versa. - } - { - // A struct literal can be denoted by providing the struct’s type - // followed by {}. A struct literal must either provide all the - // arguments or none: - Vector3 :: struct { - x, y, z: f32, - }; - v: Vector3; - v = Vector3{}; // Zero value - v = Vector3{1, 4, 9}; - - // You can list just a subset of the fields if you specify the - // field by name (the order of the named fields does not matter): - v = Vector3{z=1, y=2}; - assert(v.x == 0); - assert(v.y == 2); - assert(v.z == 1); - } - { - // Structs can tagged with different memory layout and alignment requirements: - - a :: struct #align 4 {}; // align to 4 bytes - b :: struct #packed {}; // remove padding between fields - c :: struct #raw_union {}; // all fields share the same offset (0). This is the same as C's union - } - -} - - -union_type :: proc() { - fmt.println("\n# union type"); - { - val: union{int, bool}; - val = 137; - if i, ok := val.(int); ok { - fmt.println(i); - } - val = true; - fmt.println(val); - - val = nil; - - switch v in val { - case int: fmt.println("int", v); - case bool: fmt.println("bool", v); - case: fmt.println("nil"); - } - } - { - // There is a duality between `any` and `union` - // An `any` has a pointer to the data and allows for any type (open) - // A `union` has as binary blob to store the data and allows only certain types (closed) - // The following code is with `any` but has the same syntax - val: any; - val = 137; - if i, ok := val.(int); ok { - fmt.println(i); - } - val = true; - fmt.println(val); - - val = nil; - - switch v in val { - case int: fmt.println("int", v); - case bool: fmt.println("bool", v); - case: fmt.println("nil"); - } - } - - Vector3 :: distinct [3]f32; - Quaternion :: distinct quaternion128; - - // More realistic examples - { - // NOTE(bill): For the above basic examples, you may not have any - // particular use for it. However, my main use for them is not for these - // simple cases. My main use is for hierarchical types. Many prefer - // subtyping, embedding the base data into the derived types. Below is - // an example of this for a basic game Entity. - - Entity :: struct { - id: u64, - name: string, - position: Vector3, - orientation: Quaternion, - - derived: any, - }; - - Frog :: struct { - using entity: Entity, - jump_height: f32, - }; - - Monster :: struct { - using entity: Entity, - is_robot: bool, - is_zombie: bool, - }; - - // See `parametric_polymorphism` procedure for details - new_entity :: proc($T: typeid) -> ^Entity { - t := new(T); - t.derived = t^; - return t; - } - - entity := new_entity(Monster); - - switch e in entity.derived { - case Frog: - fmt.println("Ribbit"); - case Monster: - if e.is_robot do fmt.println("Robotic"); - if e.is_zombie do fmt.println("Grrrr!"); - fmt.println("I'm a monster"); - } - } - - { - // NOTE(bill): A union can be used to achieve something similar. Instead - // of embedding the base data into the derived types, the derived data - // in embedded into the base type. Below is the same example of the - // basic game Entity but using an union. - - Entity :: struct { - id: u64, - name: string, - position: Vector3, - orientation: Quaternion, - - derived: union {Frog, Monster}, - }; - - Frog :: struct { - using entity: ^Entity, - jump_height: f32, - }; - - Monster :: struct { - using entity: ^Entity, - is_robot: bool, - is_zombie: bool, - }; - - // See `parametric_polymorphism` procedure for details - new_entity :: proc($T: typeid) -> ^Entity { - t := new(Entity); - t.derived = T{entity = t}; - return t; - } - - entity := new_entity(Monster); - - switch e in entity.derived { - case Frog: - fmt.println("Ribbit"); - case Monster: - if e.is_robot do fmt.println("Robotic"); - if e.is_zombie do fmt.println("Grrrr!"); - } - - // NOTE(bill): As you can see, the usage code has not changed, only its - // memory layout. Both approaches have their own advantages but they can - // be used together to achieve different results. The subtyping approach - // can allow for a greater control of the memory layout and memory - // allocation, e.g. storing the derivatives together. However, this is - // also its disadvantage. You must either preallocate arrays for each - // derivative separation (which can be easily missed) or preallocate a - // bunch of "raw" memory; determining the maximum size of the derived - // types would require the aid of metaprogramming. Unions solve this - // particular problem as the data is stored with the base data. - // Therefore, it is possible to preallocate, e.g. [100]Entity. - - // It should be noted that the union approach can have the same memory - // layout as the any and with the same type restrictions by using a - // pointer type for the derivatives. - - /* - Entity :: struct { - ... - derived: union{^Frog, ^Monster}, - } - - Frog :: struct { - using entity: Entity, - ... - } - Monster :: struct { - using entity: Entity, - ... - - } - new_entity :: proc(T: type) -> ^Entity { - t := new(T); - t.derived = t; - return t; - } - */ - } -} - -using_statement :: proc() { - fmt.println("\n# using statement"); - // using can used to bring entities declared in a scope/namespace - // into the current scope. This can be applied to import declarations, - // import names, struct fields, procedure fields, and struct values. - - Vector3 :: struct{x, y, z: f32}; - { - Entity :: struct { - position: Vector3, - orientation: quaternion128, - }; - - // It can used like this: - foo0 :: proc(entity: ^Entity) { - fmt.println(entity.position.x, entity.position.y, entity.position.z); - } - - // The entity members can be brought into the procedure scope by using it: - foo1 :: proc(entity: ^Entity) { - using entity; - fmt.println(position.x, position.y, position.z); - } - - // The using can be applied to the parameter directly: - foo2 :: proc(using entity: ^Entity) { - fmt.println(position.x, position.y, position.z); - } - - // It can also be applied to sub-fields: - foo3 :: proc(entity: ^Entity) { - using entity.position; - fmt.println(x, y, z); - } - } - { - // We can also apply the using statement to the struct fields directly, - // making all the fields of position appear as if they on Entity itself: - Entity :: struct { - using position: Vector3, - orientation: quaternion128, - }; - foo :: proc(entity: ^Entity) { - fmt.println(entity.x, entity.y, entity.z); - } - - - // Subtype polymorphism - // It is possible to get subtype polymorphism, similar to inheritance-like - // functionality in C++, but without the requirement of vtables or unknown - // struct layout: - - Colour :: struct {r, g, b, a: u8}; - Frog :: struct { - ribbit_volume: f32, - using entity: Entity, - colour: Colour, - }; - - frog: Frog; - // Both work - foo(&frog.entity); - foo(&frog); - frog.x = 123; - - // Note: using can be applied to arbitrarily many things, which allows - // the ability to have multiple subtype polymorphism (but also its issues). - - // Note: using’d fields can still be referred by name. - } - { // using on an enum declaration - - using Foo :: enum {A, B, C}; - - f0 := A; - f1 := B; - f2 := C; - fmt.println(f0, f1, f2); - fmt.println(len(Foo)); - } -} - - -implicit_context_system :: proc() { - fmt.println("\n# implicit context system"); - // In each scope, there is an implicit value named context. This - // context variable is local to each scope and is implicitly passed - // by pointer to any procedure call in that scope (if the procedure - // has the Odin calling convention). - - // The main purpose of the implicit context system is for the ability - // to intercept third-party code and libraries and modify their - // functionality. One such case is modifying how a library allocates - // something or logs something. In C, this was usually achieved with - // the library defining macros which could be overridden so that the - // user could define what he wanted. However, not many libraries - // supported this in many languages by default which meant intercepting - // third-party code to see what it does and to change how it does it is - // not possible. - - c := context; // copy the current scope's context - - context.user_index = 456; - { - context.allocator = my_custom_allocator(); - context.user_index = 123; - what_a_fool_believes(); // the `context` for this scope is implicitly passed to `what_a_fool_believes` - } - - // `context` value is local to the scope it is in - assert(context.user_index == 456); - - what_a_fool_believes :: proc() { - c := context; // this `context` is the same as the parent procedure that it was called from - // From this example, context.user_index == 123 - // An context.allocator is assigned to the return value of `my_custom_allocator()` - assert(context.user_index == 123); - - // The memory management procedure use the `context.allocator` by - // default unless explicitly specified otherwise - china_grove := new(int); - free(china_grove); - } - - my_custom_allocator :: mem.nil_allocator; - - // By default, the context value has default values for its parameters which is - // decided in the package runtime. What the defaults are are compiler specific. - - // To see what the implicit context value contains, please see the following - // definition in package runtime. -} - -parametric_polymorphism :: proc() { - fmt.println("\n# parametric polymorphism"); - - print_value :: proc(value: $T) { - fmt.printf("print_value: %T %v\n", value, value); - } - - v1: int = 1; - v2: f32 = 2.1; - v3: f64 = 3.14; - v4: string = "message"; - - print_value(v1); - print_value(v2); - print_value(v3); - print_value(v4); - - fmt.println(); - - add :: proc(p, q: $T) -> T { - x: T = p + q; - return x; - } - - a := add(3, 4); - fmt.printf("a: %T = %v\n", a, a); - - b := add(3.2, 4.3); - fmt.printf("b: %T = %v\n", b, b); - - // This is how `new` is implemented - alloc_type :: proc($T: typeid) -> ^T { - t := cast(^T)alloc(size_of(T), align_of(T)); - t^ = T{}; // Use default initialization value - return t; - } - - copy_slice :: proc(dst, src: []$T) -> int { - n := min(len(dst), len(src)); - if n > 0 { - mem.copy(&dst[0], &src[0], n*size_of(T)); - } - return n; - } - - double_params :: proc(a: $A, b: $B) -> A { - return a + A(b); - } - - fmt.println(double_params(12, 1.345)); - - - - { // Polymorphic Types and Type Specialization - Table_Slot :: struct(Key, Value: typeid) { - occupied: bool, - hash: u32, - key: Key, - value: Value, - }; - TABLE_SIZE_MIN :: 32; - Table :: struct(Key, Value: typeid) { - count: int, - allocator: mem.Allocator, - slots: []Table_Slot(Key, Value), - }; - - // Only allow types that are specializations of a (polymorphic) slice - make_slice :: proc($T: typeid/[]$E, len: int) -> T { - return make(T, len); - } - - // Only allow types that are specializations of `Table` - allocate :: proc(table: ^$T/Table, capacity: int) { - c := context; - if table.allocator.procedure != nil do c.allocator = table.allocator; - context = c; - - table.slots = make_slice(type_of(table.slots), max(capacity, TABLE_SIZE_MIN)); - } - - expand :: proc(table: ^$T/Table) { - c := context; - if table.allocator.procedure != nil do c.allocator = table.allocator; - context = c; - - old_slots := table.slots; - defer delete(old_slots); - - cap := max(2*len(table.slots), TABLE_SIZE_MIN); - allocate(table, cap); - - for s in old_slots do if s.occupied { - put(table, s.key, s.value); - } - } - - // Polymorphic determination of a polymorphic struct - // put :: proc(table: ^$T/Table, key: T.Key, value: T.Value) { - put :: proc(table: ^Table($Key, $Value), key: Key, value: Value) { - hash := get_hash(key); // Ad-hoc method which would fail in a different scope - index := find_index(table, key, hash); - if index < 0 { - if f64(table.count) >= 0.75*f64(len(table.slots)) { - expand(table); - } - assert(table.count <= len(table.slots)); - - index = int(hash % u32(len(table.slots))); - - for table.slots[index].occupied { - if index += 1; index >= len(table.slots) { - index = 0; - } - } - - table.count += 1; - } - - slot := &table.slots[index]; - slot.occupied = true; - slot.hash = hash; - slot.key = key; - slot.value = value; - } - - - // find :: proc(table: ^$T/Table, key: T.Key) -> (T.Value, bool) { - find :: proc(table: ^Table($Key, $Value), key: Key) -> (Value, bool) { - hash := get_hash(key); - index := find_index(table, key, hash); - if index < 0 { - return Value{}, false; - } - return table.slots[index].value, true; - } - - find_index :: proc(table: ^Table($Key, $Value), key: Key, hash: u32) -> int { - if len(table.slots) <= 0 do return -1; - - index := int(hash % u32(len(table.slots))); - for table.slots[index].occupied { - if table.slots[index].hash == hash { - if table.slots[index].key == key { - return index; - } - } - - if index += 1; index >= len(table.slots) { - index = 0; - } - } - - return -1; - } - - get_hash :: proc(s: string) -> u32 { // fnv32a - h: u32 = 0x811c9dc5; - for i in 0.. (res: [N]T) { - // `N` is the constant value passed - // `I` is the type of N - // `T` is the type passed - fmt.printf("Generating an array of type %v from the value %v of type %v\n", - typeid_of(type_of(res)), N, typeid_of(I)); - for i in 0.. (c: [M][P]T) { - for i in 0.. Vector3 { - i := swizzle(a, 1, 2, 0) * swizzle(b, 2, 0, 1); - j := swizzle(a, 2, 0, 1) * swizzle(b, 1, 2, 0); - return i - j; - } - - blah :: proc(a: Vector3) -> f32 { - return a.x + a.y + a.z; - } - - x := cross(a, b); - fmt.println(x); - fmt.println(blah(x)); - } -} - -map_type :: proc() { - fmt.println("\n# map type"); - - m := make(map[string]int); - defer delete(m); - - m["Bob"] = 2; - m["Ted"] = 5; - fmt.println(m["Bob"]); - - delete_key(&m, "Ted"); - - // If an element of a key does not exist, the zero value of the - // element will be returned. To check to see if an element exists - // can be done in two ways: - elem, ok := m["Bob"]; - exists := "Bob" in m; - -} - -implicit_selector_expression :: proc() { - fmt.println("\n# implicit selector expression"); - - Foo :: enum {A, B, C}; - - f: Foo; - f = Foo.A; - f = .A; - - BAR :: bit_set[Foo]{.B, .C}; - - switch f { - case .A: - fmt.println("HERE"); - case .B: - fmt.println("NEVER"); - case .C: - fmt.println("FOREVER"); - } - - my_map := make(map[Foo]int); - defer delete(my_map); - - my_map[.A] = 123; - my_map[Foo.B] = 345; - - fmt.println(my_map[.A] + my_map[Foo.B] + my_map[.C]); -} - - -complete_switch :: proc() { - fmt.println("\n# complete_switch"); - { // enum - Foo :: enum { - A, - B, - C, - D, - }; - - f := Foo.A; - #complete switch f { - case .A: fmt.println("A"); - case .B: fmt.println("B"); - case .C: fmt.println("C"); - case .D: fmt.println("D"); - case: fmt.println("?"); - } - } - { // union - Foo :: union {int, bool}; - f: Foo = 123; - #complete switch in f { - case int: fmt.println("int"); - case bool: fmt.println("bool"); - case: - } - } -} - -cstring_example :: proc() { - fmt.println("\n# cstring_example"); - - W :: "Hellope"; - X :: cstring(W); - Y :: string(X); - - w := W; - _ = w; - x: cstring = X; - y: string = Y; - z := string(x); - fmt.println(x, y, z); - fmt.println(len(x), len(y), len(z)); - fmt.println(len(W), len(X), len(Y)); - // IMPORTANT NOTE for cstring variables - // len(cstring) is O(N) - // cast(string)cstring is O(N) -} - -bit_set_type :: proc() { - fmt.println("\n# bit_set type"); - - { - using Day :: enum { - Sunday, - Monday, - Tuesday, - Wednesday, - Thursday, - Friday, - Saturday, - }; - - Days :: distinct bit_set[Day]; - WEEKEND :: Days{Sunday, Saturday}; - - d: Days; - d = {Sunday, Monday}; - e := d | WEEKEND; - e |= {Monday}; - fmt.println(d, e); - - ok := Saturday in e; // `in` is only allowed for `map` and `bit_set` types - fmt.println(ok); - if Saturday in e { - fmt.println("Saturday in", e); - } - X :: Saturday in WEEKEND; // Constant evaluation - fmt.println(X); - fmt.println("Cardinality:", card(e)); - } - { - x: bit_set['A'..'Z']; - #assert(size_of(x) == size_of(u32)); - y: bit_set[0..8; u16]; - fmt.println(typeid_of(type_of(x))); // bit_set[A..Z] - fmt.println(typeid_of(type_of(y))); // bit_set[0..8; u16] - - incl(&x, 'F'); - assert('F' in x); - excl(&x, 'F'); - assert('F' not_in x); - - y |= {1, 4, 2}; - assert(2 in y); - } - { - Letters :: bit_set['A'..'Z']; - a := Letters{'A', 'B'}; - b := Letters{'A', 'B', 'C', 'D', 'F'}; - c := Letters{'A', 'B'}; - - assert(a <= b); // 'a' is a subset of 'b' - assert(b >= a); // 'b' is a superset of 'a' - assert(a < b); // 'a' is a strict subset of 'b' - assert(b > a); // 'b' is a strict superset of 'a' - - assert(!(a < c)); // 'a' is a not strict subset of 'c' - assert(!(c > a)); // 'c' is a not strict superset of 'a' - } -} - -deferred_procedure_associations :: proc() { - fmt.println("\n# deferred procedure associations"); - - @(deferred_out=closure) - open :: proc(s: string) -> bool { - fmt.println(s); - return true; - } - - closure :: proc(ok: bool) { - fmt.println("Goodbye?", ok); - } - - if open("Welcome") { - fmt.println("Something in the middle, mate."); - } -} - -reflection :: proc() { - fmt.println("\n# reflection"); - - Foo :: struct { - x: int `tag1`, - y: string `json:"y_field"`, - z: bool, // no tag - }; - - id := typeid_of(Foo); - names := reflect.struct_field_names(id); - types := reflect.struct_field_types(id); - tags := reflect.struct_field_tags(id); - - assert(len(names) == len(types) && len(names) == len(tags)); - - fmt.println("Foo :: struct {"); - for tag, i in tags { - name, type := names[i], types[i]; - if tag != "" { - fmt.printf("\t%s: %T `%s`,\n", name, type, tag); - } else { - fmt.printf("\t%s: %T,\n", name, type); - } - } - fmt.println("}"); - - - for tag, i in tags { - if val, ok := reflect.struct_tag_lookup(tag, "json"); ok { - fmt.printf("json: %s -> %s\n", names[i], val); - } - } -} - -quaternions :: proc() { - // Not just an April Fool's Joke any more, but a fully working thing! - fmt.println("\n# quaternions"); - - { // Quaternion operations - q := 1 + 2i + 3j + 4k; - r := quaternion(5, 6, 7, 8); - t := q * r; - fmt.printf("(%v) * (%v) = %v\n", q, r, t); - v := q / r; - fmt.printf("(%v) / (%v) = %v\n", q, r, v); - u := q + r; - fmt.printf("(%v) + (%v) = %v\n", q, r, u); - s := q - r; - fmt.printf("(%v) - (%v) = %v\n", q, r, s); - } - { // The quaternion types - q128: quaternion128; // 4xf32 - q256: quaternion256; // 4xf64 - q128 = quaternion(1, 0, 0, 0); - q256 = 1; // quaternion(1, 0, 0, 0); - } - { // Built-in procedures - q := 1 + 2i + 3j + 4k; - fmt.println("q =", q); - fmt.println("real(q) =", real(q)); - fmt.println("imag(q) =", imag(q)); - fmt.println("jmag(q) =", jmag(q)); - fmt.println("kmag(q) =", kmag(q)); - fmt.println("conj(q) =", conj(q)); - fmt.println("abs(q) =", abs(q)); - } - { // Conversion of a complex type to a quaternion type - c := 1 + 2i; - q := quaternion256(c); - fmt.println(c); - fmt.println(q); - } - { // Memory layout of Quaternions - q := 1 + 2i + 3j + 4k; - a := transmute([4]f64)q; - fmt.println("Quaternion memory layout: xyzw/(ijkr)"); - fmt.println(q); // 1.000+2.000i+3.000j+4.000k - fmt.println(a); // [2.000, 3.000, 4.000, 1.000] - } -} - -inline_for_statement :: proc() { - fmt.println("\n#inline for statements"); - - // 'inline for' works the same as if the 'inline' prefix did not - // exist but these ranged loops are explicitly unrolled which can - // be very very useful for certain optimizations - - fmt.println("Ranges"); - inline for x, i in 1..<4 { - fmt.println(x, i); - } - - fmt.println("Strings"); - inline for r, i in "Hello, 世界" { - fmt.println(r, i); - } - - fmt.println("Arrays"); - inline for elem, idx in ([4]int{1, 4, 9, 16}) { - fmt.println(elem, idx); - } - - - Foo_Enum :: enum { - A = 1, - B, - C = 6, - D, - }; - fmt.println("Enum types"); - inline for elem, idx in Foo_Enum { - fmt.println(elem, idx); - } -} - -where_clauses :: proc() { - fmt.println("\n#procedure 'where' clauses"); - - { // Sanity checks - simple_sanity_check :: proc(x: [2]int) - where len(x) > 1, - type_of(x) == [2]int { - fmt.println(x); - } - } - { // Parametric polymorphism checks - cross_2d :: proc(a, b: $T/[2]$E) -> E - where intrinsics.type_is_numeric(E) { - return a.x*b.y - a.y*b.x; - } - cross_3d :: proc(a, b: $T/[3]$E) -> T - where intrinsics.type_is_numeric(E) { - x := a.y*b.z - a.z*b.y; - y := a.z*b.x - a.x*b.z; - z := a.x*b.y - a.y*b.z; - return T{x, y, z}; - } - - a := [2]int{1, 2}; - b := [2]int{5, -3}; - fmt.println(cross_2d(a, b)); - - x := [3]f32{1, 4, 9}; - y := [3]f32{-5, 0, 3}; - fmt.println(cross_3d(x, y)); - - // Failure case - // i := [2]bool{true, false}; - // j := [2]bool{false, true}; - // fmt.println(cross_2d(i, j)); - - } - - { // Procedure groups usage - foo :: proc(x: [$N]int) -> bool - where N > 2 { - fmt.println(#procedure, "was called with the parameter", x); - return true; - } - - bar :: proc(x: [$N]int) -> bool - where 0 < N, - N <= 2 { - fmt.println(#procedure, "was called with the parameter", x); - return false; - } - - baz :: proc{foo, bar}; - - x := [3]int{1, 2, 3}; - y := [2]int{4, 9}; - ok_x := baz(x); - ok_y := baz(y); - assert(ok_x == true); - assert(ok_y == false); - } - - { // Record types - Foo :: struct(T: typeid, N: int) - where intrinsics.type_is_integer(T), - N > 2 { - x: [N]T, - y: [N-2]T, - }; - - T :: i32; - N :: 5; - f: Foo(T, N); - #assert(size_of(f) == (N+N-2)*size_of(T)); - } -} - - -when ODIN_OS == "windows" do foreign import kernel32 "system:kernel32.lib" - -foreign_system :: proc() { - fmt.println("\n#foreign system"); - when ODIN_OS == "windows" { - // It is sometimes necessarily to interface with foreign code, - // such as a C library. In Odin, this is achieved through the - // foreign system. You can “import” a library into the code - // using the same semantics as a normal import declaration. - - // This foreign import declaration will create a - // “foreign import name” which can then be used to associate - // entities within a foreign block. - - foreign kernel32 { - ExitProcess :: proc "stdcall" (exit_code: u32) --- - } - - // Foreign procedure declarations have the cdecl/c calling - // convention by default unless specified otherwise. Due to - // foreign procedures do not have a body declared within this - // code, you need append the --- symbol to the end to distinguish - // it as a procedure literal without a body and not a procedure type. - - // The attributes system can be used to change specific properties - // of entities declared within a block: - - @(default_calling_convention = "std") - foreign kernel32 { - @(link_name="GetLastError") get_last_error :: proc() -> i32 --- - } - - // Example using the link_prefix attribute - @(default_calling_convention = "std") - @(link_prefix = "Get") - foreign kernel32 { - LastError :: proc() -> i32 --- - } - } -} - -ranged_fields_for_array_compound_literals :: proc() { - fmt.println("\n#ranged fields for array compound literals"); - { // Normal Array Literal - foo := [?]int{1, 4, 9, 16}; - fmt.println(foo); - } - { // Indexed - foo := [?]int{ - 3 = 16, - 1 = 4, - 2 = 9, - 0 = 1, - }; - fmt.println(foo); - } - { // Ranges - i := 2; - foo := [?]int { - 0 = 123, - 5..9 = 54, - 10..<16 = i*3 + (i-1)*2, - }; - #assert(len(foo) == 16); - fmt.println(foo); // [123, 0, 0, 0, 0, 54, 54, 54, 54, 54, 8, 8, 8, 8, 8] - } - { // Slice and Dynamic Array support - i := 2; - foo_slice := []int { - 0 = 123, - 5..9 = 54, - 10..<16 = i*3 + (i-1)*2, - }; - assert(len(foo_slice) == 16); - fmt.println(foo_slice); // [123, 0, 0, 0, 0, 54, 54, 54, 54, 54, 8, 8, 8, 8, 8] - - foo_dynamic_array := [dynamic]int { - 0 = 123, - 5..9 = 54, - 10..<16 = i*3 + (i-1)*2, - }; - assert(len(foo_dynamic_array) == 16); - fmt.println(foo_dynamic_array); // [123, 0, 0, 0, 0, 54, 54, 54, 54, 54, 8, 8, 8, 8, 8] - } -} - -deprecated_attribute :: proc() { - @(deprecated="Use foo_v2 instead") - foo_v1 :: proc(x: int) { - fmt.println("foo_v1"); - } - foo_v2 :: proc(x: int) { - fmt.println("foo_v2"); - } - - // NOTE: Uncomment to see the warning messages - // foo_v1(1); -} - -range_statements_with_multiple_return_values :: proc() { - // IMPORTANT NOTE(bill, 2019-11-02): This feature is subject to be changed/removed - fmt.println("\n#range statements with multiple return values"); - My_Iterator :: struct { - index: int, - data: []i32, - }; - make_my_iterator :: proc(data: []i32) -> My_Iterator { - return My_Iterator{data = data}; - } - my_iterator :: proc(it: ^My_Iterator) -> (val: i32, idx: int, cond: bool) { - if cond = it.index < len(it.data); cond { - val = it.data[it.index]; - idx = it.index; - it.index += 1; - } - return; - } - - data := make([]i32, 6); - for _, i in data { - data[i] = i32(i*i); - } - - { - it := make_my_iterator(data); - for val in my_iterator(&it) { - fmt.println(val); - } - } - { - it := make_my_iterator(data); - for val, idx in my_iterator(&it) { - fmt.println(val, idx); - } - } - { - it := make_my_iterator(data); - for { - val, _, cond := my_iterator(&it); - if !cond do break; - fmt.println(val); - } - } -} - -soa_struct_layout :: proc() { - // IMPORTANT NOTE(bill, 2019-11-03): This feature is subject to be changed/removed - // NOTE(bill): Most likely #soa [N]T - fmt.println("\n#SOA Struct Layout"); - - { - Vector3 :: struct {x, y, z: f32}; - - N :: 2; - v_aos: [N]Vector3; - v_aos[0].x = 1; - v_aos[0].y = 4; - v_aos[0].z = 9; - - fmt.println(len(v_aos)); - fmt.println(v_aos[0]); - fmt.println(v_aos[0].x); - fmt.println(&v_aos[0].x); - - v_aos[1] = {0, 3, 4}; - v_aos[1].x = 2; - fmt.println(v_aos[1]); - fmt.println(v_aos); - - v_soa: #soa[N]Vector3; - - v_soa[0].x = 1; - v_soa[0].y = 4; - v_soa[0].z = 9; - - - // Same syntax as AOS and treat as if it was an array - fmt.println(len(v_soa)); - fmt.println(v_soa[0]); - fmt.println(v_soa[0].x); - v_soa[1] = {0, 3, 4}; - v_soa[1].x = 2; - fmt.println(v_soa[1]); - - // Can use SOA syntax if necessary - v_soa.x[0] = 1; - v_soa.y[0] = 4; - v_soa.z[0] = 9; - fmt.println(v_soa.x[0]); - - // Same pointer addresses with both syntaxes - assert(&v_soa[0].x == &v_soa.x[0]); - - - // Same fmt printing - fmt.println(v_aos); - fmt.println(v_soa); - } - { - // Works with arrays of length <= 4 which have the implicit fields xyzw/rgba - Vector3 :: distinct [3]f32; - - N :: 2; - v_aos: [N]Vector3; - v_aos[0].x = 1; - v_aos[0].y = 4; - v_aos[0].z = 9; - - v_soa: #soa[N]Vector3; - - v_soa[0].x = 1; - v_soa[0].y = 4; - v_soa[0].z = 9; - } -} - - -main :: proc() { - when true { - the_basics(); - control_flow(); - named_proc_return_parameters(); - explicit_procedure_overloading(); - struct_type(); - union_type(); - using_statement(); - implicit_context_system(); - parametric_polymorphism(); - array_programming(); - map_type(); - implicit_selector_expression(); - complete_switch(); - cstring_example(); - bit_set_type(); - deferred_procedure_associations(); - reflection(); - quaternions(); - inline_for_statement(); - where_clauses(); - foreign_system(); - ranged_fields_for_array_compound_literals(); - deprecated_attribute(); - range_statements_with_multiple_return_values(); - soa_struct_layout(); - } -} - diff --git a/src/array.cpp b/src/array.cpp index c41125c6d..d08bd647f 100644 --- a/src/array.cpp +++ b/src/array.cpp @@ -77,15 +77,21 @@ template Slice slice_from_array(Array const &a); template Slice slice_make(gbAllocator const &allocator, isize count) { + GB_ASSERT(count >= 0); Slice s = {}; s.data = gb_alloc_array(allocator, T, count); + GB_ASSERT(s.data != nullptr); s.count = count; return s; } template void slice_init(Slice *s, gbAllocator const &allocator, isize count) { + GB_ASSERT(count >= 0); s->data = gb_alloc_array(allocator, T, count); + if (count > 0) { + GB_ASSERT(s->data != nullptr); + } s->count = count; } diff --git a/src/bug_report.cpp b/src/bug_report.cpp index 27e7fcf9a..02a2b1ba2 100644 --- a/src/bug_report.cpp +++ b/src/bug_report.cpp @@ -17,6 +17,11 @@ #include #endif +#if defined(GB_SYSTEM_OPENBSD) + #include + #include +#endif + /* NOTE(Jeroen): This prints the Windows product edition only, to be called from `print_platform_details`. */ @@ -140,7 +145,7 @@ void report_windows_product_type(DWORD ProductType) { break; default: - gb_printf("Unknown Edition (%08x)", ProductType); + gb_printf("Unknown Edition (%08x)", cast(unsigned)ProductType); } } #endif @@ -242,6 +247,14 @@ void report_ram_info() { if (sysctl(sysctls, 2, &ram_amount, &val_size, NULL, 0) != -1) { gb_printf("%lld MiB\n", ram_amount / gb_megabytes(1)); } + #elif defined(GB_SYSTEM_OPENBSD) + uint64_t ram_amount; + size_t val_size = sizeof(ram_amount); + + int sysctls[] = { CTL_HW, HW_PHYSMEM64 }; + if (sysctl(sysctls, 2, &ram_amount, &val_size, NULL, 0) != -1) { + gb_printf("%lld MiB\n", ram_amount / gb_megabytes(1)); + } #else gb_printf("Unknown.\n"); #endif @@ -316,14 +329,14 @@ void print_bug_report_help() { } if (false) { - gb_printf("dwMajorVersion: %d\n", osvi.dwMajorVersion); - gb_printf("dwMinorVersion: %d\n", osvi.dwMinorVersion); - gb_printf("dwBuildNumber: %d\n", osvi.dwBuildNumber); - gb_printf("dwPlatformId: %d\n", osvi.dwPlatformId); - gb_printf("wServicePackMajor: %d\n", osvi.wServicePackMajor); - gb_printf("wServicePackMinor: %d\n", osvi.wServicePackMinor); - gb_printf("wSuiteMask: %d\n", osvi.wSuiteMask); - gb_printf("wProductType: %d\n", osvi.wProductType); + gb_printf("dwMajorVersion: %u\n", cast(unsigned)osvi.dwMajorVersion); + gb_printf("dwMinorVersion: %u\n", cast(unsigned)osvi.dwMinorVersion); + gb_printf("dwBuildNumber: %u\n", cast(unsigned)osvi.dwBuildNumber); + gb_printf("dwPlatformId: %u\n", cast(unsigned)osvi.dwPlatformId); + gb_printf("wServicePackMajor: %u\n", cast(unsigned)osvi.wServicePackMajor); + gb_printf("wServicePackMinor: %u\n", cast(unsigned)osvi.wServicePackMinor); + gb_printf("wSuiteMask: %u\n", cast(unsigned)osvi.wSuiteMask); + gb_printf("wProductType: %u\n", cast(unsigned)osvi.wProductType); } gb_printf("Windows "); @@ -441,18 +454,18 @@ void print_bug_report_help() { TEXT("DisplayVersion"), RRF_RT_REG_SZ, ValueType, - &DisplayVersion, + DisplayVersion, &ValueSize ); if (status == 0x0) { - gb_printf(" (version: %s)", &DisplayVersion); + gb_printf(" (version: %s)", DisplayVersion); } /* Now print build number. */ - gb_printf(", build %d", osvi.dwBuildNumber); + gb_printf(", build %u", cast(unsigned)osvi.dwBuildNumber); ValueSize = sizeof(UBR); status = RegGetValue( @@ -466,18 +479,18 @@ void print_bug_report_help() { ); if (status == 0x0) { - gb_printf(".%d", UBR); + gb_printf(".%u", cast(unsigned)UBR); } gb_printf("\n"); } #elif defined(GB_SYSTEM_LINUX) /* - Try to parse `/usr/lib/os-release` for `PRETTY_NAME="Ubuntu 20.04.3 LTS` + Try to parse `/etc/os-release` for `PRETTY_NAME="Ubuntu 20.04.3 LTS` */ gbAllocator a = heap_allocator(); - gbFileContents release = gb_file_read_contents(a, 1, "/usr/lib/os-release"); + gbFileContents release = gb_file_read_contents(a, 1, "/etc/os-release"); defer (gb_file_free_contents(&release)); b32 found = 0; @@ -643,6 +656,14 @@ void print_bug_report_help() { } else { gb_printf("macOS: Unknown\n"); } + #elif defined(GB_SYSTEM_OPENBSD) + struct utsname un; + + if (uname(&un) != -1) { + gb_printf("%s %s %s %s\n", un.sysname, un.release, un.version, un.machine); + } else { + gb_printf("OpenBSD: Unknown\n"); + } #else gb_printf("Unknown\n"); @@ -657,4 +678,4 @@ void print_bug_report_help() { And RAM info. */ report_ram_info(); -} \ No newline at end of file +} diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 29abd441c..89d370144 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -1,14 +1,13 @@ -#if defined(GB_SYSTEM_FREEBSD) +#if defined(GB_SYSTEM_FREEBSD) || defined(GB_SYSTEM_OPENBSD) #include #include #endif - // #if defined(GB_SYSTEM_WINDOWS) -#define DEFAULT_TO_THREADED_CHECKER +// #define DEFAULT_TO_THREADED_CHECKER // #endif -enum TargetOsKind { +enum TargetOsKind : u16 { TargetOs_Invalid, TargetOs_windows, @@ -16,6 +15,7 @@ enum TargetOsKind { TargetOs_linux, TargetOs_essence, TargetOs_freebsd, + TargetOs_openbsd, TargetOs_wasi, TargetOs_js, @@ -25,11 +25,11 @@ enum TargetOsKind { TargetOs_COUNT, }; -enum TargetArchKind { +enum TargetArchKind : u16 { TargetArch_Invalid, TargetArch_amd64, - TargetArch_386, + TargetArch_i386, TargetArch_arm64, TargetArch_wasm32, TargetArch_wasm64, @@ -37,7 +37,7 @@ enum TargetArchKind { TargetArch_COUNT, }; -enum TargetEndianKind { +enum TargetEndianKind : u8 { TargetEndian_Invalid, TargetEndian_Little, @@ -46,6 +46,16 @@ enum TargetEndianKind { TargetEndian_COUNT, }; +enum TargetABIKind : u16 { + TargetABI_Default, + + TargetABI_Win64, + TargetABI_SysV, + + TargetABI_COUNT, +}; + + String target_os_names[TargetOs_COUNT] = { str_lit(""), str_lit("windows"), @@ -53,6 +63,7 @@ String target_os_names[TargetOs_COUNT] = { str_lit("linux"), str_lit("essence"), str_lit("freebsd"), + str_lit("openbsd"), str_lit("wasi"), str_lit("js"), @@ -63,7 +74,7 @@ String target_os_names[TargetOs_COUNT] = { String target_arch_names[TargetArch_COUNT] = { str_lit(""), str_lit("amd64"), - str_lit("386"), + str_lit("i386"), str_lit("arm64"), str_lit("wasm32"), str_lit("wasm64"), @@ -75,6 +86,12 @@ String target_endian_names[TargetEndian_COUNT] = { str_lit("big"), }; +String target_abi_names[TargetABI_COUNT] = { + str_lit(""), + str_lit("win64"), + str_lit("sysv"), +}; + TargetEndianKind target_endians[TargetArch_COUNT] = { TargetEndian_Invalid, TargetEndian_Little, @@ -98,6 +115,7 @@ struct TargetMetrics { isize max_align; String target_triplet; String target_data_layout; + TargetABIKind abi; }; @@ -119,6 +137,8 @@ enum BuildModeKind { BuildMode_Object, BuildMode_Assembly, BuildMode_LLVM_IR, + + BuildMode_COUNT, }; enum CommandKind : u32 { @@ -163,19 +183,50 @@ enum TimingsExportFormat : i32 { TimingsExportCSV = 2, }; +enum ErrorPosStyle { + ErrorPosStyle_Default, // path(line:column) msg + ErrorPosStyle_Unix, // path:line:column: msg + + ErrorPosStyle_COUNT +}; + +enum RelocMode : u8 { + RelocMode_Default, + RelocMode_Static, + RelocMode_PIC, + RelocMode_DynamicNoPIC, +}; + +enum BuildPath : u8 { + BuildPath_Main_Package, // Input Path to the package directory (or file) we're building. + BuildPath_RC, // Input Path for .rc file, can be set with `-resource:`. + BuildPath_RES, // Output Path for .res file, generated from previous. + BuildPath_Win_SDK_Root, // windows_sdk_root + BuildPath_Win_SDK_UM_Lib, // windows_sdk_um_library_path + BuildPath_Win_SDK_UCRT_Lib, // windows_sdk_ucrt_library_path + BuildPath_VS_EXE, // vs_exe_path + BuildPath_VS_LIB, // vs_library_path + + BuildPath_Output, // Output Path for .exe, .dll, .so, etc. Can be overridden with `-out:`. + BuildPath_PDB, // Output Path for .pdb file, can be overridden with `-pdb-name:`. + + BuildPathCOUNT, +}; + // This stores the information for the specify architecture of this build struct BuildContext { // Constants String ODIN_OS; // target operating system String ODIN_ARCH; // target architecture - String ODIN_ENDIAN; // target endian String ODIN_VENDOR; // compiler vendor String ODIN_VERSION; // compiler version String ODIN_ROOT; // Odin ROOT - String ODIN_BUILD_MODE; bool ODIN_DEBUG; // Odin in debug mode bool ODIN_DISABLE_ASSERT; // Whether the default 'assert' et al is disabled in code or not bool ODIN_DEFAULT_TO_NIL_ALLOCATOR; // Whether the default allocator is a "nil" allocator or not (i.e. it does nothing) + bool ODIN_FOREIGN_ERROR_PROCEDURES; + + ErrorPosStyle ODIN_ERROR_POS_STYLE; TargetEndianKind endian_kind; @@ -190,14 +241,19 @@ struct BuildContext { bool show_help; + Array build_paths; // Contains `Path` objects to output filename, pdb, resource and intermediate files. + // BuildPath enum contains the indices of paths we know *before* the work starts. + String out_filepath; String resource_filepath; String pdb_filepath; + bool has_resource; String link_flags; String extra_linker_flags; String extra_assembler_flags; String microarch; + String target_features; BuildModeKind build_mode; bool generate_docs; i32 optimization_level; @@ -243,6 +299,12 @@ struct BuildContext { bool copy_file_contents; + bool disallow_rtti; + + RelocMode reloc_mode; + bool disable_red_zone; + + u32 cmd_doc_flags; Array extra_packages; @@ -254,10 +316,9 @@ struct BuildContext { isize thread_count; PtrMap defined_values; + }; - - gb_global BuildContext build_context = {0}; bool global_warnings_as_errors(void) { @@ -268,9 +329,9 @@ bool global_ignore_warnings(void) { } -gb_global TargetMetrics target_windows_386 = { +gb_global TargetMetrics target_windows_i386 = { TargetOs_windows, - TargetArch_386, + TargetArch_i386, 4, 8, str_lit("i386-pc-windows-msvc"), @@ -284,9 +345,9 @@ gb_global TargetMetrics target_windows_amd64 = { str_lit("e-m:w-i64:64-f80:128-n8:16:32:64-S128"), }; -gb_global TargetMetrics target_linux_386 = { +gb_global TargetMetrics target_linux_i386 = { TargetOs_linux, - TargetArch_386, + TargetArch_i386, 4, 8, str_lit("i386-pc-linux-gnu"), @@ -300,6 +361,14 @@ gb_global TargetMetrics target_linux_amd64 = { str_lit("x86_64-pc-linux-gnu"), str_lit("e-m:w-i64:64-f80:128-n8:16:32:64-S128"), }; +gb_global TargetMetrics target_linux_arm64 = { + TargetOs_linux, + TargetArch_arm64, + 8, + 16, + str_lit("aarch64-linux-elf"), + str_lit("e-m:e-i8:8:32-i16:32-i64:64-i128:128-n32:64-S128"), +}; gb_global TargetMetrics target_darwin_amd64 = { TargetOs_darwin, @@ -319,9 +388,9 @@ gb_global TargetMetrics target_darwin_arm64 = { str_lit("e-m:o-i64:64-i128:128-n32:64-S128"), // TODO(bill): Is this correct? }; -gb_global TargetMetrics target_freebsd_386 = { +gb_global TargetMetrics target_freebsd_i386 = { TargetOs_freebsd, - TargetArch_386, + TargetArch_i386, 4, 8, str_lit("i386-unknown-freebsd-elf"), @@ -336,6 +405,15 @@ gb_global TargetMetrics target_freebsd_amd64 = { str_lit("e-m:w-i64:64-f80:128-n8:16:32:64-S128"), }; +gb_global TargetMetrics target_openbsd_amd64 = { + TargetOs_openbsd, + TargetArch_amd64, + 8, + 16, + str_lit("x86_64-unknown-openbsd-elf"), + str_lit("e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"), +}; + gb_global TargetMetrics target_essence_amd64 = { TargetOs_essence, TargetArch_amd64, @@ -381,6 +459,16 @@ gb_global TargetMetrics target_wasi_wasm32 = { // str_lit(""), // }; +gb_global TargetMetrics target_freestanding_amd64_sysv = { + TargetOs_freestanding, + TargetArch_amd64, + 8, + 16, + str_lit("x86_64-pc-none-gnu"), + str_lit("e-m:w-i64:64-f80:128-n8:16:32:64-S128"), + TargetABI_SysV, +}; + struct NamedTargetMetrics { @@ -392,16 +480,19 @@ gb_global NamedTargetMetrics named_targets[] = { { str_lit("darwin_amd64"), &target_darwin_amd64 }, { str_lit("darwin_arm64"), &target_darwin_arm64 }, { str_lit("essence_amd64"), &target_essence_amd64 }, - { str_lit("linux_386"), &target_linux_386 }, + { str_lit("linux_i386"), &target_linux_i386 }, { str_lit("linux_amd64"), &target_linux_amd64 }, - { str_lit("windows_386"), &target_windows_386 }, + { str_lit("linux_arm64"), &target_linux_arm64 }, + { str_lit("windows_i386"), &target_windows_i386 }, { str_lit("windows_amd64"), &target_windows_amd64 }, - { str_lit("freebsd_386"), &target_freebsd_386 }, + { str_lit("freebsd_i386"), &target_freebsd_i386 }, { str_lit("freebsd_amd64"), &target_freebsd_amd64 }, + { str_lit("openbsd_amd64"), &target_openbsd_amd64 }, { str_lit("freestanding_wasm32"), &target_freestanding_wasm32 }, { str_lit("wasi_wasm32"), &target_wasi_wasm32 }, { str_lit("js_wasm32"), &target_js_wasm32 }, - // { str_lit("freestanding_wasm64"), &target_freestanding_wasm64 }, + + { str_lit("freestanding_amd64_sysv"), &target_freestanding_amd64_sysv }, }; NamedTargetMetrics *selected_target_metrics; @@ -524,7 +615,6 @@ bool allow_check_foreign_filepath(void) { return true; } - // TODO(bill): OS dependent versions for the BuildContext // join_path // is_dir @@ -703,10 +793,38 @@ String internal_odin_root_dir(void) { len = readlink("/proc/curproc/exe", &path_buf[0], path_buf.count); #elif defined(GB_SYSTEM_DRAGONFLYBSD) len = readlink("/proc/curproc/file", &path_buf[0], path_buf.count); -#else +#elif defined(GB_SYSTEM_LINUX) len = readlink("/proc/self/exe", &path_buf[0], path_buf.count); +#elif defined(GB_SYSTEM_OPENBSD) + int error; + int mib[] = { + CTL_KERN, + KERN_PROC_ARGS, + getpid(), + KERN_PROC_ARGV, + }; + // get argv size + error = sysctl(mib, 4, NULL, (size_t *) &len, NULL, 0); + if (error == -1) { + // sysctl error + return make_string(nullptr, 0); + } + // get argv + char **argv = (char **)gb_malloc(len); + error = sysctl(mib, 4, argv, (size_t *) &len, NULL, 0); + if (error == -1) { + // sysctl error + gb_mfree(argv); + return make_string(nullptr, 0); + } + // copy argv[0] to path_buf + len = gb_strlen(argv[0]); + if(len < path_buf.count) { + gb_memmove(&path_buf[0], argv[0], len); + } + gb_mfree(argv); #endif - if(len == 0) { + if(len == 0 || len == -1) { return make_string(nullptr, 0); } if (len < path_buf.count) { @@ -834,6 +952,21 @@ bool has_asm_extension(String const &path) { return false; } +// temporary +char *token_pos_to_string(TokenPos const &pos) { + gbString s = gb_string_make_reserve(temporary_allocator(), 128); + String file = get_file_path_string(pos.file_id); + switch (build_context.ODIN_ERROR_POS_STYLE) { + default: /*fallthrough*/ + case ErrorPosStyle_Default: + s = gb_string_append_fmt(s, "%.*s(%d:%d)", LIT(file), pos.line, pos.column); + break; + case ErrorPosStyle_Unix: + s = gb_string_append_fmt(s, "%.*s:%d:%d:", LIT(file), pos.line, pos.column); + break; + } + return s; +} void init_build_context(TargetMetrics *cross_target) { BuildContext *bc = &build_context; @@ -846,25 +979,31 @@ void init_build_context(TargetMetrics *cross_target) { bc->ODIN_VENDOR = str_lit("odin"); bc->ODIN_VERSION = ODIN_VERSION; bc->ODIN_ROOT = odin_root_dir(); - switch (bc->build_mode) { - default: - case BuildMode_Executable: - bc->ODIN_BUILD_MODE = str_lit("executable"); - break; - case BuildMode_DynamicLibrary: - bc->ODIN_BUILD_MODE = str_lit("dynamic"); - break; - case BuildMode_Object: - bc->ODIN_BUILD_MODE = str_lit("object"); - break; - case BuildMode_Assembly: - bc->ODIN_BUILD_MODE = str_lit("assembly"); - break; - case BuildMode_LLVM_IR: - bc->ODIN_BUILD_MODE = str_lit("llvm-ir"); - break; + + { + char const *found = gb_get_env("ODIN_ERROR_POS_STYLE", permanent_allocator()); + if (found) { + ErrorPosStyle kind = ErrorPosStyle_Default; + String style = make_string_c(found); + style = string_trim_whitespace(style); + if (style == "" || style == "default" || style == "odin") { + kind = ErrorPosStyle_Default; + } else if (style == "unix" || style == "gcc" || style == "clang" || style == "llvm") { + kind = ErrorPosStyle_Unix; + } else { + gb_printf_err("Invalid ODIN_ERROR_POS_STYLE: got %.*s\n", LIT(style)); + gb_printf_err("Valid formats:\n"); + gb_printf_err("\t\"default\" or \"odin\"\n"); + gb_printf_err("\t\tpath(line:column) message\n"); + gb_printf_err("\t\"unix\"\n"); + gb_printf_err("\t\tpath:line:column: message\n"); + gb_exit(1); + } + + build_context.ODIN_ERROR_POS_STYLE = kind; + } } - + bc->copy_file_contents = true; TargetMetrics *metrics = nullptr; @@ -880,18 +1019,22 @@ void init_build_context(TargetMetrics *cross_target) { #endif #elif defined(GB_SYSTEM_FREEBSD) metrics = &target_freebsd_amd64; + #elif defined(GB_SYSTEM_OPENBSD) + metrics = &target_openbsd_amd64; + #elif defined(GB_CPU_ARM) + metrics = &target_linux_arm64; #else metrics = &target_linux_amd64; #endif #else #if defined(GB_SYSTEM_WINDOWS) - metrics = &target_windows_386; + metrics = &target_windows_i386; #elif defined(GB_SYSTEM_OSX) #error "Build Error: Unsupported architecture" #elif defined(GB_SYSTEM_FREEBSD) - metrics = &target_freebsd_386; + metrics = &target_freebsd_i386; #else - metrics = &target_linux_386; + metrics = &target_linux_i386; #endif #endif @@ -910,7 +1053,6 @@ void init_build_context(TargetMetrics *cross_target) { bc->metrics = *metrics; bc->ODIN_OS = target_os_names[metrics->os]; bc->ODIN_ARCH = target_arch_names[metrics->arch]; - bc->ODIN_ENDIAN = target_endian_names[target_endians[metrics->arch]]; bc->endian_kind = target_endians[metrics->arch]; bc->word_size = metrics->word_size; bc->max_align = metrics->max_align; @@ -920,6 +1062,21 @@ void init_build_context(TargetMetrics *cross_target) { bc->threaded_checker = true; #endif + if (bc->disable_red_zone) { + if (!!is_arch_wasm() && bc->metrics.os == TargetOs_freestanding) { + gb_printf_err("-disable-red-zone is not support for this target"); + gb_exit(1); + } + } + + if (bc->metrics.os == TargetOs_freestanding) { + bc->no_entry_point = true; + } else { + if (bc->disallow_rtti) { + gb_printf_err("-disallow-rtti is only allowed on freestanding targets\n"); + gb_exit(1); + } + } // NOTE(zangent): The linker flags to set the build architecture are different // across OSs. It doesn't make sense to allocate extra data on the heap @@ -937,8 +1094,11 @@ void init_build_context(TargetMetrics *cross_target) { case TargetOs_freebsd: bc->link_flags = str_lit("-arch x86-64 "); break; + case TargetOs_openbsd: + bc->link_flags = str_lit("-arch x86-64 "); + break; } - } else if (bc->metrics.arch == TargetArch_386) { + } else if (bc->metrics.arch == TargetArch_i386) { switch (bc->metrics.os) { case TargetOs_windows: bc->link_flags = str_lit("/machine:x86 "); @@ -959,6 +1119,9 @@ void init_build_context(TargetMetrics *cross_target) { case TargetOs_darwin: bc->link_flags = str_lit("-arch arm64 "); break; + case TargetOs_linux: + bc->link_flags = str_lit("-arch aarch64 "); + break; } } else if (is_arch_wasm()) { gbString link_flags = gb_string_make(heap_allocator(), " "); @@ -968,14 +1131,14 @@ void init_build_context(TargetMetrics *cross_target) { if (bc->metrics.arch == TargetArch_wasm64) { link_flags = gb_string_appendc(link_flags, "-mwas64 "); } - if (bc->metrics.os == TargetOs_freestanding) { + if (bc->no_entry_point) { link_flags = gb_string_appendc(link_flags, "--no-entry "); } bc->link_flags = make_string_c(link_flags); // Disallow on wasm - build_context.use_separate_modules = false; + bc->use_separate_modules = false; } else { gb_printf_err("Compiler Error: Unsupported architecture\n"); gb_exit(1); @@ -986,3 +1149,191 @@ void init_build_context(TargetMetrics *cross_target) { #undef LINK_FLAG_X64 #undef LINK_FLAG_386 } + +#if defined(GB_SYSTEM_WINDOWS) +// NOTE(IC): In order to find Visual C++ paths without relying on environment variables. +// NOTE(Jeroen): No longer needed in `main.cpp -> linker_stage`. We now resolve those paths in `init_build_paths`. +#include "microsoft_craziness.h" +#endif + +// NOTE(Jeroen): Set/create the output and other paths and report an error as appropriate. +// We've previously called `parse_build_flags`, so `out_filepath` should be set. +bool init_build_paths(String init_filename) { + gbAllocator ha = heap_allocator(); + BuildContext *bc = &build_context; + + // NOTE(Jeroen): We're pre-allocating BuildPathCOUNT slots so that certain paths are always at the same enumerated index. + array_init(&bc->build_paths, permanent_allocator(), BuildPathCOUNT); + + // [BuildPathMainPackage] Turn given init path into a `Path`, which includes normalizing it into a full path. + bc->build_paths[BuildPath_Main_Package] = path_from_string(ha, init_filename); + + bool produces_output_file = false; + if (bc->command_kind == Command_doc && bc->cmd_doc_flags & CmdDocFlag_DocFormat) { + produces_output_file = true; + } else if (bc->command_kind & Command__does_build) { + produces_output_file = true; + } + + if (!produces_output_file) { + // Command doesn't produce output files. We're done. + return true; + } + + #if defined(GB_SYSTEM_WINDOWS) + if (bc->resource_filepath.len > 0) { + bc->build_paths[BuildPath_RC] = path_from_string(ha, bc->resource_filepath); + bc->build_paths[BuildPath_RES] = path_from_string(ha, bc->resource_filepath); + bc->build_paths[BuildPath_RC].ext = copy_string(ha, STR_LIT("rc")); + bc->build_paths[BuildPath_RES].ext = copy_string(ha, STR_LIT("res")); + } + + if (bc->pdb_filepath.len > 0) { + bc->build_paths[BuildPath_PDB] = path_from_string(ha, bc->pdb_filepath); + } + + if ((bc->command_kind & Command__does_build) && (!bc->ignore_microsoft_magic)) { + // NOTE(ic): It would be nice to extend this so that we could specify the Visual Studio version that we want instead of defaulting to the latest. + Find_Result_Utf8 find_result = find_visual_studio_and_windows_sdk_utf8(); + + if (find_result.windows_sdk_version == 0) { + gb_printf_err("Windows SDK not found.\n"); + return false; + } + + GB_ASSERT(find_result.windows_sdk_um_library_path.len > 0); + GB_ASSERT(find_result.windows_sdk_ucrt_library_path.len > 0); + + if (find_result.windows_sdk_root.len > 0) { + bc->build_paths[BuildPath_Win_SDK_Root] = path_from_string(ha, find_result.windows_sdk_root); + } + + if (find_result.windows_sdk_um_library_path.len > 0) { + bc->build_paths[BuildPath_Win_SDK_UM_Lib] = path_from_string(ha, find_result.windows_sdk_um_library_path); + } + + if (find_result.windows_sdk_ucrt_library_path.len > 0) { + bc->build_paths[BuildPath_Win_SDK_UCRT_Lib] = path_from_string(ha, find_result.windows_sdk_ucrt_library_path); + } + + if (find_result.vs_exe_path.len > 0) { + bc->build_paths[BuildPath_VS_EXE] = path_from_string(ha, find_result.vs_exe_path); + } + + if (find_result.vs_library_path.len > 0) { + bc->build_paths[BuildPath_VS_LIB] = path_from_string(ha, find_result.vs_library_path); + } + + gb_free(ha, find_result.windows_sdk_root.text); + gb_free(ha, find_result.windows_sdk_um_library_path.text); + gb_free(ha, find_result.windows_sdk_ucrt_library_path.text); + gb_free(ha, find_result.vs_exe_path.text); + gb_free(ha, find_result.vs_library_path.text); + + } + #endif + + // All the build targets and OSes. + String output_extension; + + if (bc->command_kind == Command_doc && bc->cmd_doc_flags & CmdDocFlag_DocFormat) { + output_extension = STR_LIT("odin-doc"); + } else if (is_arch_wasm()) { + output_extension = STR_LIT("wasm"); + } else if (build_context.build_mode == BuildMode_Executable) { + // By default use a .bin executable extension. + output_extension = STR_LIT("bin"); + + if (build_context.metrics.os == TargetOs_windows) { + output_extension = STR_LIT("exe"); + } else if (build_context.cross_compiling && selected_target_metrics->metrics == &target_essence_amd64) { + output_extension = make_string(nullptr, 0); + } + } else if (build_context.build_mode == BuildMode_DynamicLibrary) { + // By default use a .so shared library extension. + output_extension = STR_LIT("so"); + + if (build_context.metrics.os == TargetOs_windows) { + output_extension = STR_LIT("dll"); + } else if (build_context.metrics.os == TargetOs_darwin) { + output_extension = STR_LIT("dylib"); + } + } else if (build_context.build_mode == BuildMode_Object) { + // By default use a .o object extension. + output_extension = STR_LIT("o"); + + if (build_context.metrics.os == TargetOs_windows) { + output_extension = STR_LIT("obj"); + } + } else if (build_context.build_mode == BuildMode_Assembly) { + // By default use a .S asm extension. + output_extension = STR_LIT("S"); + } else if (build_context.build_mode == BuildMode_LLVM_IR) { + output_extension = STR_LIT("ll"); + } else { + GB_PANIC("Unhandled build mode/target combination.\n"); + } + + if (bc->out_filepath.len > 0) { + bc->build_paths[BuildPath_Output] = path_from_string(ha, bc->out_filepath); + if (build_context.metrics.os == TargetOs_windows) { + String output_file = path_to_string(ha, bc->build_paths[BuildPath_Output]); + defer (gb_free(ha, output_file.text)); + if (path_is_directory(bc->build_paths[BuildPath_Output])) { + gb_printf_err("Output path %.*s is a directory.\n", LIT(output_file)); + return false; + } else if (bc->build_paths[BuildPath_Output].ext.len == 0) { + gb_printf_err("Output path %.*s must have an appropriate extension.\n", LIT(output_file)); + return false; + } + } + } else { + Path output_path; + + if (str_eq(init_filename, str_lit("."))) { + // We must name the output file after the current directory. + debugf("Output name will be created from current base name %.*s.\n", LIT(bc->build_paths[BuildPath_Main_Package].basename)); + String last_element = last_path_element(bc->build_paths[BuildPath_Main_Package].basename); + + if (last_element.len == 0) { + gb_printf_err("The output name is created from the last path element. `%.*s` has none. Use `-out:output_name.ext` to set it.\n", LIT(bc->build_paths[BuildPath_Main_Package].basename)); + return false; + } + output_path.basename = copy_string(ha, bc->build_paths[BuildPath_Main_Package].basename); + output_path.name = copy_string(ha, last_element); + + } else { + // Init filename was not 'current path'. + // Contruct the output name from the path elements as usual. + String output_name = remove_directory_from_path(init_filename); + output_name = remove_extension_from_path(output_name); + output_name = copy_string(ha, string_trim_whitespace(output_name)); + output_path = path_from_string(ha, output_name); + + // Replace extension. + if (output_path.ext.len > 0) { + gb_free(ha, output_path.ext.text); + } + } + output_path.ext = copy_string(ha, output_extension); + + bc->build_paths[BuildPath_Output] = output_path; + } + + // Do we have an extension? We might not if the output filename was supplied. + if (bc->build_paths[BuildPath_Output].ext.len == 0) { + if (build_context.metrics.os == TargetOs_windows || build_context.build_mode != BuildMode_Executable) { + bc->build_paths[BuildPath_Output].ext = copy_string(ha, output_extension); + } + } + + // Check if output path is a directory. + if (path_is_directory(bc->build_paths[BuildPath_Output])) { + String output_file = path_to_string(ha, bc->build_paths[BuildPath_Output]); + defer (gb_free(ha, output_file.text)); + gb_printf_err("Output path %.*s is a directory.\n", LIT(output_file)); + return false; + } + + return true; +} \ No newline at end of file diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index f93cf9886..6c7972d45 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -143,6 +143,270 @@ void check_or_return_split_types(CheckerContext *c, Operand *x, String const &na } +bool does_require_msgSend_stret(Type *return_type) { + if (return_type == nullptr) { + return false; + } + if (build_context.metrics.arch == TargetArch_i386 || build_context.metrics.arch == TargetArch_amd64) { + i64 struct_limit = type_size_of(t_uintptr) << 1; + return type_size_of(return_type) > struct_limit; + } + if (build_context.metrics.arch == TargetArch_arm64) { + return false; + } + + // if (build_context.metrics.arch == TargetArch_arm32) { + // i64 struct_limit = type_size_of(t_uintptr); + // // NOTE(bill): This is technically wrong + // return is_type_struct(return_type) && !is_type_raw_union(return_type) && type_size_of(return_type) > struct_limit; + // } + GB_PANIC("unsupported architecture"); + return false; +} + +ObjcMsgKind get_objc_proc_kind(Type *return_type) { + if (return_type == nullptr) { + return ObjcMsg_normal; + } + + if (build_context.metrics.arch == TargetArch_i386 || build_context.metrics.arch == TargetArch_amd64) { + if (is_type_float(return_type)) { + return ObjcMsg_fpret; + } + if (build_context.metrics.arch == TargetArch_amd64) { + if (is_type_complex(return_type)) { + // URL: https://github.com/opensource-apple/objc4/blob/cd5e62a5597ea7a31dccef089317abb3a661c154/runtime/message.h#L143-L159 + return ObjcMsg_fpret; + } + } + } + if (build_context.metrics.arch != TargetArch_arm64) { + if (does_require_msgSend_stret(return_type)) { + return ObjcMsg_stret; + } + } + return ObjcMsg_normal; +} + +void add_objc_proc_type(CheckerContext *c, Ast *call, Type *return_type, Slice param_types) { + ObjcMsgKind kind = get_objc_proc_kind(return_type); + + Scope *scope = create_scope(c->info, nullptr); + + // NOTE(bill, 2022-02-08): the backend's ABI handling should handle this correctly, I hope + Type *params = alloc_type_tuple(); + { + auto variables = array_make(permanent_allocator(), 0, param_types.count); + + for_array(i, param_types) { + Type *type = param_types[i]; + Entity *param = alloc_entity_param(scope, blank_token, type, false, true); + array_add(&variables, param); + } + params->Tuple.variables = slice_from_array(variables); + } + + Type *results = alloc_type_tuple(); + if (return_type) { + auto variables = array_make(permanent_allocator(), 1); + results->Tuple.variables = slice_from_array(variables); + Entity *param = alloc_entity_param(scope, blank_token, return_type, false, true); + results->Tuple.variables[0] = param; + } + + + ObjcMsgData data = {}; + data.kind = kind; + data.proc_type = alloc_type_proc(scope, params, param_types.count, results, results->Tuple.variables.count, false, ProcCC_CDecl); + + mutex_lock(&c->info->objc_types_mutex); + map_set(&c->info->objc_msgSend_types, call, data); + mutex_unlock(&c->info->objc_types_mutex); + + try_to_add_package_dependency(c, "runtime", "objc_msgSend"); + try_to_add_package_dependency(c, "runtime", "objc_msgSend_fpret"); + try_to_add_package_dependency(c, "runtime", "objc_msgSend_fp2ret"); + try_to_add_package_dependency(c, "runtime", "objc_msgSend_stret"); +} + +bool is_constant_string(CheckerContext *c, String const &builtin_name, Ast *expr, String *name_) { + Operand op = {}; + check_expr(c, &op, expr); + if (op.mode == Addressing_Constant && op.value.kind == ExactValue_String) { + if (name_) *name_ = op.value.value_string; + return true; + } + gbString e = expr_to_string(op.expr); + gbString t = type_to_string(op.type); + error(op.expr, "'%.*s' expected a constant string value, got %s of type %s", LIT(builtin_name), e, t); + gb_string_free(t); + gb_string_free(e); + return false; +} + +bool check_builtin_objc_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 id, Type *type_hint) { + String builtin_name = builtin_procs[id].name; + + if (build_context.metrics.os != TargetOs_darwin) { + // allow on doc generation (e.g. Metal stuff) + if (build_context.command_kind != Command_doc && build_context.command_kind != Command_check) { + error(call, "'%.*s' only works on darwin", LIT(builtin_name)); + } + } + + + ast_node(ce, CallExpr, call); + switch (id) { + default: + GB_PANIC("Implement objective built-in procedure: %.*s", LIT(builtin_name)); + return false; + + case BuiltinProc_objc_send: { + Type *return_type = nullptr; + + Operand rt = {}; + check_expr_or_type(c, &rt, ce->args[0]); + if (rt.mode == Addressing_Type) { + return_type = rt.type; + } else if (is_operand_nil(rt)) { + return_type = nullptr; + } else { + gbString e = expr_to_string(rt.expr); + error(rt.expr, "'%.*s' expected a type or nil to define the return type of the Objective-C call, got %s", LIT(builtin_name), e); + gb_string_free(e); + return false; + } + + operand->type = return_type; + operand->mode = return_type ? Addressing_Value : Addressing_NoValue; + + String class_name = {}; + String sel_name = {}; + + Type *sel_type = t_objc_SEL; + Operand self = {}; + check_expr_or_type(c, &self, ce->args[1]); + if (self.mode == Addressing_Type) { + if (!is_type_objc_object(self.type)) { + gbString t = type_to_string(self.type); + error(self.expr, "'%.*s' expected a type or value derived from intrinsics.objc_object, got type %s", LIT(builtin_name), t); + gb_string_free(t); + return false; + } + if (!has_type_got_objc_class_attribute(self.type)) { + gbString t = type_to_string(self.type); + error(self.expr, "'%.*s' expected a named type with the attribute @(obj_class=) , got type %s", LIT(builtin_name), t); + gb_string_free(t); + return false; + } + + sel_type = t_objc_Class; + } else if (!is_operand_value(self) || !check_is_assignable_to(c, &self, t_objc_id)) { + gbString e = expr_to_string(self.expr); + gbString t = type_to_string(self.type); + error(self.expr, "'%.*s' expected a type or value derived from intrinsics.objc_object, got '%s' of type %s", LIT(builtin_name), e, t); + gb_string_free(t); + gb_string_free(e); + return false; + } else if (!is_type_pointer(self.type)) { + gbString e = expr_to_string(self.expr); + gbString t = type_to_string(self.type); + error(self.expr, "'%.*s' expected a pointer of a value derived from intrinsics.objc_object, got '%s' of type %s", LIT(builtin_name), e, t); + gb_string_free(t); + gb_string_free(e); + return false; + } else { + Type *type = type_deref(self.type); + if (!(type->kind == Type_Named && + type->Named.type_name != nullptr && + type->Named.type_name->TypeName.objc_class_name != "")) { + gbString t = type_to_string(type); + error(self.expr, "'%.*s' expected a named type with the attribute @(obj_class=) , got type %s", LIT(builtin_name), t); + gb_string_free(t); + return false; + } + } + + + if (!is_constant_string(c, builtin_name, ce->args[2], &sel_name)) { + return false; + } + + isize const arg_offset = 1; + auto param_types = slice_make(permanent_allocator(), ce->args.count-arg_offset); + param_types[0] = t_objc_id; + param_types[1] = sel_type; + + for (isize i = 2+arg_offset; i < ce->args.count; i++) { + Operand x = {}; + check_expr(c, &x, ce->args[i]); + param_types[i-arg_offset] = x.type; + } + + add_objc_proc_type(c, call, return_type, param_types); + + return true; + } break; + + case BuiltinProc_objc_find_selector: + case BuiltinProc_objc_find_class: + case BuiltinProc_objc_register_selector: + case BuiltinProc_objc_register_class: + { + String sel_name = {}; + if (!is_constant_string(c, builtin_name, ce->args[0], &sel_name)) { + return false; + } + + switch (id) { + case BuiltinProc_objc_find_selector: + case BuiltinProc_objc_register_selector: + operand->type = t_objc_SEL; + break; + case BuiltinProc_objc_find_class: + case BuiltinProc_objc_register_class: + operand->type = t_objc_Class; + break; + + } + operand->mode = Addressing_Value; + + try_to_add_package_dependency(c, "runtime", "objc_lookUpClass"); + try_to_add_package_dependency(c, "runtime", "sel_registerName"); + try_to_add_package_dependency(c, "runtime", "objc_allocateClassPair"); + return true; + } break; + } +} + +bool check_atomic_memory_order_argument(CheckerContext *c, Ast *expr, String const &builtin_name, OdinAtomicMemoryOrder *memory_order_, char const *extra_message = nullptr) { + Operand x = {}; + check_expr_with_type_hint(c, &x, expr, t_atomic_memory_order); + if (x.mode == Addressing_Invalid) { + return false; + } + if (!are_types_identical(x.type, t_atomic_memory_order) || x.mode != Addressing_Constant) { + gbString str = type_to_string(x.type); + if (extra_message) { + error(x.expr, "Expected a constant Atomic_Memory_Order value for the %s of '%.*s', got %s", extra_message, LIT(builtin_name), str); + } else { + error(x.expr, "Expected a constant Atomic_Memory_Order value for '%.*s', got %s", LIT(builtin_name), str); + } + gb_string_free(str); + return false; + } + i64 value = exact_value_to_i64(x.value); + if (value < 0 || value >= OdinAtomicMemoryOrder_COUNT) { + error(x.expr, "Illegal Atomic_Memory_Order value, got %lld", cast(long long)value); + return false; + } + if (memory_order_) { + *memory_order_ = cast(OdinAtomicMemoryOrder)value; + } + + return true; + +} bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 id, Type *type_hint) { ast_node(ce, CallExpr, call); @@ -179,9 +443,21 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 case BuiltinProc_len: case BuiltinProc_min: case BuiltinProc_max: + case BuiltinProc_type_is_subtype_of: + case BuiltinProc_objc_send: + case BuiltinProc_objc_find_selector: + case BuiltinProc_objc_find_class: + case BuiltinProc_objc_register_selector: + case BuiltinProc_objc_register_class: + case BuiltinProc_atomic_type_is_lock_free: // NOTE(bill): The first arg may be a Type, this will be checked case by case break; + case BuiltinProc_atomic_thread_fence: + case BuiltinProc_atomic_signal_fence: + // NOTE(bill): first type will require a type hint + break; + case BuiltinProc_DIRECTIVE: { ast_node(bd, BasicDirective, ce->proc); String name = bd->name.string; @@ -202,7 +478,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 break; } - String builtin_name = builtin_procs[id].name;; + String builtin_name = builtin_procs[id].name; if (ce->args.count > 0) { @@ -219,6 +495,19 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 GB_PANIC("Implement built-in procedure: %.*s", LIT(builtin_name)); break; + case BuiltinProc_objc_send: + case BuiltinProc_objc_find_selector: + case BuiltinProc_objc_find_class: + case BuiltinProc_objc_register_selector: + case BuiltinProc_objc_register_class: + return check_builtin_objc_procedure(c, operand, call, id, type_hint); + + case BuiltinProc___entry_point: + operand->mode = Addressing_NoValue; + operand->type = nullptr; + mpmc_enqueue(&c->info->intrinsics_entry_point_usage, call); + break; + case BuiltinProc_DIRECTIVE: { ast_node(bd, BasicDirective, ce->proc); String name = bd->name.string; @@ -542,8 +831,8 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 } } else if (name == "assert") { - if (ce->args.count != 1) { - error(call, "'#assert' expects 1 argument, got %td", ce->args.count); + if (ce->args.count != 1 && ce->args.count != 2) { + error(call, "'#assert' expects either 1 or 2 arguments, got %td", ce->args.count); return false; } if (!is_type_boolean(operand->type) || operand->mode != Addressing_Constant) { @@ -552,15 +841,37 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 gb_string_free(str); return false; } + if (ce->args.count == 2) { + Ast *arg = unparen_expr(ce->args[1]); + if (arg == nullptr || arg->kind != Ast_BasicLit || arg->BasicLit.token.kind != Token_String) { + gbString str = expr_to_string(arg); + error(call, "'%s' is not a constant string", str); + gb_string_free(str); + return false; + } + } + if (!operand->value.value_bool) { - gbString arg = expr_to_string(ce->args[0]); - error(call, "Compile time assertion: %s", arg); + gbString arg1 = expr_to_string(ce->args[0]); + gbString arg2 = {}; + + if (ce->args.count == 1) { + error(call, "Compile time assertion: %s", arg1); + } else { + arg2 = expr_to_string(ce->args[1]); + error(call, "Compile time assertion: %s (%s)", arg1, arg2); + } + if (c->proc_name != "") { gbString str = type_to_string(c->curr_proc_sig); error_line("\tCalled within '%.*s' :: %s\n", LIT(c->proc_name), str); gb_string_free(str); } - gb_string_free(arg); + + gb_string_free(arg1); + if (ce->args.count == 2) { + gb_string_free(arg2); + } } operand->type = t_untyped_bool; @@ -698,7 +1009,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 mode = Addressing_Constant; value = exact_value_i64(at->EnumeratedArray.count); type = t_untyped_integer; - } else if (is_type_slice(op_type) && id == BuiltinProc_len) { + } else if ((is_type_slice(op_type) || is_type_relative_slice(op_type)) && id == BuiltinProc_len) { mode = Addressing_Value; } else if (is_type_dynamic_array(op_type)) { mode = Addressing_Value; @@ -852,7 +1163,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 Selection sel = lookup_field(type, field_name, false); if (sel.entity == nullptr) { - gbString type_str = type_to_string(type); + gbString type_str = type_to_string_shorthand(type); error(ce->args[0], "'%s' has no field named '%.*s'", type_str, LIT(field_name)); gb_string_free(type_str); @@ -864,7 +1175,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 return false; } if (sel.indirect) { - gbString type_str = type_to_string(type); + gbString type_str = type_to_string_shorthand(type); error(ce->args[0], "Field '%.*s' is embedded via a pointer in '%s'", LIT(field_name), type_str); gb_string_free(type_str); @@ -925,7 +1236,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 Selection sel = lookup_field(type, field_name, false); if (sel.entity == nullptr) { - gbString type_str = type_to_string(type); + gbString type_str = type_to_string_shorthand(type); error(ce->args[0], "'%s' has no field named '%.*s'", type_str, LIT(field_name)); gb_string_free(type_str); @@ -937,7 +1248,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 return false; } if (sel.indirect) { - gbString type_str = type_to_string(type); + gbString type_str = type_to_string_shorthand(type); error(ce->args[0], "Field '%.*s' is embedded via a pointer in '%s'", LIT(field_name), type_str); gb_string_free(type_str); @@ -987,6 +1298,10 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 if (c->scope->flags&ScopeFlag_Global) { compiler_error("'type_info_of' Cannot be declared within the runtime package due to how the internals of the compiler works"); } + if (build_context.disallow_rtti) { + error(call, "'%.*s' has been disallowed", LIT(builtin_name)); + return false; + } // NOTE(bill): The type information may not be setup yet init_core_type_info(c->checker); @@ -999,9 +1314,9 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 Type *t = o.type; if (t == nullptr || t == t_invalid || is_type_asm_proc(o.type) || is_type_polymorphic(t)) { if (is_type_polymorphic(t)) { - error(ce->args[0], "Invalid argument for 'type_info_of', unspecialized polymorphic type"); + error(ce->args[0], "Invalid argument for '%.*s', unspecialized polymorphic type", LIT(builtin_name)); } else { - error(ce->args[0], "Invalid argument for 'type_info_of'"); + error(ce->args[0], "Invalid argument for '%.*s'", LIT(builtin_name)); } return false; } @@ -1012,7 +1327,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 if (is_operand_value(o) && is_type_typeid(t)) { add_package_dependency(c, "runtime", "__type_info_of"); } else if (o.mode != Addressing_Type) { - error(expr, "Expected a type or typeid for 'type_info_of'"); + error(expr, "Expected a type or typeid for '%.*s'", LIT(builtin_name)); return false; } @@ -1026,6 +1341,10 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 if (c->scope->flags&ScopeFlag_Global) { compiler_error("'typeid_of' Cannot be declared within the runtime package due to how the internals of the compiler works"); } + if (build_context.disallow_rtti) { + error(call, "'%.*s' has been disallowed", LIT(builtin_name)); + return false; + } // NOTE(bill): The type information may not be setup yet init_core_type_info(c->checker); @@ -1037,7 +1356,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 } Type *t = o.type; if (t == nullptr || t == t_invalid || is_type_asm_proc(o.type) || is_type_polymorphic(operand->type)) { - error(ce->args[0], "Invalid argument for 'typeid_of'"); + error(ce->args[0], "Invalid argument for '%.*s'", LIT(builtin_name)); return false; } t = default_type(t); @@ -1045,7 +1364,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 add_type_info_type(c, t); if (o.mode != Addressing_Type) { - error(expr, "Expected a type for 'typeid_of'"); + error(expr, "Expected a type for '%.*s'", LIT(builtin_name)); return false; } @@ -1858,7 +2177,14 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 f64 r = operand->value.value_complex->real; f64 i = operand->value.value_complex->imag; operand->value = exact_value_float(gb_sqrt(r*r + i*i)); - + break; + } + case ExactValue_Quaternion: { + f64 r = operand->value.value_quaternion->real; + f64 i = operand->value.value_quaternion->imag; + f64 j = operand->value.value_quaternion->jmag; + f64 k = operand->value.value_quaternion->kmag; + operand->value = exact_value_float(gb_sqrt(r*r + i*i + j*j + k*k)); break; } default: @@ -1877,10 +2203,10 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 } } - if (is_type_complex(operand->type)) { + if (is_type_complex_or_quaternion(operand->type)) { operand->type = base_complex_elem_type(operand->type); } - GB_ASSERT(!is_type_complex(operand->type)); + GB_ASSERT(!is_type_complex_or_quaternion(operand->type)); break; } @@ -2170,9 +2496,43 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 } operand->mode = Addressing_Value; - if (is_type_array(t)) { + if (t->kind == Type_Array) { + i32 rank = type_math_rank(t); // Do nothing - operand->type = x.type; + operand->type = x.type; + if (rank > 2) { + gbString s = type_to_string(x.type); + error(call, "'%.*s' expects a matrix or array with a rank of 2, got %s of rank %d", LIT(builtin_name), s, rank); + gb_string_free(s); + return false; + } else if (rank == 2) { + Type *inner = base_type(t->Array.elem); + GB_ASSERT(inner->kind == Type_Array); + Type *elem = inner->Array.elem; + Type *array_inner = alloc_type_array(elem, t->Array.count); + Type *array_outer = alloc_type_array(array_inner, inner->Array.count); + operand->type = array_outer; + + i64 elements = t->Array.count*inner->Array.count; + i64 size = type_size_of(operand->type); + if (!is_type_valid_for_matrix_elems(elem)) { + gbString s = type_to_string(x.type); + error(call, "'%.*s' expects a matrix or array with a base element type of an integer, float, or complex number, got %s", LIT(builtin_name), s); + gb_string_free(s); + } else if (elements > MATRIX_ELEMENT_COUNT_MAX) { + gbString s = type_to_string(x.type); + error(call, "'%.*s' expects a matrix or array with a maximum of %d elements, got %s with %lld elements", LIT(builtin_name), MATRIX_ELEMENT_COUNT_MAX, s, elements); + gb_string_free(s); + } else if (elements > MATRIX_ELEMENT_COUNT_MAX) { + gbString s = type_to_string(x.type); + error(call, "'%.*s' expects a matrix or array with non-zero elements, got %s", LIT(builtin_name), MATRIX_ELEMENT_COUNT_MAX, s); + gb_string_free(s); + } else if (size > MATRIX_ELEMENT_MAX_SIZE) { + gbString s = type_to_string(x.type); + error(call, "Too large of a type for '%.*s', got %s of size %lld, maximum size %d", LIT(builtin_name), s, cast(long long)size, MATRIX_ELEMENT_MAX_SIZE); + gb_string_free(s); + } + } } else { GB_ASSERT(t->kind == Type_Matrix); operand->type = alloc_type_matrix(t->Matrix.elem, t->Matrix.column_count, t->Matrix.row_count); @@ -2895,11 +3255,56 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 break; - case BuiltinProc_atomic_fence: - case BuiltinProc_atomic_fence_acq: - case BuiltinProc_atomic_fence_rel: - case BuiltinProc_atomic_fence_acqrel: - operand->mode = Addressing_NoValue; + case BuiltinProc_atomic_type_is_lock_free: + { + Ast *expr = ce->args[0]; + Operand o = {}; + check_expr_or_type(c, &o, expr); + + if (o.mode == Addressing_Invalid || o.mode == Addressing_Builtin) { + return false; + } + if (o.type == nullptr || o.type == t_invalid || is_type_asm_proc(o.type)) { + error(o.expr, "Invalid argument to '%.*s'", LIT(builtin_name)); + return false; + } + if (is_type_polymorphic(o.type)) { + error(o.expr, "'%.*s' of polymorphic type cannot be determined", LIT(builtin_name)); + return false; + } + if (is_type_untyped(o.type)) { + error(o.expr, "'%.*s' of untyped type is not allowed", LIT(builtin_name)); + return false; + } + Type *t = o.type; + bool is_lock_free = is_type_lock_free(t); + + operand->mode = Addressing_Constant; + operand->type = t_untyped_bool; + operand->value = exact_value_bool(is_lock_free); + break; + } + + case BuiltinProc_atomic_thread_fence: + case BuiltinProc_atomic_signal_fence: + { + OdinAtomicMemoryOrder memory_order = {}; + if (!check_atomic_memory_order_argument(c, ce->args[0], builtin_name, &memory_order)) { + return false; + } + switch (memory_order) { + case OdinAtomicMemoryOrder_acquire: + case OdinAtomicMemoryOrder_release: + case OdinAtomicMemoryOrder_acq_rel: + case OdinAtomicMemoryOrder_seq_cst: + break; + default: + error(ce->args[0], "Illegal memory ordering for '%.*s', got .%s", LIT(builtin_name), OdinAtomicMemoryOrder_strings[memory_order]); + break; + } + + operand->mode = Addressing_NoValue; + } break; case BuiltinProc_volatile_store: @@ -2907,9 +3312,6 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 case BuiltinProc_unaligned_store: /*fallthrough*/ case BuiltinProc_atomic_store: - case BuiltinProc_atomic_store_rel: - case BuiltinProc_atomic_store_relaxed: - case BuiltinProc_atomic_store_unordered: { Type *elem = nullptr; if (!is_type_normal_pointer(operand->type, &elem)) { @@ -2925,60 +3327,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 break; } - case BuiltinProc_volatile_load: - /*fallthrough*/ - case BuiltinProc_unaligned_load: - /*fallthrough*/ - case BuiltinProc_atomic_load: - case BuiltinProc_atomic_load_acq: - case BuiltinProc_atomic_load_relaxed: - case BuiltinProc_atomic_load_unordered: - { - Type *elem = nullptr; - if (!is_type_normal_pointer(operand->type, &elem)) { - error(operand->expr, "Expected a pointer for '%.*s'", LIT(builtin_name)); - return false; - } - operand->type = elem; - operand->mode = Addressing_Value; - break; - } - - case BuiltinProc_atomic_add: - case BuiltinProc_atomic_add_acq: - case BuiltinProc_atomic_add_rel: - case BuiltinProc_atomic_add_acqrel: - case BuiltinProc_atomic_add_relaxed: - case BuiltinProc_atomic_sub: - case BuiltinProc_atomic_sub_acq: - case BuiltinProc_atomic_sub_rel: - case BuiltinProc_atomic_sub_acqrel: - case BuiltinProc_atomic_sub_relaxed: - case BuiltinProc_atomic_and: - case BuiltinProc_atomic_and_acq: - case BuiltinProc_atomic_and_rel: - case BuiltinProc_atomic_and_acqrel: - case BuiltinProc_atomic_and_relaxed: - case BuiltinProc_atomic_nand: - case BuiltinProc_atomic_nand_acq: - case BuiltinProc_atomic_nand_rel: - case BuiltinProc_atomic_nand_acqrel: - case BuiltinProc_atomic_nand_relaxed: - case BuiltinProc_atomic_or: - case BuiltinProc_atomic_or_acq: - case BuiltinProc_atomic_or_rel: - case BuiltinProc_atomic_or_acqrel: - case BuiltinProc_atomic_or_relaxed: - case BuiltinProc_atomic_xor: - case BuiltinProc_atomic_xor_acq: - case BuiltinProc_atomic_xor_rel: - case BuiltinProc_atomic_xor_acqrel: - case BuiltinProc_atomic_xor_relaxed: - case BuiltinProc_atomic_xchg: - case BuiltinProc_atomic_xchg_acq: - case BuiltinProc_atomic_xchg_rel: - case BuiltinProc_atomic_xchg_acqrel: - case BuiltinProc_atomic_xchg_relaxed: + case BuiltinProc_atomic_store_explicit: { Type *elem = nullptr; if (!is_type_normal_pointer(operand->type, &elem)) { @@ -2989,30 +3338,147 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 check_expr_with_type_hint(c, &x, ce->args[1], elem); check_assignment(c, &x, elem, builtin_name); + OdinAtomicMemoryOrder memory_order = {}; + if (!check_atomic_memory_order_argument(c, ce->args[2], builtin_name, &memory_order)) { + return false; + } + switch (memory_order) { + case OdinAtomicMemoryOrder_consume: + case OdinAtomicMemoryOrder_acquire: + case OdinAtomicMemoryOrder_acq_rel: + error(ce->args[2], "Illegal memory order .%s for '%.*s'", OdinAtomicMemoryOrder_strings[memory_order], LIT(builtin_name)); + break; + } + + operand->type = nullptr; + operand->mode = Addressing_NoValue; + break; + } + + + case BuiltinProc_volatile_load: + /*fallthrough*/ + case BuiltinProc_unaligned_load: + /*fallthrough*/ + case BuiltinProc_atomic_load: + { + Type *elem = nullptr; + if (!is_type_normal_pointer(operand->type, &elem)) { + error(operand->expr, "Expected a pointer for '%.*s'", LIT(builtin_name)); + return false; + } operand->type = elem; operand->mode = Addressing_Value; break; } - case BuiltinProc_atomic_cxchg: - case BuiltinProc_atomic_cxchg_acq: - case BuiltinProc_atomic_cxchg_rel: - case BuiltinProc_atomic_cxchg_acqrel: - case BuiltinProc_atomic_cxchg_relaxed: - case BuiltinProc_atomic_cxchg_failrelaxed: - case BuiltinProc_atomic_cxchg_failacq: - case BuiltinProc_atomic_cxchg_acq_failrelaxed: - case BuiltinProc_atomic_cxchg_acqrel_failrelaxed: + case BuiltinProc_atomic_load_explicit: + { + Type *elem = nullptr; + if (!is_type_normal_pointer(operand->type, &elem)) { + error(operand->expr, "Expected a pointer for '%.*s'", LIT(builtin_name)); + return false; + } - case BuiltinProc_atomic_cxchgweak: - case BuiltinProc_atomic_cxchgweak_acq: - case BuiltinProc_atomic_cxchgweak_rel: - case BuiltinProc_atomic_cxchgweak_acqrel: - case BuiltinProc_atomic_cxchgweak_relaxed: - case BuiltinProc_atomic_cxchgweak_failrelaxed: - case BuiltinProc_atomic_cxchgweak_failacq: - case BuiltinProc_atomic_cxchgweak_acq_failrelaxed: - case BuiltinProc_atomic_cxchgweak_acqrel_failrelaxed: + OdinAtomicMemoryOrder memory_order = {}; + if (!check_atomic_memory_order_argument(c, ce->args[1], builtin_name, &memory_order)) { + return false; + } + + switch (memory_order) { + case OdinAtomicMemoryOrder_release: + case OdinAtomicMemoryOrder_acq_rel: + error(ce->args[1], "Illegal memory order .%s for '%.*s'", OdinAtomicMemoryOrder_strings[memory_order], LIT(builtin_name)); + break; + } + + operand->type = elem; + operand->mode = Addressing_Value; + break; + } + + case BuiltinProc_atomic_add: + case BuiltinProc_atomic_sub: + case BuiltinProc_atomic_and: + case BuiltinProc_atomic_nand: + case BuiltinProc_atomic_or: + case BuiltinProc_atomic_xor: + case BuiltinProc_atomic_exchange: + { + Type *elem = nullptr; + if (!is_type_normal_pointer(operand->type, &elem)) { + error(operand->expr, "Expected a pointer for '%.*s'", LIT(builtin_name)); + return false; + } + Operand x = {}; + check_expr_with_type_hint(c, &x, ce->args[1], elem); + check_assignment(c, &x, elem, builtin_name); + + Type *t = type_deref(operand->type); + switch (id) { + case BuiltinProc_atomic_add: + case BuiltinProc_atomic_sub: + if (!is_type_numeric(t)) { + gbString str = type_to_string(t); + error(operand->expr, "Expected a numeric type for '%.*s', got %s", LIT(builtin_name), str); + gb_string_free(str); + } else if (is_type_different_to_arch_endianness(t)) { + gbString str = type_to_string(t); + error(operand->expr, "Expected a numeric type of the same platform endianness for '%.*s', got %s", LIT(builtin_name), str); + gb_string_free(str); + } + } + + operand->type = elem; + operand->mode = Addressing_Value; + break; + } + + case BuiltinProc_atomic_add_explicit: + case BuiltinProc_atomic_sub_explicit: + case BuiltinProc_atomic_and_explicit: + case BuiltinProc_atomic_nand_explicit: + case BuiltinProc_atomic_or_explicit: + case BuiltinProc_atomic_xor_explicit: + case BuiltinProc_atomic_exchange_explicit: + { + Type *elem = nullptr; + if (!is_type_normal_pointer(operand->type, &elem)) { + error(operand->expr, "Expected a pointer for '%.*s'", LIT(builtin_name)); + return false; + } + Operand x = {}; + check_expr_with_type_hint(c, &x, ce->args[1], elem); + check_assignment(c, &x, elem, builtin_name); + + + if (!check_atomic_memory_order_argument(c, ce->args[2], builtin_name, nullptr)) { + return false; + } + + Type *t = type_deref(operand->type); + switch (id) { + case BuiltinProc_atomic_add_explicit: + case BuiltinProc_atomic_sub_explicit: + if (!is_type_numeric(t)) { + gbString str = type_to_string(t); + error(operand->expr, "Expected a numeric type for '%.*s', got %s", LIT(builtin_name), str); + gb_string_free(str); + } else if (is_type_different_to_arch_endianness(t)) { + gbString str = type_to_string(t); + error(operand->expr, "Expected a numeric type of the same platform endianness for '%.*s', got %s", LIT(builtin_name), str); + gb_string_free(str); + } + break; + } + + operand->type = elem; + operand->mode = Addressing_Value; + break; + } + + case BuiltinProc_atomic_compare_exchange_strong: + case BuiltinProc_atomic_compare_exchange_weak: { Type *elem = nullptr; if (!is_type_normal_pointer(operand->type, &elem)) { @@ -3026,11 +3492,110 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 check_assignment(c, &x, elem, builtin_name); check_assignment(c, &y, elem, builtin_name); + Type *t = type_deref(operand->type); + if (!is_type_comparable(t)) { + gbString str = type_to_string(t); + error(operand->expr, "Expected a comparable type for '%.*s', got %s", LIT(builtin_name), str); + gb_string_free(str); + } + + operand->mode = Addressing_OptionalOk; + operand->type = elem; + break; + } + + case BuiltinProc_atomic_compare_exchange_strong_explicit: + case BuiltinProc_atomic_compare_exchange_weak_explicit: + { + Type *elem = nullptr; + if (!is_type_normal_pointer(operand->type, &elem)) { + error(operand->expr, "Expected a pointer for '%.*s'", LIT(builtin_name)); + return false; + } + Operand x = {}; + Operand y = {}; + check_expr_with_type_hint(c, &x, ce->args[1], elem); + check_expr_with_type_hint(c, &y, ce->args[2], elem); + check_assignment(c, &x, elem, builtin_name); + check_assignment(c, &y, elem, builtin_name); + + OdinAtomicMemoryOrder success_memory_order = {}; + OdinAtomicMemoryOrder failure_memory_order = {}; + if (!check_atomic_memory_order_argument(c, ce->args[3], builtin_name, &success_memory_order, "success ordering")) { + return false; + } + if (!check_atomic_memory_order_argument(c, ce->args[4], builtin_name, &failure_memory_order, "failure ordering")) { + return false; + } + + Type *t = type_deref(operand->type); + if (!is_type_comparable(t)) { + gbString str = type_to_string(t); + error(operand->expr, "Expected a comparable type for '%.*s', got %s", LIT(builtin_name), str); + gb_string_free(str); + } + + bool invalid_combination = false; + + switch (success_memory_order) { + case OdinAtomicMemoryOrder_relaxed: + case OdinAtomicMemoryOrder_release: + if (failure_memory_order != OdinAtomicMemoryOrder_relaxed) { + invalid_combination = true; + } + break; + case OdinAtomicMemoryOrder_consume: + switch (failure_memory_order) { + case OdinAtomicMemoryOrder_relaxed: + case OdinAtomicMemoryOrder_consume: + break; + default: + invalid_combination = true; + break; + } + break; + case OdinAtomicMemoryOrder_acquire: + case OdinAtomicMemoryOrder_acq_rel: + switch (failure_memory_order) { + case OdinAtomicMemoryOrder_relaxed: + case OdinAtomicMemoryOrder_consume: + case OdinAtomicMemoryOrder_acquire: + break; + default: + invalid_combination = true; + break; + } + break; + case OdinAtomicMemoryOrder_seq_cst: + switch (failure_memory_order) { + case OdinAtomicMemoryOrder_relaxed: + case OdinAtomicMemoryOrder_consume: + case OdinAtomicMemoryOrder_acquire: + case OdinAtomicMemoryOrder_seq_cst: + break; + default: + invalid_combination = true; + break; + } + break; + default: + invalid_combination = true; + break; + } + + + if (invalid_combination) { + error(ce->args[3], "Illegal memory order pairing for '%.*s', success = .%s, failure = .%s", + LIT(builtin_name), + OdinAtomicMemoryOrder_strings[success_memory_order], + OdinAtomicMemoryOrder_strings[failure_memory_order] + ); + } + operand->mode = Addressing_OptionalOk; operand->type = elem; break; } - break; case BuiltinProc_fixed_point_mul: case BuiltinProc_fixed_point_div: @@ -3211,8 +3776,9 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 case TargetOs_linux: case TargetOs_essence: case TargetOs_freebsd: + case TargetOs_openbsd: switch (build_context.metrics.arch) { - case TargetArch_386: + case TargetArch_i386: case TargetArch_amd64: case TargetArch_arm64: max_arg_count = 7; @@ -3297,9 +3863,11 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 case BuiltinProc_type_is_simple_compare: case BuiltinProc_type_is_dereferenceable: case BuiltinProc_type_is_valid_map_key: + case BuiltinProc_type_is_valid_matrix_elements: case BuiltinProc_type_is_named: case BuiltinProc_type_is_pointer: case BuiltinProc_type_is_array: + case BuiltinProc_type_is_enumerated_array: case BuiltinProc_type_is_slice: case BuiltinProc_type_is_dynamic_array: case BuiltinProc_type_is_map: @@ -3307,10 +3875,9 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 case BuiltinProc_type_is_union: case BuiltinProc_type_is_enum: case BuiltinProc_type_is_proc: - case BuiltinProc_type_is_bit_field: - case BuiltinProc_type_is_bit_field_value: case BuiltinProc_type_is_bit_set: case BuiltinProc_type_is_simd_vector: + case BuiltinProc_type_is_matrix: case BuiltinProc_type_is_specialized_polymorphic_record: case BuiltinProc_type_is_unspecialized_polymorphic_record: case BuiltinProc_type_has_nil: @@ -3359,6 +3926,37 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 break; } break; + case BuiltinProc_type_field_type: + { + Operand op = {}; + Type *bt = check_type(c, ce->args[0]); + Type *type = base_type(bt); + if (type == nullptr || type == t_invalid) { + error(ce->args[0], "Expected a type for '%.*s'", LIT(builtin_name)); + return false; + } + Operand x = {}; + check_expr(c, &x, ce->args[1]); + + if (!is_type_string(x.type) || x.mode != Addressing_Constant || x.value.kind != ExactValue_String) { + error(ce->args[1], "Expected a const string for field argument"); + return false; + } + + String field_name = x.value.value_string; + + Selection sel = lookup_field(type, field_name, false); + if (sel.index.count == 0) { + gbString t = type_to_string(type); + error(ce->args[1], "'%.*s' is not a field of type %s", LIT(field_name), t); + gb_string_free(t); + return false; + } + operand->mode = Addressing_Type; + operand->type = sel.entity->type; + break; + } + break; case BuiltinProc_type_is_specialization_of: { @@ -3678,6 +4276,31 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 break; + case BuiltinProc_type_is_subtype_of: + { + Operand op_src = {}; + Operand op_dst = {}; + + check_expr_or_type(c, &op_src, ce->args[0]); + if (op_src.mode != Addressing_Type) { + gbString e = expr_to_string(op_src.expr); + error(op_src.expr, "'%.*s' expects a type, got %s", LIT(builtin_name), e); + gb_string_free(e); + return false; + } + check_expr_or_type(c, &op_dst, ce->args[1]); + if (op_dst.mode != Addressing_Type) { + gbString e = expr_to_string(op_dst.expr); + error(op_dst.expr, "'%.*s' expects a type, got %s", LIT(builtin_name), e); + gb_string_free(e); + return false; + } + + operand->value = exact_value_bool(is_type_subtype_of(op_src.type, op_dst.type)); + operand->mode = Addressing_Constant; + operand->type = t_untyped_bool; + } break; + case BuiltinProc_type_field_index_of: { Operand op = {}; @@ -3767,6 +4390,87 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 operand->type = t_hasher_proc; break; } + + case BuiltinProc_constant_utf16_cstring: + { + String value = {}; + if (!is_constant_string(c, builtin_name, ce->args[0], &value)) { + return false; + } + operand->mode = Addressing_Value; + operand->type = alloc_type_multi_pointer(t_u16); + operand->value = {}; + break; + } + + + case BuiltinProc_wasm_memory_grow: + { + if (!is_arch_wasm()) { + error(call, "'%.*s' is only allowed on wasm targets", LIT(builtin_name)); + return false; + } + + Operand index = {}; + Operand delta = {}; + check_expr(c, &index, ce->args[0]); if (index.mode == Addressing_Invalid) return false; + check_expr(c, &delta, ce->args[1]); if (delta.mode == Addressing_Invalid) return false; + + convert_to_typed(c, &index, t_uintptr); if (index.mode == Addressing_Invalid) return false; + convert_to_typed(c, &delta, t_uintptr); if (delta.mode == Addressing_Invalid) return false; + + if (!is_operand_value(index) || !check_is_assignable_to(c, &index, t_uintptr)) { + gbString e = expr_to_string(index.expr); + gbString t = type_to_string(index.type); + error(index.expr, "'%.*s' expected a uintptr for the memory index, got '%s' of type %s", LIT(builtin_name), e, t); + gb_string_free(t); + gb_string_free(e); + return false; + } + + if (!is_operand_value(delta) || !check_is_assignable_to(c, &delta, t_uintptr)) { + gbString e = expr_to_string(delta.expr); + gbString t = type_to_string(delta.type); + error(delta.expr, "'%.*s' expected a uintptr for the memory delta, got '%s' of type %s", LIT(builtin_name), e, t); + gb_string_free(t); + gb_string_free(e); + return false; + } + + operand->mode = Addressing_Value; + operand->type = t_int; + operand->value = {}; + break; + } + break; + case BuiltinProc_wasm_memory_size: + { + if (!is_arch_wasm()) { + error(call, "'%.*s' is only allowed on wasm targets", LIT(builtin_name)); + return false; + } + + Operand index = {}; + check_expr(c, &index, ce->args[0]); if (index.mode == Addressing_Invalid) return false; + + convert_to_typed(c, &index, t_uintptr); if (index.mode == Addressing_Invalid) return false; + + if (!is_operand_value(index) || !check_is_assignable_to(c, &index, t_uintptr)) { + gbString e = expr_to_string(index.expr); + gbString t = type_to_string(index.type); + error(index.expr, "'%.*s' expected a uintptr for the memory index, got '%s' of type %s", LIT(builtin_name), e, t); + gb_string_free(t); + gb_string_free(e); + return false; + } + + operand->mode = Addressing_Value; + operand->type = t_int; + operand->value = {}; + break; + } + break; + } return true; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 42f68203c..5acd56097 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -174,6 +174,10 @@ void check_init_constant(CheckerContext *ctx, Entity *e, Operand *operand) { return; } + if (is_type_proc(e->type)) { + error(e->token, "Illegal declaration of a constant procedure value"); + } + e->parent_proc_decl = ctx->curr_proc_decl; e->Constant.value = operand->value; @@ -238,6 +242,51 @@ isize total_attribute_count(DeclInfo *decl) { return attribute_count; } +Type *clone_enum_type(CheckerContext *ctx, Type *original_enum_type, Type *named_type) { + // NOTE(bill, 2022-02-05): Stupid edge case for `distinct` declarations + // + // X :: enum {A, B, C} + // Y :: distinct X + // + // To make Y be just like X, it will need to copy the elements of X and change their type + // so that they match Y rather than X. + GB_ASSERT(original_enum_type != nullptr); + GB_ASSERT(named_type != nullptr); + GB_ASSERT(original_enum_type->kind == Type_Enum); + GB_ASSERT(named_type->kind == Type_Named); + + Scope *parent = original_enum_type->Enum.scope->parent; + Scope *scope = create_scope(nullptr, parent); + + + Type *et = alloc_type_enum(); + et->Enum.base_type = original_enum_type->Enum.base_type; + et->Enum.min_value = original_enum_type->Enum.min_value; + et->Enum.max_value = original_enum_type->Enum.max_value; + et->Enum.min_value_index = original_enum_type->Enum.min_value_index; + et->Enum.max_value_index = original_enum_type->Enum.max_value_index; + et->Enum.scope = scope; + + auto fields = array_make(permanent_allocator(), original_enum_type->Enum.fields.count); + for_array(i, fields) { + Entity *old = original_enum_type->Enum.fields[i]; + + Entity *e = alloc_entity_constant(scope, old->token, named_type, old->Constant.value); + e->file = old->file; + e->identifier = clone_ast(old->identifier); + e->flags |= EntityFlag_Visited; + e->state = EntityState_Resolved; + e->Constant.flags = old->Constant.flags; + e->Constant.docs = old->Constant.docs; + e->Constant.comment = old->Constant.comment; + + fields[i] = e; + add_entity(ctx, scope, nullptr, e); + add_entity_use(ctx, e->identifier, e); + } + et->Enum.fields = fields; + return et; +} void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def) { GB_ASSERT(e->type == nullptr); @@ -258,7 +307,11 @@ void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def) Type *bt = check_type_expr(ctx, te, named); check_type_path_pop(ctx); - named->Named.base = base_type(bt); + Type *base = base_type(bt); + if (is_distinct && bt->kind == Type_Named && base->kind == Type_Enum) { + base = clone_enum_type(ctx, base, named); + } + named->Named.base = base; if (is_distinct && is_type_typeid(e->type)) { error(init_expr, "'distinct' cannot be applied to 'typeid'"); @@ -289,6 +342,13 @@ void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def) if (decl != nullptr) { AttributeContext ac = {}; check_decl_attributes(ctx, decl->attributes, type_decl_attribute, &ac); + if (e->kind == Entity_TypeName && ac.objc_class != "") { + e->TypeName.objc_class_name = ac.objc_class; + + if (type_size_of(e->type) > 0) { + error(e->token, "@(objc_class) marked type must be of zero size"); + } + } } @@ -380,12 +440,56 @@ void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init, if (type_expr) { e->type = check_type(ctx, type_expr); + if (are_types_identical(e->type, t_typeid)) { + e->type = nullptr; + e->kind = Entity_TypeName; + check_type_decl(ctx, e, init, named_type); + return; + } } Operand operand = {}; if (init != nullptr) { - Entity *entity = nullptr; + Entity *entity = check_entity_from_ident_or_selector(ctx, init, false); + if (entity != nullptr && entity->kind == Entity_TypeName) { + // @TypeAliasingProblem + // NOTE(bill, 2022-02-03): This is used to solve the problem caused by type aliases + // being "confused" as constants + // + // A :: B + // C :: proc "c" (^A) + // B :: struct {x: C} + // + // A gets evaluated first, and then checks B. + // B then checks C. + // C then tries to check A which is unresolved but thought to be a constant. + // Therefore within C's check, A errs as "not a type". + // + // This is because a const declaration may or may not be a type and this cannot + // be determined from a syntactical standpoint. + // This check allows the compiler to override the entity to be checked as a type. + // + // There is no problem if B is prefixed with the `#type` helper enforcing at + // both a syntax and semantic level that B must be a type. + // + // A :: #type B + // + // This approach is not fool proof and can fail in case such as: + // + // X :: type_of(x) + // X :: Foo(int).Type + // + // Since even these kind of declarations may cause weird checking cycles. + // For the time being, these are going to be treated as an unfortunate error + // until there is a proper delaying system to try declaration again if they + // have failed. + + e->kind = Entity_TypeName; + check_type_decl(ctx, e, init, named_type); + return; + } + entity = nullptr; if (init->kind == Ast_Ident) { entity = check_ident(ctx, &operand, init, nullptr, e->type, true); } else if (init->kind == Ast_SelectorExpr) { @@ -732,6 +836,63 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { } e->Procedure.optimization_mode = cast(ProcedureOptimizationMode)ac.optimization_mode; + if (ac.objc_name.len || ac.objc_is_class_method || ac.objc_type) { + if (ac.objc_name.len == 0 && ac.objc_is_class_method) { + error(e->token, "@(objc_name) is required with @(objc_is_class_method)"); + } else if (ac.objc_type == nullptr) { + error(e->token, "@(objc_name) requires that @(objc_type) to be set"); + } else if (ac.objc_name.len == 0 && ac.objc_type) { + error(e->token, "@(objc_name) is required with @(objc_type)"); + } else { + Type *t = ac.objc_type; + if (t->kind == Type_Named) { + Entity *tn = t->Named.type_name; + + GB_ASSERT(tn->kind == Entity_TypeName); + + if (tn->scope != e->scope) { + error(e->token, "@(objc_name) attribute may only be applied to procedures and types within the same scope"); + } else { + mutex_lock(&global_type_name_objc_metadata_mutex); + defer (mutex_unlock(&global_type_name_objc_metadata_mutex)); + + if (!tn->TypeName.objc_metadata) { + tn->TypeName.objc_metadata = create_type_name_obj_c_metadata(); + } + auto *md = tn->TypeName.objc_metadata; + mutex_lock(md->mutex); + defer (mutex_unlock(md->mutex)); + + if (!ac.objc_is_class_method) { + bool ok = true; + for (TypeNameObjCMetadataEntry const &entry : md->value_entries) { + if (entry.name == ac.objc_name) { + error(e->token, "Previous declaration of @(objc_name=\"%.*s\")", LIT(ac.objc_name)); + ok = false; + break; + } + } + if (ok) { + array_add(&md->value_entries, TypeNameObjCMetadataEntry{ac.objc_name, e}); + } + } else { + bool ok = true; + for (TypeNameObjCMetadataEntry const &entry : md->type_entries) { + if (entry.name == ac.objc_name) { + error(e->token, "Previous declaration of @(objc_name=\"%.*s\")", LIT(ac.objc_name)); + ok = false; + break; + } + } + if (ok) { + array_add(&md->type_entries, TypeNameObjCMetadataEntry{ac.objc_name, e}); + } + } + } + } + } + } + switch (e->Procedure.optimization_mode) { case ProcedureOptimizationMode_None: @@ -777,21 +938,23 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { if (e->pkg != nullptr && e->token.string == "main") { - if (pt->param_count != 0 || - pt->result_count != 0) { - gbString str = type_to_string(proc_type); - error(e->token, "Procedure type of 'main' was expected to be 'proc()', got %s", str); - gb_string_free(str); - } - if (pt->calling_convention != default_calling_convention()) { - error(e->token, "Procedure 'main' cannot have a custom calling convention"); - } - pt->calling_convention = default_calling_convention(); - if (e->pkg->kind == Package_Init) { - if (ctx->info->entry_point != nullptr) { - error(e->token, "Redeclaration of the entry pointer procedure 'main'"); - } else { - ctx->info->entry_point = e; + if (e->pkg->kind != Package_Runtime) { + if (pt->param_count != 0 || + pt->result_count != 0) { + gbString str = type_to_string(proc_type); + error(e->token, "Procedure type of 'main' was expected to be 'proc()', got %s", str); + gb_string_free(str); + } + if (pt->calling_convention != default_calling_convention()) { + error(e->token, "Procedure 'main' cannot have a custom calling convention"); + } + pt->calling_convention = default_calling_convention(); + if (e->pkg->kind == Package_Init) { + if (ctx->info->entry_point != nullptr) { + error(e->token, "Redeclaration of the entry pointer procedure 'main'"); + } else { + ctx->info->entry_point = e; + } } } } @@ -924,7 +1087,9 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { "\tother at %s", LIT(name), token_pos_to_string(pos)); } else if (name == "main") { - error(d->proc_lit, "The link name 'main' is reserved for internal use"); + if (d->entity->pkg->kind != Package_Runtime) { + error(d->proc_lit, "The link name 'main' is reserved for internal use"); + } } else { string_map_set(fp, key, e); } @@ -971,6 +1136,12 @@ void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr, } ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix); + if (is_arch_wasm() && e->Variable.thread_local_model.len != 0) { + e->Variable.thread_local_model.len = 0; + // NOTE(bill): ignore this message for the time begin + // error(e->token, "@(thread_local) is not supported for this target platform"); + } + String context_name = str_lit("variable declaration"); if (type_expr != nullptr) { @@ -1046,6 +1217,8 @@ void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr, Operand o = {}; check_expr_with_type_hint(ctx, &o, init_expr, e->type); check_init_variable(ctx, e, &o, str_lit("variable declaration")); + + check_rtti_type_disallowed(e->token, e->type, "A variable declaration is using a type, %s, which has been disallowed"); } void check_proc_group_decl(CheckerContext *ctx, Entity *&pg_entity, DeclInfo *d) { @@ -1303,7 +1476,7 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty if (t->kind == Type_Struct) { Scope *scope = t->Struct.scope; GB_ASSERT(scope != nullptr); - for_array(i, scope->elements.entries) { + MUTEX_GUARD_BLOCK(scope->mutex) for_array(i, scope->elements.entries) { Entity *f = scope->elements.entries[i].value; if (f->kind == Entity_Variable) { Entity *uvar = alloc_entity_using_variable(e, f->token, f->type, nullptr); @@ -1321,11 +1494,10 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty } } - - for_array(i, using_entities) { + MUTEX_GUARD_BLOCK(ctx->scope->mutex) for_array(i, using_entities) { Entity *e = using_entities[i].e; Entity *uvar = using_entities[i].uvar; - Entity *prev = scope_insert(ctx->scope, uvar); + Entity *prev = scope_insert(ctx->scope, uvar, false); if (prev != nullptr) { error(e->token, "Namespace collision while 'using' procedure argument '%.*s' of: %.*s", LIT(e->token.string), LIT(prev->token.string)); error_line("%.*s != %.*s\n", LIT(uvar->token.string), LIT(prev->token.string)); diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 560e5e607..336a711d4 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -119,6 +119,115 @@ void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Operand const &x, Type *type_hint); void check_or_return_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_); + +void check_did_you_mean_print(DidYouMeanAnswers *d, char const *prefix = "") { + auto results = did_you_mean_results(d); + if (results.count != 0) { + error_line("\tSuggestion: Did you mean?\n"); + for_array(i, results) { + String const &target = results[i].target; + error_line("\t\t%s%.*s\n", prefix, LIT(target)); + // error_line("\t\t%.*s %td\n", LIT(target), results[i].distance); + } + } +} + +void populate_check_did_you_mean_objc_entity(StringSet *set, Entity *e, bool is_type) { + if (e->kind != Entity_TypeName) { + return; + } + if (e->TypeName.objc_metadata == nullptr) { + return; + } + TypeNameObjCMetadata *objc_metadata = e->TypeName.objc_metadata; + Type *t = base_type(e->type); + GB_ASSERT(t->kind == Type_Struct); + + if (is_type) { + for_array(i, objc_metadata->type_entries) { + String name = objc_metadata->type_entries[i].name; + string_set_add(set, name); + } + } else { + for_array(i, objc_metadata->value_entries) { + String name = objc_metadata->value_entries[i].name; + string_set_add(set, name); + } + } + + for_array(i, t->Struct.fields) { + Entity *f = t->Struct.fields[i]; + if (f->flags & EntityFlag_Using && f->type != nullptr) { + if (f->type->kind == Type_Named && f->type->Named.type_name) { + populate_check_did_you_mean_objc_entity(set, f->type->Named.type_name, is_type); + } + } + } +} + + +void check_did_you_mean_objc_entity(String const &name, Entity *e, bool is_type, char const *prefix = "") { + ERROR_BLOCK(); + GB_ASSERT(e->kind == Entity_TypeName); + GB_ASSERT(e->TypeName.objc_metadata != nullptr); + auto *objc_metadata = e->TypeName.objc_metadata; + mutex_lock(objc_metadata->mutex); + defer (mutex_unlock(objc_metadata->mutex)); + + StringSet set = {}; + string_set_init(&set, heap_allocator()); + defer (string_set_destroy(&set)); + populate_check_did_you_mean_objc_entity(&set, e, is_type); + + + DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), set.entries.count, name); + defer (did_you_mean_destroy(&d)); + for_array(i, set.entries) { + did_you_mean_append(&d, set.entries[i].value); + } + check_did_you_mean_print(&d, prefix); +} + +void check_did_you_mean_type(String const &name, Array const &fields, char const *prefix = "") { + ERROR_BLOCK(); + + DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name); + defer (did_you_mean_destroy(&d)); + + for_array(i, fields) { + did_you_mean_append(&d, fields[i]->token.string); + } + check_did_you_mean_print(&d, prefix); +} + + +void check_did_you_mean_type(String const &name, Slice const &fields, char const *prefix = "") { + ERROR_BLOCK(); + + DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name); + defer (did_you_mean_destroy(&d)); + + for_array(i, fields) { + did_you_mean_append(&d, fields[i]->token.string); + } + check_did_you_mean_print(&d, prefix); +} + +void check_did_you_mean_scope(String const &name, Scope *scope, char const *prefix = "") { + ERROR_BLOCK(); + + DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.entries.count, name); + defer (did_you_mean_destroy(&d)); + + mutex_lock(&scope->mutex); + for_array(i, scope->elements.entries) { + Entity *e = scope->elements.entries[i].value; + did_you_mean_append(&d, e->token.string); + } + mutex_unlock(&scope->mutex); + check_did_you_mean_print(&d, prefix); +} + Entity *entity_from_expr(Ast *expr) { expr = unparen_expr(expr); switch (expr->kind) { @@ -176,42 +285,6 @@ void check_scope_decls(CheckerContext *c, Slice const &nodes, isize reser } } - -isize check_is_assignable_to_using_subtype(Type *src, Type *dst, isize level = 0, bool src_is_ptr = false) { - Type *prev_src = src; - src = type_deref(src); - if (!src_is_ptr) { - src_is_ptr = src != prev_src; - } - src = base_type(src); - - if (!is_type_struct(src)) { - return 0; - } - - for_array(i, src->Struct.fields) { - Entity *f = src->Struct.fields[i]; - if (f->kind != Entity_Variable || (f->flags&EntityFlag_Using) == 0) { - continue; - } - - if (are_types_identical(f->type, dst)) { - return level+1; - } - if (src_is_ptr && is_type_pointer(dst)) { - if (are_types_identical(f->type, type_deref(dst))) { - return level+1; - } - } - isize nested_level = check_is_assignable_to_using_subtype(f->type, dst, level+1, src_is_ptr); - if (nested_level > 0) { - return nested_level; - } - } - - return 0; -} - bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, Entity *base_entity, Type *type, Array *param_operands, Ast *poly_def_node, PolyProcData *poly_proc_data) { /////////////////////////////////////////////////////////////////////////////// @@ -456,6 +529,10 @@ bool check_cast_internal(CheckerContext *c, Operand *x, Type *type); #define MAXIMUM_TYPE_DISTANCE 10 i64 check_distance_between_types(CheckerContext *c, Operand *operand, Type *type) { + if (c == nullptr) { + GB_ASSERT(operand->mode == Addressing_Value); + GB_ASSERT(is_type_typed(operand->type)); + } if (operand->mode == Addressing_Invalid || type == t_invalid) { return -1; @@ -621,6 +698,42 @@ i64 check_distance_between_types(CheckerContext *c, Operand *operand, Type *type return 1; } } + + // TODO(bill): Determine which rule is a better on in practice + #if 1 + if (dst->Union.variants.count == 1) { + Type *vt = dst->Union.variants[0]; + i64 score = check_distance_between_types(c, operand, vt); + if (score >= 0) { + return score+2; + } + } + #else + // NOTE(bill): check to see you can assign to it with one of the variants? + i64 prev_lowest_score = -1; + i64 lowest_score = -1; + for_array(i, dst->Union.variants) { + Type *vt = dst->Union.variants[i]; + i64 score = check_distance_between_types(c, operand, vt); + if (score >= 0) { + if (lowest_score < 0) { + lowest_score = score; + } else { + if (prev_lowest_score < 0) { + prev_lowest_score = lowest_score; + } else { + prev_lowest_score = gb_min(prev_lowest_score, lowest_score); + } + lowest_score = gb_min(lowest_score, score); + } + } + } + if (lowest_score >= 0) { + if (prev_lowest_score != lowest_score) { // remove possible ambiguities + return lowest_score+2; + } + } + #endif } if (is_type_relative_pointer(dst)) { @@ -649,6 +762,13 @@ i64 check_distance_between_types(CheckerContext *c, Operand *operand, Type *type return 4; } } + + if (is_type_complex_or_quaternion(dst)) { + Type *elem = base_complex_elem_type(dst); + if (are_types_identical(elem, base_type(src))) { + return 5; + } + } if (is_type_array(dst)) { Type *elem = base_array_type(dst); @@ -723,6 +843,13 @@ bool check_is_assignable_to(CheckerContext *c, Operand *operand, Type *type) { return check_is_assignable_to_with_score(c, operand, type, &score); } +bool internal_check_is_assignable_to(Type *src, Type *dst) { + Operand x = {}; + x.type = src; + x.mode = Addressing_Value; + return check_is_assignable_to(nullptr, &x, dst); +} + AstPackage *get_package_of_type(Type *type) { for (;;) { if (type == nullptr) { @@ -1227,7 +1354,6 @@ bool check_cycle(CheckerContext *c, Entity *curr, bool report) { return false; } - Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *named_type, Type *type_hint, bool allow_import_name) { GB_ASSERT(n->kind == Ast_Ident); o->mode = Addressing_Invalid; @@ -1363,8 +1489,12 @@ Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *named_type, Typ case Entity_TypeName: o->mode = Addressing_Type; if (check_cycle(c, e, true)) { - type = t_invalid; + o->type = t_invalid; } + if (o->type != nullptr && type->kind == Type_Named && o->type->Named.type_name->TypeName.is_type_alias) { + o->type = base_type(o->type); + } + break; case Entity_ImportName: @@ -3354,7 +3484,16 @@ void convert_untyped_error(CheckerContext *c, Operand *operand, Type *target_typ } } } + ERROR_BLOCK(); + error(operand->expr, "Cannot convert untyped value '%s' to '%s' from '%s'%s", expr_str, type_str, from_type_str, extra_text); + if (operand->value.kind == ExactValue_String) { + String key = operand->value.value_string; + if (is_type_string(operand->type) && is_type_enum(target_type)) { + Type *et = base_type(target_type); + check_did_you_mean_type(key, et->Enum.fields, "."); + } + } gb_string_free(from_type_str); gb_string_free(type_str); @@ -3972,54 +4111,6 @@ ExactValue get_constant_field(CheckerContext *c, Operand const *operand, Selecti if (success_) *success_ = true; return empty_exact_value; } -void check_did_you_mean_print(DidYouMeanAnswers *d) { - auto results = did_you_mean_results(d); - if (results.count != 0) { - error_line("\tSuggestion: Did you mean?\n"); - for_array(i, results) { - String const &target = results[i].target; - error_line("\t\t%.*s\n", LIT(target)); - // error_line("\t\t%.*s %td\n", LIT(target), results[i].distance); - } - } -} - -void check_did_you_mean_type(String const &name, Array const &fields) { - ERROR_BLOCK(); - - DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name); - defer (did_you_mean_destroy(&d)); - - for_array(i, fields) { - did_you_mean_append(&d, fields[i]->token.string); - } - check_did_you_mean_print(&d); -} - -void check_did_you_mean_type(String const &name, Slice const &fields) { - ERROR_BLOCK(); - - DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), fields.count, name); - defer (did_you_mean_destroy(&d)); - - for_array(i, fields) { - did_you_mean_append(&d, fields[i]->token.string); - } - check_did_you_mean_print(&d); -} - -void check_did_you_mean_scope(String const &name, Scope *scope) { - ERROR_BLOCK(); - - DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), scope->elements.entries.count, name); - defer (did_you_mean_destroy(&d)); - - for_array(i, scope->elements.entries) { - Entity *e = scope->elements.entries[i].value; - did_you_mean_append(&d, e->token.string); - } - check_did_you_mean_print(&d); -} Type *determine_swizzle_array_type(Type *original_type, Type *type_hint, isize new_count) { Type *array_type = base_type(type_deref(original_type)); @@ -4044,6 +4135,101 @@ Type *determine_swizzle_array_type(Type *original_type, Type *type_hint, isize n } +bool is_entity_declared_for_selector(Entity *entity, Scope *import_scope, bool *allow_builtin) { + bool is_declared = entity != nullptr; + if (is_declared) { + if (entity->kind == Entity_Builtin) { + // NOTE(bill): Builtin's are in the universal scope which is part of every scopes hierarchy + // This means that we should just ignore the found result through it + *allow_builtin = entity->scope == import_scope || entity->scope != builtin_pkg->scope; + } else if ((entity->scope->flags&ScopeFlag_Global) == ScopeFlag_Global && (import_scope->flags&ScopeFlag_Global) == 0) { + is_declared = false; + } + } + return is_declared; +} + +// NOTE(bill, 2022-02-03): see `check_const_decl` for why it exists reasoning +Entity *check_entity_from_ident_or_selector(CheckerContext *c, Ast *node, bool ident_only) { + if (node->kind == Ast_Ident) { + String name = node->Ident.token.string; + return scope_lookup(c->scope, name); + } else if (!ident_only) if (node->kind == Ast_SelectorExpr) { + ast_node(se, SelectorExpr, node); + if (se->token.kind == Token_ArrowRight) { + return nullptr; + } + + Ast *op_expr = se->expr; + Ast *selector = unparen_expr(se->selector); + if (selector == nullptr) { + return nullptr; + } + if (selector->kind != Ast_Ident) { + return nullptr; + } + + Entity *entity = nullptr; + Entity *expr_entity = nullptr; + bool check_op_expr = true; + + if (op_expr->kind == Ast_Ident) { + String op_name = op_expr->Ident.token.string; + Entity *e = scope_lookup(c->scope, op_name); + if (e == nullptr) { + return nullptr; + } + add_entity_use(c, op_expr, e); + expr_entity = e; + + if (e != nullptr && e->kind == Entity_ImportName && selector->kind == Ast_Ident) { + // IMPORTANT NOTE(bill): This is very sloppy code but it's also very fragile + // It pretty much needs to be in this order and this way + // If you can clean this up, please do but be really careful + String import_name = op_name; + Scope *import_scope = e->ImportName.scope; + String entity_name = selector->Ident.token.string; + + check_op_expr = false; + entity = scope_lookup_current(import_scope, entity_name); + bool allow_builtin = false; + if (!is_entity_declared_for_selector(entity, import_scope, &allow_builtin)) { + return nullptr; + } + + check_entity_decl(c, entity, nullptr, nullptr); + if (entity->kind == Entity_ProcGroup) { + return entity; + } + GB_ASSERT_MSG(entity->type != nullptr, "%.*s (%.*s)", LIT(entity->token.string), LIT(entity_strings[entity->kind])); + } + } + + Operand operand = {}; + if (check_op_expr) { + check_expr_base(c, &operand, op_expr, nullptr); + if (operand.mode == Addressing_Invalid) { + return nullptr; + } + } + + if (entity == nullptr && selector->kind == Ast_Ident) { + String field_name = selector->Ident.token.string; + if (is_type_dynamic_array(type_deref(operand.type))) { + init_mem_allocator(c->checker); + } + auto sel = lookup_field(operand.type, field_name, operand.mode == Addressing_Type); + entity = sel.entity; + } + + if (entity != nullptr) { + return entity; + } + } + return nullptr; +} + + Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *type_hint) { ast_node(se, SelectorExpr, node); @@ -4092,18 +4278,8 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ check_op_expr = false; entity = scope_lookup_current(import_scope, entity_name); - bool is_declared = entity != nullptr; bool allow_builtin = false; - if (is_declared) { - if (entity->kind == Entity_Builtin) { - // NOTE(bill): Builtin's are in the universal scope which is part of every scopes hierarchy - // This means that we should just ignore the found result through it - allow_builtin = entity->scope == import_scope || entity->scope != builtin_pkg->scope; - } else if ((entity->scope->flags&ScopeFlag_Global) == ScopeFlag_Global && (import_scope->flags&ScopeFlag_Global) == 0) { - is_declared = false; - } - } - if (!is_declared) { + if (!is_entity_declared_for_selector(entity, import_scope, &allow_builtin)) { error(op_expr, "'%.*s' is not declared by '%.*s'", LIT(entity_name), LIT(import_name)); operand->mode = Addressing_Invalid; operand->expr = node; @@ -4193,7 +4369,7 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ } } - if (entity == nullptr && selector->kind == Ast_Ident && is_type_array(type_deref(operand->type))) { + if (entity == nullptr && selector->kind == Ast_Ident && is_type_array(type_deref(operand->type))) { // TODO(bill): Simd_Vector swizzling String field_name = selector->Ident.token.string; @@ -4294,14 +4470,19 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ if (entity == nullptr) { gbString op_str = expr_to_string(op_expr); - gbString type_str = type_to_string(operand->type); + gbString type_str = type_to_string_shorthand(operand->type); gbString sel_str = expr_to_string(selector); error(op_expr, "'%s' of type '%s' has no field '%s'", op_str, type_str, sel_str); if (operand->type != nullptr && selector->kind == Ast_Ident) { String const &name = selector->Ident.token.string; Type *bt = base_type(operand->type); - if (bt->kind == Type_Struct) { + if (operand->type->kind == Type_Named && + operand->type->Named.type_name && + operand->type->Named.type_name->kind == Entity_TypeName && + operand->type->Named.type_name->TypeName.objc_metadata) { + check_did_you_mean_objc_entity(name, operand->type->Named.type_name, operand->mode == Addressing_Type); + } else if (bt->kind == Type_Struct) { check_did_you_mean_type(name, bt->Struct.fields); } else if (bt->kind == Type_Enum) { check_did_you_mean_type(name, bt->Enum.fields); @@ -4330,7 +4511,7 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ } gbString op_str = expr_to_string(op_expr); - gbString type_str = type_to_string(operand->type); + gbString type_str = type_to_string_shorthand(operand->type); gbString sel_str = expr_to_string(selector); error(op_expr, "Cannot access non-constant field '%s' from '%s'", sel_str, op_str); gb_string_free(sel_str); @@ -4355,7 +4536,7 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ } gbString op_str = expr_to_string(op_expr); - gbString type_str = type_to_string(operand->type); + gbString type_str = type_to_string_shorthand(operand->type); gbString sel_str = expr_to_string(selector); error(op_expr, "Cannot access non-constant field '%s' from '%s'", sel_str, op_str); gb_string_free(sel_str); @@ -4368,7 +4549,7 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ if (expr_entity != nullptr && is_type_polymorphic(expr_entity->type)) { gbString op_str = expr_to_string(op_expr); - gbString type_str = type_to_string(operand->type); + gbString type_str = type_to_string_shorthand(operand->type); gbString sel_str = expr_to_string(selector); error(op_expr, "Cannot access field '%s' from non-specialized polymorphic type '%s'", sel_str, op_str); gb_string_free(sel_str); @@ -4691,25 +4872,16 @@ bool is_expr_constant_zero(Ast *expr) { return false; } - -CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { - ast_node(ce, CallExpr, call); - GB_ASSERT(is_type_proc(proc_type)); - proc_type = base_type(proc_type); - TypeProc *pt = &proc_type->Proc; - +isize get_procedure_param_count_excluding_defaults(Type *pt, isize *param_count_) { + GB_ASSERT(pt != nullptr); + GB_ASSERT(pt->kind == Type_Proc); isize param_count = 0; isize param_count_excluding_defaults = 0; - bool variadic = pt->variadic; - bool vari_expand = (ce->ellipsis.pos.line != 0); - i64 score = 0; - bool show_error = show_error_mode == CallArgumentMode_ShowErrors; - - + bool variadic = pt->Proc.variadic; TypeTuple *param_tuple = nullptr; - if (pt->params != nullptr) { - param_tuple = &pt->params->Tuple; + if (pt->Proc.params != nullptr) { + param_tuple = &pt->Proc.params->Tuple; param_count = param_tuple->variables.count; if (variadic) { @@ -4749,6 +4921,31 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { } } + if (param_count_) *param_count_ = param_count; + return param_count_excluding_defaults; +} + + +CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { + ast_node(ce, CallExpr, call); + GB_ASSERT(is_type_proc(proc_type)); + proc_type = base_type(proc_type); + TypeProc *pt = &proc_type->Proc; + + isize param_count = 0; + isize param_count_excluding_defaults = get_procedure_param_count_excluding_defaults(proc_type, ¶m_count); + bool variadic = pt->variadic; + bool vari_expand = (ce->ellipsis.pos.line != 0); + i64 score = 0; + bool show_error = show_error_mode == CallArgumentMode_ShowErrors; + + + TypeTuple *param_tuple = nullptr; + if (pt->params != nullptr) { + param_tuple = &pt->params->Tuple; + } + + CallArgumentError err = CallArgumentError_None; Type *final_proc_type = proc_type; Entity *gen_entity = nullptr; @@ -5421,7 +5618,37 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type if (operand->mode == Addressing_ProcGroup) { check_entity_decl(c, operand->proc_group, nullptr, nullptr); - Array procs = proc_group_entities(c, *operand); + auto procs = proc_group_entities_cloned(c, *operand); + + if (procs.count > 1) { + isize max_arg_count = args.count; + for_array(i, args) { + // NOTE(bill): The only thing that may have multiple values + // will be a call expression (assuming `or_return` and `()` will be stripped) + Ast *arg = strip_or_return_expr(args[i]); + if (arg && arg->kind == Ast_CallExpr) { + max_arg_count = ISIZE_MAX; + break; + } + } + + for (isize proc_index = 0; proc_index < procs.count; /**/) { + Entity *proc = procs[proc_index]; + Type *pt = base_type(proc->type); + if (!(pt != nullptr && is_type_proc(pt))) { + continue; + } + + isize param_count = 0; + isize param_count_excluding_defaults = get_procedure_param_count_excluding_defaults(pt, ¶m_count); + + if (param_count_excluding_defaults > max_arg_count) { + array_unordered_remove(&procs, proc_index); + } else { + proc_index++; + } + } + } if (procs.count == 1) { Ast *ident = operand->expr; @@ -5451,6 +5678,7 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type return data; } + Entity **lhs = nullptr; isize lhs_count = -1; @@ -5735,8 +5963,12 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type ctx.curr_proc_sig = e->type; GB_ASSERT(decl->proc_lit->kind == Ast_ProcLit); - evaluate_where_clauses(&ctx, call, decl->scope, &decl->proc_lit->ProcLit.where_clauses, true); + bool ok = evaluate_where_clauses(&ctx, call, decl->scope, &decl->proc_lit->ProcLit.where_clauses, true); decl->where_clauses_evaluated = true; + + if (ok && (data.gen_entity->flags & EntityFlag_ProcBodyChecked) == 0) { + check_procedure_later(c, e->file, e->token, decl, e->type, decl->proc_lit->ProcLit.body, decl->proc_lit->ProcLit.tags); + } } return data; } @@ -5749,6 +5981,7 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type Entity *e = entity_of_node(ident); + CallArgumentData data = {}; CallArgumentError err = call_checker(c, call, proc_type, e, operands, CallArgumentMode_ShowErrors, &data); gb_unused(err); @@ -5757,7 +5990,6 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type if (entity_to_use != nullptr) { update_untyped_expr_type(c, operand->expr, entity_to_use->type, true); } - if (data.gen_entity != nullptr) { Entity *e = data.gen_entity; DeclInfo *decl = data.gen_entity->decl_info; @@ -5769,8 +6001,12 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type ctx.curr_proc_sig = e->type; GB_ASSERT(decl->proc_lit->kind == Ast_ProcLit); - evaluate_where_clauses(&ctx, call, decl->scope, &decl->proc_lit->ProcLit.where_clauses, true); + bool ok = evaluate_where_clauses(&ctx, call, decl->scope, &decl->proc_lit->ProcLit.where_clauses, true); decl->where_clauses_evaluated = true; + + if (ok && (data.gen_entity->flags & EntityFlag_ProcBodyChecked) == 0) { + check_procedure_later(c, e->file, e->token, decl, e->type, decl->proc_lit->ProcLit.body, decl->proc_lit->ProcLit.tags); + } } return data; } @@ -6064,7 +6300,8 @@ CallArgumentError check_polymorphic_record_type(CheckerContext *c, Operand *oper } // NOTE(bill): Add type info the parameters - add_type_info_type(c, o->type); + // TODO(bill, 2022-01-23): why was this line added in the first place? I'm commenting it out for the time being + // add_type_info_type(c, o->type); } { @@ -6268,10 +6505,10 @@ ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Ast *pr return builtin_procs[id].kind; } - Entity *e = entity_of_node(operand->expr); + Entity *initial_entity = entity_of_node(operand->expr); - if (e != nullptr && e->kind == Entity_Procedure) { - if (e->Procedure.deferred_procedure.entity != nullptr) { + if (initial_entity != nullptr && initial_entity->kind == Entity_Procedure) { + if (initial_entity->Procedure.deferred_procedure.entity != nullptr) { call->viral_state_flags |= ViralStateFlag_ContainsDeferredProcedure; } } @@ -6839,6 +7076,1903 @@ void check_matrix_index_expr(CheckerContext *c, Operand *o, Ast *node, Type *typ } +struct TypeAndToken { + Type *type; + Token token; +}; + +typedef PtrMap SeenMap; + +void add_constant_switch_case(CheckerContext *ctx, SeenMap *seen, Operand operand, bool use_expr = true) { + if (operand.mode != Addressing_Constant) { + return; + } + if (operand.value.kind == ExactValue_Invalid) { + return; + } + + uintptr key = hash_exact_value(operand.value); + TypeAndToken *found = map_get(seen, key); + if (found != nullptr) { + isize count = multi_map_count(seen, key); + TypeAndToken *taps = gb_alloc_array(temporary_allocator(), TypeAndToken, count); + + multi_map_get_all(seen, key, taps); + for (isize i = 0; i < count; i++) { + TypeAndToken tap = taps[i]; + if (!are_types_identical(operand.type, tap.type)) { + continue; + } + + TokenPos pos = tap.token.pos; + if (use_expr) { + gbString expr_str = expr_to_string(operand.expr); + error(operand.expr, + "Duplicate case '%s'\n" + "\tprevious case at %s", + expr_str, + token_pos_to_string(pos)); + gb_string_free(expr_str); + } else { + error(operand.expr, "Duplicate case found with previous case at %s", token_pos_to_string(pos)); + } + return; + } + } + + TypeAndToken tap = {operand.type, ast_token(operand.expr)}; + multi_map_insert(seen, key, tap); +} + + +void add_to_seen_map(CheckerContext *ctx, SeenMap *seen, TokenKind upper_op, Operand const &x, Operand const &lhs, Operand const &rhs) { + if (is_type_enum(x.type)) { + // TODO(bill): Fix this logic so it's fast!!! + + i64 v0 = exact_value_to_i64(lhs.value); + i64 v1 = exact_value_to_i64(rhs.value); + Operand v = {}; + v.mode = Addressing_Constant; + v.type = x.type; + v.expr = x.expr; + + Type *bt = base_type(x.type); + GB_ASSERT(bt->kind == Type_Enum); + for (i64 vi = v0; vi <= v1; vi++) { + if (upper_op != Token_LtEq && vi == v1) { + break; + } + + bool found = false; + for_array(j, bt->Enum.fields) { + Entity *f = bt->Enum.fields[j]; + GB_ASSERT(f->kind == Entity_Constant); + + i64 fv = exact_value_to_i64(f->Constant.value); + if (fv == vi) { + found = true; + break; + } + } + if (found) { + v.value = exact_value_i64(vi); + add_constant_switch_case(ctx, seen, v); + } + } + } else { + add_constant_switch_case(ctx, seen, lhs); + if (upper_op == Token_LtEq) { + add_constant_switch_case(ctx, seen, rhs); + } + } +} +void add_to_seen_map(CheckerContext *ctx, SeenMap *seen, Operand const &x) { + add_constant_switch_case(ctx, seen, x); +} + +ExprKind check_basic_directive_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { + ast_node(bd, BasicDirective, node); + + ExprKind kind = Expr_Expr; + + o->mode = Addressing_Constant; + String name = bd->name.string; + if (name == "file") { + o->type = t_untyped_string; + o->value = exact_value_string(get_file_path_string(bd->token.pos.file_id)); + } else if (name == "line") { + o->type = t_untyped_integer; + o->value = exact_value_i64(bd->token.pos.line); + } else if (name == "procedure") { + if (c->curr_proc_decl == nullptr) { + error(node, "#procedure may only be used within procedures"); + o->type = t_untyped_string; + o->value = exact_value_string(str_lit("")); + } else { + o->type = t_untyped_string; + o->value = exact_value_string(c->proc_name); + } + } else if (name == "caller_location") { + init_core_source_code_location(c->checker); + error(node, "#caller_location may only be used as a default argument parameter"); + o->type = t_source_code_location; + o->mode = Addressing_Value; + } else { + if (name == "location") { + init_core_source_code_location(c->checker); + error(node, "'#%.*s' must be used in a call expression", LIT(name)); + o->type = t_source_code_location; + o->mode = Addressing_Value; + } else if ( + name == "assert" || + name == "defined" || + name == "config" || + name == "load" || + name == "load_hash" || + name == "load_or" + ) { + error(node, "'#%.*s' must be used as a call", LIT(name)); + o->type = t_invalid; + o->mode = Addressing_Invalid; + } else { + error(node, "Unknown directive: #%.*s", LIT(name)); + o->type = t_invalid; + o->mode = Addressing_Invalid; + } + + } + return kind; +} + +ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { + ExprKind kind = Expr_Expr; + Operand cond = {Addressing_Invalid}; + ast_node(te, TernaryIfExpr, node); + check_expr(c, &cond, te->cond); + node->viral_state_flags |= te->cond->viral_state_flags; + + if (cond.mode != Addressing_Invalid && !is_type_boolean(cond.type)) { + error(te->cond, "Non-boolean condition in ternary if expression"); + } + + Operand x = {Addressing_Invalid}; + Operand y = {Addressing_Invalid}; + check_expr_or_type(c, &x, te->x, type_hint); + node->viral_state_flags |= te->x->viral_state_flags; + + if (te->y != nullptr) { + check_expr_or_type(c, &y, te->y, type_hint); + node->viral_state_flags |= te->y->viral_state_flags; + } else { + error(node, "A ternary expression must have an else clause"); + return kind; + } + + if (x.type == nullptr || x.type == t_invalid || + y.type == nullptr || y.type == t_invalid) { + return kind; + } + + convert_to_typed(c, &x, y.type); + if (x.mode == Addressing_Invalid) { + return kind; + } + convert_to_typed(c, &y, x.type); + if (y.mode == Addressing_Invalid) { + x.mode = Addressing_Invalid; + return kind; + } + + if (!ternary_compare_types(x.type, y.type)) { + gbString its = type_to_string(x.type); + gbString ets = type_to_string(y.type); + error(node, "Mismatched types in ternary if expression, %s vs %s", its, ets); + gb_string_free(ets); + gb_string_free(its); + return kind; + } + + o->type = x.type; + if (is_type_untyped_nil(o->type) || is_type_untyped_undef(o->type)) { + o->type = y.type; + } + + o->mode = Addressing_Value; + o->expr = node; + if (type_hint != nullptr && is_type_untyped(o->type)) { + if (check_cast_internal(c, &x, type_hint) && + check_cast_internal(c, &y, type_hint)) { + convert_to_typed(c, o, type_hint); + update_untyped_expr_type(c, node, type_hint, !is_type_untyped(type_hint)); + } + } + return kind; +} + +ExprKind check_ternary_when_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { + ExprKind kind = Expr_Expr; + Operand cond = {}; + ast_node(te, TernaryWhenExpr, node); + check_expr(c, &cond, te->cond); + node->viral_state_flags |= te->cond->viral_state_flags; + + if (cond.mode != Addressing_Constant || !is_type_boolean(cond.type)) { + error(te->cond, "Expected a constant boolean condition in ternary when expression"); + return kind; + } + + if (cond.value.value_bool) { + check_expr_or_type(c, o, te->x, type_hint); + node->viral_state_flags |= te->x->viral_state_flags; + } else { + if (te->y != nullptr) { + check_expr_or_type(c, o, te->y, type_hint); + node->viral_state_flags |= te->y->viral_state_flags; + } else { + error(node, "A ternary when expression must have an else clause"); + return kind; + } + } + return kind; +} + +ExprKind check_or_else_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { + ast_node(oe, OrElseExpr, node); + + String name = oe->token.string; + Ast *arg = oe->x; + Ast *default_value = oe->y; + + Operand x = {}; + Operand y = {}; + check_multi_expr_with_type_hint(c, &x, arg, type_hint); + if (x.mode == Addressing_Invalid) { + o->mode = Addressing_Value; + o->type = t_invalid; + o->expr = node; + return Expr_Expr; + } + + check_multi_expr_with_type_hint(c, &y, default_value, x.type); + error_operand_no_value(&y); + if (y.mode == Addressing_Invalid) { + o->mode = Addressing_Value; + o->type = t_invalid; + o->expr = node; + return Expr_Expr; + } + + Type *left_type = nullptr; + Type *right_type = nullptr; + check_or_else_split_types(c, &x, name, &left_type, &right_type); + add_type_and_value(&c->checker->info, arg, x.mode, x.type, x.value); + + if (left_type != nullptr) { + check_assignment(c, &y, left_type, name); + } else { + check_or_else_expr_no_value_error(c, name, x, type_hint); + } + + if (left_type == nullptr) { + left_type = t_invalid; + } + o->mode = Addressing_Value; + o->type = left_type; + o->expr = node; + return Expr_Expr; +} + +ExprKind check_or_return_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { + ast_node(re, OrReturnExpr, node); + + String name = re->token.string; + Operand x = {}; + check_multi_expr_with_type_hint(c, &x, re->expr, type_hint); + if (x.mode == Addressing_Invalid) { + o->mode = Addressing_Value; + o->type = t_invalid; + o->expr = node; + return Expr_Expr; + } + + Type *left_type = nullptr; + Type *right_type = nullptr; + check_or_return_split_types(c, &x, name, &left_type, &right_type); + add_type_and_value(&c->checker->info, re->expr, x.mode, x.type, x.value); + + if (right_type == nullptr) { + check_or_else_expr_no_value_error(c, name, x, type_hint); + } else { + Type *proc_type = base_type(c->curr_proc_sig); + GB_ASSERT(proc_type->kind == Type_Proc); + Type *result_type = proc_type->Proc.results; + if (result_type == nullptr) { + error(node, "'%.*s' requires the current procedure to have at least one return value", LIT(name)); + } else { + GB_ASSERT(result_type->kind == Type_Tuple); + + auto const &vars = result_type->Tuple.variables; + Type *end_type = vars[vars.count-1]->type; + + if (vars.count > 1) { + if (!proc_type->Proc.has_named_results) { + error(node, "'%.*s' within a procedure with more than 1 return value requires that the return values are named, allowing for early return", LIT(name)); + } + } + + Operand rhs = {}; + rhs.type = right_type; + rhs.mode = Addressing_Value; + + // TODO(bill): better error message + if (!check_is_assignable_to(c, &rhs, end_type)) { + gbString a = type_to_string(right_type); + gbString b = type_to_string(end_type); + gbString ret_type = type_to_string(result_type); + error(node, "Cannot assign end value of type '%s' to '%s' in '%.*s'", a, b, LIT(name)); + if (vars.count == 1) { + error_line("\tProcedure return value type: %s\n", ret_type); + } else { + error_line("\tProcedure return value types: (%s)\n", ret_type); + } + gb_string_free(ret_type); + gb_string_free(b); + gb_string_free(a); + } + } + } + + o->expr = node; + o->type = left_type; + if (left_type != nullptr) { + o->mode = Addressing_Value; + } else { + o->mode = Addressing_NoValue; + } + + if (c->curr_proc_sig == nullptr) { + error(node, "'%.*s' can only be used within a procedure", LIT(name)); + } + + if (c->in_defer) { + error(node, "'or_return' cannot be used within a defer statement"); + } + + return Expr_Expr; +} + +ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { + ExprKind kind = Expr_Expr; + ast_node(cl, CompoundLit, node); + + Type *type = type_hint; + if (type != nullptr && is_type_untyped(type)) { + type = nullptr; + } + bool is_to_be_determined_array_count = false; + bool is_constant = true; + if (cl->type != nullptr) { + type = nullptr; + + // [?]Type + if (cl->type->kind == Ast_ArrayType && cl->type->ArrayType.count != nullptr) { + Ast *count = cl->type->ArrayType.count; + if (count->kind == Ast_UnaryExpr && + count->UnaryExpr.op.kind == Token_Question) { + type = alloc_type_array(check_type(c, cl->type->ArrayType.elem), -1); + is_to_be_determined_array_count = true; + } + if (cl->elems.count > 0) { + if (cl->type->ArrayType.tag != nullptr) { + Ast *tag = cl->type->ArrayType.tag; + GB_ASSERT(tag->kind == Ast_BasicDirective); + String name = tag->BasicDirective.name.string; + if (name == "soa") { + error(node, "#soa arrays are not supported for compound literals"); + return kind; + } + } + } + } + if (cl->type->kind == Ast_DynamicArrayType && cl->type->DynamicArrayType.tag != nullptr) { + if (cl->elems.count > 0) { + Ast *tag = cl->type->DynamicArrayType.tag; + GB_ASSERT(tag->kind == Ast_BasicDirective); + String name = tag->BasicDirective.name.string; + if (name == "soa") { + error(node, "#soa arrays are not supported for compound literals"); + return kind; + } + } + } + + if (type == nullptr) { + type = check_type(c, cl->type); + } + } + + if (type == nullptr) { + error(node, "Missing type in compound literal"); + return kind; + } + + + Type *t = base_type(type); + if (is_type_polymorphic(t)) { + gbString str = type_to_string(type); + error(node, "Cannot use a polymorphic type for a compound literal, got '%s'", str); + o->expr = node; + o->type = type; + gb_string_free(str); + return kind; + } + + + switch (t->kind) { + case Type_Struct: { + if (cl->elems.count == 0) { + break; // NOTE(bill): No need to init + } + if (t->Struct.is_raw_union) { + if (cl->elems.count > 0) { + // NOTE: unions cannot be constant + is_constant = false; + + if (cl->elems[0]->kind != Ast_FieldValue) { + gbString type_str = type_to_string(type); + error(node, "%s ('struct #raw_union') compound literals are only allowed to contain 'field = value' elements", type_str); + gb_string_free(type_str); + } else { + if (cl->elems.count != 1) { + gbString type_str = type_to_string(type); + error(node, "%s ('struct #raw_union') compound literals are only allowed to contain up to 1 'field = value' element, got %td", type_str, cl->elems.count); + gb_string_free(type_str); + } else { + Ast *elem = cl->elems[0]; + ast_node(fv, FieldValue, elem); + if (fv->field->kind != Ast_Ident) { + gbString expr_str = expr_to_string(fv->field); + error(elem, "Invalid field name '%s' in structure literal", expr_str); + gb_string_free(expr_str); + break; + } + + String name = fv->field->Ident.token.string; + + Selection sel = lookup_field(type, name, o->mode == Addressing_Type); + bool is_unknown = sel.entity == nullptr; + if (is_unknown) { + error(elem, "Unknown field '%.*s' in structure literal", LIT(name)); + break; + } + + if (sel.index.count > 1) { + error(elem, "Cannot assign to an anonymous field '%.*s' in a structure literal (at the moment)", LIT(name)); + break; + } + + Entity *field = t->Struct.fields[sel.index[0]]; + add_entity_use(c, fv->field, field); + + Operand o = {}; + check_expr_or_type(c, &o, fv->value, field->type); + + + check_assignment(c, &o, field->type, str_lit("structure literal")); + } + + } + } + break; + } + + + isize field_count = t->Struct.fields.count; + isize min_field_count = t->Struct.fields.count; + for (isize i = min_field_count-1; i >= 0; i--) { + Entity *e = t->Struct.fields[i]; + GB_ASSERT(e->kind == Entity_Variable); + if (e->Variable.param_value.kind != ParameterValue_Invalid) { + min_field_count--; + } else { + break; + } + } + + if (cl->elems[0]->kind == Ast_FieldValue) { + bool *fields_visited = gb_alloc_array(temporary_allocator(), bool, field_count); + + for_array(i, cl->elems) { + Ast *elem = cl->elems[i]; + if (elem->kind != Ast_FieldValue) { + error(elem, "Mixture of 'field = value' and value elements in a literal is not allowed"); + continue; + } + ast_node(fv, FieldValue, elem); + if (fv->field->kind != Ast_Ident) { + gbString expr_str = expr_to_string(fv->field); + error(elem, "Invalid field name '%s' in structure literal", expr_str); + gb_string_free(expr_str); + continue; + } + String name = fv->field->Ident.token.string; + + Selection sel = lookup_field(type, name, o->mode == Addressing_Type); + bool is_unknown = sel.entity == nullptr; + if (is_unknown) { + error(elem, "Unknown field '%.*s' in structure literal", LIT(name)); + continue; + } + + if (sel.index.count > 1) { + error(elem, "Cannot assign to an anonymous field '%.*s' in a structure literal (at the moment)", LIT(name)); + continue; + } + + Entity *field = t->Struct.fields[sel.index[0]]; + add_entity_use(c, fv->field, field); + + if (fields_visited[sel.index[0]]) { + error(elem, "Duplicate field '%.*s' in structure literal", LIT(name)); + continue; + } + + fields_visited[sel.index[0]] = true; + + Operand o = {}; + check_expr_or_type(c, &o, fv->value, field->type); + + if (is_type_any(field->type) || is_type_union(field->type) || is_type_raw_union(field->type) || is_type_typeid(field->type)) { + is_constant = false; + } + if (is_constant) { + is_constant = check_is_operand_compound_lit_constant(c, &o); + } + + check_assignment(c, &o, field->type, str_lit("structure literal")); + } + } else { + bool seen_field_value = false; + + for_array(index, cl->elems) { + Entity *field = nullptr; + Ast *elem = cl->elems[index]; + if (elem->kind == Ast_FieldValue) { + seen_field_value = true; + error(elem, "Mixture of 'field = value' and value elements in a literal is not allowed"); + continue; + } else if (seen_field_value) { + error(elem, "Value elements cannot be used after a 'field = value'"); + continue; + } + if (index >= field_count) { + error(elem, "Too many values in structure literal, expected %td, got %td", field_count, cl->elems.count); + break; + } + + if (field == nullptr) { + field = t->Struct.fields[index]; + } + + Operand o = {}; + check_expr_or_type(c, &o, elem, field->type); + + if (is_type_any(field->type) || is_type_union(field->type) || is_type_raw_union(field->type) || is_type_typeid(field->type)) { + is_constant = false; + } + if (is_constant) { + is_constant = check_is_operand_compound_lit_constant(c, &o); + } + + check_assignment(c, &o, field->type, str_lit("structure literal")); + } + if (cl->elems.count < field_count) { + if (min_field_count < field_count) { + if (cl->elems.count < min_field_count) { + error(cl->close, "Too few values in structure literal, expected at least %td, got %td", min_field_count, cl->elems.count); + } + } else { + error(cl->close, "Too few values in structure literal, expected %td, got %td", field_count, cl->elems.count); + } + } + } + + break; + } + + case Type_Slice: + case Type_Array: + case Type_DynamicArray: + case Type_SimdVector: + case Type_Matrix: + { + Type *elem_type = nullptr; + String context_name = {}; + i64 max_type_count = -1; + if (t->kind == Type_Slice) { + elem_type = t->Slice.elem; + context_name = str_lit("slice literal"); + } else if (t->kind == Type_Array) { + elem_type = t->Array.elem; + context_name = str_lit("array literal"); + if (!is_to_be_determined_array_count) { + max_type_count = t->Array.count; + } + } else if (t->kind == Type_DynamicArray) { + elem_type = t->DynamicArray.elem; + context_name = str_lit("dynamic array literal"); + is_constant = false; + + if (!build_context.no_dynamic_literals) { + add_package_dependency(c, "runtime", "__dynamic_array_reserve"); + add_package_dependency(c, "runtime", "__dynamic_array_append"); + } + } else if (t->kind == Type_SimdVector) { + elem_type = t->SimdVector.elem; + context_name = str_lit("simd vector literal"); + max_type_count = t->SimdVector.count; + } else if (t->kind == Type_Matrix) { + elem_type = t->Matrix.elem; + context_name = str_lit("matrix literal"); + max_type_count = t->Matrix.row_count*t->Matrix.column_count; + } else { + GB_PANIC("unreachable"); + } + + + i64 max = 0; + + Type *bet = base_type(elem_type); + if (!elem_type_can_be_constant(bet)) { + is_constant = false; + } + + if (bet == t_invalid) { + break; + } + + if (cl->elems.count > 0 && cl->elems[0]->kind == Ast_FieldValue) { + if (is_type_simd_vector(t)) { + error(cl->elems[0], "'field = value' is not allowed for SIMD vector literals"); + } else { + RangeCache rc = range_cache_make(heap_allocator()); + defer (range_cache_destroy(&rc)); + + for_array(i, cl->elems) { + Ast *elem = cl->elems[i]; + if (elem->kind != Ast_FieldValue) { + error(elem, "Mixture of 'field = value' and value elements in a literal is not allowed"); + continue; + } + ast_node(fv, FieldValue, elem); + + if (is_ast_range(fv->field)) { + Token op = fv->field->BinaryExpr.op; + + Operand x = {}; + Operand y = {}; + bool ok = check_range(c, fv->field, &x, &y, nullptr); + if (!ok) { + continue; + } + if (x.mode != Addressing_Constant || !is_type_integer(core_type(x.type))) { + error(x.expr, "Expected a constant integer as an array field"); + continue; + } + + if (y.mode != Addressing_Constant || !is_type_integer(core_type(y.type))) { + error(y.expr, "Expected a constant integer as an array field"); + continue; + } + + i64 lo = exact_value_to_i64(x.value); + i64 hi = exact_value_to_i64(y.value); + i64 max_index = hi; + if (op.kind == Token_RangeHalf) { // ..< (exclusive) + hi -= 1; + } else { // .. (inclusive) + max_index += 1; + } + + bool new_range = range_cache_add_range(&rc, lo, hi); + if (!new_range) { + error(elem, "Overlapping field range index %lld %.*s %lld for %.*s", lo, LIT(op.string), hi, LIT(context_name)); + continue; + } + + + if (max_type_count >= 0 && (lo < 0 || lo >= max_type_count)) { + error(elem, "Index %lld is out of bounds (0..<%lld) for %.*s", lo, max_type_count, LIT(context_name)); + continue; + } + if (max_type_count >= 0 && (hi < 0 || hi >= max_type_count)) { + error(elem, "Index %lld is out of bounds (0..<%lld) for %.*s", hi, max_type_count, LIT(context_name)); + continue; + } + + if (max < hi) { + max = max_index; + } + + Operand operand = {}; + check_expr_with_type_hint(c, &operand, fv->value, elem_type); + check_assignment(c, &operand, elem_type, context_name); + + is_constant = is_constant && operand.mode == Addressing_Constant; + } else { + Operand op_index = {}; + check_expr(c, &op_index, fv->field); + + if (op_index.mode != Addressing_Constant || !is_type_integer(core_type(op_index.type))) { + error(elem, "Expected a constant integer as an array field"); + continue; + } + // add_type_and_value(c->info, op_index.expr, op_index.mode, op_index.type, op_index.value); + + i64 index = exact_value_to_i64(op_index.value); + + if (max_type_count >= 0 && (index < 0 || index >= max_type_count)) { + error(elem, "Index %lld is out of bounds (0..<%lld) for %.*s", index, max_type_count, LIT(context_name)); + continue; + } + + bool new_index = range_cache_add_index(&rc, index); + if (!new_index) { + error(elem, "Duplicate field index %lld for %.*s", index, LIT(context_name)); + continue; + } + + if (max < index+1) { + max = index+1; + } + + Operand operand = {}; + check_expr_with_type_hint(c, &operand, fv->value, elem_type); + check_assignment(c, &operand, elem_type, context_name); + + is_constant = is_constant && operand.mode == Addressing_Constant; + } + } + + cl->max_count = max; + } + + } else { + isize index = 0; + for (; index < cl->elems.count; index++) { + Ast *e = cl->elems[index]; + if (e == nullptr) { + error(node, "Invalid literal element"); + continue; + } + + if (e->kind == Ast_FieldValue) { + error(e, "Mixture of 'field = value' and value elements in a literal is not allowed"); + continue; + } + + if (0 <= max_type_count && max_type_count <= index) { + error(e, "Index %lld is out of bounds (>= %lld) for %.*s", index, max_type_count, LIT(context_name)); + } + + Operand operand = {}; + check_expr_with_type_hint(c, &operand, e, elem_type); + check_assignment(c, &operand, elem_type, context_name); + + is_constant = is_constant && operand.mode == Addressing_Constant; + } + + if (max < index) { + max = index; + } + } + + + if (t->kind == Type_Array) { + if (is_to_be_determined_array_count) { + t->Array.count = max; + } else if (cl->elems.count > 0 && cl->elems[0]->kind != Ast_FieldValue) { + if (0 < max && max < t->Array.count) { + error(node, "Expected %lld values for this array literal, got %lld", cast(long long)t->Array.count, cast(long long)max); + } + } + } + + + if (t->kind == Type_SimdVector) { + if (!is_constant) { + error(node, "Expected all constant elements for a simd vector"); + } + } + + + if (t->kind == Type_DynamicArray) { + if (build_context.no_dynamic_literals && cl->elems.count) { + error(node, "Compound literals of dynamic types have been disabled"); + } + } + + if (t->kind == Type_Matrix) { + if (cl->elems.count > 0 && cl->elems[0]->kind != Ast_FieldValue) { + if (0 < max && max < max_type_count) { + error(node, "Expected %lld values for this matrix literal, got %lld", cast(long long)max_type_count, cast(long long)max); + } + } + } + + break; + } + + case Type_EnumeratedArray: + { + Type *elem_type = t->EnumeratedArray.elem; + Type *index_type = t->EnumeratedArray.index; + String context_name = str_lit("enumerated array literal"); + i64 max_type_count = t->EnumeratedArray.count; + + gbString index_type_str = type_to_string(index_type); + defer (gb_string_free(index_type_str)); + + i64 total_lo = exact_value_to_i64(*t->EnumeratedArray.min_value); + i64 total_hi = exact_value_to_i64(*t->EnumeratedArray.max_value); + + String total_lo_string = {}; + String total_hi_string = {}; + GB_ASSERT(is_type_enum(index_type)); + { + Type *bt = base_type(index_type); + GB_ASSERT(bt->kind == Type_Enum); + for_array(i, bt->Enum.fields) { + Entity *f = bt->Enum.fields[i]; + if (f->kind != Entity_Constant) { + continue; + } + if (total_lo_string.len == 0 && compare_exact_values(Token_CmpEq, f->Constant.value, *t->EnumeratedArray.min_value)) { + total_lo_string = f->token.string; + } + if (total_hi_string.len == 0 && compare_exact_values(Token_CmpEq, f->Constant.value, *t->EnumeratedArray.max_value)) { + total_hi_string = f->token.string; + } + if (total_lo_string.len != 0 && total_hi_string.len != 0) { + break; + } + } + } + + i64 max = 0; + + Type *bet = base_type(elem_type); + if (!elem_type_can_be_constant(bet)) { + is_constant = false; + } + + if (bet == t_invalid) { + break; + } + bool is_partial = cl->tag && (cl->tag->BasicDirective.name.string == "partial"); + + SeenMap seen = {}; // NOTE(bill): Multimap, Key: ExactValue + map_init(&seen, heap_allocator()); + defer (map_destroy(&seen)); + + if (cl->elems.count > 0 && cl->elems[0]->kind == Ast_FieldValue) { + RangeCache rc = range_cache_make(heap_allocator()); + defer (range_cache_destroy(&rc)); + + for_array(i, cl->elems) { + Ast *elem = cl->elems[i]; + if (elem->kind != Ast_FieldValue) { + error(elem, "Mixture of 'field = value' and value elements in a literal is not allowed"); + continue; + } + ast_node(fv, FieldValue, elem); + + if (is_ast_range(fv->field)) { + Token op = fv->field->BinaryExpr.op; + + Operand x = {}; + Operand y = {}; + bool ok = check_range(c, fv->field, &x, &y, nullptr, index_type); + if (!ok) { + continue; + } + if (x.mode != Addressing_Constant || !are_types_identical(x.type, index_type)) { + error(x.expr, "Expected a constant enum of type '%s' as an array field", index_type_str); + continue; + } + + if (y.mode != Addressing_Constant || !are_types_identical(x.type, index_type)) { + error(y.expr, "Expected a constant enum of type '%s' as an array field", index_type_str); + continue; + } + + i64 lo = exact_value_to_i64(x.value); + i64 hi = exact_value_to_i64(y.value); + i64 max_index = hi; + if (op.kind == Token_RangeHalf) { + hi -= 1; + } + + bool new_range = range_cache_add_range(&rc, lo, hi); + if (!new_range) { + gbString lo_str = expr_to_string(x.expr); + gbString hi_str = expr_to_string(y.expr); + error(elem, "Overlapping field range index %s %.*s %s for %.*s", lo_str, LIT(op.string), hi_str, LIT(context_name)); + gb_string_free(hi_str); + gb_string_free(lo_str); + continue; + } + + + // NOTE(bill): These are sanity checks for invalid enum values + if (max_type_count >= 0 && (lo < total_lo || lo > total_hi)) { + gbString lo_str = expr_to_string(x.expr); + error(elem, "Index %s is out of bounds (%.*s .. %.*s) for %.*s", lo_str, LIT(total_lo_string), LIT(total_hi_string), LIT(context_name)); + gb_string_free(lo_str); + continue; + } + if (max_type_count >= 0 && (hi < 0 || hi > total_hi)) { + gbString hi_str = expr_to_string(y.expr); + error(elem, "Index %s is out of bounds (%.*s .. %.*s) for %.*s", hi_str, LIT(total_lo_string), LIT(total_hi_string), LIT(context_name)); + gb_string_free(hi_str); + continue; + } + + if (max < hi) { + max = max_index; + } + + Operand operand = {}; + check_expr_with_type_hint(c, &operand, fv->value, elem_type); + check_assignment(c, &operand, elem_type, context_name); + + is_constant = is_constant && operand.mode == Addressing_Constant; + + TokenKind upper_op = Token_LtEq; + if (op.kind == Token_RangeHalf) { + upper_op = Token_Lt; + } + add_to_seen_map(c, &seen, upper_op, x, x, y); + } else { + Operand op_index = {}; + check_expr_with_type_hint(c, &op_index, fv->field, index_type); + + if (op_index.mode != Addressing_Constant || !are_types_identical(op_index.type, index_type)) { + error(op_index.expr, "Expected a constant enum of type '%s' as an array field", index_type_str); + continue; + } + + i64 index = exact_value_to_i64(op_index.value); + + if (max_type_count >= 0 && (index < total_lo || index > total_hi)) { + gbString idx_str = expr_to_string(op_index.expr); + error(elem, "Index %s is out of bounds (%.*s .. %.*s) for %.*s", idx_str, LIT(total_lo_string), LIT(total_hi_string), LIT(context_name)); + gb_string_free(idx_str); + continue; + } + + bool new_index = range_cache_add_index(&rc, index); + if (!new_index) { + gbString idx_str = expr_to_string(op_index.expr); + error(elem, "Duplicate field index %s for %.*s", idx_str, LIT(context_name)); + gb_string_free(idx_str); + continue; + } + + if (max < index+1) { + max = index+1; + } + + Operand operand = {}; + check_expr_with_type_hint(c, &operand, fv->value, elem_type); + check_assignment(c, &operand, elem_type, context_name); + + is_constant = is_constant && operand.mode == Addressing_Constant; + + add_to_seen_map(c, &seen, op_index); + } + } + + cl->max_count = max; + + } else { + isize index = 0; + for (; index < cl->elems.count; index++) { + Ast *e = cl->elems[index]; + if (e == nullptr) { + error(node, "Invalid literal element"); + continue; + } + + if (e->kind == Ast_FieldValue) { + error(e, "Mixture of 'field = value' and value elements in a literal is not allowed"); + continue; + } + + if (0 <= max_type_count && max_type_count <= index) { + error(e, "Index %lld is out of bounds (>= %lld) for %.*s", index, max_type_count, LIT(context_name)); + } + + Operand operand = {}; + check_expr_with_type_hint(c, &operand, e, elem_type); + check_assignment(c, &operand, elem_type, context_name); + + is_constant = is_constant && operand.mode == Addressing_Constant; + } + + if (max < index) { + max = index; + } + } + + bool was_error = false; + if (cl->elems.count > 0 && cl->elems[0]->kind != Ast_FieldValue) { + if (0 < max && max < t->EnumeratedArray.count) { + error(node, "Expected %lld values for this enumerated array literal, got %lld", cast(long long)t->EnumeratedArray.count, cast(long long)max); + was_error = true; + } else { + error(node, "Enumerated array literals must only have 'field = value' elements, bare elements are not allowed"); + was_error = true; + } + } + + // NOTE(bill): Check for missing cases when `#partial literal` is not present + if (cl->elems.count > 0 && !was_error && !is_partial) { + Type *et = base_type(index_type); + GB_ASSERT(et->kind == Type_Enum); + auto fields = et->Enum.fields; + + auto unhandled = array_make(temporary_allocator(), 0, fields.count); + + for_array(i, fields) { + Entity *f = fields[i]; + if (f->kind != Entity_Constant) { + continue; + } + ExactValue v = f->Constant.value; + auto found = map_get(&seen, hash_exact_value(v)); + if (!found) { + array_add(&unhandled, f); + } + } + + if (unhandled.count > 0) { + begin_error_block(); + defer (end_error_block()); + + if (unhandled.count == 1) { + error_no_newline(node, "Unhandled enumerated array case: %.*s", LIT(unhandled[0]->token.string)); + } else { + error(node, "Unhandled enumerated array cases:"); + for_array(i, unhandled) { + Entity *f = unhandled[i]; + error_line("\t%.*s\n", LIT(f->token.string)); + } + } + error_line("\n"); + + error_line("\tSuggestion: Was '#partial %s{...}' wanted?\n", type_to_string(type)); + } + } + + break; + } + + case Type_Basic: { + if (!is_type_any(t)) { + if (cl->elems.count != 0) { + gbString s = type_to_string(t); + error(node, "Illegal compound literal, %s cannot be used as a compound literal with fields", s); + gb_string_free(s); + is_constant = false; + } + break; + } + if (cl->elems.count == 0) { + break; // NOTE(bill): No need to init + } + { // Checker values + Type *field_types[2] = {t_rawptr, t_typeid}; + isize field_count = 2; + if (cl->elems[0]->kind == Ast_FieldValue) { + bool fields_visited[2] = {}; + + for_array(i, cl->elems) { + Ast *elem = cl->elems[i]; + if (elem->kind != Ast_FieldValue) { + error(elem, "Mixture of 'field = value' and value elements in a 'any' literal is not allowed"); + continue; + } + ast_node(fv, FieldValue, elem); + if (fv->field->kind != Ast_Ident) { + gbString expr_str = expr_to_string(fv->field); + error(elem, "Invalid field name '%s' in 'any' literal", expr_str); + gb_string_free(expr_str); + continue; + } + String name = fv->field->Ident.token.string; + + Selection sel = lookup_field(type, name, o->mode == Addressing_Type); + if (sel.entity == nullptr) { + error(elem, "Unknown field '%.*s' in 'any' literal", LIT(name)); + continue; + } + + isize index = sel.index[0]; + + if (fields_visited[index]) { + error(elem, "Duplicate field '%.*s' in 'any' literal", LIT(name)); + continue; + } + + fields_visited[index] = true; + check_expr(c, o, fv->value); + + // NOTE(bill): 'any' literals can never be constant + is_constant = false; + + check_assignment(c, o, field_types[index], str_lit("'any' literal")); + } + } else { + for_array(index, cl->elems) { + Ast *elem = cl->elems[index]; + if (elem->kind == Ast_FieldValue) { + error(elem, "Mixture of 'field = value' and value elements in a 'any' literal is not allowed"); + continue; + } + + + check_expr(c, o, elem); + if (index >= field_count) { + error(o->expr, "Too many values in 'any' literal, expected %td", field_count); + break; + } + + // NOTE(bill): 'any' literals can never be constant + is_constant = false; + + check_assignment(c, o, field_types[index], str_lit("'any' literal")); + } + if (cl->elems.count < field_count) { + error(cl->close, "Too few values in 'any' literal, expected %td, got %td", field_count, cl->elems.count); + } + } + } + + break; + } + + case Type_Map: { + if (cl->elems.count == 0) { + break; + } + is_constant = false; + { // Checker values + bool key_is_typeid = is_type_typeid(t->Map.key); + bool value_is_typeid = is_type_typeid(t->Map.value); + + for_array(i, cl->elems) { + Ast *elem = cl->elems[i]; + if (elem->kind != Ast_FieldValue) { + error(elem, "Only 'field = value' elements are allowed in a map literal"); + continue; + } + ast_node(fv, FieldValue, elem); + + if (key_is_typeid) { + check_expr_or_type(c, o, fv->field, t->Map.key); + } else { + check_expr_with_type_hint(c, o, fv->field, t->Map.key); + } + check_assignment(c, o, t->Map.key, str_lit("map literal")); + if (o->mode == Addressing_Invalid) { + continue; + } + + if (value_is_typeid) { + check_expr_or_type(c, o, fv->value, t->Map.value); + } else { + check_expr_with_type_hint(c, o, fv->value, t->Map.value); + } + check_assignment(c, o, t->Map.value, str_lit("map literal")); + } + } + + if (build_context.no_dynamic_literals && cl->elems.count) { + error(node, "Compound literals of dynamic types have been disabled"); + } else { + add_package_dependency(c, "runtime", "__dynamic_map_reserve"); + add_package_dependency(c, "runtime", "__dynamic_map_set"); + } + break; + } + + case Type_BitSet: { + if (cl->elems.count == 0) { + break; // NOTE(bill): No need to init + } + Type *et = base_type(t->BitSet.elem); + isize field_count = 0; + if (et->kind == Type_Enum) { + field_count = et->Enum.fields.count; + } + + if (cl->elems[0]->kind == Ast_FieldValue) { + error(cl->elems[0], "'field = value' in a bit_set a literal is not allowed"); + is_constant = false; + } else { + for_array(index, cl->elems) { + Ast *elem = cl->elems[index]; + if (elem->kind == Ast_FieldValue) { + error(elem, "'field = value' in a bit_set a literal is not allowed"); + continue; + } + + check_expr_with_type_hint(c, o, elem, et); + + if (is_constant) { + is_constant = o->mode == Addressing_Constant; + } + + check_assignment(c, o, t->BitSet.elem, str_lit("bit_set literal")); + if (o->mode == Addressing_Constant) { + i64 lower = t->BitSet.lower; + i64 upper = t->BitSet.upper; + i64 v = exact_value_to_i64(o->value); + if (lower <= v && v <= upper) { + // okay + } else { + error(elem, "Bit field value out of bounds, %lld not in the range %lld .. %lld", v, lower, upper); + continue; + } + } + } + } + break; + } + + default: { + if (cl->elems.count == 0) { + break; // NOTE(bill): No need to init + } + + gbString str = type_to_string(type); + error(node, "Invalid compound literal type '%s'", str); + gb_string_free(str); + return kind; + } + } + + if (is_constant) { + o->mode = Addressing_Constant; + + if (is_type_bit_set(type)) { + // NOTE(bill): Encode as an integer + + i64 lower = base_type(type)->BitSet.lower; + + u64 bits = 0; + for_array(index, cl->elems) { + Ast *elem = cl->elems[index]; + GB_ASSERT(elem->kind != Ast_FieldValue); + TypeAndValue tav = elem->tav; + ExactValue i = exact_value_to_integer(tav.value); + if (i.kind != ExactValue_Integer) { + continue; + } + i64 val = big_int_to_i64(&i.value_integer); + val -= lower; + u64 bit = u64(1ll<value = exact_value_u64(bits); + } else if (is_type_constant_type(type) && cl->elems.count == 0) { + ExactValue value = exact_value_compound(node); + Type *bt = core_type(type); + if (bt->kind == Type_Basic) { + if (bt->Basic.flags & BasicFlag_Boolean) { + value = exact_value_bool(false); + } else if (bt->Basic.flags & BasicFlag_Integer) { + value = exact_value_i64(0); + } else if (bt->Basic.flags & BasicFlag_Unsigned) { + value = exact_value_i64(0); + } else if (bt->Basic.flags & BasicFlag_Float) { + value = exact_value_float(0); + } else if (bt->Basic.flags & BasicFlag_Complex) { + value = exact_value_complex(0, 0); + } else if (bt->Basic.flags & BasicFlag_Quaternion) { + value = exact_value_quaternion(0, 0, 0, 0); + } else if (bt->Basic.flags & BasicFlag_Pointer) { + value = exact_value_pointer(0); + } else if (bt->Basic.flags & BasicFlag_String) { + String empty_string = {}; + value = exact_value_string(empty_string); + } else if (bt->Basic.flags & BasicFlag_Rune) { + value = exact_value_i64(0); + } + } + + o->value = value; + } else { + o->value = exact_value_compound(node); + } + } else { + o->mode = Addressing_Value; + } + o->type = type; + return kind; +} + +ExprKind check_type_assertion(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { + ExprKind kind = Expr_Expr; + ast_node(ta, TypeAssertion, node); + check_expr(c, o, ta->expr); + node->viral_state_flags |= ta->expr->viral_state_flags; + + if (o->mode == Addressing_Invalid) { + o->expr = node; + return kind; + } + if (o->mode == Addressing_Constant) { + gbString expr_str = expr_to_string(o->expr); + error(o->expr, "A type assertion cannot be applied to a constant expression: '%s'", expr_str); + gb_string_free(expr_str); + o->mode = Addressing_Invalid; + o->expr = node; + return kind; + } + + if (is_type_untyped(o->type)) { + gbString expr_str = expr_to_string(o->expr); + error(o->expr, "A type assertion cannot be applied to an untyped expression: '%s'", expr_str); + gb_string_free(expr_str); + o->mode = Addressing_Invalid; + o->expr = node; + return kind; + } + + Type *src = type_deref(o->type); + Type *bsrc = base_type(src); + + + if (ta->type != nullptr && ta->type->kind == Ast_UnaryExpr && ta->type->UnaryExpr.op.kind == Token_Question) { + if (!is_type_union(src)) { + gbString str = type_to_string(o->type); + error(o->expr, "Type assertions with .? can only operate on unions, got %s", str); + gb_string_free(str); + o->mode = Addressing_Invalid; + o->expr = node; + return kind; + } + + if (bsrc->Union.variants.count != 1 && type_hint != nullptr) { + bool allowed = false; + for_array(i, bsrc->Union.variants) { + Type *vt = bsrc->Union.variants[i]; + if (are_types_identical(vt, type_hint)) { + allowed = true; + add_type_info_type(c, vt); + break; + } + } + if (allowed) { + add_type_info_type(c, o->type); + o->type = type_hint; + o->mode = Addressing_OptionalOk; + return kind; + } + } + + if (bsrc->Union.variants.count != 1) { + error(o->expr, "Type assertions with .? can only operate on unions with 1 variant, got %lld", cast(long long)bsrc->Union.variants.count); + o->mode = Addressing_Invalid; + o->expr = node; + return kind; + } + + add_type_info_type(c, o->type); + add_type_info_type(c, bsrc->Union.variants[0]); + + o->type = bsrc->Union.variants[0]; + o->mode = Addressing_OptionalOk; + } else { + Type *t = check_type(c, ta->type); + Type *dst = t; + + if (is_type_union(src)) { + bool ok = false; + for_array(i, bsrc->Union.variants) { + Type *vt = bsrc->Union.variants[i]; + if (are_types_identical(vt, dst)) { + ok = true; + break; + } + } + + if (!ok) { + gbString expr_str = expr_to_string(o->expr); + gbString dst_type_str = type_to_string(t); + defer (gb_string_free(expr_str)); + defer (gb_string_free(dst_type_str)); + if (bsrc->Union.variants.count == 0) { + error(o->expr, "Cannot type assert '%s' to '%s' as this is an empty union", expr_str, dst_type_str); + } else { + error(o->expr, "Cannot type assert '%s' to '%s' as it is not a variant of that union", expr_str, dst_type_str); + } + o->mode = Addressing_Invalid; + o->expr = node; + return kind; + } + + add_type_info_type(c, o->type); + add_type_info_type(c, t); + + o->type = t; + o->mode = Addressing_OptionalOk; + } else if (is_type_any(src)) { + o->type = t; + o->mode = Addressing_OptionalOk; + + add_type_info_type(c, o->type); + add_type_info_type(c, t); + } else { + gbString str = type_to_string(o->type); + error(o->expr, "Type assertions can only operate on unions and 'any', got %s", str); + gb_string_free(str); + o->mode = Addressing_Invalid; + o->expr = node; + return kind; + } + } + + if ((c->state_flags & StateFlag_no_type_assert) == 0) { + add_package_dependency(c, "runtime", "type_assertion_check"); + add_package_dependency(c, "runtime", "type_assertion_check2"); + } + return kind; +} + +ExprKind check_selector_call_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { + ast_node(se, SelectorCallExpr, node); + // IMPORTANT NOTE(bill, 2020-05-22): This is a complete hack to get a shorthand which is extremely useful for vtables + // COM APIs is a great example of where this kind of thing is extremely useful + // General idea: + // + // x->y(123) == x.y(x, 123) + // + // How this has been implemented at the moment is quite hacky but it's done so to reduce need for huge backend changes + // Just regenerating a new AST aids things + // + // TODO(bill): Is this a good hack or not? + // + // NOTE(bill, 2020-05-22): I'm going to regret this decision, ain't I? + + + if (se->modified_call) { + // Prevent double evaluation + o->expr = node; + o->type = node->tav.type; + o->value = node->tav.value; + o->mode = node->tav.mode; + return Expr_Expr; + } + + bool allow_arrow_right_selector_expr; + allow_arrow_right_selector_expr = c->allow_arrow_right_selector_expr; + c->allow_arrow_right_selector_expr = true; + Operand x = {}; + ExprKind kind = check_expr_base(c, &x, se->expr, nullptr); + c->allow_arrow_right_selector_expr = allow_arrow_right_selector_expr; + + if (x.mode == Addressing_Invalid || x.type == t_invalid) { + o->mode = Addressing_Invalid; + o->type = t_invalid; + o->expr = node; + return kind; + } + if (!is_type_proc(x.type)) { + gbString type_str = type_to_string(x.type); + error(se->call, "Selector call expressions expect a procedure type for the call, got '%s'", type_str); + gb_string_free(type_str); + + o->mode = Addressing_Invalid; + o->type = t_invalid; + o->expr = node; + return Expr_Stmt; + } + + ast_node(ce, CallExpr, se->call); + + GB_ASSERT(x.expr->kind == Ast_SelectorExpr); + + Ast *first_arg = x.expr->SelectorExpr.expr; + GB_ASSERT(first_arg != nullptr); + + Type *pt = base_type(x.type); + GB_ASSERT(pt->kind == Type_Proc); + Type *first_type = nullptr; + String first_arg_name = {}; + if (pt->Proc.param_count > 0) { + Entity *f = pt->Proc.params->Tuple.variables[0]; + first_type = f->type; + first_arg_name = f->token.string; + } + if (first_arg_name.len == 0) { + first_arg_name = str_lit("_"); + } + + if (first_type == nullptr) { + error(se->call, "Selector call expressions expect a procedure type for the call with at least 1 parameter"); + o->mode = Addressing_Invalid; + o->type = t_invalid; + o->expr = node; + return Expr_Stmt; + } + + Operand y = {}; + y.mode = first_arg->tav.mode; + y.type = first_arg->tav.type; + y.value = first_arg->tav.value; + if (check_is_assignable_to(c, &y, first_type)) { + // Do nothing, it's valid + } else { + Operand z = y; + z.type = type_deref(y.type); + if (check_is_assignable_to(c, &z, first_type)) { + // NOTE(bill): AST GENERATION HACK! + Token op = {Token_Pointer}; + first_arg = ast_deref_expr(first_arg->file(), first_arg, op); + } else if (y.mode == Addressing_Variable) { + Operand w = y; + w.type = alloc_type_pointer(y.type); + if (check_is_assignable_to(c, &w, first_type)) { + // NOTE(bill): AST GENERATION HACK! + Token op = {Token_And}; + first_arg = ast_unary_expr(first_arg->file(), op, first_arg); + } + } + } + + if (ce->args.count > 0) { + bool fail = false; + bool first_is_field_value = (ce->args[0]->kind == Ast_FieldValue); + for_array(i, ce->args) { + Ast *arg = ce->args[i]; + bool mix = false; + if (first_is_field_value) { + mix = arg->kind != Ast_FieldValue; + } else { + mix = arg->kind == Ast_FieldValue; + } + if (mix) { + fail = true; + break; + } + } + if (!fail && first_is_field_value) { + Token op = {Token_Eq}; + AstFile *f = first_arg->file(); + first_arg = ast_field_value(f, ast_ident(f, make_token_ident(first_arg_name)), first_arg, op); + } + } + + + + auto modified_args = slice_make(heap_allocator(), ce->args.count+1); + modified_args[0] = first_arg; + slice_copy(&modified_args, ce->args, 1); + ce->args = modified_args; + se->modified_call = true; + + allow_arrow_right_selector_expr = c->allow_arrow_right_selector_expr; + c->allow_arrow_right_selector_expr = true; + check_expr_base(c, o, se->call, type_hint); + c->allow_arrow_right_selector_expr = allow_arrow_right_selector_expr; + + o->expr = node; + return Expr_Expr; +} + + +ExprKind check_index_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { + ExprKind kind = Expr_Expr; + ast_node(ie, IndexExpr, node); + check_expr(c, o, ie->expr); + node->viral_state_flags |= ie->expr->viral_state_flags; + if (o->mode == Addressing_Invalid) { + o->expr = node; + return kind; + } + + Type *t = base_type(type_deref(o->type)); + bool is_ptr = is_type_pointer(o->type); + bool is_const = o->mode == Addressing_Constant; + + if (is_type_map(t)) { + Operand key = {}; + if (is_type_typeid(t->Map.key)) { + check_expr_or_type(c, &key, ie->index, t->Map.key); + } else { + check_expr_with_type_hint(c, &key, ie->index, t->Map.key); + } + check_assignment(c, &key, t->Map.key, str_lit("map index")); + if (key.mode == Addressing_Invalid) { + o->mode = Addressing_Invalid; + o->expr = node; + return kind; + } + o->mode = Addressing_MapIndex; + o->type = t->Map.value; + o->expr = node; + + add_package_dependency(c, "runtime", "__dynamic_map_get"); + add_package_dependency(c, "runtime", "__dynamic_map_set"); + return Expr_Expr; + } + + i64 max_count = -1; + bool valid = check_set_index_data(o, t, is_ptr, &max_count, o->type); + + if (is_const) { + if (is_type_array(t)) { + // OKay + } else if (is_type_slice(t)) { + // Okay + } else if (is_type_enumerated_array(t)) { + // Okay + } else if (is_type_string(t)) { + // Okay + } else if (is_type_relative_slice(t)) { + // Okay + } else if (is_type_matrix(t)) { + // Okay + } else { + valid = false; + } + } + + if (!valid) { + gbString str = expr_to_string(o->expr); + gbString type_str = type_to_string(o->type); + defer (gb_string_free(str)); + defer (gb_string_free(type_str)); + if (is_const) { + error(o->expr, "Cannot index constant '%s' of type '%s'", str, type_str); + } else { + error(o->expr, "Cannot index '%s' of type '%s'", str, type_str); + } + o->mode = Addressing_Invalid; + o->expr = node; + return kind; + } + + if (ie->index == nullptr) { + gbString str = expr_to_string(o->expr); + error(o->expr, "Missing index for '%s'", str); + gb_string_free(str); + o->mode = Addressing_Invalid; + o->expr = node; + return kind; + } + + Type *index_type_hint = nullptr; + if (is_type_enumerated_array(t)) { + Type *bt = base_type(t); + GB_ASSERT(bt->kind == Type_EnumeratedArray); + index_type_hint = bt->EnumeratedArray.index; + } + + i64 index = 0; + bool ok = check_index_value(c, t, false, ie->index, max_count, &index, index_type_hint); + if (is_const) { + if (index < 0) { + gbString str = expr_to_string(o->expr); + error(o->expr, "Cannot index a constant '%s'", str); + error_line("\tSuggestion: store the constant into a variable in order to index it with a variable index\n"); + gb_string_free(str); + o->mode = Addressing_Invalid; + o->expr = node; + return kind; + } else if (ok) { + ExactValue value = type_and_value_of_expr(ie->expr).value; + o->mode = Addressing_Constant; + bool success = false; + bool finish = false; + o->value = get_constant_field_single(c, value, cast(i32)index, &success, &finish); + if (!success) { + gbString str = expr_to_string(o->expr); + error(o->expr, "Cannot index a constant '%s' with index %lld", str, cast(long long)index); + error_line("\tSuggestion: store the constant into a variable in order to index it with a variable index\n"); + gb_string_free(str); + o->mode = Addressing_Invalid; + o->expr = node; + return kind; + } + } + } + + if (type_hint != nullptr && is_type_matrix(t)) { + // TODO(bill): allow matrix columns to be assignable to other types which are the same internally + // if a type hint exists + } + return kind; +} + +ExprKind check_slice_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { + ExprKind kind = Expr_Stmt; + ast_node(se, SliceExpr, node); + check_expr(c, o, se->expr); + node->viral_state_flags |= se->expr->viral_state_flags; + + if (o->mode == Addressing_Invalid) { + o->mode = Addressing_Invalid; + o->expr = node; + return kind; + } + + bool valid = false; + i64 max_count = -1; + Type *t = base_type(type_deref(o->type)); + switch (t->kind) { + case Type_Basic: + if (t->Basic.kind == Basic_string || t->Basic.kind == Basic_UntypedString) { + valid = true; + if (o->mode == Addressing_Constant) { + max_count = o->value.value_string.len; + } + o->type = type_deref(o->type); + } + break; + + case Type_Array: + valid = true; + max_count = t->Array.count; + if (o->mode != Addressing_Variable && !is_type_pointer(o->type)) { + gbString str = expr_to_string(node); + error(node, "Cannot slice array '%s', value is not addressable", str); + gb_string_free(str); + o->mode = Addressing_Invalid; + o->expr = node; + return kind; + } + o->type = alloc_type_slice(t->Array.elem); + break; + + case Type_MultiPointer: + valid = true; + o->type = type_deref(o->type); + break; + + case Type_Slice: + valid = true; + o->type = type_deref(o->type); + break; + + case Type_DynamicArray: + valid = true; + o->type = alloc_type_slice(t->DynamicArray.elem); + break; + + case Type_Struct: + if (is_type_soa_struct(t)) { + valid = true; + o->type = make_soa_struct_slice(c, nullptr, nullptr, t->Struct.soa_elem); + } + break; + + case Type_RelativeSlice: + valid = true; + o->type = t->RelativeSlice.slice_type; + if (o->mode != Addressing_Variable) { + gbString str = expr_to_string(node); + error(node, "Cannot relative slice '%s', value is not addressable", str); + gb_string_free(str); + o->mode = Addressing_Invalid; + o->expr = node; + return kind; + } + break; + } + + if (!valid) { + gbString str = expr_to_string(o->expr); + gbString type_str = type_to_string(o->type); + error(o->expr, "Cannot slice '%s' of type '%s'", str, type_str); + gb_string_free(type_str); + gb_string_free(str); + o->mode = Addressing_Invalid; + o->expr = node; + return kind; + } + + if (se->low == nullptr && se->high != nullptr) { + // It is okay to continue as it will assume the 1st index is zero + } + + i64 indices[2] = {}; + Ast *nodes[2] = {se->low, se->high}; + for (isize i = 0; i < gb_count_of(nodes); i++) { + i64 index = max_count; + if (nodes[i] != nullptr) { + i64 capacity = -1; + if (max_count >= 0) { + capacity = max_count; + } + i64 j = 0; + if (check_index_value(c, t, true, nodes[i], capacity, &j)) { + index = j; + } + + node->viral_state_flags |= nodes[i]->viral_state_flags; + } else if (i == 0) { + index = 0; + } + indices[i] = index; + } + + for (isize i = 0; i < gb_count_of(indices); i++) { + i64 a = indices[i]; + for (isize j = i+1; j < gb_count_of(indices); j++) { + i64 b = indices[j]; + if (a > b && b >= 0) { + error(se->close, "Invalid slice indices: [%td > %td]", a, b); + } + } + } + + if (max_count < 0) { + if (o->mode == Addressing_Constant) { + gbString s = expr_to_string(se->expr); + error(se->expr, "Cannot slice constant value '%s'", s); + gb_string_free(s); + } + } + + if (t->kind == Type_MultiPointer && se->high != nullptr) { + /* + x[:] -> [^]T + x[i:] -> [^]T + x[:n] -> []T + x[i:n] -> []T + */ + o->type = alloc_type_slice(t->MultiPointer.elem); + } + + o->mode = Addressing_Value; + + if (is_type_string(t) && max_count >= 0) { + bool all_constant = true; + for (isize i = 0; i < gb_count_of(nodes); i++) { + if (nodes[i] != nullptr) { + TypeAndValue tav = type_and_value_of_expr(nodes[i]); + if (tav.mode != Addressing_Constant) { + all_constant = false; + break; + } + } + } + if (!all_constant) { + gbString str = expr_to_string(o->expr); + error(o->expr, "Cannot slice '%s' with non-constant indices", str); + error_line("\tSuggestion: store the constant into a variable in order to index it with a variable index\n"); + gb_string_free(str); + o->mode = Addressing_Value; // NOTE(bill): Keep subsequent values going without erring + o->expr = node; + return kind; + } + + String s = {}; + if (o->value.kind == ExactValue_String) { + s = o->value.value_string; + } + + o->mode = Addressing_Constant; + o->type = t; + o->value = exact_value_string(substring(s, cast(isize)indices[0], cast(isize)indices[1])); + } + return kind; +} + ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { u32 prev_state_flags = c->state_flags; defer (c->state_flags = prev_state_flags); @@ -6854,6 +8988,14 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type out &= ~StateFlag_no_bounds_check; } + if (in & StateFlag_no_type_assert) { + out |= StateFlag_no_type_assert; + out &= ~StateFlag_type_assert; + } else if (in & StateFlag_type_assert) { + out |= StateFlag_type_assert; + out &= ~StateFlag_no_type_assert; + } + c->state_flags = out; } @@ -6861,6 +9003,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type o->mode = Addressing_Invalid; o->type = t_invalid; + o->value = {ExactValue_Invalid}; switch (node->kind) { default: @@ -6933,52 +9076,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type case_end; case_ast_node(bd, BasicDirective, node); - o->mode = Addressing_Constant; - String name = bd->name.string; - if (name == "file") { - o->type = t_untyped_string; - o->value = exact_value_string(get_file_path_string(bd->token.pos.file_id)); - } else if (name == "line") { - o->type = t_untyped_integer; - o->value = exact_value_i64(bd->token.pos.line); - } else if (name == "procedure") { - if (c->curr_proc_decl == nullptr) { - error(node, "#procedure may only be used within procedures"); - o->type = t_untyped_string; - o->value = exact_value_string(str_lit("")); - } else { - o->type = t_untyped_string; - o->value = exact_value_string(c->proc_name); - } - } else if (name == "caller_location") { - init_core_source_code_location(c->checker); - error(node, "#caller_location may only be used as a default argument parameter"); - o->type = t_source_code_location; - o->mode = Addressing_Value; - } else { - if (name == "location") { - init_core_source_code_location(c->checker); - error(node, "'#%.*s' must be used in a call expression", LIT(name)); - o->type = t_source_code_location; - o->mode = Addressing_Value; - } else if ( - name == "assert" || - name == "defined" || - name == "config" || - name == "load" || - name == "load_hash" || - name == "load_or" - ) { - error(node, "'#%.*s' must be used as a call", LIT(name)); - o->type = t_invalid; - o->mode = Addressing_Invalid; - } else { - error(node, "Unknown directive: #%.*s", LIT(name)); - o->type = t_invalid; - o->mode = Addressing_Invalid; - } - - } + kind = check_basic_directive_expr(c, o, node, type_hint); case_end; case_ast_node(pg, ProcGroup, node); @@ -7027,1102 +9125,23 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type case_end; case_ast_node(te, TernaryIfExpr, node); - Operand cond = {Addressing_Invalid}; - check_expr(c, &cond, te->cond); - node->viral_state_flags |= te->cond->viral_state_flags; - - if (cond.mode != Addressing_Invalid && !is_type_boolean(cond.type)) { - error(te->cond, "Non-boolean condition in ternary if expression"); - } - - Operand x = {Addressing_Invalid}; - Operand y = {Addressing_Invalid}; - check_expr_or_type(c, &x, te->x, type_hint); - node->viral_state_flags |= te->x->viral_state_flags; - - if (te->y != nullptr) { - check_expr_or_type(c, &y, te->y, type_hint); - node->viral_state_flags |= te->y->viral_state_flags; - } else { - error(node, "A ternary expression must have an else clause"); - return kind; - } - - if (x.type == nullptr || x.type == t_invalid || - y.type == nullptr || y.type == t_invalid) { - return kind; - } - - convert_to_typed(c, &x, y.type); - if (x.mode == Addressing_Invalid) { - return kind; - } - convert_to_typed(c, &y, x.type); - if (y.mode == Addressing_Invalid) { - x.mode = Addressing_Invalid; - return kind; - } - - if (!ternary_compare_types(x.type, y.type)) { - gbString its = type_to_string(x.type); - gbString ets = type_to_string(y.type); - error(node, "Mismatched types in ternary if expression, %s vs %s", its, ets); - gb_string_free(ets); - gb_string_free(its); - return kind; - } - - o->type = x.type; - if (is_type_untyped_nil(o->type) || is_type_untyped_undef(o->type)) { - o->type = y.type; - } - - o->mode = Addressing_Value; - o->expr = node; - if (type_hint != nullptr && is_type_untyped(o->type)) { - if (check_cast_internal(c, &x, type_hint) && - check_cast_internal(c, &y, type_hint)) { - convert_to_typed(c, o, type_hint); - update_untyped_expr_type(c, node, type_hint, !is_type_untyped(type_hint)); - } - } + kind = check_ternary_if_expr(c, o, node, type_hint); case_end; case_ast_node(te, TernaryWhenExpr, node); - Operand cond = {}; - check_expr(c, &cond, te->cond); - node->viral_state_flags |= te->cond->viral_state_flags; - - if (cond.mode != Addressing_Constant || !is_type_boolean(cond.type)) { - error(te->cond, "Expected a constant boolean condition in ternary when expression"); - return kind; - } - - if (cond.value.value_bool) { - check_expr_or_type(c, o, te->x, type_hint); - node->viral_state_flags |= te->x->viral_state_flags; - } else { - if (te->y != nullptr) { - check_expr_or_type(c, o, te->y, type_hint); - node->viral_state_flags |= te->y->viral_state_flags; - } else { - error(node, "A ternary when expression must have an else clause"); - return kind; - } - } + kind = check_ternary_when_expr(c, o, node, type_hint); case_end; case_ast_node(oe, OrElseExpr, node); - String name = oe->token.string; - Ast *arg = oe->x; - Ast *default_value = oe->y; - - Operand x = {}; - Operand y = {}; - check_multi_expr_with_type_hint(c, &x, arg, type_hint); - if (x.mode == Addressing_Invalid) { - o->mode = Addressing_Value; - o->type = t_invalid; - o->expr = node; - return Expr_Expr; - } - - check_multi_expr_with_type_hint(c, &y, default_value, x.type); - error_operand_no_value(&y); - if (y.mode == Addressing_Invalid) { - o->mode = Addressing_Value; - o->type = t_invalid; - o->expr = node; - return Expr_Expr; - } - - Type *left_type = nullptr; - Type *right_type = nullptr; - check_or_else_split_types(c, &x, name, &left_type, &right_type); - add_type_and_value(&c->checker->info, arg, x.mode, x.type, x.value); - - if (left_type != nullptr) { - check_assignment(c, &y, left_type, name); - } else { - check_or_else_expr_no_value_error(c, name, x, type_hint); - } - - if (left_type == nullptr) { - left_type = t_invalid; - } - o->mode = Addressing_Value; - o->type = left_type; - o->expr = node; - return Expr_Expr; + return check_or_else_expr(c, o, node, type_hint); case_end; case_ast_node(re, OrReturnExpr, node); - String name = re->token.string; - Operand x = {}; - check_multi_expr_with_type_hint(c, &x, re->expr, type_hint); - if (x.mode == Addressing_Invalid) { - o->mode = Addressing_Value; - o->type = t_invalid; - o->expr = node; - return Expr_Expr; - } - - Type *left_type = nullptr; - Type *right_type = nullptr; - check_or_return_split_types(c, &x, name, &left_type, &right_type); - add_type_and_value(&c->checker->info, re->expr, x.mode, x.type, x.value); - - if (right_type == nullptr) { - check_or_else_expr_no_value_error(c, name, x, type_hint); - } else { - Type *proc_type = base_type(c->curr_proc_sig); - GB_ASSERT(proc_type->kind == Type_Proc); - Type *result_type = proc_type->Proc.results; - if (result_type == nullptr) { - error(node, "'%.*s' requires the current procedure to have at least one return value", LIT(name)); - } else { - GB_ASSERT(result_type->kind == Type_Tuple); - - auto const &vars = result_type->Tuple.variables; - Type *end_type = vars[vars.count-1]->type; - - if (vars.count > 1) { - if (!proc_type->Proc.has_named_results) { - error(node, "'%.*s' within a procedure with more than 1 return value requires that the return values are named, allowing for early return", LIT(name)); - } - } - - Operand rhs = {}; - rhs.type = right_type; - rhs.mode = Addressing_Value; - - // TODO(bill): better error message - if (!check_is_assignable_to(c, &rhs, end_type)) { - gbString a = type_to_string(right_type); - gbString b = type_to_string(end_type); - gbString ret_type = type_to_string(result_type); - error(node, "Cannot assign end value of type '%s' to '%s' in '%.*s'", a, b, LIT(name)); - if (vars.count == 1) { - error_line("\tProcedure return value type: %s\n", ret_type); - } else { - error_line("\tProcedure return value types: (%s)\n", ret_type); - } - gb_string_free(ret_type); - gb_string_free(b); - gb_string_free(a); - } - } - } - - o->expr = node; - o->type = left_type; - if (left_type != nullptr) { - o->mode = Addressing_Value; - } else { - o->mode = Addressing_NoValue; - } - - if (c->curr_proc_sig == nullptr) { - error(node, "'%.*s' can only be used within a procedure", LIT(name)); - } - - if (c->in_defer) { - error(node, "'or_return' cannot be used within a defer statement"); - } - - return Expr_Expr; + return check_or_return_expr(c, o, node, type_hint); case_end; case_ast_node(cl, CompoundLit, node); - Type *type = type_hint; - if (type != nullptr && is_type_untyped(type)) { - type = nullptr; - } - bool is_to_be_determined_array_count = false; - bool is_constant = true; - if (cl->type != nullptr) { - type = nullptr; - - // [?]Type - if (cl->type->kind == Ast_ArrayType && cl->type->ArrayType.count != nullptr) { - Ast *count = cl->type->ArrayType.count; - if (count->kind == Ast_UnaryExpr && - count->UnaryExpr.op.kind == Token_Question) { - type = alloc_type_array(check_type(c, cl->type->ArrayType.elem), -1); - is_to_be_determined_array_count = true; - } - if (cl->elems.count > 0) { - if (cl->type->ArrayType.tag != nullptr) { - Ast *tag = cl->type->ArrayType.tag; - GB_ASSERT(tag->kind == Ast_BasicDirective); - String name = tag->BasicDirective.name.string; - if (name == "soa") { - error(node, "#soa arrays are not supported for compound literals"); - return kind; - } - } - } - } - if (cl->type->kind == Ast_DynamicArrayType && cl->type->DynamicArrayType.tag != nullptr) { - if (cl->elems.count > 0) { - Ast *tag = cl->type->DynamicArrayType.tag; - GB_ASSERT(tag->kind == Ast_BasicDirective); - String name = tag->BasicDirective.name.string; - if (name == "soa") { - error(node, "#soa arrays are not supported for compound literals"); - return kind; - } - } - } - - if (type == nullptr) { - type = check_type(c, cl->type); - } - } - - if (type == nullptr) { - error(node, "Missing type in compound literal"); - return kind; - } - - - Type *t = base_type(type); - if (is_type_polymorphic(t)) { - gbString str = type_to_string(type); - error(node, "Cannot use a polymorphic type for a compound literal, got '%s'", str); - o->expr = node; - o->type = type; - gb_string_free(str); - return kind; - } - - - switch (t->kind) { - case Type_Struct: { - if (cl->elems.count == 0) { - break; // NOTE(bill): No need to init - } - if (t->Struct.is_raw_union) { - if (cl->elems.count > 0) { - // NOTE: unions cannot be constant - is_constant = false; - - if (cl->elems[0]->kind != Ast_FieldValue) { - gbString type_str = type_to_string(type); - error(node, "%s ('struct #raw_union') compound literals are only allowed to contain 'field = value' elements", type_str); - gb_string_free(type_str); - } else { - if (cl->elems.count != 1) { - gbString type_str = type_to_string(type); - error(node, "%s ('struct #raw_union') compound literals are only allowed to contain up to 1 'field = value' element, got %td", type_str, cl->elems.count); - gb_string_free(type_str); - } else { - Ast *elem = cl->elems[0]; - ast_node(fv, FieldValue, elem); - if (fv->field->kind != Ast_Ident) { - gbString expr_str = expr_to_string(fv->field); - error(elem, "Invalid field name '%s' in structure literal", expr_str); - gb_string_free(expr_str); - break; - } - - String name = fv->field->Ident.token.string; - - Selection sel = lookup_field(type, name, o->mode == Addressing_Type); - bool is_unknown = sel.entity == nullptr; - if (is_unknown) { - error(elem, "Unknown field '%.*s' in structure literal", LIT(name)); - break; - } - - if (sel.index.count > 1) { - error(elem, "Cannot assign to an anonymous field '%.*s' in a structure literal (at the moment)", LIT(name)); - break; - } - - Entity *field = t->Struct.fields[sel.index[0]]; - add_entity_use(c, fv->field, field); - - Operand o = {}; - check_expr_or_type(c, &o, fv->value, field->type); - - - check_assignment(c, &o, field->type, str_lit("structure literal")); - } - - } - } - break; - } - - - isize field_count = t->Struct.fields.count; - isize min_field_count = t->Struct.fields.count; - for (isize i = min_field_count-1; i >= 0; i--) { - Entity *e = t->Struct.fields[i]; - GB_ASSERT(e->kind == Entity_Variable); - if (e->Variable.param_value.kind != ParameterValue_Invalid) { - min_field_count--; - } else { - break; - } - } - - if (cl->elems[0]->kind == Ast_FieldValue) { - bool *fields_visited = gb_alloc_array(temporary_allocator(), bool, field_count); - - for_array(i, cl->elems) { - Ast *elem = cl->elems[i]; - if (elem->kind != Ast_FieldValue) { - error(elem, "Mixture of 'field = value' and value elements in a literal is not allowed"); - continue; - } - ast_node(fv, FieldValue, elem); - if (fv->field->kind != Ast_Ident) { - gbString expr_str = expr_to_string(fv->field); - error(elem, "Invalid field name '%s' in structure literal", expr_str); - gb_string_free(expr_str); - continue; - } - String name = fv->field->Ident.token.string; - - Selection sel = lookup_field(type, name, o->mode == Addressing_Type); - bool is_unknown = sel.entity == nullptr; - if (is_unknown) { - error(elem, "Unknown field '%.*s' in structure literal", LIT(name)); - continue; - } - - if (sel.index.count > 1) { - error(elem, "Cannot assign to an anonymous field '%.*s' in a structure literal (at the moment)", LIT(name)); - continue; - } - - Entity *field = t->Struct.fields[sel.index[0]]; - add_entity_use(c, fv->field, field); - - if (fields_visited[sel.index[0]]) { - error(elem, "Duplicate field '%.*s' in structure literal", LIT(name)); - continue; - } - - fields_visited[sel.index[0]] = true; - - Operand o = {}; - check_expr_or_type(c, &o, fv->value, field->type); - - if (is_type_any(field->type) || is_type_union(field->type) || is_type_raw_union(field->type) || is_type_typeid(field->type)) { - is_constant = false; - } - if (is_constant) { - is_constant = check_is_operand_compound_lit_constant(c, &o); - } - - check_assignment(c, &o, field->type, str_lit("structure literal")); - } - } else { - bool seen_field_value = false; - - for_array(index, cl->elems) { - Entity *field = nullptr; - Ast *elem = cl->elems[index]; - if (elem->kind == Ast_FieldValue) { - seen_field_value = true; - error(elem, "Mixture of 'field = value' and value elements in a literal is not allowed"); - continue; - } else if (seen_field_value) { - error(elem, "Value elements cannot be used after a 'field = value'"); - continue; - } - if (index >= field_count) { - error(elem, "Too many values in structure literal, expected %td, got %td", field_count, cl->elems.count); - break; - } - - if (field == nullptr) { - field = t->Struct.fields[index]; - } - - Operand o = {}; - check_expr_or_type(c, &o, elem, field->type); - - if (is_type_any(field->type) || is_type_union(field->type) || is_type_raw_union(field->type) || is_type_typeid(field->type)) { - is_constant = false; - } - if (is_constant) { - is_constant = check_is_operand_compound_lit_constant(c, &o); - } - - check_assignment(c, &o, field->type, str_lit("structure literal")); - } - if (cl->elems.count < field_count) { - if (min_field_count < field_count) { - if (cl->elems.count < min_field_count) { - error(cl->close, "Too few values in structure literal, expected at least %td, got %td", min_field_count, cl->elems.count); - } - } else { - error(cl->close, "Too few values in structure literal, expected %td, got %td", field_count, cl->elems.count); - } - } - } - - break; - } - - case Type_Slice: - case Type_Array: - case Type_DynamicArray: - case Type_SimdVector: - case Type_Matrix: - { - Type *elem_type = nullptr; - String context_name = {}; - i64 max_type_count = -1; - if (t->kind == Type_Slice) { - elem_type = t->Slice.elem; - context_name = str_lit("slice literal"); - } else if (t->kind == Type_Array) { - elem_type = t->Array.elem; - context_name = str_lit("array literal"); - if (!is_to_be_determined_array_count) { - max_type_count = t->Array.count; - } - } else if (t->kind == Type_DynamicArray) { - elem_type = t->DynamicArray.elem; - context_name = str_lit("dynamic array literal"); - is_constant = false; - - if (!build_context.no_dynamic_literals) { - add_package_dependency(c, "runtime", "__dynamic_array_reserve"); - add_package_dependency(c, "runtime", "__dynamic_array_append"); - } - } else if (t->kind == Type_SimdVector) { - elem_type = t->SimdVector.elem; - context_name = str_lit("simd vector literal"); - max_type_count = t->SimdVector.count; - } else if (t->kind == Type_Matrix) { - elem_type = t->Matrix.elem; - context_name = str_lit("matrix literal"); - max_type_count = t->Matrix.row_count*t->Matrix.column_count; - } else { - GB_PANIC("unreachable"); - } - - - i64 max = 0; - - Type *bet = base_type(elem_type); - if (!elem_type_can_be_constant(bet)) { - is_constant = false; - } - - if (bet == t_invalid) { - break; - } - - if (cl->elems.count > 0 && cl->elems[0]->kind == Ast_FieldValue) { - if (is_type_simd_vector(t)) { - error(cl->elems[0], "'field = value' is not allowed for SIMD vector literals"); - } else { - RangeCache rc = range_cache_make(heap_allocator()); - defer (range_cache_destroy(&rc)); - - for_array(i, cl->elems) { - Ast *elem = cl->elems[i]; - if (elem->kind != Ast_FieldValue) { - error(elem, "Mixture of 'field = value' and value elements in a literal is not allowed"); - continue; - } - ast_node(fv, FieldValue, elem); - - if (is_ast_range(fv->field)) { - Token op = fv->field->BinaryExpr.op; - - Operand x = {}; - Operand y = {}; - bool ok = check_range(c, fv->field, &x, &y, nullptr); - if (!ok) { - continue; - } - if (x.mode != Addressing_Constant || !is_type_integer(core_type(x.type))) { - error(x.expr, "Expected a constant integer as an array field"); - continue; - } - - if (y.mode != Addressing_Constant || !is_type_integer(core_type(y.type))) { - error(y.expr, "Expected a constant integer as an array field"); - continue; - } - - i64 lo = exact_value_to_i64(x.value); - i64 hi = exact_value_to_i64(y.value); - i64 max_index = hi; - if (op.kind == Token_RangeHalf) { // ..< (exclusive) - hi -= 1; - } else { // .. (inclusive) - max_index += 1; - } - - bool new_range = range_cache_add_range(&rc, lo, hi); - if (!new_range) { - error(elem, "Overlapping field range index %lld %.*s %lld for %.*s", lo, LIT(op.string), hi, LIT(context_name)); - continue; - } - - - if (max_type_count >= 0 && (lo < 0 || lo >= max_type_count)) { - error(elem, "Index %lld is out of bounds (0..<%lld) for %.*s", lo, max_type_count, LIT(context_name)); - continue; - } - if (max_type_count >= 0 && (hi < 0 || hi >= max_type_count)) { - error(elem, "Index %lld is out of bounds (0..<%lld) for %.*s", hi, max_type_count, LIT(context_name)); - continue; - } - - if (max < hi) { - max = max_index; - } - - Operand operand = {}; - check_expr_with_type_hint(c, &operand, fv->value, elem_type); - check_assignment(c, &operand, elem_type, context_name); - - is_constant = is_constant && operand.mode == Addressing_Constant; - } else { - Operand op_index = {}; - check_expr(c, &op_index, fv->field); - - if (op_index.mode != Addressing_Constant || !is_type_integer(core_type(op_index.type))) { - error(elem, "Expected a constant integer as an array field"); - continue; - } - // add_type_and_value(c->info, op_index.expr, op_index.mode, op_index.type, op_index.value); - - i64 index = exact_value_to_i64(op_index.value); - - if (max_type_count >= 0 && (index < 0 || index >= max_type_count)) { - error(elem, "Index %lld is out of bounds (0..<%lld) for %.*s", index, max_type_count, LIT(context_name)); - continue; - } - - bool new_index = range_cache_add_index(&rc, index); - if (!new_index) { - error(elem, "Duplicate field index %lld for %.*s", index, LIT(context_name)); - continue; - } - - if (max < index+1) { - max = index+1; - } - - Operand operand = {}; - check_expr_with_type_hint(c, &operand, fv->value, elem_type); - check_assignment(c, &operand, elem_type, context_name); - - is_constant = is_constant && operand.mode == Addressing_Constant; - } - } - - cl->max_count = max; - } - - } else { - isize index = 0; - for (; index < cl->elems.count; index++) { - Ast *e = cl->elems[index]; - if (e == nullptr) { - error(node, "Invalid literal element"); - continue; - } - - if (e->kind == Ast_FieldValue) { - error(e, "Mixture of 'field = value' and value elements in a literal is not allowed"); - continue; - } - - if (0 <= max_type_count && max_type_count <= index) { - error(e, "Index %lld is out of bounds (>= %lld) for %.*s", index, max_type_count, LIT(context_name)); - } - - Operand operand = {}; - check_expr_with_type_hint(c, &operand, e, elem_type); - check_assignment(c, &operand, elem_type, context_name); - - is_constant = is_constant && operand.mode == Addressing_Constant; - } - - if (max < index) { - max = index; - } - } - - - if (t->kind == Type_Array) { - if (is_to_be_determined_array_count) { - t->Array.count = max; - } else if (cl->elems.count > 0 && cl->elems[0]->kind != Ast_FieldValue) { - if (0 < max && max < t->Array.count) { - error(node, "Expected %lld values for this array literal, got %lld", cast(long long)t->Array.count, cast(long long)max); - } - } - } - - - if (t->kind == Type_SimdVector) { - if (!is_constant) { - error(node, "Expected all constant elements for a simd vector"); - } - } - - - if (t->kind == Type_DynamicArray) { - if (build_context.no_dynamic_literals && cl->elems.count) { - error(node, "Compound literals of dynamic types have been disabled"); - } - } - - break; - } - - case Type_EnumeratedArray: - { - Type *elem_type = t->EnumeratedArray.elem; - Type *index_type = t->EnumeratedArray.index; - String context_name = str_lit("enumerated array literal"); - i64 max_type_count = t->EnumeratedArray.count; - - gbString index_type_str = type_to_string(index_type); - defer (gb_string_free(index_type_str)); - - i64 total_lo = exact_value_to_i64(*t->EnumeratedArray.min_value); - i64 total_hi = exact_value_to_i64(*t->EnumeratedArray.max_value); - - String total_lo_string = {}; - String total_hi_string = {}; - GB_ASSERT(is_type_enum(index_type)); - { - Type *bt = base_type(index_type); - GB_ASSERT(bt->kind == Type_Enum); - for_array(i, bt->Enum.fields) { - Entity *f = bt->Enum.fields[i]; - if (f->kind != Entity_Constant) { - continue; - } - if (total_lo_string.len == 0 && compare_exact_values(Token_CmpEq, f->Constant.value, *t->EnumeratedArray.min_value)) { - total_lo_string = f->token.string; - } - if (total_hi_string.len == 0 && compare_exact_values(Token_CmpEq, f->Constant.value, *t->EnumeratedArray.max_value)) { - total_hi_string = f->token.string; - } - if (total_lo_string.len != 0 && total_hi_string.len != 0) { - break; - } - } - } - - i64 max = 0; - - Type *bet = base_type(elem_type); - if (!elem_type_can_be_constant(bet)) { - is_constant = false; - } - - if (bet == t_invalid) { - break; - } - - if (cl->elems.count > 0 && cl->elems[0]->kind == Ast_FieldValue) { - RangeCache rc = range_cache_make(heap_allocator()); - defer (range_cache_destroy(&rc)); - - for_array(i, cl->elems) { - Ast *elem = cl->elems[i]; - if (elem->kind != Ast_FieldValue) { - error(elem, "Mixture of 'field = value' and value elements in a literal is not allowed"); - continue; - } - ast_node(fv, FieldValue, elem); - - if (is_ast_range(fv->field)) { - Token op = fv->field->BinaryExpr.op; - - Operand x = {}; - Operand y = {}; - bool ok = check_range(c, fv->field, &x, &y, nullptr, index_type); - if (!ok) { - continue; - } - if (x.mode != Addressing_Constant || !are_types_identical(x.type, index_type)) { - error(x.expr, "Expected a constant enum of type '%s' as an array field", index_type_str); - continue; - } - - if (y.mode != Addressing_Constant || !are_types_identical(x.type, index_type)) { - error(y.expr, "Expected a constant enum of type '%s' as an array field", index_type_str); - continue; - } - - i64 lo = exact_value_to_i64(x.value); - i64 hi = exact_value_to_i64(y.value); - i64 max_index = hi; - if (op.kind == Token_RangeHalf) { - hi -= 1; - } - - bool new_range = range_cache_add_range(&rc, lo, hi); - if (!new_range) { - gbString lo_str = expr_to_string(x.expr); - gbString hi_str = expr_to_string(y.expr); - error(elem, "Overlapping field range index %s %.*s %s for %.*s", lo_str, LIT(op.string), hi_str, LIT(context_name)); - gb_string_free(hi_str); - gb_string_free(lo_str); - continue; - } - - - // NOTE(bill): These are sanity checks for invalid enum values - if (max_type_count >= 0 && (lo < total_lo || lo > total_hi)) { - gbString lo_str = expr_to_string(x.expr); - error(elem, "Index %s is out of bounds (%.*s .. %.*s) for %.*s", lo_str, LIT(total_lo_string), LIT(total_hi_string), LIT(context_name)); - gb_string_free(lo_str); - continue; - } - if (max_type_count >= 0 && (hi < 0 || hi > total_hi)) { - gbString hi_str = expr_to_string(y.expr); - error(elem, "Index %s is out of bounds (%.*s .. %.*s) for %.*s", hi_str, LIT(total_lo_string), LIT(total_hi_string), LIT(context_name)); - gb_string_free(hi_str); - continue; - } - - if (max < hi) { - max = max_index; - } - - Operand operand = {}; - check_expr_with_type_hint(c, &operand, fv->value, elem_type); - check_assignment(c, &operand, elem_type, context_name); - - is_constant = is_constant && operand.mode == Addressing_Constant; - } else { - Operand op_index = {}; - check_expr_with_type_hint(c, &op_index, fv->field, index_type); - - if (op_index.mode != Addressing_Constant || !are_types_identical(op_index.type, index_type)) { - error(op_index.expr, "Expected a constant enum of type '%s' as an array field", index_type_str); - continue; - } - - i64 index = exact_value_to_i64(op_index.value); - - if (max_type_count >= 0 && (index < total_lo || index > total_hi)) { - gbString idx_str = expr_to_string(op_index.expr); - error(elem, "Index %s is out of bounds (%.*s .. %.*s) for %.*s", idx_str, LIT(total_lo_string), LIT(total_hi_string), LIT(context_name)); - gb_string_free(idx_str); - continue; - } - - bool new_index = range_cache_add_index(&rc, index); - if (!new_index) { - gbString idx_str = expr_to_string(op_index.expr); - error(elem, "Duplicate field index %s for %.*s", idx_str, LIT(context_name)); - gb_string_free(idx_str); - continue; - } - - if (max < index+1) { - max = index+1; - } - - Operand operand = {}; - check_expr_with_type_hint(c, &operand, fv->value, elem_type); - check_assignment(c, &operand, elem_type, context_name); - - is_constant = is_constant && operand.mode == Addressing_Constant; - } - } - - cl->max_count = max; - - } else { - isize index = 0; - for (; index < cl->elems.count; index++) { - Ast *e = cl->elems[index]; - if (e == nullptr) { - error(node, "Invalid literal element"); - continue; - } - - if (e->kind == Ast_FieldValue) { - error(e, "Mixture of 'field = value' and value elements in a literal is not allowed"); - continue; - } - - if (0 <= max_type_count && max_type_count <= index) { - error(e, "Index %lld is out of bounds (>= %lld) for %.*s", index, max_type_count, LIT(context_name)); - } - - Operand operand = {}; - check_expr_with_type_hint(c, &operand, e, elem_type); - check_assignment(c, &operand, elem_type, context_name); - - is_constant = is_constant && operand.mode == Addressing_Constant; - } - - if (max < index) { - max = index; - } - } - - if (cl->elems.count > 0 && cl->elems[0]->kind != Ast_FieldValue) { - if (0 < max && max < t->EnumeratedArray.count) { - error(node, "Expected %lld values for this enumerated array literal, got %lld", cast(long long)t->EnumeratedArray.count, cast(long long)max); - } else { - error(node, "Enumerated array literals must only have 'field = value' elements, bare elements are not allowed"); - } - } - - break; - } - - case Type_Basic: { - if (!is_type_any(t)) { - if (cl->elems.count != 0) { - error(node, "Illegal compound literal"); - } - break; - } - if (cl->elems.count == 0) { - break; // NOTE(bill): No need to init - } - { // Checker values - Type *field_types[2] = {t_rawptr, t_typeid}; - isize field_count = 2; - if (cl->elems[0]->kind == Ast_FieldValue) { - bool fields_visited[2] = {}; - - for_array(i, cl->elems) { - Ast *elem = cl->elems[i]; - if (elem->kind != Ast_FieldValue) { - error(elem, "Mixture of 'field = value' and value elements in a 'any' literal is not allowed"); - continue; - } - ast_node(fv, FieldValue, elem); - if (fv->field->kind != Ast_Ident) { - gbString expr_str = expr_to_string(fv->field); - error(elem, "Invalid field name '%s' in 'any' literal", expr_str); - gb_string_free(expr_str); - continue; - } - String name = fv->field->Ident.token.string; - - Selection sel = lookup_field(type, name, o->mode == Addressing_Type); - if (sel.entity == nullptr) { - error(elem, "Unknown field '%.*s' in 'any' literal", LIT(name)); - continue; - } - - isize index = sel.index[0]; - - if (fields_visited[index]) { - error(elem, "Duplicate field '%.*s' in 'any' literal", LIT(name)); - continue; - } - - fields_visited[index] = true; - check_expr(c, o, fv->value); - - // NOTE(bill): 'any' literals can never be constant - is_constant = false; - - check_assignment(c, o, field_types[index], str_lit("'any' literal")); - } - } else { - for_array(index, cl->elems) { - Ast *elem = cl->elems[index]; - if (elem->kind == Ast_FieldValue) { - error(elem, "Mixture of 'field = value' and value elements in a 'any' literal is not allowed"); - continue; - } - - - check_expr(c, o, elem); - if (index >= field_count) { - error(o->expr, "Too many values in 'any' literal, expected %td", field_count); - break; - } - - // NOTE(bill): 'any' literals can never be constant - is_constant = false; - - check_assignment(c, o, field_types[index], str_lit("'any' literal")); - } - if (cl->elems.count < field_count) { - error(cl->close, "Too few values in 'any' literal, expected %td, got %td", field_count, cl->elems.count); - } - } - } - - break; - } - - case Type_Map: { - if (cl->elems.count == 0) { - break; - } - is_constant = false; - { // Checker values - bool key_is_typeid = is_type_typeid(t->Map.key); - bool value_is_typeid = is_type_typeid(t->Map.value); - - for_array(i, cl->elems) { - Ast *elem = cl->elems[i]; - if (elem->kind != Ast_FieldValue) { - error(elem, "Only 'field = value' elements are allowed in a map literal"); - continue; - } - ast_node(fv, FieldValue, elem); - - if (key_is_typeid) { - check_expr_or_type(c, o, fv->field, t->Map.key); - } else { - check_expr_with_type_hint(c, o, fv->field, t->Map.key); - } - check_assignment(c, o, t->Map.key, str_lit("map literal")); - if (o->mode == Addressing_Invalid) { - continue; - } - - if (value_is_typeid) { - check_expr_or_type(c, o, fv->value, t->Map.value); - } else { - check_expr_with_type_hint(c, o, fv->value, t->Map.value); - } - check_assignment(c, o, t->Map.value, str_lit("map literal")); - } - } - - if (build_context.no_dynamic_literals && cl->elems.count) { - error(node, "Compound literals of dynamic types have been disabled"); - } else { - add_package_dependency(c, "runtime", "__dynamic_map_reserve"); - add_package_dependency(c, "runtime", "__dynamic_map_set"); - } - break; - } - - case Type_BitSet: { - if (cl->elems.count == 0) { - break; // NOTE(bill): No need to init - } - Type *et = base_type(t->BitSet.elem); - isize field_count = 0; - if (et->kind == Type_Enum) { - field_count = et->Enum.fields.count; - } - - if (cl->elems[0]->kind == Ast_FieldValue) { - error(cl->elems[0], "'field = value' in a bit_set a literal is not allowed"); - is_constant = false; - } else { - for_array(index, cl->elems) { - Ast *elem = cl->elems[index]; - if (elem->kind == Ast_FieldValue) { - error(elem, "'field = value' in a bit_set a literal is not allowed"); - continue; - } - - check_expr_with_type_hint(c, o, elem, et); - - if (is_constant) { - is_constant = o->mode == Addressing_Constant; - } - - check_assignment(c, o, t->BitSet.elem, str_lit("bit_set literal")); - if (o->mode == Addressing_Constant) { - i64 lower = t->BitSet.lower; - i64 upper = t->BitSet.upper; - i64 v = exact_value_to_i64(o->value); - if (lower <= v && v <= upper) { - // okay - } else { - error(elem, "Bit field value out of bounds, %lld not in the range %lld .. %lld", v, lower, upper); - continue; - } - } - } - } - break; - } - - default: { - if (cl->elems.count == 0) { - break; // NOTE(bill): No need to init - } - - gbString str = type_to_string(type); - error(node, "Invalid compound literal type '%s'", str); - gb_string_free(str); - return kind; - } - } - - if (is_constant) { - o->mode = Addressing_Constant; - - if (is_type_bit_set(type)) { - // NOTE(bill): Encode as an integer - - i64 lower = base_type(type)->BitSet.lower; - - u64 bits = 0; - for_array(index, cl->elems) { - Ast *elem = cl->elems[index]; - GB_ASSERT(elem->kind != Ast_FieldValue); - TypeAndValue tav = elem->tav; - ExactValue i = exact_value_to_integer(tav.value); - if (i.kind != ExactValue_Integer) { - continue; - } - i64 val = big_int_to_i64(&i.value_integer); - val -= lower; - u64 bit = u64(1ll<value = exact_value_u64(bits); - } else if (is_type_constant_type(type) && cl->elems.count == 0) { - ExactValue value = exact_value_compound(node); - Type *bt = core_type(type); - if (bt->kind == Type_Basic) { - if (bt->Basic.flags & BasicFlag_Boolean) { - value = exact_value_bool(false); - } else if (bt->Basic.flags & BasicFlag_Integer) { - value = exact_value_i64(0); - } else if (bt->Basic.flags & BasicFlag_Unsigned) { - value = exact_value_i64(0); - } else if (bt->Basic.flags & BasicFlag_Float) { - value = exact_value_float(0); - } else if (bt->Basic.flags & BasicFlag_Complex) { - value = exact_value_complex(0, 0); - } else if (bt->Basic.flags & BasicFlag_Quaternion) { - value = exact_value_quaternion(0, 0, 0, 0); - } else if (bt->Basic.flags & BasicFlag_Pointer) { - value = exact_value_pointer(0); - } else if (bt->Basic.flags & BasicFlag_String) { - String empty_string = {}; - value = exact_value_string(empty_string); - } else if (bt->Basic.flags & BasicFlag_Rune) { - value = exact_value_i64(0); - } - } - - o->value = value; - } else { - o->value = exact_value_compound(node); - } - } else { - o->mode = Addressing_Value; - } - o->type = type; + kind = check_compound_literal(c, o, node, type_hint); case_end; case_ast_node(pe, ParenExpr, node); @@ -8142,127 +9161,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type case_end; case_ast_node(ta, TypeAssertion, node); - check_expr(c, o, ta->expr); - node->viral_state_flags |= ta->expr->viral_state_flags; - - if (o->mode == Addressing_Invalid) { - o->expr = node; - return kind; - } - if (o->mode == Addressing_Constant) { - gbString expr_str = expr_to_string(o->expr); - error(o->expr, "A type assertion cannot be applied to a constant expression: '%s'", expr_str); - gb_string_free(expr_str); - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } - - if (is_type_untyped(o->type)) { - gbString expr_str = expr_to_string(o->expr); - error(o->expr, "A type assertion cannot be applied to an untyped expression: '%s'", expr_str); - gb_string_free(expr_str); - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } - - Type *src = type_deref(o->type); - Type *bsrc = base_type(src); - - - if (ta->type != nullptr && ta->type->kind == Ast_UnaryExpr && ta->type->UnaryExpr.op.kind == Token_Question) { - if (!is_type_union(src)) { - gbString str = type_to_string(o->type); - error(o->expr, "Type assertions with .? can only operate on unions, got %s", str); - gb_string_free(str); - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } - - if (bsrc->Union.variants.count != 1 && type_hint != nullptr) { - bool allowed = false; - for_array(i, bsrc->Union.variants) { - Type *vt = bsrc->Union.variants[i]; - if (are_types_identical(vt, type_hint)) { - allowed = true; - add_type_info_type(c, vt); - break; - } - } - if (allowed) { - add_type_info_type(c, o->type); - o->type = type_hint; - o->mode = Addressing_OptionalOk; - return kind; - } - } - - if (bsrc->Union.variants.count != 1) { - error(o->expr, "Type assertions with .? can only operate on unions with 1 variant, got %lld", cast(long long)bsrc->Union.variants.count); - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } - - add_type_info_type(c, o->type); - add_type_info_type(c, bsrc->Union.variants[0]); - - o->type = bsrc->Union.variants[0]; - o->mode = Addressing_OptionalOk; - } else { - Type *t = check_type(c, ta->type); - Type *dst = t; - - if (is_type_union(src)) { - bool ok = false; - for_array(i, bsrc->Union.variants) { - Type *vt = bsrc->Union.variants[i]; - if (are_types_identical(vt, dst)) { - ok = true; - break; - } - } - - if (!ok) { - gbString expr_str = expr_to_string(o->expr); - gbString dst_type_str = type_to_string(t); - defer (gb_string_free(expr_str)); - defer (gb_string_free(dst_type_str)); - if (bsrc->Union.variants.count == 0) { - error(o->expr, "Cannot type assert '%s' to '%s' as this is an empty union", expr_str, dst_type_str); - } else { - error(o->expr, "Cannot type assert '%s' to '%s' as it is not a variant of that union", expr_str, dst_type_str); - } - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } - - add_type_info_type(c, o->type); - add_type_info_type(c, t); - - o->type = t; - o->mode = Addressing_OptionalOk; - } else if (is_type_any(src)) { - o->type = t; - o->mode = Addressing_OptionalOk; - - add_type_info_type(c, o->type); - add_type_info_type(c, t); - } else { - gbString str = type_to_string(o->type); - error(o->expr, "Type assertions can only operate on unions and 'any', got %s", str); - gb_string_free(str); - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } - } - - add_package_dependency(c, "runtime", "type_assertion_check"); - add_package_dependency(c, "runtime", "type_assertion_check2"); + kind = check_type_assertion(c, o, node, type_hint); case_end; case_ast_node(tc, TypeCast, node); @@ -8350,443 +9249,19 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type case_end; case_ast_node(se, SelectorCallExpr, node); - // IMPORTANT NOTE(bill, 2020-05-22): This is a complete hack to get a shorthand which is extremely useful for vtables - // COM APIs is a great example of where this kind of thing is extremely useful - // General idea: - // - // x->y(123) == x.y(x, 123) - // - // How this has been implemented at the moment is quite hacky but it's done so to reduce need for huge backend changes - // Just regenerating a new AST aids things - // - // TODO(bill): Is this a good hack or not? - // - // NOTE(bill, 2020-05-22): I'm going to regret this decision, ain't I? - - - if (se->modified_call) { - // Prevent double evaluation - o->expr = node; - o->type = node->tav.type; - o->value = node->tav.value; - o->mode = node->tav.mode; - return Expr_Expr; - } - - bool allow_arrow_right_selector_expr; - allow_arrow_right_selector_expr = c->allow_arrow_right_selector_expr; - c->allow_arrow_right_selector_expr = true; - Operand x = {}; - ExprKind kind = check_expr_base(c, &x, se->expr, nullptr); - c->allow_arrow_right_selector_expr = allow_arrow_right_selector_expr; - - if (x.mode == Addressing_Invalid || x.type == t_invalid) { - o->mode = Addressing_Invalid; - o->type = t_invalid; - o->expr = node; - return kind; - } - if (!is_type_proc(x.type)) { - gbString type_str = type_to_string(x.type); - error(se->call, "Selector call expressions expect a procedure type for the call, got '%s'", type_str); - gb_string_free(type_str); - - o->mode = Addressing_Invalid; - o->type = t_invalid; - o->expr = node; - return Expr_Stmt; - } - - ast_node(ce, CallExpr, se->call); - - GB_ASSERT(x.expr->kind == Ast_SelectorExpr); - - Ast *first_arg = x.expr->SelectorExpr.expr; - GB_ASSERT(first_arg != nullptr); - - Type *pt = base_type(x.type); - GB_ASSERT(pt->kind == Type_Proc); - Type *first_type = nullptr; - String first_arg_name = {}; - if (pt->Proc.param_count > 0) { - Entity *f = pt->Proc.params->Tuple.variables[0]; - first_type = f->type; - first_arg_name = f->token.string; - } - if (first_arg_name.len == 0) { - first_arg_name = str_lit("_"); - } - - if (first_type == nullptr) { - error(se->call, "Selector call expressions expect a procedure type for the call with at least 1 parameter"); - o->mode = Addressing_Invalid; - o->type = t_invalid; - o->expr = node; - return Expr_Stmt; - } - - Operand y = {}; - y.mode = first_arg->tav.mode; - y.type = first_arg->tav.type; - y.value = first_arg->tav.value; - if (check_is_assignable_to(c, &y, first_type)) { - // Do nothing, it's valid - } else { - Operand z = y; - z.type = type_deref(y.type); - if (check_is_assignable_to(c, &z, first_type)) { - // NOTE(bill): AST GENERATION HACK! - Token op = {Token_Pointer}; - first_arg = ast_deref_expr(first_arg->file(), first_arg, op); - } else if (y.mode == Addressing_Variable) { - Operand w = y; - w.type = alloc_type_pointer(y.type); - if (check_is_assignable_to(c, &w, first_type)) { - // NOTE(bill): AST GENERATION HACK! - Token op = {Token_And}; - first_arg = ast_unary_expr(first_arg->file(), op, first_arg); - } - } - } - - if (ce->args.count > 0) { - bool fail = false; - bool first_is_field_value = (ce->args[0]->kind == Ast_FieldValue); - for_array(i, ce->args) { - Ast *arg = ce->args[i]; - bool mix = false; - if (first_is_field_value) { - mix = arg->kind != Ast_FieldValue; - } else { - mix = arg->kind == Ast_FieldValue; - } - if (mix) { - fail = true; - break; - } - } - if (!fail && first_is_field_value) { - Token op = {Token_Eq}; - AstFile *f = first_arg->file(); - first_arg = ast_field_value(f, ast_ident(f, make_token_ident(first_arg_name)), first_arg, op); - } - } - - - - auto modified_args = slice_make(heap_allocator(), ce->args.count+1); - modified_args[0] = first_arg; - slice_copy(&modified_args, ce->args, 1); - ce->args = modified_args; - se->modified_call = true; - - allow_arrow_right_selector_expr = c->allow_arrow_right_selector_expr; - c->allow_arrow_right_selector_expr = true; - check_expr_base(c, o, se->call, type_hint); - c->allow_arrow_right_selector_expr = allow_arrow_right_selector_expr; - - o->expr = node; - return Expr_Expr; + return check_selector_call_expr(c, o, node, type_hint); case_end; - case_ast_node(ise, ImplicitSelectorExpr, node); return check_implicit_selector_expr(c, o, node, type_hint); case_end; case_ast_node(ie, IndexExpr, node); - check_expr(c, o, ie->expr); - node->viral_state_flags |= ie->expr->viral_state_flags; - if (o->mode == Addressing_Invalid) { - o->expr = node; - return kind; - } - - Type *t = base_type(type_deref(o->type)); - bool is_ptr = is_type_pointer(o->type); - bool is_const = o->mode == Addressing_Constant; - - if (is_type_map(t)) { - Operand key = {}; - if (is_type_typeid(t->Map.key)) { - check_expr_or_type(c, &key, ie->index, t->Map.key); - } else { - check_expr_with_type_hint(c, &key, ie->index, t->Map.key); - } - check_assignment(c, &key, t->Map.key, str_lit("map index")); - if (key.mode == Addressing_Invalid) { - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } - o->mode = Addressing_MapIndex; - o->type = t->Map.value; - o->expr = node; - - add_package_dependency(c, "runtime", "__dynamic_map_get"); - add_package_dependency(c, "runtime", "__dynamic_map_set"); - return Expr_Expr; - } - - i64 max_count = -1; - bool valid = check_set_index_data(o, t, is_ptr, &max_count, o->type); - - if (is_const) { - if (is_type_array(t)) { - // OKay - } else if (is_type_slice(t)) { - // Okay - } else if (is_type_enumerated_array(t)) { - // Okay - } else if (is_type_string(t)) { - // Okay - } else if (is_type_relative_slice(t)) { - // Okay - } else if (is_type_matrix(t)) { - // Okay - } else { - valid = false; - } - } - - if (!valid) { - gbString str = expr_to_string(o->expr); - gbString type_str = type_to_string(o->type); - defer (gb_string_free(str)); - defer (gb_string_free(type_str)); - if (is_const) { - error(o->expr, "Cannot index constant '%s' of type '%s'", str, type_str); - } else { - error(o->expr, "Cannot index '%s' of type '%s'", str, type_str); - } - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } - - if (ie->index == nullptr) { - gbString str = expr_to_string(o->expr); - error(o->expr, "Missing index for '%s'", str); - gb_string_free(str); - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } - - Type *index_type_hint = nullptr; - if (is_type_enumerated_array(t)) { - Type *bt = base_type(t); - GB_ASSERT(bt->kind == Type_EnumeratedArray); - index_type_hint = bt->EnumeratedArray.index; - } - - i64 index = 0; - bool ok = check_index_value(c, t, false, ie->index, max_count, &index, index_type_hint); - if (is_const) { - if (index < 0) { - gbString str = expr_to_string(o->expr); - error(o->expr, "Cannot index a constant '%s'", str); - error_line("\tSuggestion: store the constant into a variable in order to index it with a variable index\n"); - gb_string_free(str); - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } else if (ok) { - ExactValue value = type_and_value_of_expr(ie->expr).value; - o->mode = Addressing_Constant; - bool success = false; - bool finish = false; - o->value = get_constant_field_single(c, value, cast(i32)index, &success, &finish); - if (!success) { - gbString str = expr_to_string(o->expr); - error(o->expr, "Cannot index a constant '%s' with index %lld", str, cast(long long)index); - error_line("\tSuggestion: store the constant into a variable in order to index it with a variable index\n"); - gb_string_free(str); - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } - } - } - - if (type_hint != nullptr && is_type_matrix(t)) { - // TODO(bill): allow matrix columns to be assignable to other types which are the same internally - // if a type hint exists - } - + kind = check_index_expr(c, o, node, type_hint); case_end; case_ast_node(se, SliceExpr, node); - check_expr(c, o, se->expr); - node->viral_state_flags |= se->expr->viral_state_flags; - - if (o->mode == Addressing_Invalid) { - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } - - bool valid = false; - i64 max_count = -1; - Type *t = base_type(type_deref(o->type)); - switch (t->kind) { - case Type_Basic: - if (t->Basic.kind == Basic_string || t->Basic.kind == Basic_UntypedString) { - valid = true; - if (o->mode == Addressing_Constant) { - max_count = o->value.value_string.len; - } - o->type = type_deref(o->type); - } - break; - - case Type_Array: - valid = true; - max_count = t->Array.count; - if (o->mode != Addressing_Variable && !is_type_pointer(o->type)) { - gbString str = expr_to_string(node); - error(node, "Cannot slice array '%s', value is not addressable", str); - gb_string_free(str); - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } - o->type = alloc_type_slice(t->Array.elem); - break; - - case Type_MultiPointer: - valid = true; - o->type = type_deref(o->type); - break; - - case Type_Slice: - valid = true; - o->type = type_deref(o->type); - break; - - case Type_DynamicArray: - valid = true; - o->type = alloc_type_slice(t->DynamicArray.elem); - break; - - case Type_Struct: - if (is_type_soa_struct(t)) { - valid = true; - o->type = make_soa_struct_slice(c, nullptr, nullptr, t->Struct.soa_elem); - } - break; - - case Type_RelativeSlice: - valid = true; - o->type = t->RelativeSlice.slice_type; - if (o->mode != Addressing_Variable) { - gbString str = expr_to_string(node); - error(node, "Cannot relative slice '%s', value is not addressable", str); - gb_string_free(str); - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } - break; - } - - if (!valid) { - gbString str = expr_to_string(o->expr); - gbString type_str = type_to_string(o->type); - error(o->expr, "Cannot slice '%s' of type '%s'", str, type_str); - gb_string_free(type_str); - gb_string_free(str); - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } - - if (se->low == nullptr && se->high != nullptr) { - // It is okay to continue as it will assume the 1st index is zero - } - - i64 indices[2] = {}; - Ast *nodes[2] = {se->low, se->high}; - for (isize i = 0; i < gb_count_of(nodes); i++) { - i64 index = max_count; - if (nodes[i] != nullptr) { - i64 capacity = -1; - if (max_count >= 0) { - capacity = max_count; - } - i64 j = 0; - if (check_index_value(c, t, true, nodes[i], capacity, &j)) { - index = j; - } - - node->viral_state_flags |= nodes[i]->viral_state_flags; - } else if (i == 0) { - index = 0; - } - indices[i] = index; - } - - for (isize i = 0; i < gb_count_of(indices); i++) { - i64 a = indices[i]; - for (isize j = i+1; j < gb_count_of(indices); j++) { - i64 b = indices[j]; - if (a > b && b >= 0) { - error(se->close, "Invalid slice indices: [%td > %td]", a, b); - } - } - } - - if (max_count < 0) { - if (o->mode == Addressing_Constant) { - gbString s = expr_to_string(se->expr); - error(se->expr, "Cannot slice constant value '%s'", s); - gb_string_free(s); - } - } - - if (t->kind == Type_MultiPointer && se->high != nullptr) { - /* - x[:] -> [^]T - x[i:] -> [^]T - x[:n] -> []T - x[i:n] -> []T - */ - o->type = alloc_type_slice(t->MultiPointer.elem); - } - - o->mode = Addressing_Value; - - if (is_type_string(t) && max_count >= 0) { - bool all_constant = true; - for (isize i = 0; i < gb_count_of(nodes); i++) { - if (nodes[i] != nullptr) { - TypeAndValue tav = type_and_value_of_expr(nodes[i]); - if (tav.mode != Addressing_Constant) { - all_constant = false; - break; - } - } - } - if (!all_constant) { - gbString str = expr_to_string(o->expr); - error(o->expr, "Cannot slice '%s' with non-constant indices", str); - error_line("\tSuggestion: store the constant into a variable in order to index it with a variable index\n"); - gb_string_free(str); - o->mode = Addressing_Value; // NOTE(bill): Keep subsequent values going without erring - o->expr = node; - return kind; - } - - String s = {}; - if (o->value.kind == ExactValue_String) { - s = o->value.value_string; - } - - o->mode = Addressing_Constant; - o->type = t; - o->value = exact_value_string(substring(s, cast(isize)indices[0], cast(isize)indices[1])); - } - + kind = check_slice_expr(c, o, node, type_hint); case_end; case_ast_node(mie, MatrixIndexExpr, node); @@ -8911,6 +9386,8 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type return kind; } + + ExprKind check_expr_base(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ExprKind kind = check_expr_base_internal(c, o, node, type_hint); if (o->type != nullptr && core_type(o->type) == nullptr) { @@ -8926,6 +9403,8 @@ ExprKind check_expr_base(CheckerContext *c, Operand *o, Ast *node, Type *type_hi if (o->type != nullptr && is_type_untyped(o->type)) { add_untyped(c, node, o->mode, o->type, o->value); } + check_rtti_type_disallowed(node, o->type, "An expression is using a type, %s, which has been disallowed"); + add_type_and_value(c->info, node, o->mode, o->type, o->value); return kind; } @@ -9085,18 +9564,7 @@ gbString string_append_string(gbString str, String string) { gbString string_append_token(gbString str, Token token) { - if (token.kind == Token_String) { - str = gb_string_append_rune(str, '"'); - } else if (token.kind == Token_Rune) { - str = gb_string_append_rune(str, '\''); - } str = string_append_string(str, token.string); - if (token.kind == Token_String) { - str = gb_string_append_rune(str, '"'); - } else if (token.kind == Token_Rune) { - str = gb_string_append_rune(str, '\''); - } - return str; } @@ -9323,6 +9791,13 @@ gbString write_expr_to_string(gbString str, Ast *node, bool shorthand) { str = gb_string_appendc(str, " = "); str = write_expr_to_string(str, fv->value, shorthand); case_end; + case_ast_node(fv, EnumFieldValue, node); + str = write_expr_to_string(str, fv->name, shorthand); + if (fv->value) { + str = gb_string_appendc(str, " = "); + str = write_expr_to_string(str, fv->value, shorthand); + } + case_end; case_ast_node(ht, HelperType, node); str = gb_string_appendc(str, "#type "); @@ -9414,6 +9889,9 @@ gbString write_expr_to_string(gbString str, Ast *node, bool shorthand) { if (f->flags&FieldFlag_const) { str = gb_string_appendc(str, "#const "); } + if (f->flags&FieldFlag_subtype) { + str = gb_string_appendc(str, "#subtype "); + } for_array(i, f->names) { Ast *name = f->names[i]; @@ -9572,8 +10050,11 @@ gbString write_expr_to_string(gbString str, Ast *node, bool shorthand) { str = write_expr_to_string(str, st->polymorphic_params, shorthand); str = gb_string_appendc(str, ") "); } - if (st->no_nil) str = gb_string_appendc(str, "#no_nil "); - if (st->maybe) str = gb_string_appendc(str, "#maybe "); + switch (st->kind) { + case UnionType_maybe: str = gb_string_appendc(str, "#maybe "); break; + case UnionType_no_nil: str = gb_string_appendc(str, "#no_nil "); break; + case UnionType_shared_nil: str = gb_string_appendc(str, "#shared_nil "); break; + } if (st->align) { str = gb_string_appendc(str, "#align "); str = write_expr_to_string(str, st->align, shorthand); diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 1a424240c..f2c830c1b 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -490,6 +490,14 @@ void check_stmt(CheckerContext *ctx, Ast *node, u32 flags) { out &= ~StateFlag_no_bounds_check; } + if (in & StateFlag_no_type_assert) { + out |= StateFlag_no_type_assert; + out &= ~StateFlag_type_assert; + } else if (in & StateFlag_type_assert) { + out |= StateFlag_type_assert; + out &= ~StateFlag_no_type_assert; + } + ctx->state_flags = out; } @@ -607,7 +615,7 @@ bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, Ast *expr, b case Entity_ImportName: { Scope *scope = e->ImportName.scope; - for_array(i, scope->elements.entries) { + MUTEX_GUARD_BLOCK(scope->mutex) for_array(i, scope->elements.entries) { String name = scope->elements.entries[i].key.string; Entity *decl = scope->elements.entries[i].value; if (!is_entity_exported(decl)) continue; @@ -689,54 +697,6 @@ bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, Ast *expr, b return true; } - -struct TypeAndToken { - Type *type; - Token token; -}; - - -void add_constant_switch_case(CheckerContext *ctx, PtrMap *seen, Operand operand, bool use_expr = true) { - if (operand.mode != Addressing_Constant) { - return; - } - if (operand.value.kind == ExactValue_Invalid) { - return; - } - - uintptr key = hash_exact_value(operand.value); - TypeAndToken *found = map_get(seen, key); - if (found != nullptr) { - isize count = multi_map_count(seen, key); - TypeAndToken *taps = gb_alloc_array(temporary_allocator(), TypeAndToken, count); - - multi_map_get_all(seen, key, taps); - for (isize i = 0; i < count; i++) { - TypeAndToken tap = taps[i]; - if (!are_types_identical(operand.type, tap.type)) { - continue; - } - - TokenPos pos = tap.token.pos; - if (use_expr) { - gbString expr_str = expr_to_string(operand.expr); - error(operand.expr, - "Duplicate case '%s'\n" - "\tprevious case at %s", - expr_str, - token_pos_to_string(pos)); - gb_string_free(expr_str); - } else { - error(operand.expr, "Duplicate case found with previous case at %s", token_pos_to_string(pos)); - } - return; - } - } - - TypeAndToken tap = {operand.type, ast_token(operand.expr)}; - multi_map_insert(seen, key, tap); -} - void check_inline_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { ast_node(irs, UnrollRangeStmt, node); check_open_scope(ctx, node); @@ -961,7 +921,7 @@ void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { } } - PtrMap seen = {}; // NOTE(bill): Multimap, Key: ExactValue + SeenMap seen = {}; // NOTE(bill): Multimap, Key: ExactValue map_init(&seen, heap_allocator()); defer (map_destroy(&seen)); @@ -1001,9 +961,9 @@ void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { TokenKind upper_op = Token_Invalid; switch (be->op.kind) { - case Token_Ellipsis: upper_op = Token_GtEq; break; - case Token_RangeFull: upper_op = Token_GtEq; break; - case Token_RangeHalf: upper_op = Token_Gt; break; + case Token_Ellipsis: upper_op = Token_LtEq; break; + case Token_RangeFull: upper_op = Token_LtEq; break; + case Token_RangeHalf: upper_op = Token_Lt; break; default: GB_PANIC("Invalid range operator"); break; } @@ -1024,45 +984,7 @@ void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { Operand b1 = rhs; check_comparison(ctx, &a1, &b1, Token_LtEq); - if (is_type_enum(x.type)) { - // TODO(bill): Fix this logic so it's fast!!! - - i64 v0 = exact_value_to_i64(lhs.value); - i64 v1 = exact_value_to_i64(rhs.value); - Operand v = {}; - v.mode = Addressing_Constant; - v.type = x.type; - v.expr = x.expr; - - Type *bt = base_type(x.type); - GB_ASSERT(bt->kind == Type_Enum); - for (i64 vi = v0; vi <= v1; vi++) { - if (upper_op != Token_GtEq && vi == v1) { - break; - } - - bool found = false; - for_array(j, bt->Enum.fields) { - Entity *f = bt->Enum.fields[j]; - GB_ASSERT(f->kind == Entity_Constant); - - i64 fv = exact_value_to_i64(f->Constant.value); - if (fv == vi) { - found = true; - break; - } - } - if (found) { - v.value = exact_value_i64(vi); - add_constant_switch_case(ctx, &seen, v); - } - } - } else { - add_constant_switch_case(ctx, &seen, lhs); - if (upper_op == Token_GtEq) { - add_constant_switch_case(ctx, &seen, rhs); - } - } + add_to_seen_map(ctx, &seen, upper_op, x, lhs, rhs); if (is_type_string(x.type)) { // NOTE(bill): Force dependency for strings here @@ -1107,7 +1029,7 @@ void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { continue; } update_untyped_expr_type(ctx, z.expr, x.type, !is_type_untyped(x.type)); - add_constant_switch_case(ctx, &seen, y); + add_to_seen_map(ctx, &seen, y); } } } @@ -1143,7 +1065,7 @@ void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { if (unhandled.count == 1) { error_no_newline(node, "Unhandled switch case: %.*s", LIT(unhandled[0]->token.string)); } else { - error_no_newline(node, "Unhandled switch cases: "); + error(node, "Unhandled switch cases:"); for_array(i, unhandled) { Entity *f = unhandled[i]; error_line("\t%.*s\n", LIT(f->token.string)); @@ -2230,7 +2152,6 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { e->state = EntityState_Resolved; } ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix); - e->Variable.thread_local_model = ac.thread_local_model; if (ac.link_name.len > 0) { e->Variable.link_name = ac.link_name; @@ -2243,6 +2164,9 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { error(e->token, "The 'static' attribute is not allowed to be applied to '_'"); } else { e->flags |= EntityFlag_Static; + if (ctx->in_defer) { + error(e->token, "'static' variables cannot be declared within a defer statement"); + } } } if (ac.thread_local_model != "") { @@ -2251,10 +2175,18 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { error(e->token, "The 'thread_local' attribute is not allowed to be applied to '_'"); } else { e->flags |= EntityFlag_Static; + if (ctx->in_defer) { + error(e->token, "'thread_local' variables cannot be declared within a defer statement"); + } } e->Variable.thread_local_model = ac.thread_local_model; } + if (is_arch_wasm() && e->Variable.thread_local_model.len != 0) { + error(e->token, "@(thread_local) is not supported for this target platform"); + } + + if (ac.is_static && ac.thread_local_model != "") { error(e->token, "The 'static' attribute is not needed if 'thread_local' is applied"); } diff --git a/src/check_type.cpp b/src/check_type.cpp index b4f30d2f0..51f472961 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -109,14 +109,19 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Slice *fields } i32 field_src_index = 0; + i32 field_group_index = -1; for_array(i, params) { Ast *param = params[i]; if (param->kind != Ast_Field) { continue; } + field_group_index += 1; + ast_node(p, Field, param); Ast *type_expr = p->type; Type *type = nullptr; + CommentGroup *docs = p->docs; + CommentGroup *comment = p->comment; if (type_expr != nullptr) { type = check_type_expr(ctx, type_expr, nullptr); @@ -139,6 +144,7 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Slice *fields } bool is_using = (p->flags&FieldFlag_using) != 0; + bool is_subtype = (p->flags&FieldFlag_subtype) != 0; for_array(j, p->names) { Ast *name = p->names[j]; @@ -152,6 +158,18 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Slice *fields Entity *field = alloc_entity_field(ctx->scope, name_token, type, is_using, field_src_index); add_entity(ctx, ctx->scope, name, field); + field->Variable.field_group_index = field_group_index; + if (is_subtype) { + field->flags |= EntityFlag_Subtype; + } + + if (j == 0) { + field->Variable.docs = docs; + } + if (j+1 == p->names.count) { + field->Variable.comment = comment; + } + array_add(&fields_array, field); String tag = p->tag.string; if (tag.len != 0 && !unquote_string(permanent_allocator(), &tag, 0, tag.text[0] == '`')) { @@ -180,6 +198,20 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Slice *fields populate_using_entity_scope(ctx, node, p, type); } + + if (is_subtype && p->names.count > 0) { + Type *first_type = fields_array[fields_array.count-1]->type; + Type *t = base_type(type_deref(first_type)); + + if (!does_field_type_allow_using(t) && + p->names.count >= 1 && + p->names[0]->kind == Ast_Ident) { + Token name_token = p->names[0]->Ident.token; + gbString type_str = type_to_string(first_type); + error(name_token, "'subtype' cannot be applied to the field '%.*s' of type '%s'", LIT(name_token.string), type_str); + gb_string_free(type_str); + } + } } *fields = slice_from_array(fields_array); @@ -309,6 +341,10 @@ void add_polymorphic_record_entity(CheckerContext *ctx, Ast *node, Type *named_t } named_type->Named.type_name = e; + GB_ASSERT(original_type->kind == Type_Named); + e->TypeName.objc_class_name = original_type->Named.type_name->TypeName.objc_class_name; + // TODO(bill): Is this even correct? Or should the metadata be copied? + e->TypeName.objc_metadata = original_type->Named.type_name->TypeName.objc_metadata; mutex_lock(&ctx->info->gen_types_mutex); auto *found_gen_types = map_get(&ctx->info->gen_types, original_type); @@ -639,22 +675,31 @@ void check_union_type(CheckerContext *ctx, Type *union_type, Ast *node, Arraykind == UnionType_shared_nil) { + if (!type_has_nil(t)) { + gbString s = type_to_string(t); + error(node, "Each variant of a union with #shared_nil must have a 'nil' value, got %s", s); + gb_string_free(s); + } + } } } } union_type->Union.variants = slice_from_array(variants); - union_type->Union.no_nil = ut->no_nil; - union_type->Union.maybe = ut->maybe; - if (union_type->Union.no_nil) { + union_type->Union.kind = ut->kind; + switch (ut->kind) { + case UnionType_no_nil: if (variants.count < 2) { error(ut->align, "A union with #no_nil must have at least 2 variants"); } - } - if (union_type->Union.maybe) { + break; + case UnionType_maybe: if (variants.count != 1) { error(ut->align, "A union with #maybe must have at 1 variant, got %lld", cast(long long)variants.count); } + break; } if (ut->align != nullptr) { @@ -718,20 +763,19 @@ void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *named_type, Ast Ast *ident = nullptr; Ast *init = nullptr; u32 entity_flags = 0; - if (field->kind == Ast_FieldValue) { - ast_node(fv, FieldValue, field); - if (fv->field == nullptr || fv->field->kind != Ast_Ident) { - error(field, "An enum field's name must be an identifier"); - continue; - } - ident = fv->field; - init = fv->value; - } else if (field->kind == Ast_Ident) { - ident = field; - } else { + if (field->kind != Ast_EnumFieldValue) { error(field, "An enum field's name must be an identifier"); continue; } + ident = field->EnumFieldValue.name; + init = field->EnumFieldValue.value; + if (ident == nullptr || ident->kind != Ast_Ident) { + error(field, "An enum field's name must be an identifier"); + continue; + } + CommentGroup *docs = field->EnumFieldValue.docs; + CommentGroup *comment = field->EnumFieldValue.comment; + String name = ident->Ident.token.string; if (init != nullptr) { @@ -789,6 +833,8 @@ void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *named_type, Ast e->flags |= EntityFlag_Visited; e->state = EntityState_Resolved; e->Constant.flags |= entity_flags; + e->Constant.docs = docs; + e->Constant.comment = comment; if (scope_lookup_current(ctx->scope, name) != nullptr) { error(ident, "'%.*s' is already declared in this enumeration", LIT(name)); @@ -922,20 +968,19 @@ void check_bit_set_type(CheckerContext *c, Type *type, Type *named_type, Ast *no i64 lower = big_int_to_i64(&i); i64 upper = big_int_to_i64(&j); - bool lower_changed = false; + i64 actual_lower = lower; i64 bits = MAX_BITS; if (type->BitSet.underlying != nullptr) { bits = 8*type_size_of(type->BitSet.underlying); if (lower > 0) { - lower = 0; - lower_changed = true; + actual_lower = 0; } else if (lower < 0) { error(bs->elem, "bit_set does not allow a negative lower bound (%lld) when an underlying type is set", lower); } } - i64 bits_required = upper-lower; + i64 bits_required = upper-actual_lower; switch (be->op.kind) { case Token_Ellipsis: case Token_RangeFull: @@ -959,7 +1004,7 @@ void check_bit_set_type(CheckerContext *c, Type *type, Type *named_type, Ast *no break; } if (!is_valid) { - if (lower_changed) { + if (actual_lower != lower) { error(bs->elem, "bit_set range is greater than %lld bits, %lld bits are required (internal the lower changed was changed 0 as an underlying type was set)", bits, bits_required); } else { error(bs->elem, "bit_set range is greater than %lld bits, %lld bits are required", bits, bits_required); @@ -1367,11 +1412,13 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is isize variadic_index = -1; bool is_c_vararg = false; auto variables = array_make(permanent_allocator(), 0, variable_count); + i32 field_group_index = -1; for_array(i, params) { Ast *param = params[i]; if (param->kind != Ast_Field) { continue; } + field_group_index += 1; ast_node(p, Field, param); Ast *type_expr = unparen_expr(p->type); Type *type = nullptr; @@ -1672,9 +1719,11 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is } param = alloc_entity_const_param(scope, name->Ident.token, type, poly_const, is_type_polymorphic(type)); + param->Constant.field_group_index = field_group_index; } else { param = alloc_entity_param(scope, name->Ident.token, type, is_using, true); param->Variable.param_value = param_value; + param->Variable.field_group_index = field_group_index; } } if (p->flags&FieldFlag_no_alias) { @@ -1768,7 +1817,10 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) { } auto variables = array_make(permanent_allocator(), 0, variable_count); + i32 field_group_index = -1; for_array(i, results) { + field_group_index += 1; + ast_node(field, Field, results[i]); Ast *default_value = unparen_expr(field->default_value); ParameterValue param_value = {}; @@ -1799,6 +1851,7 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) { token.string = str_lit(""); Entity *param = alloc_entity_param(scope, token, type, false, false); param->Variable.param_value = param_value; + param->Variable.field_group_index = -1; array_add(&variables, param); } else { for_array(j, field->names) { @@ -1822,6 +1875,7 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) { Entity *param = alloc_entity_param(scope, token, type, false, false); param->flags |= EntityFlag_Result; param->Variable.param_value = param_value; + param->Variable.field_group_index = field_group_index; array_add(&variables, param); add_entity(ctx, scope, name, param); // NOTE(bill): Removes `declared but not used` when using -vet @@ -1883,6 +1937,25 @@ bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node, c->scope->flags &= ~ScopeFlag_ContextDefined; } + TargetArchKind arch = build_context.metrics.arch; + switch (cc) { + case ProcCC_StdCall: + case ProcCC_FastCall: + if (arch != TargetArch_i386 && arch != TargetArch_amd64) { + error(proc_type_node, "Invalid procedure calling convention \"%s\" for target architecture, expected either i386 or amd64, got %.*s", + proc_calling_convention_strings[cc], LIT(target_arch_names[arch])); + } + break; + case ProcCC_Win64: + case ProcCC_SysV: + if (arch != TargetArch_amd64) { + error(proc_type_node, "Invalid procedure calling convention \"%s\" for target architecture, expected amd64, got %.*s", + proc_calling_convention_strings[cc], LIT(target_arch_names[arch])); + } + break; + } + + bool variadic = false; isize variadic_index = -1; bool success = true; @@ -1896,20 +1969,6 @@ bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node, if (params) param_count = params ->Tuple.variables.count; if (results) result_count = results->Tuple.variables.count; - if (param_count > 0) { - for_array(i, params->Tuple.variables) { - Entity *param = params->Tuple.variables[i]; - if (param->kind == Entity_Variable) { - ParameterValue pv = param->Variable.param_value; - if (pv.kind == ParameterValue_Constant && - pv.value.kind == ExactValue_Procedure) { - type->Proc.has_proc_default_values = true; - break; - } - } - } - } - if (result_count > 0) { Entity *first = results->Tuple.variables[0]; type->Proc.has_named_results = first->token.string != ""; @@ -1967,10 +2026,14 @@ bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node, if (param_count > 0) { Entity *end = params->Tuple.variables[param_count-1]; if (end->flags&EntityFlag_CVarArg) { - if (cc == ProcCC_StdCall || cc == ProcCC_CDecl) { + switch (cc) { + default: type->Proc.c_vararg = true; - } else { + break; + case ProcCC_Odin: + case ProcCC_Contextless: error(end->token, "Calling convention does not support #c_vararg"); + break; } } } @@ -2106,7 +2169,7 @@ void init_map_entry_type(Type *type) { /* struct { - hash: runtime.Map_Hash, + hash: uintptr, next: int, key: Key, value: Value, @@ -2285,10 +2348,21 @@ void check_matrix_type(CheckerContext *ctx, Type **type, Ast *node) { } if (!is_type_valid_for_matrix_elems(elem)) { + if (elem == t_typeid) { + Entity *e = entity_of_node(mt->elem); + if (e && e->kind == Entity_TypeName && e->TypeName.is_type_alias) { + // HACK TODO(bill): This is to allow polymorphic parameters for matrix elements + // proc($T: typeid) -> matrix[2, 2]T + // + // THIS IS NEEDS TO BE FIXED AND NOT USE THIS HACK + goto type_assign; + } + } gbString s = type_to_string(elem); error(column.expr, "Matrix elements types are limited to integers, floats, and complex, got %s", s); gb_string_free(s); } +type_assign:; *type = alloc_type_matrix(elem, row_count, column_count, generic_row, generic_column); @@ -2679,29 +2753,30 @@ bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_t Type *t = alloc_type_enumerated_array(elem, index, bt->Enum.min_value, bt->Enum.max_value, Token_Invalid); - bool is_partial = false; + bool is_sparse = false; if (at->tag != nullptr) { GB_ASSERT(at->tag->kind == Ast_BasicDirective); String name = at->tag->BasicDirective.name.string; - if (name == "partial") { - is_partial = true; + if (name == "sparse") { + is_sparse = true; } else { error(at->tag, "Invalid tag applied to an enumerated array, got #%.*s", LIT(name)); } } - if (!is_partial && t->EnumeratedArray.count > bt->Enum.fields.count) { + if (!is_sparse && t->EnumeratedArray.count > bt->Enum.fields.count) { error(e, "Non-contiguous enumeration used as an index in an enumerated array"); long long ea_count = cast(long long)t->EnumeratedArray.count; long long enum_count = cast(long long)bt->Enum.fields.count; error_line("\tenumerated array length: %lld\n", ea_count); error_line("\tenum field count: %lld\n", enum_count); - error_line("\tSuggestion: prepend #partial to the enumerated array to allow for non-named elements\n"); + error_line("\tSuggestion: prepend #sparse to the enumerated array to allow for non-contiguous elements\n"); if (2*enum_count < ea_count) { error_line("\tWarning: the number of named elements is much smaller than the length of the array, are you sure this is what you want?\n"); - error_line("\t this warning will be removed if #partial is applied\n"); + error_line("\t this warning will be removed if #sparse is applied\n"); } } + t->EnumeratedArray.is_sparse = is_sparse; *type = t; @@ -2951,5 +3026,7 @@ Type *check_type_expr(CheckerContext *ctx, Ast *e, Type *named_type) { } set_base_type(named_type, type); + check_rtti_type_disallowed(e, type, "Use of a type, %s, which has been disallowed"); + return type; } diff --git a/src/checker.cpp b/src/checker.cpp index 667146eda..1bb786ea1 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -4,7 +4,7 @@ void check_expr(CheckerContext *c, Operand *operand, Ast *expression); void check_expr_or_type(CheckerContext *c, Operand *operand, Ast *expression, Type *type_hint=nullptr); void add_comparison_procedures_for_fields(CheckerContext *c, Type *t); - +Type *check_type(CheckerContext *ctx, Ast *e); bool is_operand_value(Operand o) { switch (o.mode) { @@ -29,6 +29,23 @@ bool is_operand_undef(Operand o) { return o.mode == Addressing_Value && o.type == t_untyped_undef; } +bool check_rtti_type_disallowed(Token const &token, Type *type, char const *format) { + if (build_context.disallow_rtti && type) { + if (is_type_any(type)) { + gbString t = type_to_string(type); + error(token, format, t); + gb_string_free(t); + return true; + } + } + return false; +} + +bool check_rtti_type_disallowed(Ast *expr, Type *type, char const *format) { + GB_ASSERT(expr != nullptr); + return check_rtti_type_disallowed(ast_token(expr), type, format); +} + void scope_reset(Scope *scope) { if (scope == nullptr) return; @@ -225,8 +242,8 @@ bool decl_info_has_init(DeclInfo *d) { Scope *create_scope(CheckerInfo *info, Scope *parent, isize init_elements_capacity=DEFAULT_SCOPE_CAPACITY) { Scope *s = gb_alloc_item(permanent_allocator(), Scope); s->parent = parent; - string_map_init(&s->elements, permanent_allocator(), init_elements_capacity); - ptr_set_init(&s->imported, permanent_allocator(), 0); + string_map_init(&s->elements, heap_allocator(), init_elements_capacity); + ptr_set_init(&s->imported, heap_allocator(), 0); mutex_init(&s->mutex); if (parent != nullptr && parent != builtin_pkg->scope) { @@ -446,7 +463,7 @@ Entity *scope_lookup(Scope *s, String const &name) { -Entity *scope_insert_with_name(Scope *s, String const &name, Entity *entity) { +Entity *scope_insert_with_name(Scope *s, String const &name, Entity *entity, bool use_mutex=true) { if (name == "") { return nullptr; } @@ -454,8 +471,8 @@ Entity *scope_insert_with_name(Scope *s, String const &name, Entity *entity) { Entity **found = nullptr; Entity *result = nullptr; - mutex_lock(&s->mutex); - defer (mutex_unlock(&s->mutex)); + if (use_mutex) mutex_lock(&s->mutex); + defer (if (use_mutex) mutex_unlock(&s->mutex)); found = string_map_get(&s->elements, key); @@ -485,9 +502,9 @@ end:; return result; } -Entity *scope_insert(Scope *s, Entity *entity) { +Entity *scope_insert(Scope *s, Entity *entity, bool use_mutex) { String name = entity->token.string; - return scope_insert_with_name(s, name, entity); + return scope_insert_with_name(s, name, entity, use_mutex); } @@ -504,6 +521,7 @@ enum VettedEntityKind { VettedEntity_Unused, VettedEntity_Shadowed, + VettedEntity_Shadowed_And_Unused, }; struct VettedEntity { VettedEntityKind kind; @@ -622,15 +640,21 @@ void check_scope_usage(Checker *c, Scope *scope) { Array vetted_entities = {}; array_init(&vetted_entities, heap_allocator()); - for_array(i, scope->elements.entries) { + MUTEX_GUARD_BLOCK(scope->mutex) for_array(i, scope->elements.entries) { Entity *e = scope->elements.entries[i].value; if (e == nullptr) continue; - VettedEntity ve = {}; - if (vet_unused && check_vet_unused(c, e, &ve)) { - array_add(&vetted_entities, ve); - } - if (vet_shadowing && check_vet_shadowing(c, e, &ve)) { - array_add(&vetted_entities, ve); + VettedEntity ve_unused = {}; + VettedEntity ve_shadowed = {}; + bool is_unused = vet_unused && check_vet_unused(c, e, &ve_unused); + bool is_shadowed = vet_shadowing && check_vet_shadowing(c, e, &ve_shadowed); + if (is_unused && is_shadowed) { + VettedEntity ve_both = ve_shadowed; + ve_both.kind = VettedEntity_Shadowed_And_Unused; + array_add(&vetted_entities, ve_both); + } else if (is_unused) { + array_add(&vetted_entities, ve_unused); + } else if (is_shadowed) { + array_add(&vetted_entities, ve_shadowed); } } @@ -642,16 +666,18 @@ void check_scope_usage(Checker *c, Scope *scope) { Entity *other = ve.other; String name = e->token.string; - if (build_context.vet) { + if (ve.kind == VettedEntity_Shadowed_And_Unused) { + error(e->token, "'%.*s' declared but not used, possibly shadows declaration at line %d", LIT(name), other->token.pos.line); + } else if (build_context.vet) { switch (ve.kind) { case VettedEntity_Unused: error(e->token, "'%.*s' declared but not used", LIT(name)); break; case VettedEntity_Shadowed: if (e->flags&EntityFlag_Using) { - error(e->token, "Declaration of '%.*s' from 'using' shadows declaration at line %lld", LIT(name), cast(long long)other->token.pos.line); + error(e->token, "Declaration of '%.*s' from 'using' shadows declaration at line %d", LIT(name), other->token.pos.line); } else { - error(e->token, "Declaration of '%.*s' shadows declaration at line %lld", LIT(name), cast(long long)other->token.pos.line); + error(e->token, "Declaration of '%.*s' shadows declaration at line %d", LIT(name), other->token.pos.line); } break; default: @@ -688,12 +714,17 @@ void add_dependency(CheckerInfo *info, DeclInfo *d, Entity *e) { ptr_set_add(&d->deps, e); mutex_unlock(&info->deps_mutex); } -void add_type_info_dependency(DeclInfo *d, Type *type) { +void add_type_info_dependency(CheckerInfo *info, DeclInfo *d, Type *type, bool require_mutex) { if (d == nullptr) { return; } - // NOTE(bill): no mutex is required here because the only procedure calling it is wrapped in a mutex already + if (require_mutex) { + mutex_lock(&info->deps_mutex); + } ptr_set_add(&d->type_info_deps, type); + if (require_mutex) { + mutex_unlock(&info->deps_mutex); + } } AstPackage *get_core_package(CheckerInfo *info, String name) { @@ -719,12 +750,25 @@ void add_package_dependency(CheckerContext *c, char const *package_name, char co String n = make_string_c(name); AstPackage *p = get_core_package(&c->checker->info, make_string_c(package_name)); Entity *e = scope_lookup(p->scope, n); - e->flags |= EntityFlag_Used; GB_ASSERT_MSG(e != nullptr, "%s", name); GB_ASSERT(c->decl != nullptr); + e->flags |= EntityFlag_Used; add_dependency(c->info, c->decl, e); } +void try_to_add_package_dependency(CheckerContext *c, char const *package_name, char const *name) { + String n = make_string_c(name); + AstPackage *p = get_core_package(&c->checker->info, make_string_c(package_name)); + Entity *e = scope_lookup(p->scope, n); + if (e == nullptr) { + return; + } + GB_ASSERT(c->decl != nullptr); + e->flags |= EntityFlag_Used; + add_dependency(c->info, c->decl, e); +} + + void add_declaration_dependency(CheckerContext *c, Entity *e) { if (e == nullptr) { return; @@ -780,6 +824,69 @@ AstPackage *create_builtin_package(char const *name) { return pkg; } +struct GlobalEnumValue { + char const *name; + i64 value; +}; + +Slice add_global_enum_type(String const &type_name, GlobalEnumValue *values, isize value_count, Type **enum_type_ = nullptr) { + Scope *scope = create_scope(nullptr, builtin_pkg->scope); + Entity *entity = alloc_entity_type_name(scope, make_token_ident(type_name), nullptr, EntityState_Resolved); + + Type *enum_type = alloc_type_enum(); + Type *named_type = alloc_type_named(type_name, enum_type, entity); + set_base_type(named_type, enum_type); + enum_type->Enum.base_type = t_int; + enum_type->Enum.scope = scope; + entity->type = named_type; + + auto fields = array_make(permanent_allocator(), value_count); + for (isize i = 0; i < value_count; i++) { + i64 value = values[i].value; + Entity *e = alloc_entity_constant(scope, make_token_ident(values[i].name), named_type, exact_value_i64(value)); + e->flags |= EntityFlag_Visited; + e->state = EntityState_Resolved; + fields[i] = e; + + Entity *ie = scope_insert(scope, e); + GB_ASSERT(ie == nullptr); + } + + + enum_type->Enum.fields = fields; + enum_type->Enum.min_value_index = 0; + enum_type->Enum.max_value_index = value_count-1; + enum_type->Enum.min_value = &enum_type->Enum.fields[enum_type->Enum.min_value_index]->Constant.value; + enum_type->Enum.max_value = &enum_type->Enum.fields[enum_type->Enum.max_value_index]->Constant.value; + + + if (enum_type_) *enum_type_ = named_type; + + return slice_from_array(fields); +} +void add_global_enum_constant(Slice const &fields, char const *name, i64 value) { + for (Entity *field : fields) { + GB_ASSERT(field->kind == Entity_Constant); + if (value == exact_value_to_i64(field->Constant.value)) { + add_global_constant(name, field->type, field->Constant.value); + return; + } + } + GB_PANIC("Unfound enum value for global constant: %s %lld", name, cast(long long)value); +} + +Type *add_global_type_name(Scope *scope, String const &type_name, Type *backing_type) { + Entity *e = alloc_entity_type_name(scope, make_token_ident(type_name), nullptr, EntityState_Resolved); + Type *named_type = alloc_type_named(type_name, backing_type, e); + e->type = named_type; + set_base_type(named_type, backing_type); + if (scope_insert(scope, e)) { + compiler_error("double declaration of %.*s", LIT(e->token.string)); + } + return named_type; +} + + void init_universal(void) { BuildContext *bc = &build_context; @@ -789,7 +896,8 @@ void init_universal(void) { // Types for (isize i = 0; i < gb_count_of(basic_types); i++) { - add_global_type_entity(basic_types[i].Basic.name, &basic_types[i]); + String const &name = basic_types[i].Basic.name; + add_global_type_entity(name, &basic_types[i]); } add_global_type_entity(str_lit("byte"), &basic_types[Basic_u8]); @@ -808,14 +916,96 @@ void init_universal(void) { add_global_bool_constant("false", false); // TODO(bill): Set through flags in the compiler - add_global_string_constant("ODIN_OS", bc->ODIN_OS); - add_global_string_constant("ODIN_ARCH", bc->ODIN_ARCH); - add_global_string_constant("ODIN_ENDIAN", bc->ODIN_ENDIAN); add_global_string_constant("ODIN_VENDOR", bc->ODIN_VENDOR); add_global_string_constant("ODIN_VERSION", bc->ODIN_VERSION); add_global_string_constant("ODIN_ROOT", bc->ODIN_ROOT); + + { + GlobalEnumValue values[TargetOs_COUNT] = { + {"Unknown", TargetOs_Invalid}, + {"Windows", TargetOs_windows}, + {"Darwin", TargetOs_darwin}, + {"Linux", TargetOs_linux}, + {"Essence", TargetOs_essence}, + {"FreeBSD", TargetOs_freebsd}, + {"OpenBSD", TargetOs_openbsd}, + {"WASI", TargetOs_wasi}, + {"JS", TargetOs_js}, + {"Freestanding", TargetOs_freestanding}, + }; + + auto fields = add_global_enum_type(str_lit("Odin_OS_Type"), values, gb_count_of(values)); + add_global_enum_constant(fields, "ODIN_OS", bc->metrics.os); + add_global_string_constant("ODIN_OS_STRING", target_os_names[bc->metrics.os]); + } + + { + GlobalEnumValue values[TargetArch_COUNT] = { + {"Unknown", TargetArch_Invalid}, + {"amd64", TargetArch_amd64}, + {"i386", TargetArch_i386}, + {"arm64", TargetArch_arm64}, + {"wasm32", TargetArch_wasm32}, + {"wasm64", TargetArch_wasm64}, + }; + + auto fields = add_global_enum_type(str_lit("Odin_Arch_Type"), values, gb_count_of(values)); + add_global_enum_constant(fields, "ODIN_ARCH", bc->metrics.arch); + add_global_string_constant("ODIN_ARCH_STRING", target_arch_names[bc->metrics.arch]); + } - add_global_string_constant("ODIN_BUILD_MODE", bc->ODIN_BUILD_MODE); + { + GlobalEnumValue values[BuildMode_COUNT] = { + {"Executable", BuildMode_Executable}, + {"Dynamic", BuildMode_DynamicLibrary}, + {"Object", BuildMode_Object}, + {"Assembly", BuildMode_Assembly}, + {"LLVM_IR", BuildMode_LLVM_IR}, + }; + + auto fields = add_global_enum_type(str_lit("Odin_Build_Mode_Type"), values, gb_count_of(values)); + add_global_enum_constant(fields, "ODIN_BUILD_MODE", bc->build_mode); + } + + { + GlobalEnumValue values[TargetEndian_COUNT] = { + {"Unknown", TargetEndian_Invalid}, + + {"Little", TargetEndian_Little}, + {"Big", TargetEndian_Big}, + }; + + auto fields = add_global_enum_type(str_lit("Odin_Endian_Type"), values, gb_count_of(values)); + add_global_enum_constant(fields, "ODIN_ENDIAN", target_endians[bc->metrics.arch]); + add_global_string_constant("ODIN_ENDIAN_STRING", target_endian_names[target_endians[bc->metrics.arch]]); + } + + { + GlobalEnumValue values[ErrorPosStyle_COUNT] = { + {"Default", ErrorPosStyle_Default}, + {"Unix", ErrorPosStyle_Unix}, + }; + + auto fields = add_global_enum_type(str_lit("Odin_Error_Pos_Style_Type"), values, gb_count_of(values)); + add_global_enum_constant(fields, "ODIN_ERROR_POS_STYLE", build_context.ODIN_ERROR_POS_STYLE); + } + + { + GlobalEnumValue values[OdinAtomicMemoryOrder_COUNT] = { + {OdinAtomicMemoryOrder_strings[OdinAtomicMemoryOrder_relaxed], OdinAtomicMemoryOrder_relaxed}, + {OdinAtomicMemoryOrder_strings[OdinAtomicMemoryOrder_consume], OdinAtomicMemoryOrder_consume}, + {OdinAtomicMemoryOrder_strings[OdinAtomicMemoryOrder_acquire], OdinAtomicMemoryOrder_acquire}, + {OdinAtomicMemoryOrder_strings[OdinAtomicMemoryOrder_release], OdinAtomicMemoryOrder_release}, + {OdinAtomicMemoryOrder_strings[OdinAtomicMemoryOrder_acq_rel], OdinAtomicMemoryOrder_acq_rel}, + {OdinAtomicMemoryOrder_strings[OdinAtomicMemoryOrder_seq_cst], OdinAtomicMemoryOrder_seq_cst}, + }; + + add_global_enum_type(str_lit("Atomic_Memory_Order"), values, gb_count_of(values), &t_atomic_memory_order); + GB_ASSERT(t_atomic_memory_order->kind == Type_Named); + scope_insert(intrinsics_pkg->scope, t_atomic_memory_order->Named.type_name); + } + + add_global_bool_constant("ODIN_DEBUG", bc->ODIN_DEBUG); add_global_bool_constant("ODIN_DISABLE_ASSERT", bc->ODIN_DISABLE_ASSERT); add_global_bool_constant("ODIN_DEFAULT_TO_NIL_ALLOCATOR", bc->ODIN_DEFAULT_TO_NIL_ALLOCATOR); @@ -823,6 +1013,9 @@ void init_universal(void) { add_global_bool_constant("ODIN_NO_CRT", bc->no_crt); add_global_bool_constant("ODIN_USE_SEPARATE_MODULES", bc->use_separate_modules); add_global_bool_constant("ODIN_TEST", bc->command_kind == Command_test); + add_global_bool_constant("ODIN_NO_ENTRY_POINT", bc->no_entry_point); + add_global_bool_constant("ODIN_FOREIGN_ERROR_PROCEDURES", bc->ODIN_FOREIGN_ERROR_PROCEDURES); + add_global_bool_constant("ODIN_DISALLOW_RTTI", bc->disallow_rtti); // Builtin Procedures @@ -887,6 +1080,17 @@ void init_universal(void) { t_f64_ptr = alloc_type_pointer(t_f64); t_u8_slice = alloc_type_slice(t_u8); t_string_slice = alloc_type_slice(t_string); + + // intrinsics types for objective-c stuff + { + t_objc_object = add_global_type_name(intrinsics_pkg->scope, str_lit("objc_object"), alloc_type_struct()); + t_objc_selector = add_global_type_name(intrinsics_pkg->scope, str_lit("objc_selector"), alloc_type_struct()); + t_objc_class = add_global_type_name(intrinsics_pkg->scope, str_lit("objc_class"), alloc_type_struct()); + + t_objc_id = alloc_type_pointer(t_objc_object); + t_objc_SEL = alloc_type_pointer(t_objc_selector); + t_objc_Class = alloc_type_pointer(t_objc_class); + } } @@ -941,6 +1145,11 @@ void init_checker_info(CheckerInfo *i) { mutex_init(&i->foreign_mutex); semaphore_init(&i->collect_semaphore); + + mpmc_init(&i->intrinsics_entry_point_usage, a, 1<<10); // just waste some memory here, even if it probably never used + + mutex_init(&i->objc_types_mutex); + map_init(&i->objc_msgSend_types, a); } void destroy_checker_info(CheckerInfo *i) { @@ -973,6 +1182,9 @@ void destroy_checker_info(CheckerInfo *i) { mutex_destroy(&i->type_and_value_mutex); mutex_destroy(&i->identifier_uses_mutex); mutex_destroy(&i->foreign_mutex); + + mutex_destroy(&i->objc_types_mutex); + map_destroy(&i->objc_msgSend_types); } CheckerContext make_checker_context(Checker *c) { @@ -1177,7 +1389,7 @@ isize type_info_index(CheckerInfo *info, Type *type, bool error_on_failure) { // TODO(bill): This is O(n) and can be very slow for_array(i, info->type_info_map.entries){ auto *e = &info->type_info_map.entries[i]; - if (are_types_identical(e->key, type)) { + if (are_types_identical_unique_tuples(e->key, type)) { entry_index = e->value; // NOTE(bill): Add it to the search map map_set(&info->type_info_map, type, entry_index); @@ -1228,7 +1440,7 @@ void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mode, Type *ty while (prev_expr != expr) { prev_expr = expr; expr->tav.mode = mode; - if (type != nullptr && expr->tav.type != nullptr && + if (type != nullptr && expr->tav.type != nullptr && is_type_any(type) && is_type_untyped(expr->tav.type)) { // ignore } else { @@ -1424,7 +1636,7 @@ bool could_entity_be_lazy(Entity *e, DeclInfo *d) { return false; } else if (name == "linkage") { return false; - } + } } } } @@ -1496,6 +1708,10 @@ void add_implicit_entity(CheckerContext *c, Ast *clause, Entity *e) { void add_type_info_type(CheckerContext *c, Type *t) { void add_type_info_type_internal(CheckerContext *c, Type *t); + if (build_context.disallow_rtti) { + return; + } + mutex_lock(&c->info->type_info_mutex); add_type_info_type_internal(c, t); mutex_unlock(&c->info->type_info_mutex); @@ -1513,7 +1729,7 @@ void add_type_info_type_internal(CheckerContext *c, Type *t) { return; } - add_type_info_dependency(c->decl, t); + add_type_info_dependency(c->info, c->decl, t, false); auto found = map_get(&c->info->type_info_map, t); if (found != nullptr) { @@ -1525,7 +1741,7 @@ void add_type_info_type_internal(CheckerContext *c, Type *t) { isize ti_index = -1; for_array(i, c->info->type_info_map.entries) { auto *e = &c->info->type_info_map.entries[i]; - if (are_types_identical(t, e->key)) { + if (are_types_identical_unique_tuples(t, e->key)) { // Duplicate entry ti_index = e->value; prev = true; @@ -1642,6 +1858,7 @@ void add_type_info_type_internal(CheckerContext *c, Type *t) { } else { add_type_info_type_internal(c, t_type_info_ptr); } + add_type_info_type_internal(c, bt->Union.polymorphic_params); for_array(i, bt->Union.variants) { add_type_info_type_internal(c, bt->Union.variants[i]); } @@ -1665,6 +1882,7 @@ void add_type_info_type_internal(CheckerContext *c, Type *t) { } } } + add_type_info_type_internal(c, bt->Struct.polymorphic_params); for_array(i, bt->Struct.fields) { Entity *f = bt->Struct.fields[i]; add_type_info_type_internal(c, f->type); @@ -1704,7 +1922,7 @@ void add_type_info_type_internal(CheckerContext *c, Type *t) { add_type_info_type_internal(c, bt->RelativeSlice.slice_type); add_type_info_type_internal(c, bt->RelativeSlice.base_integer); break; - + case Type_Matrix: add_type_info_type_internal(c, bt->Matrix.elem); break; @@ -1858,6 +2076,7 @@ void add_min_dep_type_info(Checker *c, Type *t) { } else { add_min_dep_type_info(c, t_type_info_ptr); } + add_min_dep_type_info(c, bt->Union.polymorphic_params); for_array(i, bt->Union.variants) { add_min_dep_type_info(c, bt->Union.variants[i]); } @@ -1881,6 +2100,7 @@ void add_min_dep_type_info(Checker *c, Type *t) { } } } + add_min_dep_type_info(c, bt->Struct.polymorphic_params); for_array(i, bt->Struct.fields) { Entity *f = bt->Struct.fields[i]; add_min_dep_type_info(c, f->type); @@ -1919,7 +2139,7 @@ void add_min_dep_type_info(Checker *c, Type *t) { add_min_dep_type_info(c, bt->RelativeSlice.slice_type); add_min_dep_type_info(c, bt->RelativeSlice.base_integer); break; - + case Type_Matrix: add_min_dep_type_info(c, bt->Matrix.elem); break; @@ -2004,23 +2224,27 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { ptr_set_init(&c->info.minimum_dependency_set, heap_allocator(), min_dep_set_cap); ptr_set_init(&c->info.minimum_dependency_type_info_set, heap_allocator()); - String required_runtime_entities[] = { +#define FORCE_ADD_RUNTIME_ENTITIES(condition, ...) do { \ + if (condition) { \ + String entities[] = {__VA_ARGS__}; \ + for (isize i = 0; i < gb_count_of(entities); i++) { \ + force_add_dependency_entity(c, c->info.runtime_package->scope, entities[i]); \ + } \ + } \ +} while (0) + + // required runtime entities + FORCE_ADD_RUNTIME_ENTITIES(true, // Odin types - str_lit("Type_Info"), str_lit("Source_Code_Location"), str_lit("Context"), str_lit("Allocator"), str_lit("Logger"), - // Global variables - str_lit("args__"), - str_lit("type_table"), - // Odin internal procedures str_lit("__init_context"), - str_lit("__type_info_of"), str_lit("cstring_to_string"), - str_lit("_cleanup_runtime"), + str_lit("_cleanup_runtime"), // Pseudo-CRT required procedures str_lit("memset"), @@ -2047,39 +2271,40 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { str_lit("gnu_h2f_ieee"), str_lit("gnu_f2h_ieee"), str_lit("extendhfsf2"), - + // WASM Specific str_lit("__ashlti3"), str_lit("__multi3"), - }; - for (isize i = 0; i < gb_count_of(required_runtime_entities); i++) { - force_add_dependency_entity(c, c->info.runtime_package->scope, required_runtime_entities[i]); - } + ); - if (build_context.no_crt) { - String required_no_crt_entities[] = { - // NOTE(bill): Only if these exist - str_lit("_tls_index"), - str_lit("_fltused"), - }; - for (isize i = 0; i < gb_count_of(required_no_crt_entities); i++) { - force_add_dependency_entity(c, c->info.runtime_package->scope, required_no_crt_entities[i]); - } - } + FORCE_ADD_RUNTIME_ENTITIES(!build_context.disallow_rtti, + // Odin types + str_lit("Type_Info"), - if (!build_context.no_bounds_check) { - String bounds_check_entities[] = { - // Bounds checking related procedures - str_lit("bounds_check_error"), - str_lit("matrix_bounds_check_error"), - str_lit("slice_expr_error_hi"), - str_lit("slice_expr_error_lo_hi"), - str_lit("multi_pointer_slice_expr_error"), - }; - for (isize i = 0; i < gb_count_of(bounds_check_entities); i++) { - force_add_dependency_entity(c, c->info.runtime_package->scope, bounds_check_entities[i]); - } - } + // Global variables + str_lit("type_table"), + str_lit("__type_info_of"), + ); + + FORCE_ADD_RUNTIME_ENTITIES(!build_context.no_entry_point, + // Global variables + str_lit("args__"), + ); + + FORCE_ADD_RUNTIME_ENTITIES((build_context.no_crt && !is_arch_wasm()), + // NOTE(bill): Only if these exist + str_lit("_tls_index"), + str_lit("_fltused"), + ); + + FORCE_ADD_RUNTIME_ENTITIES(!build_context.no_bounds_check, + // Bounds checking related procedures + str_lit("bounds_check_error"), + str_lit("matrix_bounds_check_error"), + str_lit("slice_expr_error_hi"), + str_lit("slice_expr_error_lo_hi"), + str_lit("multi_pointer_slice_expr_error"), + ); for_array(i, c->info.definitions) { Entity *e = c->info.definitions[i]; @@ -2110,34 +2335,38 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { case Entity_Variable: if (e->Variable.is_export) { add_dependency_to_set(c, e); + } else if (e->flags & EntityFlag_Require) { + add_dependency_to_set(c, e); } break; case Entity_Procedure: if (e->Procedure.is_export) { add_dependency_to_set(c, e); + } else if (e->flags & EntityFlag_Require) { + add_dependency_to_set(c, e); } if (e->flags & EntityFlag_Init) { Type *t = base_type(e->type); GB_ASSERT(t->kind == Type_Proc); - + bool is_init = true; - + if (t->Proc.param_count != 0 || t->Proc.result_count != 0) { gbString str = type_to_string(t); error(e->token, "@(init) procedures must have a signature type with no parameters nor results, got %s", str); gb_string_free(str); is_init = false; } - + if ((e->scope->flags & (ScopeFlag_File|ScopeFlag_Pkg)) == 0) { error(e->token, "@(init) procedures must be declared at the file scope"); is_init = false; } - + if (is_init) { add_dependency_to_set(c, e); array_add(&c->info.init_procedures, e); - } + } } break; } @@ -2197,6 +2426,8 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { start->flags |= EntityFlag_Used; add_dependency_to_set(c, start); } + +#undef FORCE_ADD_RUNTIME_ENTITIES } bool is_entity_a_dependency(Entity *e) { @@ -2445,6 +2676,15 @@ Array proc_group_entities(CheckerContext *c, Operand o) { return procs; } +Array proc_group_entities_cloned(CheckerContext *c, Operand o) { + auto entities = proc_group_entities(c, o); + if (entities.count == 0) { + return {}; + } + return array_clone(permanent_allocator(), entities); +} + + void init_core_type_info(Checker *c) { @@ -2604,6 +2844,14 @@ ExactValue check_decl_attribute_value(CheckerContext *c, Ast *value) { return ev; } +Type *check_decl_attribute_type(CheckerContext *c, Ast *value) { + if (value != nullptr) { + return check_type(c, value); + } + return nullptr; +} + + #define ATTRIBUTE_USER_TAG_NAME "tag" @@ -2903,6 +3151,42 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) { error(elem, "Expected a string for '%.*s'", LIT(name)); } return true; + } else if (name == "objc_name") { + ExactValue ev = check_decl_attribute_value(c, value); + if (ev.kind == ExactValue_String) { + if (string_is_valid_identifier(ev.value_string)) { + ac->objc_name = ev.value_string; + } else { + error(elem, "Invalid identifier for '%.*s', got '%.*s'", LIT(name), LIT(ev.value_string)); + } + } else { + error(elem, "Expected a string value for '%.*s'", LIT(name)); + } + return true; + } else if (name == "objc_is_class_method") { + ExactValue ev = check_decl_attribute_value(c, value); + if (ev.kind == ExactValue_Bool) { + ac->objc_is_class_method = ev.value_bool; + } else { + error(elem, "Expected a boolean value for '%.*s'", LIT(name)); + } + return true; + } else if (name == "objc_type") { + if (value == nullptr) { + error(elem, "Expected a type for '%.*s'", LIT(name)); + } else { + Type *objc_type = check_type(c, value); + if (objc_type != nullptr) { + if (!has_type_got_objc_class_attribute(objc_type)) { + gbString t = type_to_string(objc_type); + error(value, "'%.*s' expected a named type with the attribute @(obj_class=), got type %s", LIT(name), t); + gb_string_free(t); + } else { + ac->objc_type = objc_type; + } + } + } + return true; } return false; } @@ -3053,6 +3337,14 @@ DECL_ATTRIBUTE_PROC(type_decl_attribute) { } else if (name == "private") { // NOTE(bill): Handled elsewhere `check_collect_value_decl` return true; + } else if (name == "objc_class") { + ExactValue ev = check_decl_attribute_value(c, value); + if (ev.kind != ExactValue_String || ev.value_string == "") { + error(elem, "Expected a non-empty string value for '%.*s'", LIT(name)); + } else { + ac->objc_class = ev.value_string; + } + return true; } return false; } @@ -3366,6 +3658,16 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { } } + if (entity_visibility_kind == EntityVisiblity_Public && + (c->scope->flags&ScopeFlag_File) && + c->scope->file) { + if (c->scope->file->flags & AstFile_IsPrivateFile) { + entity_visibility_kind = EntityVisiblity_PrivateToFile; + } else if (c->scope->file->flags & AstFile_IsPrivatePkg) { + entity_visibility_kind = EntityVisiblity_PrivateToPackage; + } + } + if (entity_visibility_kind != EntityVisiblity_Public && !(c->scope->flags&ScopeFlag_File)) { error(decl, "Attribute 'private' is not allowed on a non file scope entity"); } @@ -3454,9 +3756,6 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { if (is_ast_type(init)) { e = alloc_entity_type_name(d->scope, token, nullptr); - // if (vd->type != nullptr) { - // error(name, "A type declaration cannot have an type parameter"); - // } } else if (init->kind == Ast_ProcLit) { if (c->scope->flags&ScopeFlag_Type) { error(name, "Procedure declarations are not allowed within a struct"); @@ -3559,6 +3858,59 @@ void check_add_foreign_block_decl(CheckerContext *ctx, Ast *decl) { check_collect_entities(&c, block->stmts); } +bool correct_single_type_alias(CheckerContext *c, Entity *e) { + if (e->kind == Entity_Constant) { + DeclInfo *d = e->decl_info; + if (d != nullptr && d->init_expr != nullptr) { + Ast *init = d->init_expr; + Entity *alias_of = check_entity_from_ident_or_selector(c, init, true); + if (alias_of != nullptr && alias_of->kind == Entity_TypeName) { + e->kind = Entity_TypeName; + return true; + } + } + } + return false; +} + +bool correct_type_alias_in_scope_backwards(CheckerContext *c, Scope *s) { + isize n = s->elements.entries.count; + bool correction = false; + for (isize i = n-1; i >= 0; i--) { + correction |= correct_single_type_alias(c, s->elements.entries[i].value); + } + return correction; +} +bool correct_type_alias_in_scope_forwards(CheckerContext *c, Scope *s) { + isize n = s->elements.entries.count; + bool correction = false; + for (isize i = 0; i < n; i++) { + correction |= correct_single_type_alias(c, s->elements.entries[i].value); + } + return correction; +} + + +void correct_type_aliases_in_scope(CheckerContext *c, Scope *s) { + // NOTE(bill, 2022-02-04): This is used to solve the problem caused by type aliases + // of type aliases being "confused" as constants + // + // A :: C + // B :: A + // C :: struct {b: ^B} + // + // See @TypeAliasingProblem for more information + for (;;) { + bool corrections = false; + corrections |= correct_type_alias_in_scope_backwards(c, s); + corrections |= correct_type_alias_in_scope_forwards(c, s); + if (!corrections) { + return; + } + } +} + + // NOTE(bill): If file_scopes == nullptr, this will act like a local scope void check_collect_entities(CheckerContext *c, Slice const &nodes) { AstFile *curr_file = nullptr; @@ -3630,6 +3982,7 @@ void check_collect_entities(CheckerContext *c, Slice const &nodes) { } } + // correct_type_aliases(c); // NOTE(bill): 'when' stmts need to be handled after the other as the condition may refer to something // declared after this stmt in source @@ -3677,11 +4030,6 @@ void check_single_global_entity(Checker *c, Entity *e, DeclInfo *d) { error(e->token, "'main' is reserved as the entry point procedure in the initial scope"); return; } - } else if (pkg->kind == Package_Runtime) { - if (e->token.string == "main") { - error(e->token, "'main' is reserved as the entry point procedure in the initial scope"); - return; - } } check_entity_decl(ctx, e, d, nullptr); @@ -3841,7 +4189,7 @@ void add_import_dependency_node(Checker *c, Ast *decl, PtrMap generate_import_dependency_graph(Checker *c) { - PtrMap M = {}; + PtrMap M = {}; map_init(&M, heap_allocator(), 2*c->parser->packages.count); defer (map_destroy(&M)); @@ -4121,11 +4469,11 @@ void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) { mpmc_enqueue(&ctx->info->required_foreign_imports_through_force_queue, e); add_entity_use(ctx, nullptr, e); } - + if (has_asm_extension(fullpath)) { if (build_context.metrics.arch != TargetArch_amd64 || build_context.metrics.os != TargetOs_windows) { - error(decl, "Assembly files are not yet supported on this platform: %.*s_%.*s", + error(decl, "Assembly files are not yet supported on this platform: %.*s_%.*s", LIT(target_os_names[build_context.metrics.os]), LIT(target_arch_names[build_context.metrics.arch])); } } @@ -4280,10 +4628,11 @@ bool collect_file_decls(CheckerContext *ctx, Slice const &decls) { for_array(i, decls) { if (collect_file_decl(ctx, decls[i])) { + correct_type_aliases_in_scope(ctx, ctx->scope); return true; } } - + correct_type_aliases_in_scope(ctx, ctx->scope); return false; } @@ -4327,7 +4676,7 @@ void check_with_workers(Checker *c, WorkerTaskProc *proc, isize total_count) { if (!build_context.threaded_checker) { worker_count = 0; } - + semaphore_post(&c->info.collect_semaphore, cast(i32)thread_count); if (worker_count == 0) { ThreadProcCheckerSection section_all = {}; @@ -4351,7 +4700,7 @@ void check_with_workers(Checker *c, WorkerTaskProc *proc, isize total_count) { } GB_ASSERT(remaining_count <= 0); - + for (isize i = 0; i < thread_count; i++) { global_thread_pool_add_task(proc, thread_data+i); } @@ -4553,6 +4902,15 @@ void check_import_entities(Checker *c) { } add_untyped_expressions(ctx.info, &untyped); } + + for_array(i, pkg->files) { + AstFile *f = pkg->files[i]; + reset_checker_context(&ctx, f, &untyped); + ctx.collect_delayed_decls = false; + + correct_type_aliases_in_scope(&ctx, pkg->scope); + } + for_array(i, pkg->files) { AstFile *f = pkg->files[i]; reset_checker_context(&ctx, f, &untyped); @@ -4750,11 +5108,11 @@ bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped, Proc ctx.decl = pi->decl; ctx.procs_to_check_queue = procs_to_check_queue; GB_ASSERT(procs_to_check_queue != nullptr); - + GB_ASSERT(pi->type->kind == Type_Proc); TypeProc *pt = &pi->type->Proc; String name = pi->token.string; - + if (pt->is_polymorphic && !pt->is_poly_specialized) { Token token = pi->token; if (pi->poly_def_node != nullptr) { @@ -4774,6 +5132,9 @@ bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped, Proc bool bounds_check = (pi->tags & ProcTag_bounds_check) != 0; bool no_bounds_check = (pi->tags & ProcTag_no_bounds_check) != 0; + bool type_assert = (pi->tags & ProcTag_type_assert) != 0; + bool no_type_assert = (pi->tags & ProcTag_no_type_assert) != 0; + if (bounds_check) { ctx.state_flags |= StateFlag_bounds_check; ctx.state_flags &= ~StateFlag_no_bounds_check; @@ -4781,6 +5142,15 @@ bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *untyped, Proc ctx.state_flags |= StateFlag_no_bounds_check; ctx.state_flags &= ~StateFlag_bounds_check; } + + if (type_assert) { + ctx.state_flags |= StateFlag_type_assert; + ctx.state_flags &= ~StateFlag_no_type_assert; + } else if (no_type_assert) { + ctx.state_flags |= StateFlag_no_type_assert; + ctx.state_flags &= ~StateFlag_type_assert; + } + if (pi->body != nullptr && e != nullptr) { GB_ASSERT((e->flags & EntityFlag_ProcBodyChecked) == 0); } @@ -4832,7 +5202,7 @@ void check_unchecked_bodies(Checker *c) { if (pi->body == nullptr) { continue; } - + debugf("unchecked: %.*s\n", LIT(e->token.string)); mpmc_enqueue(&c->procs_to_check_queue, pi); } @@ -4941,17 +5311,16 @@ void check_procedure_bodies(Checker *c) { if (!build_context.threaded_checker) { worker_count = 0; } - worker_count = 0; if (worker_count == 0) { auto *this_queue = &c->procs_to_check_queue; - + UntypedExprInfoMap untyped = {}; map_init(&untyped, heap_allocator()); - + for (ProcInfo *pi = nullptr; mpmc_dequeue(this_queue, &pi); /**/) { consume_proc_info_queue(c, pi, this_queue, &untyped); } - + map_destroy(&untyped); debugf("Total Procedure Bodies Checked: %td\n", total_bodies_checked.load(std::memory_order_relaxed)); @@ -4995,7 +5364,7 @@ void check_procedure_bodies(Checker *c) { GB_ASSERT(total_queued == original_queue_count); semaphore_post(&c->procs_to_check_semaphore, cast(i32)thread_count); - + for (isize i = 0; i < thread_count; i++) { global_thread_pool_add_task(thread_proc_body, thread_data+i); } @@ -5032,7 +5401,7 @@ void check_deferred_procedures(Checker *c) { Entity *dst = src->Procedure.deferred_procedure.entity; GB_ASSERT(dst != nullptr); GB_ASSERT(dst->kind == Entity_Procedure); - + char const *attribute = "deferred_none"; switch (dst_kind) { case DeferredProcedure_none: @@ -5195,12 +5564,18 @@ void check_unique_package_names(Checker *c) { string_map_set(&pkgs, key, pkg); continue; } + auto *curr = pkg->files[0]->pkg_decl; + auto *prev = (*found)->files[0]->pkg_decl; + if (curr == prev) { + // NOTE(bill): A false positive was found, ignore it + continue; + } - error(pkg->files[0]->pkg_decl, "Duplicate declaration of 'package %.*s'", LIT(name)); + error(curr, "Duplicate declaration of 'package %.*s'", LIT(name)); error_line("\tA package name must be unique\n" "\tThere is no relation between a package name and the directory that contains it, so they can be completely different\n" "\tA package name is required for link name prefixing to have a consistent ABI\n"); - error((*found)->files[0]->pkg_decl, "found at previous location"); + error(prev, "found at previous location"); } } @@ -5233,7 +5608,7 @@ GB_COMPARE_PROC(init_procedures_cmp) { cmp = 0; return cmp; } - + if (x->pkg != y->pkg) { isize order_x = x->pkg ? x->pkg->order : 0; isize order_y = y->pkg ? y->pkg->order : 0; @@ -5247,14 +5622,14 @@ GB_COMPARE_PROC(init_procedures_cmp) { String fullpath_y = y->file ? y->file->fullpath : (String{}); String file_x = filename_from_path(fullpath_x); String file_y = filename_from_path(fullpath_y); - + cmp = string_compare(file_x, file_y); if (cmp) { return cmp; } } - + cmp = u64_cmp(x->order_in_src, y->order_in_src); if (cmp) { return cmp; @@ -5392,9 +5767,6 @@ void check_parsed_files(Checker *c) { TIME_SECTION("calculate global init order"); calculate_global_init_order(c); - TIME_SECTION("generate minimum dependency set"); - generate_minimum_dependency_set(c, c->info.entry_point); - TIME_SECTION("check test procedures"); check_test_procedures(c); @@ -5405,6 +5777,9 @@ void check_parsed_files(Checker *c) { add_type_info_for_type_definitions(c); check_merge_queues_into_arrays(c); + TIME_SECTION("generate minimum dependency set"); + generate_minimum_dependency_set(c, c->info.entry_point); + TIME_SECTION("check entry point"); if (build_context.build_mode == BuildMode_Executable && !build_context.no_entry_point && build_context.command_kind != Command_test) { Scope *s = c->info.init_scope; @@ -5434,9 +5809,21 @@ void check_parsed_files(Checker *c) { TIME_SECTION("sanity checks"); GB_ASSERT(c->info.entity_queue.count.load(std::memory_order_relaxed) == 0); GB_ASSERT(c->info.definition_queue.count.load(std::memory_order_relaxed) == 0); - + TIME_SECTION("sort init procedures"); check_sort_init_procedures(c); + if (c->info.intrinsics_entry_point_usage.count > 0) { + TIME_SECTION("check intrinsics.__entry_point usage"); + Ast *node = nullptr; + while (mpmc_dequeue(&c->info.intrinsics_entry_point_usage, &node)) { + if (c->info.entry_point == nullptr && node != nullptr) { + if (node->file()->pkg->kind != Package_Runtime) { + warning(node, "usage of intrinsics.__entry_point will be a no-op"); + } + } + } + } + TIME_SECTION("type check finish"); } diff --git a/src/checker.hpp b/src/checker.hpp index 74435c1d4..552e6aca7 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -118,6 +118,11 @@ struct AttributeContext { bool init : 1; bool set_cold : 1; u32 optimization_mode; // ProcedureOptimizationMode + + String objc_class; + String objc_name; + bool objc_is_class_method; + Type * objc_type; }; AttributeContext make_attribute_context(String link_prefix) { @@ -267,6 +272,17 @@ struct UntypedExprInfo { typedef PtrMap UntypedExprInfoMap; typedef MPMCQueue ProcBodyQueue; +enum ObjcMsgKind : u32 { + ObjcMsg_normal, + ObjcMsg_fpret, + ObjcMsg_fp2ret, + ObjcMsg_stret, +}; +struct ObjcMsgData { + ObjcMsgKind kind; + Type *proc_type; +}; + // CheckerInfo stores all the symbol information for a type-checked program struct CheckerInfo { Checker *checker; @@ -338,6 +354,10 @@ struct CheckerInfo { MPMCQueue required_global_variable_queue; MPMCQueue required_foreign_imports_through_force_queue; + MPMCQueue intrinsics_entry_point_usage; + + BlockingMutex objc_types_mutex; + PtrMap objc_msgSend_types; }; struct CheckerContext { @@ -423,7 +443,7 @@ Entity *entity_of_node(Ast *expr); Entity *scope_lookup_current(Scope *s, String const &name); Entity *scope_lookup (Scope *s, String const &name); void scope_lookup_parent (Scope *s, String const &name, Scope **scope_, Entity **entity_); -Entity *scope_insert (Scope *s, Entity *entity); +Entity *scope_insert (Scope *s, Entity *entity, bool use_mutex=true); void add_type_and_value (CheckerInfo *i, Ast *expression, AddressingMode mode, Type *type, ExactValue value); diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index abd9fc6ca..0f72f01f7 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -86,77 +86,31 @@ enum BuiltinProcId { BuiltinProc_prefetch_write_instruction, BuiltinProc_prefetch_write_data, - BuiltinProc_atomic_fence, - BuiltinProc_atomic_fence_acq, - BuiltinProc_atomic_fence_rel, - BuiltinProc_atomic_fence_acqrel, - + BuiltinProc_atomic_type_is_lock_free, + BuiltinProc_atomic_thread_fence, + BuiltinProc_atomic_signal_fence, BuiltinProc_atomic_store, - BuiltinProc_atomic_store_rel, - BuiltinProc_atomic_store_relaxed, - BuiltinProc_atomic_store_unordered, - + BuiltinProc_atomic_store_explicit, BuiltinProc_atomic_load, - BuiltinProc_atomic_load_acq, - BuiltinProc_atomic_load_relaxed, - BuiltinProc_atomic_load_unordered, - + BuiltinProc_atomic_load_explicit, BuiltinProc_atomic_add, - BuiltinProc_atomic_add_acq, - BuiltinProc_atomic_add_rel, - BuiltinProc_atomic_add_acqrel, - BuiltinProc_atomic_add_relaxed, + BuiltinProc_atomic_add_explicit, BuiltinProc_atomic_sub, - BuiltinProc_atomic_sub_acq, - BuiltinProc_atomic_sub_rel, - BuiltinProc_atomic_sub_acqrel, - BuiltinProc_atomic_sub_relaxed, + BuiltinProc_atomic_sub_explicit, BuiltinProc_atomic_and, - BuiltinProc_atomic_and_acq, - BuiltinProc_atomic_and_rel, - BuiltinProc_atomic_and_acqrel, - BuiltinProc_atomic_and_relaxed, + BuiltinProc_atomic_and_explicit, BuiltinProc_atomic_nand, - BuiltinProc_atomic_nand_acq, - BuiltinProc_atomic_nand_rel, - BuiltinProc_atomic_nand_acqrel, - BuiltinProc_atomic_nand_relaxed, + BuiltinProc_atomic_nand_explicit, BuiltinProc_atomic_or, - BuiltinProc_atomic_or_acq, - BuiltinProc_atomic_or_rel, - BuiltinProc_atomic_or_acqrel, - BuiltinProc_atomic_or_relaxed, + BuiltinProc_atomic_or_explicit, BuiltinProc_atomic_xor, - BuiltinProc_atomic_xor_acq, - BuiltinProc_atomic_xor_rel, - BuiltinProc_atomic_xor_acqrel, - BuiltinProc_atomic_xor_relaxed, - - BuiltinProc_atomic_xchg, - BuiltinProc_atomic_xchg_acq, - BuiltinProc_atomic_xchg_rel, - BuiltinProc_atomic_xchg_acqrel, - BuiltinProc_atomic_xchg_relaxed, - - BuiltinProc_atomic_cxchg, - BuiltinProc_atomic_cxchg_acq, - BuiltinProc_atomic_cxchg_rel, - BuiltinProc_atomic_cxchg_acqrel, - BuiltinProc_atomic_cxchg_relaxed, - BuiltinProc_atomic_cxchg_failrelaxed, - BuiltinProc_atomic_cxchg_failacq, - BuiltinProc_atomic_cxchg_acq_failrelaxed, - BuiltinProc_atomic_cxchg_acqrel_failrelaxed, - - BuiltinProc_atomic_cxchgweak, - BuiltinProc_atomic_cxchgweak_acq, - BuiltinProc_atomic_cxchgweak_rel, - BuiltinProc_atomic_cxchgweak_acqrel, - BuiltinProc_atomic_cxchgweak_relaxed, - BuiltinProc_atomic_cxchgweak_failrelaxed, - BuiltinProc_atomic_cxchgweak_failacq, - BuiltinProc_atomic_cxchgweak_acq_failrelaxed, - BuiltinProc_atomic_cxchgweak_acqrel_failrelaxed, + BuiltinProc_atomic_xor_explicit, + BuiltinProc_atomic_exchange, + BuiltinProc_atomic_exchange_explicit, + BuiltinProc_atomic_compare_exchange_strong, + BuiltinProc_atomic_compare_exchange_strong_explicit, + BuiltinProc_atomic_compare_exchange_weak, + BuiltinProc_atomic_compare_exchange_weak_explicit, BuiltinProc_fixed_point_mul, BuiltinProc_fixed_point_div, @@ -213,8 +167,6 @@ BuiltinProc__type_simple_boolean_begin, BuiltinProc_type_is_union, BuiltinProc_type_is_enum, BuiltinProc_type_is_proc, - BuiltinProc_type_is_bit_field, - BuiltinProc_type_is_bit_field_value, BuiltinProc_type_is_bit_set, BuiltinProc_type_is_simd_vector, BuiltinProc_type_is_matrix, @@ -227,6 +179,7 @@ BuiltinProc__type_simple_boolean_begin, BuiltinProc__type_simple_boolean_end, BuiltinProc_type_has_field, + BuiltinProc_type_field_type, BuiltinProc_type_is_specialization_of, @@ -243,6 +196,8 @@ BuiltinProc__type_simple_boolean_end, BuiltinProc_type_polymorphic_record_parameter_count, BuiltinProc_type_polymorphic_record_parameter_value, + BuiltinProc_type_is_subtype_of, + BuiltinProc_type_field_index_of, BuiltinProc_type_equal_proc, @@ -250,6 +205,19 @@ BuiltinProc__type_simple_boolean_end, BuiltinProc__type_end, + BuiltinProc___entry_point, + + BuiltinProc_objc_send, + BuiltinProc_objc_find_selector, + BuiltinProc_objc_find_class, + BuiltinProc_objc_register_selector, + BuiltinProc_objc_register_class, + + BuiltinProc_constant_utf16_cstring, + + BuiltinProc_wasm_memory_grow, + BuiltinProc_wasm_memory_size, + BuiltinProc_COUNT, }; gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { @@ -339,78 +307,31 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("prefetch_write_instruction"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, {STR_LIT("prefetch_write_data"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_fence"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_fence_acq"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_fence_rel"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_fence_acqrel"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, - - {STR_LIT("atomic_store"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_store_rel"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_store_relaxed"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_store_unordered"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, - - {STR_LIT("atomic_load"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_load_acq"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_load_relaxed"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_load_unordered"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - - {STR_LIT("atomic_add"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_add_acq"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_add_rel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_add_acqrel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_add_relaxed"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_sub"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_sub_acq"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_sub_rel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_sub_acqrel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_sub_relaxed"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_and"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_and_acq"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_and_rel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_and_acqrel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_and_relaxed"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_nand"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_nand_acq"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_nand_rel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_nand_acqrel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_nand_relaxed"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_or"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_or_acq"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_or_rel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_or_acqrel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_or_relaxed"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_xor"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_xor_acq"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_xor_rel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_xor_acqrel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_xor_relaxed"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - - {STR_LIT("atomic_xchg"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_xchg_acq"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_xchg_rel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_xchg_acqrel"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_xchg_relaxed"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - - {STR_LIT("atomic_cxchg"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchg_acq"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchg_rel"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchg_acqrel"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchg_relaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchg_failrelaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchg_failacq"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchg_acq_failrelaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchg_acqrel_failrelaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - - {STR_LIT("atomic_cxchgweak"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchgweak_acq"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchgweak_rel"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchgweak_acqrel"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchgweak_relaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchgweak_failrelaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchgweak_failacq"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchgweak_acq_failrelaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("atomic_cxchgweak_acqrel_failrelaxed"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - + {STR_LIT("atomic_type_is_lock_free"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_thread_fence"), 1, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_signal_fence"), 1, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_store"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_store_explicit"), 3, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_load"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_load_explicit"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_add"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_add_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_sub"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_sub_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_and"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_and_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_nand"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_nand_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_or"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_or_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_xor"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_xor_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_exchange"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_exchange_explicit"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_compare_exchange_strong"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_compare_exchange_strong_explicit"), 5, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_compare_exchange_weak"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("atomic_compare_exchange_weak_explicit"), 5, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("fixed_point_mul"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("fixed_point_div"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics}, @@ -464,8 +385,6 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("type_is_union"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_enum"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_proc"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("type_is_bit_field"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("type_is_bit_field_value"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_bit_set"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_simd_vector"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_matrix"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, @@ -477,6 +396,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, {STR_LIT("type_has_field"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_field_type"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_specialization_of"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, @@ -493,10 +413,27 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("type_polymorphic_record_parameter_count"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_polymorphic_record_parameter_value"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_is_subtype_of"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_field_index_of"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_equal_proc"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_hasher_proc"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - + + {STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, + + {STR_LIT("__entry_point"), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, + + {STR_LIT("objc_send"), 3, true, Expr_Expr, BuiltinProcPkg_intrinsics}, + + {STR_LIT("objc_find_selector"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("objc_find_class"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("objc_register_selector"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("objc_register_class"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + + {STR_LIT("constant_utf16_cstring"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + + {STR_LIT("wasm_memory_grow"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("wasm_memory_size"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, }; diff --git a/src/common.cpp b/src/common.cpp index ab2a46118..94248fb62 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -675,262 +675,7 @@ wchar_t **command_line_to_wargv(wchar_t *cmd_line, int *_argc) { #endif - -#if defined(GB_SYSTEM_WINDOWS) - bool path_is_directory(String path) { - gbAllocator a = heap_allocator(); - String16 wstr = string_to_string16(a, path); - defer (gb_free(a, wstr.text)); - - i32 attribs = GetFileAttributesW(wstr.text); - if (attribs < 0) return false; - - return (attribs & FILE_ATTRIBUTE_DIRECTORY) != 0; - } - -#else - bool path_is_directory(String path) { - gbAllocator a = heap_allocator(); - char *copy = cast(char *)copy_string(a, path).text; - defer (gb_free(a, copy)); - - struct stat s; - if (stat(copy, &s) == 0) { - return (s.st_mode & S_IFDIR) != 0; - } - return false; - } -#endif - - -String path_to_full_path(gbAllocator a, String path) { - gbAllocator ha = heap_allocator(); - char *path_c = gb_alloc_str_len(ha, cast(char *)path.text, path.len); - defer (gb_free(ha, path_c)); - - char *fullpath = gb_path_get_full_name(a, path_c); - String res = string_trim_whitespace(make_string_c(fullpath)); -#if defined(GB_SYSTEM_WINDOWS) - for (isize i = 0; i < res.len; i++) { - if (res.text[i] == '\\') { - res.text[i] = '/'; - } - } -#endif - return res; -} - - - -struct FileInfo { - String name; - String fullpath; - i64 size; - bool is_dir; -}; - -enum ReadDirectoryError { - ReadDirectory_None, - - ReadDirectory_InvalidPath, - ReadDirectory_NotExists, - ReadDirectory_Permission, - ReadDirectory_NotDir, - ReadDirectory_Empty, - ReadDirectory_Unknown, - - ReadDirectory_COUNT, -}; - -i64 get_file_size(String path) { - char *c_str = alloc_cstring(heap_allocator(), path); - defer (gb_free(heap_allocator(), c_str)); - - gbFile f = {}; - gbFileError err = gb_file_open(&f, c_str); - defer (gb_file_close(&f)); - if (err != gbFileError_None) { - return -1; - } - return gb_file_size(&f); -} - - -#if defined(GB_SYSTEM_WINDOWS) -ReadDirectoryError read_directory(String path, Array *fi) { - GB_ASSERT(fi != nullptr); - - gbAllocator a = heap_allocator(); - - while (path.len > 0) { - Rune end = path[path.len-1]; - if (end == '/') { - path.len -= 1; - } else if (end == '\\') { - path.len -= 1; - } else { - break; - } - } - - if (path.len == 0) { - return ReadDirectory_InvalidPath; - } - { - char *c_str = alloc_cstring(a, path); - defer (gb_free(a, c_str)); - - gbFile f = {}; - gbFileError file_err = gb_file_open(&f, c_str); - defer (gb_file_close(&f)); - - switch (file_err) { - case gbFileError_Invalid: return ReadDirectory_InvalidPath; - case gbFileError_NotExists: return ReadDirectory_NotExists; - // case gbFileError_Permission: return ReadDirectory_Permission; - } - } - - if (!path_is_directory(path)) { - return ReadDirectory_NotDir; - } - - - char *new_path = gb_alloc_array(a, char, path.len+3); - defer (gb_free(a, new_path)); - - gb_memmove(new_path, path.text, path.len); - gb_memmove(new_path+path.len, "/*", 2); - new_path[path.len+2] = 0; - - String np = make_string(cast(u8 *)new_path, path.len+2); - String16 wstr = string_to_string16(a, np); - defer (gb_free(a, wstr.text)); - - WIN32_FIND_DATAW file_data = {}; - HANDLE find_file = FindFirstFileW(wstr.text, &file_data); - if (find_file == INVALID_HANDLE_VALUE) { - return ReadDirectory_Unknown; - } - defer (FindClose(find_file)); - - array_init(fi, a, 0, 100); - - do { - wchar_t *filename_w = file_data.cFileName; - i64 size = cast(i64)file_data.nFileSizeLow; - size |= (cast(i64)file_data.nFileSizeHigh) << 32; - String name = string16_to_string(a, make_string16_c(filename_w)); - if (name == "." || name == "..") { - gb_free(a, name.text); - continue; - } - - String filepath = {}; - filepath.len = path.len+1+name.len; - filepath.text = gb_alloc_array(a, u8, filepath.len+1); - defer (gb_free(a, filepath.text)); - gb_memmove(filepath.text, path.text, path.len); - gb_memmove(filepath.text+path.len, "/", 1); - gb_memmove(filepath.text+path.len+1, name.text, name.len); - - FileInfo info = {}; - info.name = name; - info.fullpath = path_to_full_path(a, filepath); - info.size = size; - info.is_dir = (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; - array_add(fi, info); - } while (FindNextFileW(find_file, &file_data)); - - if (fi->count == 0) { - return ReadDirectory_Empty; - } - - return ReadDirectory_None; -} -#elif defined(GB_SYSTEM_LINUX) || defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_FREEBSD) - -#include - -ReadDirectoryError read_directory(String path, Array *fi) { - GB_ASSERT(fi != nullptr); - - gbAllocator a = heap_allocator(); - - char *c_path = alloc_cstring(a, path); - defer (gb_free(a, c_path)); - - DIR *dir = opendir(c_path); - if (!dir) { - switch (errno) { - case ENOENT: - return ReadDirectory_NotExists; - case EACCES: - return ReadDirectory_Permission; - case ENOTDIR: - return ReadDirectory_NotDir; - default: - // ENOMEM: out of memory - // EMFILE: per-process limit on open fds reached - // ENFILE: system-wide limit on total open files reached - return ReadDirectory_Unknown; - } - GB_PANIC("unreachable"); - } - - array_init(fi, a, 0, 100); - - for (;;) { - struct dirent *entry = readdir(dir); - if (entry == nullptr) { - break; - } - - String name = make_string_c(entry->d_name); - if (name == "." || name == "..") { - continue; - } - - String filepath = {}; - filepath.len = path.len+1+name.len; - filepath.text = gb_alloc_array(a, u8, filepath.len+1); - defer (gb_free(a, filepath.text)); - gb_memmove(filepath.text, path.text, path.len); - gb_memmove(filepath.text+path.len, "/", 1); - gb_memmove(filepath.text+path.len+1, name.text, name.len); - filepath.text[filepath.len] = 0; - - - struct stat dir_stat = {}; - - if (stat((char *)filepath.text, &dir_stat)) { - continue; - } - - if (S_ISDIR(dir_stat.st_mode)) { - continue; - } - - i64 size = dir_stat.st_size; - - FileInfo info = {}; - info.name = name; - info.fullpath = path_to_full_path(a, filepath); - info.size = size; - array_add(fi, info); - } - - if (fi->count == 0) { - return ReadDirectory_Empty; - } - - return ReadDirectory_None; -} -#else -#error Implement read_directory -#endif - - +#include "path.cpp" struct LoadedFile { void *handle; @@ -1021,7 +766,7 @@ LoadedFileError load_file_32(char const *fullpath, LoadedFile *memory_mapped_fil #endif } - gbFileContents fc = gb_file_read_contents(heap_allocator(), true, fullpath); + gbFileContents fc = gb_file_read_contents(permanent_allocator(), true, fullpath); if (fc.size > I32_MAX) { err = LoadedFile_FileTooLarge; diff --git a/src/common_memory.cpp b/src/common_memory.cpp index 2d7a7a246..953462077 100644 --- a/src/common_memory.cpp +++ b/src/common_memory.cpp @@ -139,6 +139,7 @@ struct PlatformMemoryBlock { }; +gb_global std::atomic global_platform_memory_total_usage; gb_global PlatformMemoryBlock global_platform_memory_block_sentinel; PlatformMemoryBlock *platform_virtual_memory_alloc(isize total_size); @@ -158,10 +159,17 @@ void platform_virtual_memory_protect(void *memory, isize size); PlatformMemoryBlock *platform_virtual_memory_alloc(isize total_size) { PlatformMemoryBlock *pmblock = (PlatformMemoryBlock *)VirtualAlloc(0, total_size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); - GB_ASSERT_MSG(pmblock != nullptr, "Out of Virtual Memory, oh no..."); + if (pmblock == nullptr) { + gb_printf_err("Out of Virtual memory, oh no...\n"); + gb_printf_err("Requested: %lld bytes\n", cast(long long)total_size); + gb_printf_err("Total Usage: %lld bytes\n", cast(long long)global_platform_memory_total_usage); + GB_ASSERT_MSG(pmblock != nullptr, "Out of Virtual Memory, oh no..."); + } + global_platform_memory_total_usage += total_size; return pmblock; } void platform_virtual_memory_free(PlatformMemoryBlock *block) { + global_platform_memory_total_usage -= block->total_size; GB_ASSERT(VirtualFree(block, 0, MEM_RELEASE)); } void platform_virtual_memory_protect(void *memory, isize size) { @@ -180,11 +188,18 @@ void platform_virtual_memory_protect(void *memory, isize size); PlatformMemoryBlock *platform_virtual_memory_alloc(isize total_size) { PlatformMemoryBlock *pmblock = (PlatformMemoryBlock *)mmap(nullptr, total_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - GB_ASSERT_MSG(pmblock != nullptr, "Out of Virtual Memory, oh no..."); + if (pmblock == nullptr) { + gb_printf_err("Out of Virtual memory, oh no...\n"); + gb_printf_err("Requested: %lld bytes\n", cast(long long)total_size); + gb_printf_err("Total Usage: %lld bytes\n", cast(long long)global_platform_memory_total_usage); + GB_ASSERT_MSG(pmblock != nullptr, "Out of Virtual Memory, oh no..."); + } + global_platform_memory_total_usage += total_size; return pmblock; } void platform_virtual_memory_free(PlatformMemoryBlock *block) { isize size = block->total_size; + global_platform_memory_total_usage -= size; munmap(block, size); } void platform_virtual_memory_protect(void *memory, isize size) { @@ -325,18 +340,32 @@ GB_ALLOCATOR_PROC(heap_allocator_proc) { // TODO(bill): Throughly test! switch (type) { #if defined(GB_COMPILER_MSVC) - case gbAllocation_Alloc: { - isize aligned_size = align_formula_isize(size, alignment); - // TODO(bill): Make sure this is aligned correctly - ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, aligned_size); - } break; - case gbAllocation_Free: - HeapFree(GetProcessHeap(), 0, old_memory); + case gbAllocation_Alloc: + if (size == 0) { + return NULL; + } else { + isize aligned_size = align_formula_isize(size, alignment); + // TODO(bill): Make sure this is aligned correctly + ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, aligned_size); + } + break; + case gbAllocation_Free: + if (old_memory != nullptr) { + HeapFree(GetProcessHeap(), 0, old_memory); + } + break; + case gbAllocation_Resize: + if (old_memory != nullptr && size > 0) { + isize aligned_size = align_formula_isize(size, alignment); + ptr = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, old_memory, aligned_size); + } else if (old_memory != nullptr) { + HeapFree(GetProcessHeap(), 0, old_memory); + } else if (size != 0) { + isize aligned_size = align_formula_isize(size, alignment); + // TODO(bill): Make sure this is aligned correctly + ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, aligned_size); + } break; - case gbAllocation_Resize: { - isize aligned_size = align_formula_isize(size, alignment); - ptr = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, old_memory, aligned_size); - } break; #elif defined(GB_SYSTEM_LINUX) // TODO(bill): *nix version that's decent case gbAllocation_Alloc: { diff --git a/src/docs.cpp b/src/docs.cpp index 8d65cb83a..3ea3cce1b 100644 --- a/src/docs.cpp +++ b/src/docs.cpp @@ -67,6 +67,14 @@ GB_COMPARE_PROC(cmp_ast_package_by_name) { #include "docs_format.cpp" #include "docs_writer.cpp" +void print_doc_line(i32 indent, String const &data) { + while (indent --> 0) { + gb_printf("\t"); + } + gb_file_write(gb_file_get_standard(gbFileStandard_Output), data.text, data.len); + gb_printf("\n"); +} + void print_doc_line(i32 indent, char const *fmt, ...) { while (indent --> 0) { gb_printf("\t"); @@ -86,6 +94,13 @@ void print_doc_line_no_newline(i32 indent, char const *fmt, ...) { gb_printf_va(fmt, va); va_end(va); } +void print_doc_line_no_newline(i32 indent, String const &data) { + while (indent --> 0) { + gb_printf("\t"); + } + gb_file_write(gb_file_get_standard(gbFileStandard_Output), data.text, data.len); +} + bool print_doc_comment_group_string(i32 indent, CommentGroup *g) { if (g == nullptr) { @@ -106,8 +121,9 @@ bool print_doc_comment_group_string(i32 indent, CommentGroup *g) { String comment = g->list[i].string; String original_comment = comment; - bool slash_slash = comment[1] == '/'; + bool slash_slash = false; if (comment[1] == '/') { + slash_slash = true; comment.text += 2; comment.len -= 2; } else if (comment[1] == '*') { @@ -131,7 +147,7 @@ bool print_doc_comment_group_string(i32 indent, CommentGroup *g) { } if (slash_slash) { - print_doc_line(indent, "%.*s", LIT(comment)); + print_doc_line(indent, comment); count += 1; } else { isize pos = 0; @@ -143,7 +159,7 @@ bool print_doc_comment_group_string(i32 indent, CommentGroup *g) { } } String line = substring(comment, pos, end); - pos = end+1; + pos = end; String trimmed_line = string_trim_whitespace(line); if (trimmed_line.len == 0) { if (count == 0) { @@ -159,7 +175,7 @@ bool print_doc_comment_group_string(i32 indent, CommentGroup *g) { line = substring(line, 2, line.len); } - print_doc_line(indent, "%.*s", LIT(line)); + print_doc_line(indent, line); count += 1; } } @@ -263,7 +279,7 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { } GB_ASSERT(type_expr != nullptr || init_expr != nullptr); - print_doc_line_no_newline(2, "%.*s", LIT(e->token.string)); + print_doc_line_no_newline(2, e->token.string); if (type_expr != nullptr) { gbString t = expr_to_string(type_expr); gb_printf(": %s ", t); @@ -298,7 +314,7 @@ void print_doc_package(CheckerInfo *info, AstPackage *pkg) { for_array(i, pkg->files) { AstFile *f = pkg->files[i]; String filename = remove_directory_from_path(f->fullpath); - print_doc_line(2, "%.*s", LIT(filename)); + print_doc_line(2, filename); } } diff --git a/src/docs_format.cpp b/src/docs_format.cpp index 1c3af6257..ee32d0e05 100644 --- a/src/docs_format.cpp +++ b/src/docs_format.cpp @@ -15,7 +15,7 @@ struct OdinDocVersionType { #define OdinDocVersionType_Major 0 #define OdinDocVersionType_Minor 2 -#define OdinDocVersionType_Patch 1 +#define OdinDocVersionType_Patch 4 struct OdinDocHeaderBase { u8 magic[8]; @@ -99,6 +99,7 @@ enum OdinDocTypeFlag_Union : u32 { OdinDocTypeFlag_Union_polymorphic = 1<<0, OdinDocTypeFlag_Union_no_nil = 1<<1, OdinDocTypeFlag_Union_maybe = 1<<2, + OdinDocTypeFlag_Union_shared_nil = 1<<3, }; enum OdinDocTypeFlag_Proc : u32 { @@ -137,6 +138,7 @@ struct OdinDocType { OdinDocArray entities; OdinDocTypeIndex polmorphic_params; OdinDocArray where_clauses; + OdinDocArray tags; // struct field tags }; struct OdinDocAttribute { @@ -153,6 +155,7 @@ enum OdinDocEntityKind : u32 { OdinDocEntity_ProcGroup = 5, OdinDocEntity_ImportName = 6, OdinDocEntity_LibraryName = 7, + OdinDocEntity_Builtin = 8, }; enum OdinDocEntityFlag : u64 { @@ -169,8 +172,13 @@ enum OdinDocEntityFlag : u64 { OdinDocEntityFlag_Type_Alias = 1ull<<20, + OdinDocEntityFlag_Builtin_Pkg_Builtin = 1ull<<30, + OdinDocEntityFlag_Builtin_Pkg_Intrinsics = 1ull<<31, + OdinDocEntityFlag_Var_Thread_Local = 1ull<<40, OdinDocEntityFlag_Var_Static = 1ull<<41, + + OdinDocEntityFlag_Private = 1ull<<50, }; struct OdinDocEntity { @@ -182,8 +190,9 @@ struct OdinDocEntity { OdinDocTypeIndex type; OdinDocString init_string; u32 reserved_for_init; - OdinDocString comment; - OdinDocString docs; + OdinDocString comment; // line comment + OdinDocString docs; // preceding comment + i32 field_group_index; OdinDocEntityIndex foreign_library; OdinDocString link_name; OdinDocArray attributes; @@ -197,15 +206,21 @@ enum OdinDocPkgFlags : u32 { OdinDocPkgFlag_Init = 1<<2, }; +struct OdinDocScopeEntry { + OdinDocString name; + OdinDocEntityIndex entity; +}; + struct OdinDocPkg { OdinDocString fullpath; OdinDocString name; u32 flags; OdinDocString docs; - OdinDocArray files; - OdinDocArray entities; + OdinDocArray files; + OdinDocArray entries; }; + struct OdinDocHeader { OdinDocHeaderBase base; diff --git a/src/docs_writer.cpp b/src/docs_writer.cpp index e8e8892ec..0ad10ac49 100644 --- a/src/docs_writer.cpp +++ b/src/docs_writer.cpp @@ -292,8 +292,9 @@ bool odin_doc_append_comment_group_string(Array *buf, CommentGroup *g) { String comment = g->list[i].string; String original_comment = comment; - bool slash_slash = comment[1] == '/'; + bool slash_slash = false; if (comment[1] == '/') { + slash_slash = true; comment.text += 2; comment.len -= 2; } else if (comment[1] == '*') { @@ -330,7 +331,7 @@ bool odin_doc_append_comment_group_string(Array *buf, CommentGroup *g) { } } String line = substring(comment, pos, end); - pos = end+1; + pos = end; String trimmed_line = string_trim_whitespace(line); if (trimmed_line.len == 0) { if (count == 0) { @@ -482,7 +483,7 @@ OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) { for_array(i, w->type_cache.entries) { // NOTE(bill): THIS IS SLOW Type *other = w->type_cache.entries[i].key; - if (are_types_identical(type, other)) { + if (are_types_identical_unique_tuples(type, other)) { OdinDocTypeIndex index = w->type_cache.entries[i].value; map_set(&w->type_cache, type, index); return index; @@ -511,10 +512,16 @@ OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) { doc_type.entities = odin_doc_add_entity_as_slice(w, type->Named.type_name); break; case Type_Generic: - doc_type.kind = OdinDocType_Generic; - doc_type.name = odin_doc_write_string(w, type->Generic.name); - if (type->Generic.specialized) { - doc_type.types = odin_doc_type_as_slice(w, type->Generic.specialized); + { + String name = type->Generic.name; + if (type->Generic.entity) { + name = type->Generic.entity->token.string; + } + doc_type.kind = OdinDocType_Generic; + doc_type.name = odin_doc_write_string(w, name); + if (type->Generic.specialized) { + doc_type.types = odin_doc_type_as_slice(w, type->Generic.specialized); + } } break; case Type_Pointer: @@ -598,14 +605,25 @@ OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) { } doc_type.where_clauses = odin_doc_where_clauses(w, st->where_clauses); } + + auto tags = array_make(heap_allocator(), type->Struct.fields.count); + defer (array_free(&tags)); + + for_array(i, type->Struct.fields) { + tags[i] = odin_doc_write_string(w, type->Struct.tags[i]); + } + + doc_type.tags = odin_write_slice(w, tags.data, tags.count); } break; case Type_Union: doc_type.kind = OdinDocType_Union; if (type->Union.is_polymorphic) { doc_type.flags |= OdinDocTypeFlag_Union_polymorphic; } - if (type->Union.no_nil) { doc_type.flags |= OdinDocTypeFlag_Union_no_nil; } - if (type->Union.maybe) { doc_type.flags |= OdinDocTypeFlag_Union_maybe; } - + switch (type->Union.kind) { + case UnionType_maybe: doc_type.flags |= OdinDocTypeFlag_Union_maybe; break; + case UnionType_no_nil: doc_type.flags |= OdinDocTypeFlag_Union_no_nil; break; + case UnionType_shared_nil: doc_type.flags |= OdinDocTypeFlag_Union_shared_nil; break; + } { auto variants = array_make(heap_allocator(), type->Union.variants.count); defer (array_free(&variants)); @@ -667,40 +685,7 @@ OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) { types[1] = odin_doc_type(w, type->Proc.results); doc_type.types = odin_write_slice(w, types, gb_count_of(types)); - String calling_convention = {}; - switch (type->Proc.calling_convention) { - case ProcCC_Invalid: - // no need - break; - case ProcCC_Odin: - if (default_calling_convention() != ProcCC_Odin) { - calling_convention = str_lit("odin"); - } - break; - case ProcCC_Contextless: - if (default_calling_convention() != ProcCC_Contextless) { - calling_convention = str_lit("contextless"); - } - break; - case ProcCC_CDecl: - calling_convention = str_lit("cdecl"); - break; - case ProcCC_StdCall: - calling_convention = str_lit("stdcall"); - break; - case ProcCC_FastCall: - calling_convention = str_lit("fastcall"); - break; - case ProcCC_None: - calling_convention = str_lit("none"); - break; - case ProcCC_Naked: - calling_convention = str_lit("naked"); - break; - case ProcCC_InlineAsm: - calling_convention = str_lit("inline-assembly"); - break; - } + String calling_convention = make_string_c(proc_calling_convention_strings[type->Proc.calling_convention]); doc_type.calling_convention = odin_doc_write_string(w, calling_convention); } break; @@ -795,11 +780,21 @@ OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) { comment = e->decl_info->comment; docs = e->decl_info->docs; } + if (e->kind == Entity_Variable) { + if (!comment) { comment = e->Variable.comment; } + if (!docs) { docs = e->Variable.docs; } + } else if (e->kind == Entity_Constant) { + if (!comment) { comment = e->Constant.comment; } + if (!docs) { docs = e->Constant.docs; } + } + String name = e->token.string; String link_name = {}; + TokenPos pos = e->token.pos; OdinDocEntityKind kind = OdinDocEntity_Invalid; - u32 flags = 0; + u64 flags = 0; + i32 field_group_index = -1; switch (e->kind) { case Entity_Invalid: kind = OdinDocEntity_Invalid; break; @@ -810,6 +805,7 @@ OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) { case Entity_ProcGroup: kind = OdinDocEntity_ProcGroup; break; case Entity_ImportName: kind = OdinDocEntity_ImportName; break; case Entity_LibraryName: kind = OdinDocEntity_LibraryName; break; + case Entity_Builtin: kind = OdinDocEntity_Builtin; break; } switch (e->kind) { @@ -829,12 +825,33 @@ OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) { if (init_expr == nullptr) { init_expr = e->Variable.init_expr; } + field_group_index = e->Variable.field_group_index; + break; + case Entity_Constant: + field_group_index = e->Constant.field_group_index; break; case Entity_Procedure: if (e->Procedure.is_foreign) { flags |= OdinDocEntityFlag_Foreign; } if (e->Procedure.is_export) { flags |= OdinDocEntityFlag_Export; } link_name = e->Procedure.link_name; break; + case Entity_Builtin: + { + auto bp = builtin_procs[e->Builtin.id]; + pos = {}; + name = bp.name; + switch (bp.pkg) { + case BuiltinProcPkg_builtin: + flags |= OdinDocEntityFlag_Builtin_Pkg_Builtin; + break; + case BuiltinProcPkg_intrinsics: + flags |= OdinDocEntityFlag_Builtin_Pkg_Intrinsics; + break; + default: + GB_PANIC("Unhandled BuiltinProcPkg"); + } + } + break; } if (e->flags & EntityFlag_Param) { @@ -845,6 +862,9 @@ OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) { if (e->flags & EntityFlag_NoAlias) { flags |= OdinDocEntityFlag_Param_NoAlias; } if (e->flags & EntityFlag_AnyInt) { flags |= OdinDocEntityFlag_Param_AnyInt; } } + if (e->scope && (e->scope->flags & (ScopeFlag_File|ScopeFlag_Pkg)) && !is_entity_exported(e)) { + flags |= OdinDocEntityFlag_Private; + } OdinDocString init_string = {}; if (init_expr) { @@ -867,12 +887,13 @@ OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e) { doc_entity.kind = kind; doc_entity.flags = flags; - doc_entity.pos = odin_doc_token_pos_cast(w, e->token.pos); - doc_entity.name = odin_doc_write_string(w, e->token.string); + doc_entity.pos = odin_doc_token_pos_cast(w, pos); + doc_entity.name = odin_doc_write_string(w, name); doc_entity.type = 0; // Set later doc_entity.init_string = init_string; doc_entity.comment = odin_doc_comment_group_string(w, comment); doc_entity.docs = odin_doc_comment_group_string(w, docs); + doc_entity.field_group_index = field_group_index; doc_entity.foreign_library = 0; // Set later doc_entity.link_name = odin_doc_write_string(w, link_name); if (e->decl_info != nullptr) { @@ -944,7 +965,7 @@ void odin_doc_update_entities(OdinDocWriter *w) { -OdinDocArray odin_doc_add_pkg_entities(OdinDocWriter *w, AstPackage *pkg) { +OdinDocArray odin_doc_add_pkg_entries(OdinDocWriter *w, AstPackage *pkg) { if (pkg->scope == nullptr) { return {}; } @@ -952,14 +973,14 @@ OdinDocArray odin_doc_add_pkg_entities(OdinDocWriter *w, Ast return {}; } - auto entities = array_make(heap_allocator(), 0, pkg->scope->elements.entries.count); - defer (array_free(&entities)); + auto entries = array_make(heap_allocator(), 0, w->entity_cache.entries.count); + defer (array_free(&entries)); for_array(i, pkg->scope->elements.entries) { + String name = pkg->scope->elements.entries[i].key.string; Entity *e = pkg->scope->elements.entries[i].value; switch (e->kind) { case Entity_Invalid: - case Entity_Builtin: case Entity_Nil: case Entity_Label: continue; @@ -970,34 +991,27 @@ OdinDocArray odin_doc_add_pkg_entities(OdinDocWriter *w, Ast case Entity_ProcGroup: case Entity_ImportName: case Entity_LibraryName: + case Entity_Builtin: // Fine break; } - array_add(&entities, e); - } - gb_sort_array(entities.data, entities.count, cmp_entities_for_printing); - - auto entity_indices = array_make(heap_allocator(), 0, w->entity_cache.entries.count); - defer (array_free(&entity_indices)); - - for_array(i, entities) { - Entity *e = entities[i]; if (e->pkg != pkg) { continue; } - if (!is_entity_exported(e)) { + if (!is_entity_exported(e, true)) { continue; } if (e->token.string.len == 0) { continue; } - OdinDocEntityIndex doc_entity_index = 0; - doc_entity_index = odin_doc_add_entity(w, e); - array_add(&entity_indices, doc_entity_index); + OdinDocScopeEntry entry = {}; + entry.name = odin_doc_write_string(w, name); + entry.entity = odin_doc_add_entity(w, e); + array_add(&entries, entry); } - return odin_write_slice(w, entity_indices.data, entity_indices.count); + return odin_write_slice(w, entries.data, entries.count); } @@ -1065,7 +1079,7 @@ void odin_doc_write_docs(OdinDocWriter *w) { } doc_pkg.files = odin_write_slice(w, file_indices.data, file_indices.count); - doc_pkg.entities = odin_doc_add_pkg_entities(w, pkg); + doc_pkg.entries = odin_doc_add_pkg_entries(w, pkg); if (dst) { *dst = doc_pkg; diff --git a/src/entity.cpp b/src/entity.cpp index b39ffc63a..1f87f7af6 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -45,9 +45,9 @@ enum EntityFlag : u64 { EntityFlag_NoAlias = 1ull<<9, EntityFlag_TypeField = 1ull<<10, EntityFlag_Value = 1ull<<11, - EntityFlag_Sret = 1ull<<12, - EntityFlag_ByVal = 1ull<<13, - EntityFlag_BitFieldValue = 1ull<<14, + + + EntityFlag_PolyConst = 1ull<<15, EntityFlag_NotExported = 1ull<<16, EntityFlag_ConstInput = 1ull<<17, @@ -74,6 +74,7 @@ enum EntityFlag : u64 { EntityFlag_Test = 1ull<<30, EntityFlag_Init = 1ull<<31, + EntityFlag_Subtype = 1ull<<32, EntityFlag_CustomLinkName = 1ull<<40, EntityFlag_CustomLinkage_Internal = 1ull<<41, @@ -86,6 +87,10 @@ enum EntityFlag : u64 { EntityFlag_Overridden = 1ull<<63, }; +enum : u64 { + EntityFlags_IsSubtype = EntityFlag_Using|EntityFlag_Subtype, +}; + enum EntityState : u32 { EntityState_Unresolved = 0, EntityState_InProgress = 1, @@ -110,6 +115,16 @@ struct ParameterValue { }; }; +bool has_parameter_value(ParameterValue const ¶m_value) { + if (param_value.kind != ParameterValue_Invalid) { + return true; + } + if (param_value.original_ast_expr != nullptr) { + return true; + } + return false; +} + enum EntityConstantFlags : u32 { EntityConstantFlag_ImplicitEnumValue = 1<<0, }; @@ -122,6 +137,28 @@ enum ProcedureOptimizationMode : u32 { ProcedureOptimizationMode_Speed, }; + +BlockingMutex global_type_name_objc_metadata_mutex; + +struct TypeNameObjCMetadataEntry { + String name; + Entity *entity; +}; +struct TypeNameObjCMetadata { + BlockingMutex *mutex; + Array type_entries; + Array value_entries; +}; + +TypeNameObjCMetadata *create_type_name_obj_c_metadata() { + TypeNameObjCMetadata *md = gb_alloc_item(permanent_allocator(), TypeNameObjCMetadata); + md->mutex = gb_alloc_item(permanent_allocator(), BlockingMutex); + mutex_init(md->mutex); + array_init(&md->type_entries, heap_allocator()); + array_init(&md->value_entries, heap_allocator()); + return md; +} + // An Entity is a named "thing" in the language struct Entity { EntityKind kind; @@ -160,10 +197,14 @@ struct Entity { ExactValue value; ParameterValue param_value; u32 flags; + i32 field_group_index; + CommentGroup *docs; + CommentGroup *comment; } Constant; struct { Ast *init_expr; // only used for some variables within procedure bodies i32 field_index; + i32 field_group_index; ParameterValue param_value; @@ -173,6 +214,8 @@ struct Entity { String link_name; String link_prefix; String link_section; + CommentGroup *docs; + CommentGroup *comment; bool is_foreign; bool is_export; } Variable; @@ -180,6 +223,8 @@ struct Entity { Type * type_parameter_specialization; String ir_mangled_name; bool is_type_alias; + String objc_class_name; + TypeNameObjCMetadata *objc_metadata; } TypeName; struct { u64 tags; @@ -239,7 +284,7 @@ bool is_entity_exported(Entity *e, bool allow_builtin = false) { if (e->flags & EntityFlag_NotExported) { return false; } - if (e->file != nullptr && (e->file->flags & AstFile_IsPrivate) != 0) { + if (e->file != nullptr && (e->file->flags & (AstFile_IsPrivatePkg|AstFile_IsPrivateFile)) != 0) { return false; } diff --git a/src/error.cpp b/src/error.cpp new file mode 100644 index 000000000..faf4d11fb --- /dev/null +++ b/src/error.cpp @@ -0,0 +1,416 @@ +struct ErrorCollector { + TokenPos prev; + std::atomic count; + std::atomic warning_count; + std::atomic in_block; + BlockingMutex mutex; + BlockingMutex error_out_mutex; + BlockingMutex string_mutex; + RecursiveMutex block_mutex; + + Array error_buffer; + Array errors; +}; + +gb_global ErrorCollector global_error_collector; + +#define MAX_ERROR_COLLECTOR_COUNT (36) + + +bool any_errors(void) { + return global_error_collector.count.load() != 0; +} + +void init_global_error_collector(void) { + mutex_init(&global_error_collector.mutex); + mutex_init(&global_error_collector.block_mutex); + mutex_init(&global_error_collector.error_out_mutex); + mutex_init(&global_error_collector.string_mutex); + array_init(&global_error_collector.errors, heap_allocator()); + array_init(&global_error_collector.error_buffer, heap_allocator()); + array_init(&global_file_path_strings, heap_allocator(), 1, 4096); + array_init(&global_files, heap_allocator(), 1, 4096); +} + + +// temporary +// defined in build_settings.cpp +char *token_pos_to_string(TokenPos const &pos); + +bool set_file_path_string(i32 index, String const &path) { + bool ok = false; + GB_ASSERT(index >= 0); + mutex_lock(&global_error_collector.string_mutex); + + if (index >= global_file_path_strings.count) { + array_resize(&global_file_path_strings, index+1); + } + String prev = global_file_path_strings[index]; + if (prev.len == 0) { + global_file_path_strings[index] = path; + ok = true; + } + + mutex_unlock(&global_error_collector.string_mutex); + return ok; +} + +bool thread_safe_set_ast_file_from_id(i32 index, AstFile *file) { + bool ok = false; + GB_ASSERT(index >= 0); + mutex_lock(&global_error_collector.string_mutex); + + if (index >= global_files.count) { + array_resize(&global_files, index+1); + } + AstFile *prev = global_files[index]; + if (prev == nullptr) { + global_files[index] = file; + ok = true; + } + + mutex_unlock(&global_error_collector.string_mutex); + return ok; +} + +String get_file_path_string(i32 index) { + GB_ASSERT(index >= 0); + mutex_lock(&global_error_collector.string_mutex); + + String path = {}; + if (index < global_file_path_strings.count) { + path = global_file_path_strings[index]; + } + + mutex_unlock(&global_error_collector.string_mutex); + return path; +} + +AstFile *thread_safe_get_ast_file_from_id(i32 index) { + GB_ASSERT(index >= 0); + mutex_lock(&global_error_collector.string_mutex); + + AstFile *file = nullptr; + if (index < global_files.count) { + file = global_files[index]; + } + + mutex_unlock(&global_error_collector.string_mutex); + return file; +} + + + +void begin_error_block(void) { + mutex_lock(&global_error_collector.block_mutex); + global_error_collector.in_block.store(true); +} + +void end_error_block(void) { + if (global_error_collector.error_buffer.count > 0) { + isize n = global_error_collector.error_buffer.count; + u8 *text = gb_alloc_array(permanent_allocator(), u8, n+1); + gb_memmove(text, global_error_collector.error_buffer.data, n); + text[n] = 0; + String s = {text, n}; + array_add(&global_error_collector.errors, s); + global_error_collector.error_buffer.count = 0; + } + + global_error_collector.in_block.store(false); + mutex_unlock(&global_error_collector.block_mutex); +} + +#define ERROR_BLOCK() begin_error_block(); defer (end_error_block()) + + +#define ERROR_OUT_PROC(name) void name(char const *fmt, va_list va) +typedef ERROR_OUT_PROC(ErrorOutProc); + +ERROR_OUT_PROC(default_error_out_va) { + gbFile *f = gb_file_get_standard(gbFileStandard_Error); + + char buf[4096] = {}; + isize len = gb_snprintf_va(buf, gb_size_of(buf), fmt, va); + isize n = len-1; + if (global_error_collector.in_block) { + isize cap = global_error_collector.error_buffer.count + n; + array_reserve(&global_error_collector.error_buffer, cap); + u8 *data = global_error_collector.error_buffer.data + global_error_collector.error_buffer.count; + gb_memmove(data, buf, n); + global_error_collector.error_buffer.count += n; + } else { + mutex_lock(&global_error_collector.error_out_mutex); + { + u8 *text = gb_alloc_array(permanent_allocator(), u8, n+1); + gb_memmove(text, buf, n); + text[n] = 0; + array_add(&global_error_collector.errors, make_string(text, n)); + } + mutex_unlock(&global_error_collector.error_out_mutex); + + } + gb_file_write(f, buf, n); +} + + +ErrorOutProc *error_out_va = default_error_out_va; + +// NOTE: defined in build_settings.cpp +bool global_warnings_as_errors(void); +bool global_ignore_warnings(void); +bool show_error_line(void); +gbString get_file_line_as_string(TokenPos const &pos, i32 *offset); + +void error_out(char const *fmt, ...) { + va_list va; + va_start(va, fmt); + error_out_va(fmt, va); + va_end(va); +} + + +bool show_error_on_line(TokenPos const &pos, TokenPos end) { + if (!show_error_line()) { + return false; + } + + i32 offset = 0; + gbString the_line = get_file_line_as_string(pos, &offset); + defer (gb_string_free(the_line)); + + if (the_line != nullptr) { + String line = make_string(cast(u8 const *)the_line, gb_string_length(the_line)); + + // TODO(bill): This assumes ASCII + + enum { + MAX_LINE_LENGTH = 76, + MAX_TAB_WIDTH = 8, + ELLIPSIS_PADDING = 8 + }; + + error_out("\n\t"); + if (line.len+MAX_TAB_WIDTH+ELLIPSIS_PADDING > MAX_LINE_LENGTH) { + i32 const half_width = MAX_LINE_LENGTH/2; + i32 left = cast(i32)(offset); + i32 right = cast(i32)(line.len - offset); + left = gb_min(left, half_width); + right = gb_min(right, half_width); + + line.text += offset-left; + line.len -= offset+right-left; + + line = string_trim_whitespace(line); + + offset = left + ELLIPSIS_PADDING/2; + + error_out("... %.*s ...", LIT(line)); + } else { + error_out("%.*s", LIT(line)); + } + error_out("\n\t"); + + for (i32 i = 0; i < offset; i++) { + error_out(" "); + } + error_out("^"); + if (end.file_id == pos.file_id) { + if (end.line > pos.line) { + for (i32 i = offset; i < line.len; i++) { + error_out("~"); + } + } else if (end.line == pos.line && end.column > pos.column) { + i32 length = gb_min(end.offset - pos.offset, cast(i32)(line.len-offset)); + for (i32 i = 1; i < length-1; i++) { + error_out("~"); + } + if (length > 1) { + error_out("^"); + } + } + } + + error_out("\n\n"); + return true; + } + return false; +} + +void error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) { + global_error_collector.count.fetch_add(1); + + mutex_lock(&global_error_collector.mutex); + // NOTE(bill): Duplicate error, skip it + if (pos.line == 0) { + error_out("Error: %s\n", gb_bprintf_va(fmt, va)); + } else if (global_error_collector.prev != pos) { + global_error_collector.prev = pos; + error_out("%s %s\n", + token_pos_to_string(pos), + gb_bprintf_va(fmt, va)); + show_error_on_line(pos, end); + } + mutex_unlock(&global_error_collector.mutex); + if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT) { + gb_exit(1); + } +} + +void warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) { + if (global_warnings_as_errors()) { + error_va(pos, end, fmt, va); + return; + } + global_error_collector.warning_count.fetch_add(1); + mutex_lock(&global_error_collector.mutex); + if (!global_ignore_warnings()) { + // NOTE(bill): Duplicate error, skip it + if (pos.line == 0) { + error_out("Warning: %s\n", gb_bprintf_va(fmt, va)); + } else if (global_error_collector.prev != pos) { + global_error_collector.prev = pos; + error_out("%s Warning: %s\n", + token_pos_to_string(pos), + gb_bprintf_va(fmt, va)); + show_error_on_line(pos, end); + } + } + mutex_unlock(&global_error_collector.mutex); +} + + +void error_line_va(char const *fmt, va_list va) { + error_out_va(fmt, va); +} + +void error_no_newline_va(TokenPos const &pos, char const *fmt, va_list va) { + mutex_lock(&global_error_collector.mutex); + global_error_collector.count++; + // NOTE(bill): Duplicate error, skip it + if (pos.line == 0) { + error_out("Error: %s", gb_bprintf_va(fmt, va)); + } else if (global_error_collector.prev != pos) { + global_error_collector.prev = pos; + error_out("%s %s", + token_pos_to_string(pos), + gb_bprintf_va(fmt, va)); + } + mutex_unlock(&global_error_collector.mutex); + if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT) { + gb_exit(1); + } +} + + +void syntax_error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) { + mutex_lock(&global_error_collector.mutex); + global_error_collector.count++; + // NOTE(bill): Duplicate error, skip it + if (global_error_collector.prev != pos) { + global_error_collector.prev = pos; + error_out("%s Syntax Error: %s\n", + token_pos_to_string(pos), + gb_bprintf_va(fmt, va)); + show_error_on_line(pos, end); + } else if (pos.line == 0) { + error_out("Syntax Error: %s\n", gb_bprintf_va(fmt, va)); + } + + mutex_unlock(&global_error_collector.mutex); + if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT) { + gb_exit(1); + } +} + +void syntax_warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) { + if (global_warnings_as_errors()) { + syntax_error_va(pos, end, fmt, va); + return; + } + mutex_lock(&global_error_collector.mutex); + global_error_collector.warning_count++; + if (!global_ignore_warnings()) { + // NOTE(bill): Duplicate error, skip it + if (global_error_collector.prev != pos) { + global_error_collector.prev = pos; + error_out("%s Syntax Warning: %s\n", + token_pos_to_string(pos), + gb_bprintf_va(fmt, va)); + show_error_on_line(pos, end); + } else if (pos.line == 0) { + error_out("Warning: %s\n", gb_bprintf_va(fmt, va)); + } + } + mutex_unlock(&global_error_collector.mutex); +} + + + +void warning(Token const &token, char const *fmt, ...) { + va_list va; + va_start(va, fmt); + warning_va(token.pos, {}, fmt, va); + va_end(va); +} + +void error(Token const &token, char const *fmt, ...) { + va_list va; + va_start(va, fmt); + error_va(token.pos, {}, fmt, va); + va_end(va); +} + +void error(TokenPos pos, char const *fmt, ...) { + va_list va; + va_start(va, fmt); + Token token = {}; + token.pos = pos; + error_va(pos, {}, fmt, va); + va_end(va); +} + +void error_line(char const *fmt, ...) { + va_list va; + va_start(va, fmt); + error_line_va(fmt, va); + va_end(va); +} + + +void syntax_error(Token const &token, char const *fmt, ...) { + va_list va; + va_start(va, fmt); + syntax_error_va(token.pos, {}, fmt, va); + va_end(va); +} + +void syntax_error(TokenPos pos, char const *fmt, ...) { + va_list va; + va_start(va, fmt); + syntax_error_va(pos, {}, fmt, va); + va_end(va); +} + +void syntax_warning(Token const &token, char const *fmt, ...) { + va_list va; + va_start(va, fmt); + syntax_warning_va(token.pos, {}, fmt, va); + va_end(va); +} + + +void compiler_error(char const *fmt, ...) { + va_list va; + + va_start(va, fmt); + gb_printf_err("Internal Compiler Error: %s\n", + gb_bprintf_va(fmt, va)); + va_end(va); + GB_DEBUG_TRAP(); + gb_exit(1); +} + + + + diff --git a/src/exact_value.cpp b/src/exact_value.cpp index fd90278e5..cedef48c4 100644 --- a/src/exact_value.cpp +++ b/src/exact_value.cpp @@ -50,9 +50,9 @@ struct ExactValue { union { bool value_bool; String value_string; - BigInt value_integer; // NOTE(bill): This must be an integer and not a pointer + BigInt value_integer; f64 value_float; - i64 value_pointer; + i64 value_pointer; // NOTE(bill): This must be an integer and not a pointer Complex128 *value_complex; Quaternion256 *value_quaternion; Ast * value_compound; @@ -591,6 +591,7 @@ failure: i32 exact_value_order(ExactValue const &v) { switch (v.kind) { case ExactValue_Invalid: + case ExactValue_Compound: return 0; case ExactValue_Bool: case ExactValue_String: @@ -607,8 +608,6 @@ i32 exact_value_order(ExactValue const &v) { return 6; case ExactValue_Procedure: return 7; - // case ExactValue_Compound: - // return 8; default: GB_PANIC("How'd you get here? Invalid Value.kind %d", v.kind); @@ -630,6 +629,9 @@ void match_exact_values(ExactValue *x, ExactValue *y) { case ExactValue_Bool: case ExactValue_String: case ExactValue_Quaternion: + case ExactValue_Pointer: + case ExactValue_Procedure: + case ExactValue_Typeid: return; case ExactValue_Integer: @@ -671,9 +673,6 @@ void match_exact_values(ExactValue *x, ExactValue *y) { return; } break; - - case ExactValue_Procedure: - return; } compiler_error("match_exact_values: How'd you get here? Invalid ExactValueKind %d", x->kind); @@ -932,6 +931,17 @@ bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) { break; } + case ExactValue_Pointer: { + switch (op) { + case Token_CmpEq: return x.value_pointer == y.value_pointer; + case Token_NotEq: return x.value_pointer != y.value_pointer; + case Token_Lt: return x.value_pointer < y.value_pointer; + case Token_LtEq: return x.value_pointer <= y.value_pointer; + case Token_Gt: return x.value_pointer > y.value_pointer; + case Token_GtEq: return x.value_pointer >= y.value_pointer; + } + } + case ExactValue_Typeid: switch (op) { case Token_CmpEq: return are_types_identical(x.value_typeid, y.value_typeid); diff --git a/src/gb/gb.h b/src/gb/gb.h index f716b0840..3b2d6434c 100644 --- a/src/gb/gb.h +++ b/src/gb/gb.h @@ -79,6 +79,10 @@ extern "C" { #ifndef GB_SYSTEM_FREEBSD #define GB_SYSTEM_FREEBSD 1 #endif + #elif defined(__OpenBSD__) + #ifndef GB_SYSTEM_OPENBSD + #define GB_SYSTEM_OPENBSD 1 + #endif #else #error This UNIX operating system is not supported #endif @@ -199,7 +203,7 @@ extern "C" { #endif #include // NOTE(bill): malloc on linux #include - #if !defined(GB_SYSTEM_OSX) && !defined(__FreeBSD__) + #if !defined(GB_SYSTEM_OSX) && !defined(__FreeBSD__) && !defined(__OpenBSD__) #include #endif #include @@ -235,6 +239,12 @@ extern "C" { #define sendfile(out, in, offset, count) sendfile(out, in, offset, count, NULL, NULL, 0) #endif +#if defined(GB_SYSTEM_OPENBSD) + #include + #include + #define lseek64 lseek +#endif + #if defined(GB_SYSTEM_UNIX) #include #endif @@ -783,6 +793,13 @@ typedef struct gbAffinity { isize thread_count; isize threads_per_core; } gbAffinity; +#elif defined(GB_SYSTEM_OPENBSD) +typedef struct gbAffinity { + b32 is_accurate; + isize core_count; + isize thread_count; + isize threads_per_core; +} gbAffinity; #else #error TODO(bill): Unknown system #endif @@ -3355,6 +3372,8 @@ gb_inline u32 gb_thread_current_id(void) { __asm__("mov %%gs:0x08,%0" : "=r"(thread_id)); #elif defined(GB_ARCH_64_BIT) && defined(GB_CPU_X86) __asm__("mov %%fs:0x10,%0" : "=r"(thread_id)); +#elif defined(GB_SYSTEM_LINUX) + thread_id = gettid(); #else #error Unsupported architecture for gb_thread_current_id() #endif @@ -3676,6 +3695,30 @@ b32 gb_affinity_set(gbAffinity *a, isize core, isize thread_index) { return true; } +isize gb_affinity_thread_count_for_core(gbAffinity *a, isize core) { + GB_ASSERT(0 <= core && core < a->core_count); + return a->threads_per_core; +} + +#elif defined(GB_SYSTEM_OPENBSD) +#include + +void gb_affinity_init(gbAffinity *a) { + a->core_count = sysconf(_SC_NPROCESSORS_ONLN); + a->threads_per_core = 1; + a->is_accurate = a->core_count > 0; + a->core_count = a->is_accurate ? a->core_count : 1; + a->thread_count = a->core_count; +} + +void gb_affinity_destroy(gbAffinity *a) { + gb_unused(a); +} + +b32 gb_affinity_set(gbAffinity *a, isize core, isize thread_index) { + return true; +} + isize gb_affinity_thread_count_for_core(gbAffinity *a, isize core) { GB_ASSERT(0 <= core && core < a->core_count); return a->threads_per_core; @@ -6023,7 +6066,7 @@ gbFileTime gb_file_last_write_time(char const *filepath) { gb_inline b32 gb_file_copy(char const *existing_filename, char const *new_filename, b32 fail_if_exists) { #if defined(GB_SYSTEM_OSX) return copyfile(existing_filename, new_filename, NULL, COPYFILE_DATA) == 0; -#else +#elif defined(GB_SYSTEM_LINUX) || defined(GB_SYSTEM_FREEBSD) isize size; int existing_fd = open(existing_filename, O_RDONLY, 0); int new_fd = open(new_filename, O_WRONLY|O_CREAT, 0666); @@ -6039,6 +6082,49 @@ gb_inline b32 gb_file_copy(char const *existing_filename, char const *new_filena close(new_fd); close(existing_fd); + return size == stat_existing.st_size; +#else + int new_flags = O_WRONLY | O_CREAT; + if (fail_if_exists) { + new_flags |= O_EXCL; + } + int existing_fd = open(existing_filename, O_RDONLY, 0); + int new_fd = open(new_filename, new_flags, 0666); + + struct stat stat_existing; + if (fstat(existing_fd, &stat_existing) == -1) { + return 0; + } + + size_t bsize = stat_existing.st_blksize > BUFSIZ ? stat_existing.st_blksize : BUFSIZ; + char *buf = (char *)malloc(bsize); + if (buf == NULL) { + close(new_fd); + close(existing_fd); + return 0; + } + + isize size = 0; + ssize_t nread, nwrite, offset; + while ((nread = read(existing_fd, buf, bsize)) != -1 && nread != 0) { + for (offset = 0; nread; nread -= nwrite, offset += nwrite) { + if ((nwrite = write(new_fd, buf + offset, nread)) == -1 || nwrite == 0) { + free(buf); + close(new_fd); + close(existing_fd); + return 0; + } + size += nwrite; + } + } + + free(buf); + close(new_fd); + close(existing_fd); + + if (nread == -1) { + return 0; + } return size == stat_existing.st_size; #endif } @@ -6091,6 +6177,7 @@ gbFileContents gb_file_read_contents(gbAllocator a, b32 zero_terminate, char con } void gb_file_free_contents(gbFileContents *fc) { + if (fc == NULL || fc->size == 0) return; GB_ASSERT_NOT_NULL(fc->data); gb_free(fc->allocator, fc->data); fc->data = NULL; @@ -6186,20 +6273,44 @@ char *gb_path_get_full_name(gbAllocator a, char const *path) { #else char *p, *result, *fullpath = NULL; isize len; - p = realpath(path, NULL); - fullpath = p; - if (p == NULL) { - // NOTE(bill): File does not exist - fullpath = cast(char *)path; + fullpath = realpath(path, NULL); + + if (fullpath == NULL) { + // NOTE(Jeroen): Path doesn't exist. + if (gb_strlen(path) > 0 && path[0] == '/') { + // But it is an absolute path, so return as-is. + + fullpath = (char *)path; + len = gb_strlen(fullpath) + 1; + result = gb_alloc_array(a, char, len + 1); + + gb_memmove(result, fullpath, len); + result[len] = 0; + + } else { + // Appears to be a relative path, so construct an absolute one relative to . + char cwd[4096]; + getcwd(&cwd[0], 4096); + + isize path_len = gb_strlen(path); + isize cwd_len = gb_strlen(cwd); + len = cwd_len + 1 + path_len + 1; + result = gb_alloc_array(a, char, len); + + gb_memmove(result, (void *)cwd, cwd_len); + result[cwd_len] = '/'; + + gb_memmove(result + cwd_len + 1, (void *)path, gb_strlen(path)); + result[len] = 0; + + } + } else { + len = gb_strlen(fullpath) + 1; + result = gb_alloc_array(a, char, len + 1); + gb_memmove(result, fullpath, len); + result[len] = 0; + free(fullpath); } - - len = gb_strlen(fullpath); - - result = gb_alloc_array(a, char, len + 1); - gb_memmove(result, fullpath, len); - result[len] = 0; - free(p); - return result; #endif } diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index e18dc344b..07d2dd6e3 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -965,6 +965,10 @@ namespace lbAbiArm64 { } return false; } + + unsigned is_homogenous_aggregate_small_enough(LLVMTypeRef *base_type_, unsigned member_count_) { + return (member_count_ <= 4); + } lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef type, bool return_is_defined) { LLVMTypeRef homo_base_type = {}; @@ -975,22 +979,31 @@ namespace lbAbiArm64 { } else if (is_register(type)) { return non_struct(c, type); } else if (is_homogenous_aggregate(c, type, &homo_base_type, &homo_member_count)) { - return lb_arg_type_direct(type, LLVMArrayType(homo_base_type, homo_member_count), nullptr, nullptr); + if(is_homogenous_aggregate_small_enough(&homo_base_type, homo_member_count)) { + return lb_arg_type_direct(type, LLVMArrayType(homo_base_type, homo_member_count), nullptr, nullptr); + } else { + //TODO(Platin): do i need to create stuff that can handle the diffrent return type? + // else this needs a fix in llvm_backend_proc as we would need to cast it to the correct array type + + //LLVMTypeRef array_type = LLVMArrayType(homo_base_type, homo_member_count); + LLVMAttributeRef attr = lb_create_enum_attribute_with_type(c, "sret", type); + return lb_arg_type_indirect(type, attr); + } } else { i64 size = lb_sizeof(type); if (size <= 16) { LLVMTypeRef cast_type = nullptr; if (size <= 1) { - cast_type = LLVMIntTypeInContext(c, 8); + cast_type = LLVMInt8TypeInContext(c); } else if (size <= 2) { - cast_type = LLVMIntTypeInContext(c, 16); + cast_type = LLVMInt16TypeInContext(c); } else if (size <= 4) { - cast_type = LLVMIntTypeInContext(c, 32); + cast_type = LLVMInt32TypeInContext(c); } else if (size <= 8) { - cast_type = LLVMIntTypeInContext(c, 64); + cast_type = LLVMInt64TypeInContext(c); } else { unsigned count = cast(unsigned)((size+7)/8); - cast_type = LLVMArrayType(LLVMIntTypeInContext(c, 64), count); + cast_type = LLVMArrayType(LLVMInt64TypeInContext(c), count); } return lb_arg_type_direct(type, cast_type, nullptr, nullptr); } else { @@ -999,7 +1012,7 @@ namespace lbAbiArm64 { } } } - + Array compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count) { auto args = array_make(heap_allocator(), arg_count); @@ -1171,16 +1184,24 @@ LB_ABI_INFO(lb_get_abi_info) { ft->calling_convention = calling_convention; return ft; } + case ProcCC_Win64: + GB_ASSERT(build_context.metrics.arch == TargetArch_amd64); + return lbAbiAmd64Win64::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention); + case ProcCC_SysV: + GB_ASSERT(build_context.metrics.arch == TargetArch_amd64); + return lbAbiAmd64SysV::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention); } switch (build_context.metrics.arch) { case TargetArch_amd64: - if (build_context.metrics.os == TargetOs_windows) { + if (build_context.metrics.os == TargetOs_windows || build_context.metrics.abi == TargetABI_Win64) { return lbAbiAmd64Win64::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention); + } else if (build_context.metrics.abi == TargetABI_SysV) { + return lbAbiAmd64SysV::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention); } else { return lbAbiAmd64SysV::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention); } - case TargetArch_386: + case TargetArch_i386: return lbAbi386::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention); case TargetArch_arm64: return lbAbiArm64::abi_info(c, arg_types, arg_count, return_type, return_is_defined, calling_convention); diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 5acd2a80f..7781997f7 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -624,6 +624,9 @@ struct lbGlobalVariable { }; lbProcedure *lb_create_startup_type_info(lbModule *m) { + if (build_context.disallow_rtti) { + return nullptr; + } LLVMPassManagerRef default_function_pass_manager = LLVMCreateFunctionPassManagerForModule(m->mod); lb_populate_function_pass_manager(m, default_function_pass_manager, false, build_context.optimization_level); LLVMFinalizeFunctionPassManager(default_function_pass_manager); @@ -652,7 +655,54 @@ lbProcedure *lb_create_startup_type_info(lbModule *m) { return p; } -lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProcedure *startup_type_info, Array &global_variables) { // Startup Runtime +lbProcedure *lb_create_objc_names(lbModule *main_module) { + if (build_context.metrics.os != TargetOs_darwin) { + return nullptr; + } + Type *proc_type = alloc_type_proc(nullptr, nullptr, 0, nullptr, 0, false, ProcCC_CDecl); + lbProcedure *p = lb_create_dummy_procedure(main_module, str_lit("__$init_objc_names"), proc_type); + p->is_startup = true; + return p; +} + +void lb_finalize_objc_names(lbProcedure *p) { + if (p == nullptr) { + return; + } + lbModule *m = p->module; + + LLVMPassManagerRef default_function_pass_manager = LLVMCreateFunctionPassManagerForModule(m->mod); + lb_populate_function_pass_manager(m, default_function_pass_manager, false, build_context.optimization_level); + LLVMFinalizeFunctionPassManager(default_function_pass_manager); + + + auto args = array_make(permanent_allocator(), 1); + + LLVMSetLinkage(p->value, LLVMInternalLinkage); + lb_begin_procedure_body(p); + for_array(i, m->objc_classes.entries) { + auto const &entry = m->objc_classes.entries[i]; + String name = entry.key.string; + args[0] = lb_const_value(m, t_cstring, exact_value_string(name)); + lbValue ptr = lb_emit_runtime_call(p, "objc_lookUpClass", args); + lb_addr_store(p, entry.value, ptr); + } + + for_array(i, m->objc_selectors.entries) { + auto const &entry = m->objc_selectors.entries[i]; + String name = entry.key.string; + args[0] = lb_const_value(m, t_cstring, exact_value_string(name)); + lbValue ptr = lb_emit_runtime_call(p, "sel_registerName", args); + lb_addr_store(p, entry.value, ptr); + } + + lb_end_procedure_body(p); + + lb_run_function_pass_manager(default_function_pass_manager, p); + +} + +lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProcedure *startup_type_info, lbProcedure *objc_names, Array &global_variables) { // Startup Runtime LLVMPassManagerRef default_function_pass_manager = LLVMCreateFunctionPassManagerForModule(main_module->mod); lb_populate_function_pass_manager(main_module, default_function_pass_manager, false, build_context.optimization_level); LLVMFinalizeFunctionPassManager(default_function_pass_manager); @@ -664,7 +714,13 @@ lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProcedure *start lb_begin_procedure_body(p); - LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(main_module, startup_type_info->type)), startup_type_info->value, nullptr, 0, ""); + if (startup_type_info) { + LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(main_module, startup_type_info->type)), startup_type_info->value, nullptr, 0, ""); + } + + if (objc_names) { + LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(main_module, objc_names->type)), objc_names->value, nullptr, 0, ""); + } for_array(i, global_variables) { auto *var = &global_variables[i]; @@ -783,7 +839,7 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime) params->Tuple.variables[1] = alloc_entity_param(nullptr, make_token_ident("fdwReason"), t_u32, false, true); params->Tuple.variables[2] = alloc_entity_param(nullptr, make_token_ident("lpReserved"), t_rawptr, false, true); call_cleanup = false; - } else if (build_context.metrics.os == TargetOs_windows && (build_context.metrics.arch == TargetArch_386 || build_context.no_crt)) { + } else if (build_context.metrics.os == TargetOs_windows && (build_context.metrics.arch == TargetArch_i386 || build_context.no_crt)) { name = str_lit("mainCRTStartup"); } else if (is_arch_wasm()) { name = str_lit("_start"); @@ -873,7 +929,7 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime) } else { if (m->info->entry_point != nullptr) { lbValue entry_point = lb_find_procedure_value_from_entity(m, m->info->entry_point); - lb_emit_call(p, entry_point, {}); + lb_emit_call(p, entry_point, {}, ProcInlining_no_inline); } } @@ -911,7 +967,12 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime) } String lb_filepath_ll_for_module(lbModule *m) { - String path = m->gen->output_base; + String path = concatenate3_strings(permanent_allocator(), + build_context.build_paths[BuildPath_Output].basename, + STR_LIT("/"), + build_context.build_paths[BuildPath_Output].name + ); + if (m->pkg) { path = concatenate3_strings(permanent_allocator(), path, STR_LIT("-"), m->pkg->name); } else if (USE_SEPARATE_MODULES) { @@ -922,7 +983,12 @@ String lb_filepath_ll_for_module(lbModule *m) { return path; } String lb_filepath_obj_for_module(lbModule *m) { - String path = m->gen->output_base; + String path = concatenate3_strings(permanent_allocator(), + build_context.build_paths[BuildPath_Output].basename, + STR_LIT("/"), + build_context.build_paths[BuildPath_Output].name + ); + if (m->pkg) { path = concatenate3_strings(permanent_allocator(), path, STR_LIT("-"), m->pkg->name); } @@ -945,6 +1011,19 @@ String lb_filepath_obj_for_module(lbModule *m) { case TargetOs_essence: ext = STR_LIT(".o"); break; + + case TargetOs_freestanding: + switch (build_context.metrics.abi) { + default: + case TargetABI_Default: + case TargetABI_SysV: + ext = STR_LIT(".o"); + break; + case TargetABI_Win64: + ext = STR_LIT(".obj"); + break; + } + break; } } } @@ -1140,7 +1219,7 @@ void lb_generate_code(lbGenerator *gen) { switch (build_context.metrics.arch) { case TargetArch_amd64: - case TargetArch_386: + case TargetArch_i386: LLVMInitializeX86TargetInfo(); LLVMInitializeX86Target(); LLVMInitializeX86TargetMC(); @@ -1197,6 +1276,8 @@ void lb_generate_code(lbGenerator *gen) { LLVMCodeModel code_mode = LLVMCodeModelDefault; if (is_arch_wasm()) { code_mode = LLVMCodeModelJITDefault; + } else if (build_context.metrics.os == TargetOs_freestanding) { + code_mode = LLVMCodeModelKernel; } char const *host_cpu_name = LLVMGetHostCPUName(); @@ -1219,10 +1300,18 @@ void lb_generate_code(lbGenerator *gen) { // x86-64-v3: (close to Haswell) AVX, AVX2, BMI1, BMI2, F16C, FMA, LZCNT, MOVBE, XSAVE // x86-64-v4: AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL if (ODIN_LLVM_MINIMUM_VERSION_12) { - llvm_cpu = "x86-64-v2"; + if (build_context.metrics.os == TargetOs_freestanding) { + llvm_cpu = "x86-64"; + } else { + llvm_cpu = "x86-64-v2"; + } } } + if (build_context.target_features.len != 0) { + llvm_features = alloc_cstring(permanent_allocator(), build_context.target_features); + } + // GB_ASSERT_MSG(LLVMTargetHasAsmBackend(target)); LLVMCodeGenOptLevel code_gen_level = LLVMCodeGenLevelNone; @@ -1238,12 +1327,36 @@ void lb_generate_code(lbGenerator *gen) { // NOTE(bill, 2021-05-04): Target machines must be unique to each module because they are not thread safe auto target_machines = array_make(permanent_allocator(), gen->modules.entries.count); + // NOTE(dweiler): Dynamic libraries require position-independent code. + LLVMRelocMode reloc_mode = LLVMRelocDefault; + if (build_context.build_mode == BuildMode_DynamicLibrary) { + reloc_mode = LLVMRelocPIC; + } + + switch (build_context.reloc_mode) { + case RelocMode_Default: + if (build_context.metrics.os == TargetOs_openbsd) { + // Always use PIC for OpenBSD: it defaults to PIE + reloc_mode = LLVMRelocPIC; + } + break; + case RelocMode_Static: + reloc_mode = LLVMRelocStatic; + break; + case RelocMode_PIC: + reloc_mode = LLVMRelocPIC; + break; + case RelocMode_DynamicNoPIC: + reloc_mode = LLVMRelocDynamicNoPic; + break; + } + for_array(i, gen->modules.entries) { target_machines[i] = LLVMCreateTargetMachine( target, target_triple, llvm_cpu, llvm_features, code_gen_level, - LLVMRelocDefault, + reloc_mode, code_mode); LLVMSetModuleDataLayout(gen->modules.entries[i].value->mod, LLVMCreateTargetDataLayout(target_machines[i])); } @@ -1304,7 +1417,7 @@ void lb_generate_code(lbGenerator *gen) { TIME_SECTION("LLVM Global Variables"); - { + if (!build_context.disallow_rtti) { lbModule *m = default_module; { // Add type info data @@ -1399,30 +1512,30 @@ void lb_generate_code(lbGenerator *gen) { isize global_variable_max_count = 0; - Entity *entry_point = info->entry_point; - bool has_dll_main = false; - bool has_win_main = false; + bool already_has_entry_point = false; for_array(i, info->entities) { Entity *e = info->entities[i]; String name = e->token.string; - bool is_global = e->pkg != nullptr; - if (e->kind == Entity_Variable) { global_variable_max_count++; - } else if (e->kind == Entity_Procedure && !is_global) { + } else if (e->kind == Entity_Procedure) { if ((e->scope->flags&ScopeFlag_Init) && name == "main") { - GB_ASSERT(e == entry_point); - // entry_point = e; + GB_ASSERT(e == info->entry_point); } - if (e->Procedure.is_export || - (e->Procedure.link_name.len > 0) || - ((e->scope->flags&ScopeFlag_File) && e->Procedure.link_name.len > 0)) { - if (!has_dll_main && name == "DllMain") { - has_dll_main = true; - } else if (!has_win_main && name == "WinMain") { - has_win_main = true; + if (build_context.command_kind == Command_test && + (e->Procedure.is_export || e->Procedure.link_name.len > 0)) { + String link_name = e->Procedure.link_name; + if (e->pkg->kind == Package_Runtime) { + if (link_name == "main" || + link_name == "DllMain" || + link_name == "WinMain" || + link_name == "wWinMain" || + link_name == "mainCRTStartup" || + link_name == "_start") { + already_has_entry_point = true; + } } } } @@ -1560,6 +1673,14 @@ void lb_generate_code(lbGenerator *gen) { } } + TIME_SECTION("LLVM Runtime Type Information Creation"); + lbProcedure *startup_type_info = lb_create_startup_type_info(default_module); + + lbProcedure *objc_names = lb_create_objc_names(default_module); + + TIME_SECTION("LLVM Runtime Startup Creation (Global Variables)"); + lbProcedure *startup_runtime = lb_create_startup_runtime(default_module, startup_type_info, objc_names, global_variables); + gb_unused(startup_runtime); TIME_SECTION("LLVM Global Procedures and Types"); for_array(i, info->entities) { @@ -1619,14 +1740,6 @@ void lb_generate_code(lbGenerator *gen) { } } - - TIME_SECTION("LLVM Runtime Type Information Creation"); - lbProcedure *startup_type_info = lb_create_startup_type_info(default_module); - - TIME_SECTION("LLVM Runtime Startup Creation (Global Variables)"); - lbProcedure *startup_runtime = lb_create_startup_runtime(default_module, startup_type_info, global_variables); - - TIME_SECTION("LLVM Procedure Generation"); for_array(j, gen->modules.entries) { lbModule *m = gen->modules.entries[j].value; @@ -1636,8 +1749,7 @@ void lb_generate_code(lbGenerator *gen) { } } - - if (!(build_context.build_mode == BuildMode_DynamicLibrary && !has_dll_main)) { + if (build_context.command_kind == Command_test && !already_has_entry_point) { TIME_SECTION("LLVM main"); lb_create_main_procedure(default_module, startup_runtime); } @@ -1651,6 +1763,8 @@ void lb_generate_code(lbGenerator *gen) { } } + lb_finalize_objc_names(objc_names); + if (build_context.ODIN_DEBUG) { TIME_SECTION("LLVM Debug Info Complete Types and Finalize"); for_array(j, gen->modules.entries) { @@ -1663,6 +1777,7 @@ void lb_generate_code(lbGenerator *gen) { } + TIME_SECTION("LLVM Function Pass"); for_array(i, gen->modules.entries) { lbModule *m = gen->modules.entries[i].value; diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index e70b1f84c..f2bcfaff6 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -144,6 +144,9 @@ struct lbModule { PtrMap debug_values; Array debug_incomplete_types; + + StringMap objc_classes; + StringMap objc_selectors; }; struct lbGenerator { @@ -204,7 +207,6 @@ enum lbDeferExitKind { enum lbDeferKind { lbDefer_Node, - lbDefer_Instr, lbDefer_Proc, }; @@ -215,8 +217,6 @@ struct lbDefer { lbBlock * block; union { Ast *stmt; - // NOTE(bill): 'instr' will be copied every time to create a new one - lbValue instr; struct { lbValue deferred; Array result_as_args; @@ -235,6 +235,7 @@ struct lbTargetList { enum lbProcedureFlag : u32 { lbProcedureFlag_WithoutMemcpyPass = 1<<0, + lbProcedureFlag_DebugAllocaCopy = 1<<1, }; struct lbCopyElisionHint { @@ -270,7 +271,6 @@ struct lbProcedure { bool is_done; lbAddr return_ptr; - Array params; Array defer_stmts; Array blocks; Array branch_blocks; @@ -296,7 +296,6 @@ struct lbProcedure { bool lb_init_generator(lbGenerator *gen, Checker *c); -void lb_generate_module(lbGenerator *gen); String lb_mangle_name(lbModule *m, Entity *e); String lb_get_entity_name(lbModule *m, Entity *e, String name = {}); @@ -369,7 +368,7 @@ lbContextData *lb_push_context_onto_stack(lbProcedure *p, lbAddr ctx); lbContextData *lb_push_context_onto_stack_from_implicit_parameter(lbProcedure *p); -lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value={}); +lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value={}, Entity **entity_=nullptr); lbAddr lb_add_local(lbProcedure *p, Type *type, Entity *e=nullptr, bool zero_init=true, i32 param_index=0, bool force_no_init=false); void lb_add_foreign_library_path(lbModule *m, Entity *e); @@ -549,6 +548,10 @@ lbCallingConventionKind const lb_calling_convention_map[ProcCC_MAX] = { lbCallingConvention_C, // ProcCC_None, lbCallingConvention_C, // ProcCC_Naked, lbCallingConvention_C, // ProcCC_InlineAsm, + + lbCallingConvention_Win64, // ProcCC_Win64, + lbCallingConvention_X86_64_SysV, // ProcCC_SysV, + }; enum : LLVMDWARFTypeEncoding { diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 5862a7add..8f17a1cfb 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -115,8 +115,8 @@ LLVMValueRef llvm_const_cast(LLVMValueRef val, LLVMTypeRef dst) { lbValue lb_const_ptr_cast(lbModule *m, lbValue value, Type *t) { - GB_ASSERT(is_type_pointer(value.type)); - GB_ASSERT(is_type_pointer(t)); + GB_ASSERT(is_type_internally_pointer_like(value.type)); + GB_ASSERT(is_type_internally_pointer_like(t)); GB_ASSERT(lb_is_const(value)); lbValue res = {}; @@ -175,7 +175,7 @@ LLVMValueRef llvm_const_array(LLVMTypeRef elem_type, LLVMValueRef *values, isize } LLVMValueRef llvm_const_slice(lbModule *m, lbValue data, lbValue len) { - GB_ASSERT(is_type_pointer(data.type)); + GB_ASSERT(is_type_pointer(data.type) || is_type_multi_pointer(data.type)); GB_ASSERT(are_types_identical(len.type, t_int)); LLVMValueRef vals[2] = { data.value, @@ -568,7 +568,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc } case ExactValue_Integer: - if (is_type_pointer(type)) { + if (is_type_pointer(type) || is_type_multi_pointer(type)) { LLVMTypeRef t = lb_type(m, original_type); LLVMValueRef i = lb_big_int_to_llvm(m, t_uintptr, &value.value_integer); res.value = LLVMConstIntToPtr(i, t); diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index 7a2b00fe9..b91f32bfc 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -958,13 +958,79 @@ void lb_add_debug_local_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, T ); LLVMValueRef storage = ptr; - LLVMValueRef instr = ptr; + LLVMBasicBlockRef block = p->decl_block->block; LLVMMetadataRef llvm_debug_loc = lb_debug_location_from_token_pos(p, token.pos); LLVMMetadataRef llvm_expr = LLVMDIBuilderCreateExpression(m->debug_builder, nullptr, 0); lb_set_llvm_metadata(m, ptr, llvm_expr); - LLVMDIBuilderInsertDeclareBefore(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, instr); + LLVMDIBuilderInsertDeclareAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block); } + +void lb_add_debug_param_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token, unsigned arg_number, lbBlock *block) { + if (p->debug_info == nullptr) { + return; + } + if (type == nullptr) { + return; + } + if (type == t_invalid) { + return; + } + if (p->body == nullptr) { + return; + } + + lbModule *m = p->module; + String const &name = token.string; + if (name == "" || name == "_") { + return; + } + + if (lb_get_llvm_metadata(m, ptr) != nullptr) { + // Already been set + return; + } + + + AstFile *file = p->body->file(); + + LLVMMetadataRef llvm_scope = lb_get_current_debug_scope(p); + LLVMMetadataRef llvm_file = lb_get_llvm_metadata(m, file); + GB_ASSERT(llvm_scope != nullptr); + if (llvm_file == nullptr) { + llvm_file = LLVMDIScopeGetFile(llvm_scope); + } + + if (llvm_file == nullptr) { + return; + } + + LLVMDIFlags flags = LLVMDIFlagZero; + LLVMBool always_preserve = build_context.optimization_level == 0; + + LLVMMetadataRef debug_type = lb_debug_type(m, type); + + LLVMMetadataRef var_info = LLVMDIBuilderCreateParameterVariable( + m->debug_builder, llvm_scope, + cast(char const *)name.text, cast(size_t)name.len, + arg_number, + llvm_file, token.pos.line, + debug_type, + always_preserve, flags + ); + + LLVMValueRef storage = ptr; + LLVMMetadataRef llvm_debug_loc = lb_debug_location_from_token_pos(p, token.pos); + LLVMMetadataRef llvm_expr = LLVMDIBuilderCreateExpression(m->debug_builder, nullptr, 0); + lb_set_llvm_metadata(m, ptr, llvm_expr); + + // NOTE(bill, 2022-02-01): For parameter values, you must insert them at the end of the decl block + // The reason is that if the parameter is at index 0 and a pointer, there is not such things as an + // instruction "before" it. + LLVMDIBuilderInsertDbgValueAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block->block); +} + + void lb_add_debug_context_variable(lbProcedure *p, lbAddr const &ctx) { if (!p->debug_info || !p->body) { return; @@ -984,5 +1050,10 @@ void lb_add_debug_context_variable(lbProcedure *p, lbAddr const &ctx) { token.string = str_lit("context"); token.pos = pos; - lb_add_debug_local_variable(p, ctx.addr.value, t_context, token); + LLVMValueRef ptr = ctx.addr.value; + while (LLVMIsABitCastInst(ptr)) { + ptr = LLVMGetOperand(ptr, 0); + } + + lb_add_debug_local_variable(p, ptr, t_context, token); } diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index edda3a267..133df4d41 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -508,7 +508,7 @@ bool lb_is_matrix_simdable(Type *t) { case TargetArch_arm64: // TODO(bill): determine when this is fine return true; - case TargetArch_386: + case TargetArch_i386: case TargetArch_wasm32: case TargetArch_wasm64: return false; @@ -580,6 +580,27 @@ LLVMValueRef lb_matrix_to_trimmed_vector(lbProcedure *p, lbValue m) { lbValue lb_emit_matrix_tranpose(lbProcedure *p, lbValue m, Type *type) { if (is_type_array(m.type)) { + i32 rank = type_math_rank(m.type); + if (rank == 2) { + lbAddr addr = lb_add_local_generated(p, type, false); + lbValue dst = addr.addr; + lbValue src = m; + i32 n = cast(i32)get_array_type_count(m.type); + i32 m = cast(i32)get_array_type_count(type); + // m.type == [n][m]T + // type == [m][n]T + + for (i32 j = 0; j < m; j++) { + lbValue dst_col = lb_emit_struct_ep(p, dst, j); + for (i32 i = 0; i < n; i++) { + lbValue dst_row = lb_emit_struct_ep(p, dst_col, i); + lbValue src_col = lb_emit_struct_ev(p, src, i); + lbValue src_row = lb_emit_struct_ev(p, src_col, j); + lb_emit_store(p, dst_row, src_row); + } + } + return lb_addr_load(p, addr); + } // no-op m.type = type; return m; @@ -1655,26 +1676,10 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { return res; } - if (is_type_float(src) && is_type_complex(dst)) { - Type *ft = base_complex_elem_type(dst); - lbAddr gen = lb_add_local_generated(p, dst, false); - lbValue gp = lb_addr_get_ptr(p, gen); - lbValue real = lb_emit_conv(p, value, ft); - lb_emit_store(p, lb_emit_struct_ep(p, gp, 0), real); - return lb_addr_load(p, gen); - } - if (is_type_float(src) && is_type_quaternion(dst)) { - Type *ft = base_complex_elem_type(dst); - lbAddr gen = lb_add_local_generated(p, dst, false); - lbValue gp = lb_addr_get_ptr(p, gen); - lbValue real = lb_emit_conv(p, value, ft); - lb_emit_store(p, lb_emit_struct_ep(p, gp, 0), real); - return lb_addr_load(p, gen); - } if (is_type_complex(src) && is_type_complex(dst)) { Type *ft = base_complex_elem_type(dst); - lbAddr gen = lb_add_local_generated(p, dst, false); + lbAddr gen = lb_add_local_generated(p, t, false); lbValue gp = lb_addr_get_ptr(p, gen); lbValue real = lb_emit_conv(p, lb_emit_struct_ev(p, value, 0), ft); lbValue imag = lb_emit_conv(p, lb_emit_struct_ev(p, value, 1), ft); @@ -1686,7 +1691,7 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { if (is_type_quaternion(src) && is_type_quaternion(dst)) { // @QuaternionLayout Type *ft = base_complex_elem_type(dst); - lbAddr gen = lb_add_local_generated(p, dst, false); + lbAddr gen = lb_add_local_generated(p, t, false); lbValue gp = lb_addr_get_ptr(p, gen); lbValue q0 = lb_emit_conv(p, lb_emit_struct_ev(p, value, 0), ft); lbValue q1 = lb_emit_conv(p, lb_emit_struct_ev(p, value, 1), ft); @@ -1701,7 +1706,7 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { if (is_type_integer(src) && is_type_complex(dst)) { Type *ft = base_complex_elem_type(dst); - lbAddr gen = lb_add_local_generated(p, dst, true); + lbAddr gen = lb_add_local_generated(p, t, true); lbValue gp = lb_addr_get_ptr(p, gen); lbValue real = lb_emit_conv(p, value, ft); lb_emit_store(p, lb_emit_struct_ep(p, gp, 0), real); @@ -1709,7 +1714,7 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { } if (is_type_float(src) && is_type_complex(dst)) { Type *ft = base_complex_elem_type(dst); - lbAddr gen = lb_add_local_generated(p, dst, true); + lbAddr gen = lb_add_local_generated(p, t, true); lbValue gp = lb_addr_get_ptr(p, gen); lbValue real = lb_emit_conv(p, value, ft); lb_emit_store(p, lb_emit_struct_ep(p, gp, 0), real); @@ -1719,7 +1724,7 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { if (is_type_integer(src) && is_type_quaternion(dst)) { Type *ft = base_complex_elem_type(dst); - lbAddr gen = lb_add_local_generated(p, dst, true); + lbAddr gen = lb_add_local_generated(p, t, true); lbValue gp = lb_addr_get_ptr(p, gen); lbValue real = lb_emit_conv(p, value, ft); // @QuaternionLayout @@ -1728,7 +1733,7 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { } if (is_type_float(src) && is_type_quaternion(dst)) { Type *ft = base_complex_elem_type(dst); - lbAddr gen = lb_add_local_generated(p, dst, true); + lbAddr gen = lb_add_local_generated(p, t, true); lbValue gp = lb_addr_get_ptr(p, gen); lbValue real = lb_emit_conv(p, value, ft); // @QuaternionLayout @@ -1737,7 +1742,7 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { } if (is_type_complex(src) && is_type_quaternion(dst)) { Type *ft = base_complex_elem_type(dst); - lbAddr gen = lb_add_local_generated(p, dst, true); + lbAddr gen = lb_add_local_generated(p, t, true); lbValue gp = lb_addr_get_ptr(p, gen); lbValue real = lb_emit_conv(p, lb_emit_struct_ev(p, value, 0), ft); lbValue imag = lb_emit_conv(p, lb_emit_struct_ev(p, value, 1), ft); @@ -1850,6 +1855,15 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { return lb_addr_load(p, parent); } } + if (dst->Union.variants.count == 1) { + Type *vt = dst->Union.variants[0]; + if (internal_check_is_assignable_to(src, vt)) { + value = lb_emit_conv(p, value, vt); + lbAddr parent = lb_add_local_generated(p, t, true); + lb_emit_store_union_variant(p, parent.addr, value, vt); + return lb_addr_load(p, parent); + } + } } // NOTE(bill): This has to be done before 'Pointer <-> Pointer' as it's @@ -2188,6 +2202,21 @@ lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue ri } } + if (is_type_matrix(a) && (op_kind == Token_CmpEq || op_kind == Token_NotEq)) { + Type *tl = base_type(a); + lbValue lhs = lb_address_from_load_or_generate_local(p, left); + lbValue rhs = lb_address_from_load_or_generate_local(p, right); + + + // TODO(bill): Test to see if this is actually faster!!!! + auto args = array_make(permanent_allocator(), 3); + args[0] = lb_emit_conv(p, lhs, t_rawptr); + args[1] = lb_emit_conv(p, rhs, t_rawptr); + args[2] = lb_const_int(p->module, t_int, type_size_of(tl)); + lbValue val = lb_emit_runtime_call(p, "memory_compare", args); + lbValue res = lb_emit_comp(p, op_kind, val, lb_const_nil(p->module, val.type)); + return lb_emit_conv(p, res, t_bool); + } if (is_type_array(a) || is_type_enumerated_array(a)) { Type *tl = base_type(a); lbValue lhs = lb_address_from_load_or_generate_local(p, left); @@ -2784,28 +2813,39 @@ lbValue lb_build_unary_and(lbProcedure *p, Ast *expr) { Type *src_type = type_deref(v.type); Type *dst_type = type; - lbValue src_tag = {}; - lbValue dst_tag = {}; - if (is_type_union_maybe_pointer(src_type)) { - src_tag = lb_emit_comp_against_nil(p, Token_NotEq, v); - dst_tag = lb_const_bool(p->module, t_bool, true); - } else { - src_tag = lb_emit_load(p, lb_emit_union_tag_ptr(p, v)); - dst_tag = lb_const_union_tag(p->module, src_type, dst_type); + + if ((p->state_flags & StateFlag_no_type_assert) == 0) { + lbValue src_tag = {}; + lbValue dst_tag = {}; + if (is_type_union_maybe_pointer(src_type)) { + src_tag = lb_emit_comp_against_nil(p, Token_NotEq, v); + dst_tag = lb_const_bool(p->module, t_bool, true); + } else { + src_tag = lb_emit_load(p, lb_emit_union_tag_ptr(p, v)); + dst_tag = lb_const_union_tag(p->module, src_type, dst_type); + } + + + isize arg_count = 6; + if (build_context.disallow_rtti) { + arg_count = 4; + } + + lbValue ok = lb_emit_comp(p, Token_CmpEq, src_tag, dst_tag); + auto args = array_make(permanent_allocator(), arg_count); + args[0] = ok; + + args[1] = lb_find_or_add_entity_string(p->module, get_file_path_string(pos.file_id)); + args[2] = lb_const_int(p->module, t_i32, pos.line); + args[3] = lb_const_int(p->module, t_i32, pos.column); + + if (!build_context.disallow_rtti) { + args[4] = lb_typeid(p->module, src_type); + args[5] = lb_typeid(p->module, dst_type); + } + lb_emit_runtime_call(p, "type_assertion_check", args); } - lbValue ok = lb_emit_comp(p, Token_CmpEq, src_tag, dst_tag); - auto args = array_make(permanent_allocator(), 6); - args[0] = ok; - - args[1] = lb_find_or_add_entity_string(p->module, get_file_path_string(pos.file_id)); - args[2] = lb_const_int(p->module, t_i32, pos.line); - args[3] = lb_const_int(p->module, t_i32, pos.column); - - args[4] = lb_typeid(p->module, src_type); - args[5] = lb_typeid(p->module, dst_type); - lb_emit_runtime_call(p, "type_assertion_check", args); - lbValue data_ptr = v; return lb_emit_conv(p, data_ptr, tv.type); } else if (is_type_any(t)) { @@ -2813,23 +2853,25 @@ lbValue lb_build_unary_and(lbProcedure *p, Ast *expr) { if (is_type_pointer(v.type)) { v = lb_emit_load(p, v); } - lbValue data_ptr = lb_emit_struct_ev(p, v, 0); - lbValue any_id = lb_emit_struct_ev(p, v, 1); - lbValue id = lb_typeid(p->module, type); + if ((p->state_flags & StateFlag_no_type_assert) == 0) { + GB_ASSERT(!build_context.disallow_rtti); + lbValue any_id = lb_emit_struct_ev(p, v, 1); - lbValue ok = lb_emit_comp(p, Token_CmpEq, any_id, id); - auto args = array_make(permanent_allocator(), 6); - args[0] = ok; + lbValue id = lb_typeid(p->module, type); + lbValue ok = lb_emit_comp(p, Token_CmpEq, any_id, id); + auto args = array_make(permanent_allocator(), 6); + args[0] = ok; - args[1] = lb_find_or_add_entity_string(p->module, get_file_path_string(pos.file_id)); - args[2] = lb_const_int(p->module, t_i32, pos.line); - args[3] = lb_const_int(p->module, t_i32, pos.column); + args[1] = lb_find_or_add_entity_string(p->module, get_file_path_string(pos.file_id)); + args[2] = lb_const_int(p->module, t_i32, pos.line); + args[3] = lb_const_int(p->module, t_i32, pos.column); - args[4] = any_id; - args[5] = id; - lb_emit_runtime_call(p, "type_assertion_check", args); + args[4] = any_id; + args[5] = id; + lb_emit_runtime_call(p, "type_assertion_check", args); + } return lb_emit_conv(p, data_ptr, tv.type); } else { @@ -2859,6 +2901,14 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { out &= ~StateFlag_bounds_check; } + if (in & StateFlag_type_assert) { + out |= StateFlag_type_assert; + out &= ~StateFlag_no_type_assert; + } else if (in & StateFlag_no_type_assert) { + out |= StateFlag_no_type_assert; + out &= ~StateFlag_type_assert; + } + p->state_flags = out; } @@ -2978,7 +3028,7 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { lbBlock *done = lb_create_block(p, "if.done"); // NOTE(bill): Append later lbBlock *else_ = lb_create_block(p, "if.else"); - lbValue cond = lb_build_cond(p, te->cond, then, else_); + lb_build_cond(p, te->cond, then, else_); lb_start_block(p, then); Type *type = default_type(type_of_expr(expr)); @@ -3279,9 +3329,9 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { case_end; case_ast_node(se, SelectorExpr, expr); - Ast *sel = unparen_expr(se->selector); - if (sel->kind == Ast_Ident) { - String selector = sel->Ident.token.string; + Ast *sel_node = unparen_expr(se->selector); + if (sel_node->kind == Ast_Ident) { + String selector = sel_node->Ident.token.string; TypeAndValue tav = type_and_value_of_expr(se->expr); if (tav.mode == Addressing_Invalid) { @@ -3296,7 +3346,12 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { Type *type = base_type(tav.type); if (tav.mode == Addressing_Type) { // Addressing_Type - GB_PANIC("Unreachable"); + Selection sel = lookup_field(tav.type, selector, true); + if (sel.pseudo_field) { + GB_ASSERT(sel.entity->kind == Entity_Procedure); + return lb_addr(lb_find_value_from_entity(p->module, sel.entity)); + } + GB_PANIC("Unreachable %.*s", LIT(selector)); } if (se->swizzle_count > 0) { @@ -3323,6 +3378,11 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { Selection sel = lookup_field(type, selector, false); GB_ASSERT(sel.entity != nullptr); + if (sel.pseudo_field) { + GB_ASSERT(sel.entity->kind == Entity_Procedure); + Entity *e = entity_of_node(sel_node); + return lb_addr(lb_find_value_from_entity(p->module, e)); + } { lbAddr addr = lb_build_addr(p, se->expr); @@ -3476,7 +3536,8 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { GB_ASSERT_MSG(is_type_indexable(t), "%s %s", type_to_string(t), expr_to_string(expr)); if (is_type_map(t)) { - lbValue map_val = lb_build_addr_ptr(p, ie->expr); + lbAddr map_addr = lb_build_addr(p, ie->expr); + lbValue map_val = lb_addr_load(p, map_addr); if (deref) { map_val = lb_emit_load(p, map_val); } @@ -3485,7 +3546,8 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { key = lb_emit_conv(p, key, t->Map.key); Type *result_type = type_of_expr(expr); - return lb_addr_map(map_val, key, t, result_type); + lbValue map_ptr = lb_address_from_load_or_generate_local(p, map_val); + return lb_addr_map(map_ptr, key, t, result_type); } switch (t->kind) { @@ -4584,7 +4646,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) { lbBlock *done = lb_create_block(p, "if.done"); // NOTE(bill): Append later lbBlock *else_ = lb_create_block(p, "if.else"); - lbValue cond = lb_build_cond(p, te->cond, then, else_); + lb_build_cond(p, te->cond, then, else_); lb_start_block(p, then); Type *ptr_type = alloc_type_pointer(default_type(type_of_expr(expr))); diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 17eeb0bea..1a431a4ac 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -72,6 +72,9 @@ void lb_init_module(lbModule *m, Checker *c) { map_init(&m->debug_values, a); array_init(&m->debug_incomplete_types, a, 0, 1024); + + string_map_init(&m->objc_classes, a); + string_map_init(&m->objc_selectors, a); } bool lb_init_generator(lbGenerator *gen, Checker *c) { @@ -84,7 +87,6 @@ bool lb_init_generator(lbGenerator *gen, Checker *c) { return false; } - String init_fullpath = c->parser->init_fullpath; if (build_context.out_filepath.len == 0) { @@ -271,6 +273,10 @@ lbAddr lb_addr(lbValue addr) { lbAddr lb_addr_map(lbValue addr, lbValue map_key, Type *map_type, Type *map_result) { + GB_ASSERT(is_type_pointer(addr.type)); + Type *mt = type_deref(addr.type); + GB_ASSERT(is_type_map(mt)); + lbAddr v = {lbAddr_Map, addr}; v.map.key = map_key; v.map.type = map_type; @@ -1169,10 +1175,35 @@ void lb_emit_store_union_variant_tag(lbProcedure *p, lbValue parent, Type *varia } void lb_emit_store_union_variant(lbProcedure *p, lbValue parent, lbValue variant, Type *variant_type) { - lbValue underlying = lb_emit_conv(p, parent, alloc_type_pointer(variant_type)); + Type *pt = base_type(type_deref(parent.type)); + GB_ASSERT(pt->kind == Type_Union); + if (pt->Union.kind == UnionType_shared_nil) { + lbBlock *if_nil = lb_create_block(p, "shared_nil.if_nil"); + lbBlock *if_not_nil = lb_create_block(p, "shared_nil.if_not_nil"); + lbBlock *done = lb_create_block(p, "shared_nil.done"); - lb_emit_store(p, underlying, variant); - lb_emit_store_union_variant_tag(p, parent, variant_type); + lbValue cond_is_nil = lb_emit_comp_against_nil(p, Token_CmpEq, variant); + lb_emit_if(p, cond_is_nil, if_nil, if_not_nil); + + lb_start_block(p, if_nil); + lb_emit_store(p, parent, lb_const_nil(p->module, type_deref(parent.type))); + lb_emit_jump(p, done); + + lb_start_block(p, if_not_nil); + lbValue underlying = lb_emit_conv(p, parent, alloc_type_pointer(variant_type)); + lb_emit_store(p, underlying, variant); + lb_emit_store_union_variant_tag(p, parent, variant_type); + lb_emit_jump(p, done); + + lb_start_block(p, done); + + + } else { + lbValue underlying = lb_emit_conv(p, parent, alloc_type_pointer(variant_type)); + + lb_emit_store(p, underlying, variant); + lb_emit_store_union_variant_tag(p, parent, variant_type); + } } @@ -1598,8 +1629,9 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { return llvm_type; } llvm_type = LLVMStructCreateNamed(ctx, name); + LLVMTypeRef found_val = *found; map_set(&m->types, type, llvm_type); - lb_clone_struct_type(llvm_type, *found); + lb_clone_struct_type(llvm_type, found_val); return llvm_type; } } @@ -2304,7 +2336,7 @@ LLVMValueRef lb_find_or_add_entity_string_ptr(lbModule *m, String const &str) { LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(data), name); LLVMSetInitializer(global_data, data); - LLVMSetLinkage(global_data, LLVMInternalLinkage); + LLVMSetLinkage(global_data, LLVMPrivateLinkage); LLVMValueRef ptr = LLVMConstInBoundsGEP(global_data, indices, 2); string_map_set(&m->const_strings, key, ptr); @@ -2346,7 +2378,7 @@ lbValue lb_find_or_add_entity_string_byte_slice(lbModule *m, String const &str) } LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(data), name); LLVMSetInitializer(global_data, data); - LLVMSetLinkage(global_data, LLVMInternalLinkage); + LLVMSetLinkage(global_data, LLVMPrivateLinkage); LLVMValueRef ptr = nullptr; if (str.len != 0) { @@ -2445,7 +2477,7 @@ lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e) { return {}; } -lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value) { +lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value, Entity **entity_) { GB_ASSERT(type != nullptr); type = default_type(type); @@ -2471,6 +2503,9 @@ lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value) { lb_add_entity(m, e, g); lb_add_member(m, name, g); + + if (entity_) *entity_ = e; + return lb_addr(g); } @@ -2579,7 +2614,7 @@ lbValue lb_generate_global_array(lbModule *m, Type *elem_type, i64 count, String g.value = LLVMAddGlobal(m->mod, lb_type(m, t), text); g.type = alloc_type_pointer(t); LLVMSetInitializer(g.value, LLVMConstNull(lb_type(m, t))); - LLVMSetLinkage(g.value, LLVMInternalLinkage); + LLVMSetLinkage(g.value, LLVMPrivateLinkage); string_map_set(&m->members, s, g); return g; } @@ -2591,6 +2626,9 @@ lbValue lb_build_cond(lbProcedure *p, Ast *cond, lbBlock *true_block, lbBlock *f GB_ASSERT(true_block != nullptr); GB_ASSERT(false_block != nullptr); + // Use to signal not to do compile time short circuit for consts + lbValue no_comptime_short_circuit = {}; + switch (cond->kind) { case_ast_node(pe, ParenExpr, cond); return lb_build_cond(p, pe->expr, true_block, false_block); @@ -2598,7 +2636,11 @@ lbValue lb_build_cond(lbProcedure *p, Ast *cond, lbBlock *true_block, lbBlock *f case_ast_node(ue, UnaryExpr, cond); if (ue->op.kind == Token_Not) { - return lb_build_cond(p, ue->expr, false_block, true_block); + lbValue cond_val = lb_build_cond(p, ue->expr, false_block, true_block); + if (cond_val.value && LLVMIsConstant(cond_val.value)) { + return lb_const_bool(p->module, cond_val.type, LLVMConstIntGetZExtValue(cond_val.value) == 0); + } + return no_comptime_short_circuit; } case_end; @@ -2607,12 +2649,14 @@ lbValue lb_build_cond(lbProcedure *p, Ast *cond, lbBlock *true_block, lbBlock *f lbBlock *block = lb_create_block(p, "cmp.and"); lb_build_cond(p, be->left, block, false_block); lb_start_block(p, block); - return lb_build_cond(p, be->right, true_block, false_block); + lb_build_cond(p, be->right, true_block, false_block); + return no_comptime_short_circuit; } else if (be->op.kind == Token_CmpOr) { lbBlock *block = lb_create_block(p, "cmp.or"); lb_build_cond(p, be->left, true_block, block); lb_start_block(p, block); - return lb_build_cond(p, be->right, true_block, false_block); + lb_build_cond(p, be->right, true_block, false_block); + return no_comptime_short_circuit; } case_end; } diff --git a/src/llvm_backend_opt.cpp b/src/llvm_backend_opt.cpp index de925655f..d36bdec0b 100644 --- a/src/llvm_backend_opt.cpp +++ b/src/llvm_backend_opt.cpp @@ -48,12 +48,6 @@ LLVMBool lb_must_preserve_predicate_callback(LLVMValueRef value, void *user_data return LLVMIsAAllocaInst(value) != nullptr; } -void lb_add_must_preserve_predicate_pass(lbModule *m, LLVMPassManagerRef fpm, i32 optimization_level) { - if (false && optimization_level == 0 && m->debug_builder) { - // LLVMAddInternalizePassWithMustPreservePredicate(fpm, m, lb_must_preserve_predicate_callback); - } -} - #if LLVM_VERSION_MAJOR < 12 #define LLVM_ADD_CONSTANT_VALUE_PASS(fpm) LLVMAddConstantPropagationPass(fpm) @@ -61,16 +55,15 @@ void lb_add_must_preserve_predicate_pass(lbModule *m, LLVMPassManagerRef fpm, i3 #define LLVM_ADD_CONSTANT_VALUE_PASS(fpm) #endif -void lb_basic_populate_function_pass_manager(LLVMPassManagerRef fpm) { - LLVMAddPromoteMemoryToRegisterPass(fpm); - LLVMAddMergedLoadStoreMotionPass(fpm); - LLVM_ADD_CONSTANT_VALUE_PASS(fpm); - LLVMAddEarlyCSEPass(fpm); - - // LLVM_ADD_CONSTANT_VALUE_PASS(fpm); - // LLVMAddMergedLoadStoreMotionPass(fpm); - // LLVMAddPromoteMemoryToRegisterPass(fpm); - // LLVMAddCFGSimplificationPass(fpm); +void lb_basic_populate_function_pass_manager(LLVMPassManagerRef fpm, i32 optimization_level) { + if (false && optimization_level == 0 && build_context.ODIN_DEBUG) { + LLVMAddMergedLoadStoreMotionPass(fpm); + } else { + LLVMAddPromoteMemoryToRegisterPass(fpm); + LLVMAddMergedLoadStoreMotionPass(fpm); + LLVM_ADD_CONSTANT_VALUE_PASS(fpm); + LLVMAddEarlyCSEPass(fpm); + } } void lb_populate_function_pass_manager(lbModule *m, LLVMPassManagerRef fpm, bool ignore_memcpy_pass, i32 optimization_level) { @@ -78,14 +71,12 @@ void lb_populate_function_pass_manager(lbModule *m, LLVMPassManagerRef fpm, bool // TODO(bill): Determine which opt definitions should exist in the first place optimization_level = gb_clamp(optimization_level, 0, 2); - lb_add_must_preserve_predicate_pass(m, fpm, optimization_level); - if (ignore_memcpy_pass) { - lb_basic_populate_function_pass_manager(fpm); + lb_basic_populate_function_pass_manager(fpm, optimization_level); return; } else if (optimization_level == 0) { LLVMAddMemCpyOptPass(fpm); - lb_basic_populate_function_pass_manager(fpm); + lb_basic_populate_function_pass_manager(fpm, optimization_level); return; } @@ -96,7 +87,7 @@ void lb_populate_function_pass_manager(lbModule *m, LLVMPassManagerRef fpm, bool LLVMPassManagerBuilderPopulateFunctionPassManager(pmb, fpm); #else LLVMAddMemCpyOptPass(fpm); - lb_basic_populate_function_pass_manager(fpm); + lb_basic_populate_function_pass_manager(fpm, optimization_level); LLVMAddSCCPPass(fpm); @@ -114,11 +105,9 @@ void lb_populate_function_pass_manager_specific(lbModule *m, LLVMPassManagerRef // TODO(bill): Determine which opt definitions should exist in the first place optimization_level = gb_clamp(optimization_level, 0, 2); - lb_add_must_preserve_predicate_pass(m, fpm, optimization_level); - if (optimization_level == 0) { LLVMAddMemCpyOptPass(fpm); - lb_basic_populate_function_pass_manager(fpm); + lb_basic_populate_function_pass_manager(fpm, optimization_level); return; } @@ -191,6 +180,9 @@ void lb_populate_module_pass_manager(LLVMTargetMachineRef target_machine, LLVMPa // NOTE(bill): Treat -opt:3 as if it was -opt:2 // TODO(bill): Determine which opt definitions should exist in the first place optimization_level = gb_clamp(optimization_level, 0, 2); + if (optimization_level == 0 && build_context.ODIN_DEBUG) { + return; + } LLVMAddAlwaysInlinerPass(mpm); LLVMAddStripDeadPrototypesPass(mpm); diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 25b27ee47..96ff19d10 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -57,11 +57,12 @@ void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbVal LLVMBuildCall(p->builder, ip, args, gb_count_of(args), ""); } + lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) { GB_ASSERT(entity != nullptr); GB_ASSERT(entity->kind == Entity_Procedure); if (!entity->Procedure.is_foreign) { - GB_ASSERT(entity->flags & EntityFlag_ProcBodyChecked); + GB_ASSERT_MSG(entity->flags & EntityFlag_ProcBodyChecked, "%.*s :: %s", LIT(entity->token.string), type_to_string(entity->type)); } String link_name = {}; @@ -107,7 +108,6 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) gbAllocator a = heap_allocator(); p->children.allocator = a; - p->params.allocator = a; p->defer_stmts.allocator = a; p->blocks.allocator = a; p->branch_blocks.allocator = a; @@ -135,6 +135,10 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) lb_add_attribute_to_proc(m, p->value, "naked"); } + if (!entity->Procedure.is_foreign && build_context.disable_red_zone) { + lb_add_attribute_to_proc(m, p->value, "noredzone"); + } + switch (p->inlining) { case ProcInlining_inline: lb_add_attribute_to_proc(m, p->value, "alwaysinline"); @@ -164,14 +168,6 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) break; } - - - // lbCallingConventionKind cc_kind = lbCallingConvention_C; - // // TODO(bill): Clean up this logic - // if (build_context.metrics.os != TargetOs_js) { - // cc_kind = lb_calling_convention_map[pt->Proc.calling_convention]; - // } - // LLVMSetFunctionCallConv(p->value, cc_kind); lbValue proc_value = {p->value, p->type}; lb_add_entity(m, entity, proc_value); lb_add_member(m, p->name, proc_value); @@ -304,7 +300,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type) { { lbValue *found = string_map_get(&m->members, link_name); - GB_ASSERT(found == nullptr); + GB_ASSERT_MSG(found == nullptr, "failed to create dummy procedure for: %.*s", LIT(link_name)); } lbProcedure *p = gb_alloc_item(permanent_allocator(), lbProcedure); @@ -323,7 +319,6 @@ lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type gbAllocator a = permanent_allocator(); p->children.allocator = a; - p->params.allocator = a; p->defer_stmts.allocator = a; p->blocks.allocator = a; p->branch_blocks.allocator = a; @@ -452,7 +447,7 @@ void lb_begin_procedure_body(lbProcedure *p) { Type *ptr_type = alloc_type_pointer(reduce_tuple_to_single_type(p->type->Proc.results)); Entity *e = alloc_entity_param(nullptr, make_token_ident(name), ptr_type, false, false); - e->flags |= EntityFlag_Sret | EntityFlag_NoAlias; + e->flags |= EntityFlag_NoAlias; return_ptr_value.value = LLVMGetParam(p->value, 0); LLVMSetValueName2(return_ptr_value.value, cast(char const *)name.text, name.len); @@ -475,44 +470,42 @@ void lb_begin_procedure_body(lbProcedure *p) { } lbArgType *arg_type = &ft->args[param_index]; + defer (param_index += 1); + if (arg_type->kind == lbArg_Ignore) { continue; } else if (arg_type->kind == lbArg_Direct) { - lbParamPasskind kind = lbParamPass_Value; - LLVMTypeRef param_type = lb_type(p->module, e->type); - if (param_type != arg_type->type) { - kind = lbParamPass_BitCast; + if (e->token.string.len != 0 && !is_blank_ident(e->token.string)) { + LLVMTypeRef param_type = lb_type(p->module, e->type); + LLVMValueRef original_value = LLVMGetParam(p->value, param_offset+param_index); + LLVMValueRef value = OdinLLVMBuildTransmute(p, original_value, param_type); + + lbValue param = {}; + param.value = value; + param.type = e->type; + + lbValue ptr = lb_address_from_load_or_generate_local(p, param); + GB_ASSERT(LLVMIsAAllocaInst(ptr.value)); + lb_add_entity(p->module, e, ptr); + + lbBlock *block = p->decl_block; + if (original_value != value) { + block = p->curr_block; + } + LLVMValueRef debug_storage_value = value; + if (original_value != value && LLVMIsALoadInst(value)) { + debug_storage_value = LLVMGetOperand(value, 0); + } + lb_add_debug_param_variable(p, debug_storage_value, e->type, e->token, param_index+1, block); } - LLVMValueRef value = LLVMGetParam(p->value, param_offset+param_index); - - value = OdinLLVMBuildTransmute(p, value, param_type); - - lbValue param = {}; - param.value = value; - param.type = e->type; - array_add(&p->params, param); - - if (e->token.string.len != 0) { - lbAddr l = lb_add_local(p, e->type, e, false, param_index); - lb_addr_store(p, l, param); - } - - param_index += 1; } else if (arg_type->kind == lbArg_Indirect) { - LLVMValueRef value_ptr = LLVMGetParam(p->value, param_offset+param_index); - LLVMValueRef value = LLVMBuildLoad(p->builder, value_ptr, ""); - - lbValue param = {}; - param.value = value; - param.type = e->type; - array_add(&p->params, param); - - lbValue ptr = {}; - ptr.value = value_ptr; - ptr.type = alloc_type_pointer(e->type); - - lb_add_entity(p->module, e, ptr); - param_index += 1; + if (e->token.string.len != 0 && !is_blank_ident(e->token.string)) { + lbValue ptr = {}; + ptr.value = LLVMGetParam(p->value, param_offset+param_index); + ptr.type = alloc_type_pointer(e->type); + lb_add_entity(p->module, e, ptr); + lb_add_debug_param_variable(p, ptr.value, e->type, e->token, param_index+1, p->decl_block); + } } } } @@ -736,6 +729,10 @@ lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr, LLVMValueRef ret = LLVMBuildCall2(p->builder, fnp, fn, args, arg_count, ""); + if (return_ptr.value != nullptr) { + LLVMAddCallSiteAttribute(ret, 1, lb_create_enum_attribute_with_type(p->module->ctx, "sret", LLVMTypeOf(args[0]))); + } + switch (inlining) { case ProcInlining_none: break; @@ -1049,7 +1046,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, return lb_string_len(p, v); } else if (is_type_array(t)) { GB_PANIC("Array lengths are constant"); - } else if (is_type_slice(t)) { + } else if (is_type_slice(t) || is_type_relative_slice(t)) { return lb_slice_len(p, v); } else if (is_type_dynamic_array(t)) { return lb_dynamic_array_len(p, v); @@ -1075,7 +1072,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, GB_PANIC("Unreachable"); } else if (is_type_array(t)) { GB_PANIC("Array lengths are constant"); - } else if (is_type_slice(t)) { + } else if (is_type_slice(t) || is_type_relative_slice(t)) { return lb_slice_len(p, v); } else if (is_type_dynamic_array(t)) { return lb_dynamic_array_cap(p, v); @@ -1372,15 +1369,23 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, } case BuiltinProc_cpu_relax: - if (build_context.metrics.arch == TargetArch_386 || + if (build_context.metrics.arch == TargetArch_i386 || build_context.metrics.arch == TargetArch_amd64) { LLVMTypeRef func_type = LLVMFunctionType(LLVMVoidTypeInContext(p->module->ctx), nullptr, 0, false); - LLVMValueRef the_asm = llvm_get_inline_asm(func_type, str_lit("pause"), {}); + LLVMValueRef the_asm = llvm_get_inline_asm(func_type, str_lit("pause"), {}, true); GB_ASSERT(the_asm != nullptr); LLVMBuildCall2(p->builder, func_type, the_asm, nullptr, 0, ""); } else if (build_context.metrics.arch == TargetArch_arm64) { LLVMTypeRef func_type = LLVMFunctionType(LLVMVoidTypeInContext(p->module->ctx), nullptr, 0, false); - LLVMValueRef the_asm = llvm_get_inline_asm(func_type, str_lit("yield"), {}); + // NOTE(bill, 2022-03-30): `isb` appears to a better option that `yield` + // See: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8258604 + LLVMValueRef the_asm = llvm_get_inline_asm(func_type, str_lit("isb"), {}, true); + GB_ASSERT(the_asm != nullptr); + LLVMBuildCall2(p->builder, func_type, the_asm, nullptr, 0, ""); + } else { + // NOTE: default to something to prevent optimization + LLVMTypeRef func_type = LLVMFunctionType(LLVMVoidTypeInContext(p->module->ctx), nullptr, 0, false); + LLVMValueRef the_asm = llvm_get_inline_asm(func_type, str_lit(""), {}, true); GB_ASSERT(the_asm != nullptr); LLVMBuildCall2(p->builder, func_type, the_asm, nullptr, 0, ""); } @@ -1409,14 +1414,23 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, case BuiltinProc_read_cycle_counter: { - char const *name = "llvm.readcyclecounter"; - unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name)); - GB_ASSERT_MSG(id != 0, "Unable to find %s", name); - LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, nullptr, 0); - lbValue res = {}; - res.value = LLVMBuildCall(p->builder, ip, nullptr, 0, ""); res.type = tv.type; + + if (build_context.metrics.arch == TargetArch_arm64) { + LLVMTypeRef func_type = LLVMFunctionType(LLVMInt64TypeInContext(p->module->ctx), nullptr, 0, false); + bool has_side_effects = false; + LLVMValueRef the_asm = llvm_get_inline_asm(func_type, str_lit("mrs x9, cntvct_el0"), str_lit("=r"), has_side_effects); + GB_ASSERT(the_asm != nullptr); + res.value = LLVMBuildCall2(p->builder, func_type, the_asm, nullptr, 0, ""); + } else { + char const *name = "llvm.readcyclecounter"; + unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name)); + GB_ASSERT_MSG(id != 0, "Unable to find %s", name); + LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, nullptr, 0); + + res.value = LLVMBuildCall(p->builder, ip, nullptr, 0, ""); + } return res; } @@ -1592,36 +1606,26 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, } - - case BuiltinProc_atomic_fence: - LLVMBuildFence(p->builder, LLVMAtomicOrderingSequentiallyConsistent, false, ""); + // TODO(bill): Which is correct? + case BuiltinProc_atomic_thread_fence: + LLVMBuildFence(p->builder, llvm_atomic_ordering_from_odin(ce->args[0]), false, ""); return {}; - case BuiltinProc_atomic_fence_acq: - LLVMBuildFence(p->builder, LLVMAtomicOrderingAcquire, false, ""); - return {}; - case BuiltinProc_atomic_fence_rel: - LLVMBuildFence(p->builder, LLVMAtomicOrderingRelease, false, ""); - return {}; - case BuiltinProc_atomic_fence_acqrel: - LLVMBuildFence(p->builder, LLVMAtomicOrderingAcquireRelease, false, ""); + case BuiltinProc_atomic_signal_fence: + LLVMBuildFence(p->builder, llvm_atomic_ordering_from_odin(ce->args[0]), true, ""); return {}; case BuiltinProc_volatile_store: case BuiltinProc_atomic_store: - case BuiltinProc_atomic_store_rel: - case BuiltinProc_atomic_store_relaxed: - case BuiltinProc_atomic_store_unordered: { + case BuiltinProc_atomic_store_explicit: { lbValue dst = lb_build_expr(p, ce->args[0]); lbValue val = lb_build_expr(p, ce->args[1]); val = lb_emit_conv(p, val, type_deref(dst.type)); LLVMValueRef instr = LLVMBuildStore(p->builder, val.value, dst.value); switch (id) { - case BuiltinProc_volatile_store: LLVMSetVolatile(instr, true); break; - case BuiltinProc_atomic_store: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break; - case BuiltinProc_atomic_store_rel: LLVMSetOrdering(instr, LLVMAtomicOrderingRelease); break; - case BuiltinProc_atomic_store_relaxed: LLVMSetOrdering(instr, LLVMAtomicOrderingMonotonic); break; - case BuiltinProc_atomic_store_unordered: LLVMSetOrdering(instr, LLVMAtomicOrderingUnordered); break; + case BuiltinProc_volatile_store: LLVMSetVolatile(instr, true); break; + case BuiltinProc_atomic_store: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break; + case BuiltinProc_atomic_store_explicit: LLVMSetOrdering(instr, llvm_atomic_ordering_from_odin(ce->args[2])); break; } LLVMSetAlignment(instr, cast(unsigned)type_align_of(type_deref(dst.type))); @@ -1631,18 +1635,14 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, case BuiltinProc_volatile_load: case BuiltinProc_atomic_load: - case BuiltinProc_atomic_load_acq: - case BuiltinProc_atomic_load_relaxed: - case BuiltinProc_atomic_load_unordered: { + case BuiltinProc_atomic_load_explicit: { lbValue dst = lb_build_expr(p, ce->args[0]); LLVMValueRef instr = LLVMBuildLoad(p->builder, dst.value, ""); switch (id) { - case BuiltinProc_volatile_load: LLVMSetVolatile(instr, true); break; - case BuiltinProc_atomic_load: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break; - case BuiltinProc_atomic_load_acq: LLVMSetOrdering(instr, LLVMAtomicOrderingAcquire); break; - case BuiltinProc_atomic_load_relaxed: LLVMSetOrdering(instr, LLVMAtomicOrderingMonotonic); break; - case BuiltinProc_atomic_load_unordered: LLVMSetOrdering(instr, LLVMAtomicOrderingUnordered); break; + case BuiltinProc_volatile_load: LLVMSetVolatile(instr, true); break; + case BuiltinProc_atomic_load: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break; + case BuiltinProc_atomic_load_explicit: LLVMSetOrdering(instr, llvm_atomic_ordering_from_odin(ce->args[1])); break; } LLVMSetAlignment(instr, cast(unsigned)type_align_of(type_deref(dst.type))); @@ -1672,40 +1672,19 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, } case BuiltinProc_atomic_add: - case BuiltinProc_atomic_add_acq: - case BuiltinProc_atomic_add_rel: - case BuiltinProc_atomic_add_acqrel: - case BuiltinProc_atomic_add_relaxed: case BuiltinProc_atomic_sub: - case BuiltinProc_atomic_sub_acq: - case BuiltinProc_atomic_sub_rel: - case BuiltinProc_atomic_sub_acqrel: - case BuiltinProc_atomic_sub_relaxed: case BuiltinProc_atomic_and: - case BuiltinProc_atomic_and_acq: - case BuiltinProc_atomic_and_rel: - case BuiltinProc_atomic_and_acqrel: - case BuiltinProc_atomic_and_relaxed: case BuiltinProc_atomic_nand: - case BuiltinProc_atomic_nand_acq: - case BuiltinProc_atomic_nand_rel: - case BuiltinProc_atomic_nand_acqrel: - case BuiltinProc_atomic_nand_relaxed: case BuiltinProc_atomic_or: - case BuiltinProc_atomic_or_acq: - case BuiltinProc_atomic_or_rel: - case BuiltinProc_atomic_or_acqrel: - case BuiltinProc_atomic_or_relaxed: case BuiltinProc_atomic_xor: - case BuiltinProc_atomic_xor_acq: - case BuiltinProc_atomic_xor_rel: - case BuiltinProc_atomic_xor_acqrel: - case BuiltinProc_atomic_xor_relaxed: - case BuiltinProc_atomic_xchg: - case BuiltinProc_atomic_xchg_acq: - case BuiltinProc_atomic_xchg_rel: - case BuiltinProc_atomic_xchg_acqrel: - case BuiltinProc_atomic_xchg_relaxed: { + case BuiltinProc_atomic_exchange: + case BuiltinProc_atomic_add_explicit: + case BuiltinProc_atomic_sub_explicit: + case BuiltinProc_atomic_and_explicit: + case BuiltinProc_atomic_nand_explicit: + case BuiltinProc_atomic_or_explicit: + case BuiltinProc_atomic_xor_explicit: + case BuiltinProc_atomic_exchange_explicit: { lbValue dst = lb_build_expr(p, ce->args[0]); lbValue val = lb_build_expr(p, ce->args[1]); val = lb_emit_conv(p, val, type_deref(dst.type)); @@ -1714,41 +1693,20 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, LLVMAtomicOrdering ordering = {}; switch (id) { - case BuiltinProc_atomic_add: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; - case BuiltinProc_atomic_add_acq: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingAcquire; break; - case BuiltinProc_atomic_add_rel: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingRelease; break; - case BuiltinProc_atomic_add_acqrel: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingAcquireRelease; break; - case BuiltinProc_atomic_add_relaxed: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingMonotonic; break; - case BuiltinProc_atomic_sub: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; - case BuiltinProc_atomic_sub_acq: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingAcquire; break; - case BuiltinProc_atomic_sub_rel: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingRelease; break; - case BuiltinProc_atomic_sub_acqrel: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingAcquireRelease; break; - case BuiltinProc_atomic_sub_relaxed: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingMonotonic; break; - case BuiltinProc_atomic_and: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; - case BuiltinProc_atomic_and_acq: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingAcquire; break; - case BuiltinProc_atomic_and_rel: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingRelease; break; - case BuiltinProc_atomic_and_acqrel: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingAcquireRelease; break; - case BuiltinProc_atomic_and_relaxed: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingMonotonic; break; - case BuiltinProc_atomic_nand: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; - case BuiltinProc_atomic_nand_acq: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingAcquire; break; - case BuiltinProc_atomic_nand_rel: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingRelease; break; - case BuiltinProc_atomic_nand_acqrel: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingAcquireRelease; break; - case BuiltinProc_atomic_nand_relaxed: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingMonotonic; break; - case BuiltinProc_atomic_or: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; - case BuiltinProc_atomic_or_acq: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingAcquire; break; - case BuiltinProc_atomic_or_rel: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingRelease; break; - case BuiltinProc_atomic_or_acqrel: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingAcquireRelease; break; - case BuiltinProc_atomic_or_relaxed: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingMonotonic; break; - case BuiltinProc_atomic_xor: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; - case BuiltinProc_atomic_xor_acq: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingAcquire; break; - case BuiltinProc_atomic_xor_rel: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingRelease; break; - case BuiltinProc_atomic_xor_acqrel: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingAcquireRelease; break; - case BuiltinProc_atomic_xor_relaxed: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingMonotonic; break; - case BuiltinProc_atomic_xchg: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; - case BuiltinProc_atomic_xchg_acq: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingAcquire; break; - case BuiltinProc_atomic_xchg_rel: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingRelease; break; - case BuiltinProc_atomic_xchg_acqrel: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingAcquireRelease; break; - case BuiltinProc_atomic_xchg_relaxed: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingMonotonic; break; + case BuiltinProc_atomic_add: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; + case BuiltinProc_atomic_sub: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; + case BuiltinProc_atomic_and: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; + case BuiltinProc_atomic_nand: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; + case BuiltinProc_atomic_or: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; + case BuiltinProc_atomic_xor: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; + case BuiltinProc_atomic_exchange: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingSequentiallyConsistent; break; + case BuiltinProc_atomic_add_explicit: op = LLVMAtomicRMWBinOpAdd; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break; + case BuiltinProc_atomic_sub_explicit: op = LLVMAtomicRMWBinOpSub; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break; + case BuiltinProc_atomic_and_explicit: op = LLVMAtomicRMWBinOpAnd; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break; + case BuiltinProc_atomic_nand_explicit: op = LLVMAtomicRMWBinOpNand; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break; + case BuiltinProc_atomic_or_explicit: op = LLVMAtomicRMWBinOpOr; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break; + case BuiltinProc_atomic_xor_explicit: op = LLVMAtomicRMWBinOpXor; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break; + case BuiltinProc_atomic_exchange_explicit: op = LLVMAtomicRMWBinOpXchg; ordering = llvm_atomic_ordering_from_odin(ce->args[2]); break; } lbValue res = {}; @@ -1757,24 +1715,10 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, return res; } - case BuiltinProc_atomic_cxchg: - case BuiltinProc_atomic_cxchg_acq: - case BuiltinProc_atomic_cxchg_rel: - case BuiltinProc_atomic_cxchg_acqrel: - case BuiltinProc_atomic_cxchg_relaxed: - case BuiltinProc_atomic_cxchg_failrelaxed: - case BuiltinProc_atomic_cxchg_failacq: - case BuiltinProc_atomic_cxchg_acq_failrelaxed: - case BuiltinProc_atomic_cxchg_acqrel_failrelaxed: - case BuiltinProc_atomic_cxchgweak: - case BuiltinProc_atomic_cxchgweak_acq: - case BuiltinProc_atomic_cxchgweak_rel: - case BuiltinProc_atomic_cxchgweak_acqrel: - case BuiltinProc_atomic_cxchgweak_relaxed: - case BuiltinProc_atomic_cxchgweak_failrelaxed: - case BuiltinProc_atomic_cxchgweak_failacq: - case BuiltinProc_atomic_cxchgweak_acq_failrelaxed: - case BuiltinProc_atomic_cxchgweak_acqrel_failrelaxed: { + case BuiltinProc_atomic_compare_exchange_strong: + case BuiltinProc_atomic_compare_exchange_weak: + case BuiltinProc_atomic_compare_exchange_strong_explicit: + case BuiltinProc_atomic_compare_exchange_weak_explicit: { lbValue address = lb_build_expr(p, ce->args[0]); Type *elem = type_deref(address.type); lbValue old_value = lb_build_expr(p, ce->args[1]); @@ -1787,28 +1731,14 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, LLVMBool weak = false; switch (id) { - case BuiltinProc_atomic_cxchg: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break; - case BuiltinProc_atomic_cxchg_acq: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break; - case BuiltinProc_atomic_cxchg_rel: success_ordering = LLVMAtomicOrderingRelease; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break; - case BuiltinProc_atomic_cxchg_acqrel: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break; - case BuiltinProc_atomic_cxchg_relaxed: success_ordering = LLVMAtomicOrderingMonotonic; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break; - case BuiltinProc_atomic_cxchg_failrelaxed: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break; - case BuiltinProc_atomic_cxchg_failacq: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingAcquire; weak = false; break; - case BuiltinProc_atomic_cxchg_acq_failrelaxed: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break; - case BuiltinProc_atomic_cxchg_acqrel_failrelaxed: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break; - case BuiltinProc_atomic_cxchgweak: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break; - case BuiltinProc_atomic_cxchgweak_acq: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = true; break; - case BuiltinProc_atomic_cxchgweak_rel: success_ordering = LLVMAtomicOrderingRelease; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = true; break; - case BuiltinProc_atomic_cxchgweak_acqrel: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = true; break; - case BuiltinProc_atomic_cxchgweak_relaxed: success_ordering = LLVMAtomicOrderingMonotonic; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break; - case BuiltinProc_atomic_cxchgweak_failrelaxed: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break; - case BuiltinProc_atomic_cxchgweak_failacq: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingAcquire; weak = true; break; - case BuiltinProc_atomic_cxchgweak_acq_failrelaxed: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break; - case BuiltinProc_atomic_cxchgweak_acqrel_failrelaxed: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break; + case BuiltinProc_atomic_compare_exchange_strong: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break; + case BuiltinProc_atomic_compare_exchange_weak: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = true; break; + case BuiltinProc_atomic_compare_exchange_strong_explicit: success_ordering = llvm_atomic_ordering_from_odin(ce->args[3]); failure_ordering = llvm_atomic_ordering_from_odin(ce->args[4]); weak = false; break; + case BuiltinProc_atomic_compare_exchange_weak_explicit: success_ordering = llvm_atomic_ordering_from_odin(ce->args[3]); failure_ordering = llvm_atomic_ordering_from_odin(ce->args[4]); weak = true; break; } // TODO(bill): Figure out how to make it weak - LLVMBool single_threaded = weak; + LLVMBool single_threaded = false; LLVMValueRef value = LLVMBuildAtomicCmpXchg( p->builder, address.value, @@ -1817,6 +1747,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, failure_ordering, single_threaded ); + LLVMSetWeak(value, weak); if (tv.type->kind == Type_Tuple) { Type *fix_typed = alloc_type_tuple(); @@ -1961,6 +1892,14 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, return res; } + case BuiltinProc___entry_point: + if (p->module->info->entry_point) { + lbValue entry_point = lb_find_procedure_value_from_entity(p->module, p->module->info->entry_point); + GB_ASSERT(entry_point.value != nullptr); + lb_emit_call(p, entry_point, {}); + } + return {}; + case BuiltinProc_syscall: { unsigned arg_count = cast(unsigned)ce->args.count; @@ -2021,7 +1960,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints)); } break; - case TargetArch_386: + case TargetArch_i386: { GB_ASSERT(arg_count <= 7); @@ -2054,26 +1993,47 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, break; case TargetArch_arm64: { - GB_ASSERT(arg_count <= 7); - - char asm_string[] = "svc #0"; - gbString constraints = gb_string_make(heap_allocator(), "={x0}"); - for (unsigned i = 0; i < arg_count; i++) { - constraints = gb_string_appendc(constraints, ",{"); - static char const *regs[] = { - "x8", - "x0", - "x1", - "x2", - "x3", - "x4", - "x5", - }; - constraints = gb_string_appendc(constraints, regs[i]); - constraints = gb_string_appendc(constraints, "}"); - } + GB_ASSERT(arg_count <= 7); + + if(build_context.metrics.os == TargetOs_darwin) { + char asm_string[] = "svc #0x80"; + gbString constraints = gb_string_make(heap_allocator(), "={x0}"); + for (unsigned i = 0; i < arg_count; i++) { + constraints = gb_string_appendc(constraints, ",{"); + static char const *regs[] = { + "x16", + "x0", + "x1", + "x2", + "x3", + "x4", + "x5", + }; + constraints = gb_string_appendc(constraints, regs[i]); + constraints = gb_string_appendc(constraints, "}"); + } - inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints)); + inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints)); + } else { + char asm_string[] = "svc #0"; + gbString constraints = gb_string_make(heap_allocator(), "={x0}"); + for (unsigned i = 0; i < arg_count; i++) { + constraints = gb_string_appendc(constraints, ",{"); + static char const *regs[] = { + "x8", + "x0", + "x1", + "x2", + "x3", + "x4", + "x5", + }; + constraints = gb_string_appendc(constraints, regs[i]); + constraints = gb_string_appendc(constraints, "}"); + } + + inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints)); + } } break; default: @@ -2085,6 +2045,124 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, res.type = t_uintptr; return res; } + + case BuiltinProc_objc_send: + return lb_handle_objc_send(p, expr); + + case BuiltinProc_objc_find_selector: return lb_handle_objc_find_selector(p, expr); + case BuiltinProc_objc_find_class: return lb_handle_objc_find_class(p, expr); + case BuiltinProc_objc_register_selector: return lb_handle_objc_register_selector(p, expr); + case BuiltinProc_objc_register_class: return lb_handle_objc_register_class(p, expr); + + + case BuiltinProc_constant_utf16_cstring: + { + auto const encode_surrogate_pair = [](Rune r, u16 *r1, u16 *r2) { + if (r < 0x10000 || r > 0x10ffff) { + *r1 = 0xfffd; + *r2 = 0xfffd; + } else { + r -= 0x10000; + *r1 = 0xd800 + ((r>>10)&0x3ff); + *r2 = 0xdc00 + (r&0x3ff); + } + }; + + lbModule *m = p->module; + + auto tav = type_and_value_of_expr(ce->args[0]); + GB_ASSERT(tav.value.kind == ExactValue_String); + String value = tav.value.value_string; + + LLVMTypeRef llvm_u16 = lb_type(m, t_u16); + + isize max_len = value.len*2 + 1; + LLVMValueRef *buffer = gb_alloc_array(temporary_allocator(), LLVMValueRef, max_len); + isize n = 0; + while (value.len > 0) { + Rune r = 0; + isize w = gb_utf8_decode(value.text, value.len, &r); + value.text += w; + value.len -= w; + if ((0 <= r && r < 0xd800) || (0xe000 <= r && r < 0x10000)) { + buffer[n++] = LLVMConstInt(llvm_u16, cast(u16)r, false); + } else if (0x10000 <= r && r <= 0x10ffff) { + u16 r1, r2; + encode_surrogate_pair(r, &r1, &r2); + buffer[n++] = LLVMConstInt(llvm_u16, r1, false); + buffer[n++] = LLVMConstInt(llvm_u16, r2, false); + } else { + buffer[n++] = LLVMConstInt(llvm_u16, 0xfffd, false); + } + } + + buffer[n++] = LLVMConstInt(llvm_u16, 0, false); + + LLVMValueRef array = LLVMConstArray(llvm_u16, buffer, cast(unsigned int)n); + + char *name = nullptr; + { + isize max_len = 7+8+1; + name = gb_alloc_array(permanent_allocator(), char, max_len); + u32 id = m->gen->global_array_index.fetch_add(1); + isize len = gb_snprintf(name, max_len, "csbs$%x", id); + len -= 1; + } + LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(array), name); + LLVMSetInitializer(global_data, array); + LLVMSetLinkage(global_data, LLVMInternalLinkage); + + + + LLVMValueRef indices[] = { + LLVMConstInt(lb_type(m, t_u32), 0, false), + LLVMConstInt(lb_type(m, t_u32), 0, false), + }; + lbValue res = {}; + res.type = tv.type; + res.value = LLVMBuildInBoundsGEP(p->builder, global_data, indices, gb_count_of(indices), ""); + return res; + + } + + case BuiltinProc_wasm_memory_grow: + { + char const *name = "llvm.wasm.memory.grow"; + LLVMTypeRef types[1] = { + lb_type(p->module, t_uintptr), + }; + unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name)); + GB_ASSERT_MSG(id != 0, "Unable to find %s", name, LLVMPrintTypeToString(types[0])); + LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types)); + + LLVMValueRef args[2] = {}; + args[0] = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_uintptr).value; + args[1] = lb_emit_conv(p, lb_build_expr(p, ce->args[1]), t_uintptr).value; + + lbValue res = {}; + res.type = tv.type; + res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), ""); + return res; + } + case BuiltinProc_wasm_memory_size: + { + char const *name = "llvm.wasm.memory.size"; + LLVMTypeRef types[1] = { + lb_type(p->module, t_uintptr), + }; + unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name)); + GB_ASSERT_MSG(id != 0, "Unable to find %s", name, LLVMPrintTypeToString(types[0])); + LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types)); + + LLVMValueRef args[1] = {}; + args[0] = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_uintptr).value; + + lbValue res = {}; + res.type = tv.type; + res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), ""); + return res; + } + } GB_PANIC("Unhandled built-in procedure %.*s", LIT(builtin_procs[id].name)); diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 016e464b8..2afb5300b 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -1652,13 +1652,16 @@ void lb_build_if_stmt(lbProcedure *p, Ast *node) { } lbValue cond = lb_build_cond(p, is->cond, then, else_); + // Note `cond.value` only set for non-and/or conditions and const negs so that the `LLVMIsConstant()` + // and `LLVMConstIntGetZExtValue()` calls below will be valid and `LLVMInstructionEraseFromParent()` + // will target the correct (& only) branch statement if (is->label != nullptr) { lbTargetList *tl = lb_push_target_list(p, is->label, done, nullptr, nullptr); tl->is_block = true; } - if (LLVMIsConstant(cond.value)) { + if (cond.value && LLVMIsConstant(cond.value)) { // NOTE(bill): Do a compile time short circuit for when the condition is constantly known. // This done manually rather than relying on the SSA passes because sometimes the SSA passes // miss some even if they are constantly known, especially with few optimization passes. @@ -1766,6 +1769,8 @@ void lb_build_for_stmt(lbProcedure *p, Ast *node) { } void lb_build_assign_stmt_array(lbProcedure *p, TokenKind op, lbAddr const &lhs, lbValue const &value) { + GB_ASSERT(op != Token_Eq); + Type *lhs_type = lb_addr_type(lhs); Type *array_type = base_type(lhs_type); GB_ASSERT(is_type_array_like(array_type)); @@ -1795,7 +1800,6 @@ void lb_build_assign_stmt_array(lbProcedure *p, TokenKind op, lbAddr const &lhs, } indices[index_count++] = index; } - gb_sort_array(indices, index_count, gb_i32_cmp(0)); lbValue lhs_ptrs[4] = {}; lbValue x_loads[4] = {}; @@ -1840,7 +1844,6 @@ void lb_build_assign_stmt_array(lbProcedure *p, TokenKind op, lbAddr const &lhs, } indices[index_count++] = index; } - gb_sort_array(indices.data, index_count, gb_i32_cmp(0)); lbValue lhs_ptrs[4] = {}; lbValue x_loads[4] = {}; @@ -1868,11 +1871,7 @@ void lb_build_assign_stmt_array(lbProcedure *p, TokenKind op, lbAddr const &lhs, lbValue x = lb_addr_get_ptr(p, lhs); - - if (inline_array_arith) { - #if 1 - #if 1 unsigned n = cast(unsigned)count; auto lhs_ptrs = slice_make(temporary_allocator(), n); @@ -1896,50 +1895,6 @@ void lb_build_assign_stmt_array(lbProcedure *p, TokenKind op, lbAddr const &lhs, for (unsigned i = 0; i < n; i++) { lb_emit_store(p, lhs_ptrs[i], ops[i]); } - - #else - lbValue y = lb_address_from_load_or_generate_local(p, rhs); - - unsigned n = cast(unsigned)count; - - auto lhs_ptrs = slice_make(temporary_allocator(), n); - auto rhs_ptrs = slice_make(temporary_allocator(), n); - auto x_loads = slice_make(temporary_allocator(), n); - auto y_loads = slice_make(temporary_allocator(), n); - auto ops = slice_make(temporary_allocator(), n); - - for (unsigned i = 0; i < n; i++) { - lhs_ptrs[i] = lb_emit_array_epi(p, x, i); - } - for (unsigned i = 0; i < n; i++) { - rhs_ptrs[i] = lb_emit_array_epi(p, y, i); - } - for (unsigned i = 0; i < n; i++) { - x_loads[i] = lb_emit_load(p, lhs_ptrs[i]); - } - for (unsigned i = 0; i < n; i++) { - y_loads[i] = lb_emit_load(p, rhs_ptrs[i]); - } - for (unsigned i = 0; i < n; i++) { - ops[i] = lb_emit_arith(p, op, x_loads[i], y_loads[i], elem_type); - } - for (unsigned i = 0; i < n; i++) { - lb_emit_store(p, lhs_ptrs[i], ops[i]); - } - #endif - #else - lbValue y = lb_address_from_load_or_generate_local(p, rhs); - - for (i64 i = 0; i < count; i++) { - lbValue a_ptr = lb_emit_array_epi(p, x, i); - lbValue b_ptr = lb_emit_array_epi(p, y, i); - - lbValue a = lb_emit_load(p, a_ptr); - lbValue b = lb_emit_load(p, b_ptr); - lbValue c = lb_emit_arith(p, op, a, b, elem_type); - lb_emit_store(p, a_ptr, c); - } - #endif } else { lbValue y = lb_address_from_load_or_generate_local(p, rhs); @@ -2039,6 +1994,13 @@ void lb_build_stmt(lbProcedure *p, Ast *node) { out |= StateFlag_no_bounds_check; out &= ~StateFlag_bounds_check; } + if (in & StateFlag_no_type_assert) { + out |= StateFlag_no_type_assert; + out &= ~StateFlag_type_assert; + } else if (in & StateFlag_type_assert) { + out |= StateFlag_type_assert; + out &= ~StateFlag_no_type_assert; + } p->state_flags = out; } @@ -2188,6 +2150,7 @@ void lb_build_stmt(lbProcedure *p, Ast *node) { lb_emit_defer_stmts(p, lbDeferExit_Branch, block); } lb_emit_jump(p, block); + lb_start_block(p, lb_create_block(p, "unreachable")); case_end; } } @@ -2219,10 +2182,6 @@ void lb_build_defer_stmt(lbProcedure *p, lbDefer const &d) { lb_start_block(p, b); if (d.kind == lbDefer_Node) { lb_build_stmt(p, d.stmt); - } else if (d.kind == lbDefer_Instr) { - // NOTE(bill): Need to make a new copy - LLVMValueRef instr = LLVMInstructionClone(d.instr.value); - LLVMInsertIntoBuilder(p->builder, instr); } else if (d.kind == lbDefer_Proc) { lb_emit_call(p, d.proc.deferred, d.proc.result_as_args); } diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index decb57702..7d73956e8 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -1,11 +1,10 @@ isize lb_type_info_index(CheckerInfo *info, Type *type, bool err_on_not_found=true) { - isize index = type_info_index(info, type, false); + auto *set = &info->minimum_dependency_type_info_set; + isize index = type_info_index(info, type, err_on_not_found); if (index >= 0) { - auto *set = &info->minimum_dependency_type_info_set; - for_array(i, set->entries) { - if (set->entries[i].ptr == index) { - return i+1; - } + isize i = ptr_entry_index(set, index); + if (i >= 0) { + return i+1; } } if (err_on_not_found) { @@ -15,6 +14,8 @@ isize lb_type_info_index(CheckerInfo *info, Type *type, bool err_on_not_found=tr } lbValue lb_typeid(lbModule *m, Type *type) { + GB_ASSERT(!build_context.disallow_rtti); + type = default_type(type); u64 id = cast(u64)lb_type_info_index(m->info, type); @@ -89,6 +90,8 @@ lbValue lb_typeid(lbModule *m, Type *type) { } lbValue lb_type_info(lbModule *m, Type *type) { + GB_ASSERT(!build_context.disallow_rtti); + type = default_type(type); isize index = lb_type_info_index(m->info, type); @@ -107,6 +110,8 @@ lbValue lb_type_info(lbModule *m, Type *type) { } lbValue lb_get_type_info_ptr(lbModule *m, Type *type) { + GB_ASSERT(!build_context.disallow_rtti); + i32 index = cast(i32)lb_type_info_index(m->info, type); GB_ASSERT(index >= 0); // gb_printf_err("%d %s\n", index, type_to_string(type)); @@ -156,6 +161,10 @@ lbValue lb_type_info_member_tags_offset(lbProcedure *p, isize count) { void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info data + if (build_context.disallow_rtti) { + return; + } + lbModule *m = p->module; CheckerInfo *info = m->info; @@ -455,7 +464,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da case Type_EnumeratedArray: { tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_enumerated_array_ptr); - LLVMValueRef vals[6] = { + LLVMValueRef vals[7] = { lb_get_type_info_ptr(m, t->EnumeratedArray.elem).value, lb_get_type_info_ptr(m, t->EnumeratedArray.index).value, lb_const_int(m, t_int, type_size_of(t->EnumeratedArray.elem)).value, @@ -464,6 +473,8 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da // Unions LLVMConstNull(lb_type(m, t_type_info_enum_value)), LLVMConstNull(lb_type(m, t_type_info_enum_value)), + + lb_const_bool(m, t_bool, t->EnumeratedArray.is_sparse).value, }; lbValue res = {}; @@ -630,7 +641,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_union_ptr); { - LLVMValueRef vals[7] = {}; + LLVMValueRef vals[8] = {}; isize variant_count = gb_max(0, t->Union.variants.count); lbValue memory_types = lb_type_info_member_types_offset(p, variant_count); @@ -664,8 +675,9 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da } vals[4] = lb_const_bool(m, t_bool, t->Union.custom_align != 0).value; - vals[5] = lb_const_bool(m, t_bool, t->Union.no_nil).value; - vals[6] = lb_const_bool(m, t_bool, t->Union.maybe).value; + vals[5] = lb_const_bool(m, t_bool, t->Union.kind == UnionType_no_nil).value; + vals[6] = lb_const_bool(m, t_bool, t->Union.kind == UnionType_maybe).value; + vals[7] = lb_const_bool(m, t_bool, t->Union.kind == UnionType_shared_nil).value; for (isize i = 0; i < gb_count_of(vals); i++) { if (vals[i] == nullptr) { diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 0350f7287..037171637 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -626,6 +626,12 @@ lbValue lb_emit_union_cast(lbProcedure *p, lbValue value, Type *type, TokenPos p lbValue value_ = lb_address_from_load_or_generate_local(p, value); + if ((p->state_flags & StateFlag_no_type_assert) != 0 && !is_tuple) { + // just do a bit cast of the data at the front + lbValue ptr = lb_emit_conv(p, value_, alloc_type_pointer(type)); + return lb_emit_load(p, ptr); + } + lbValue tag = {}; lbValue dst_tag = {}; lbValue cond = {}; @@ -666,23 +672,29 @@ lbValue lb_emit_union_cast(lbProcedure *p, lbValue value, Type *type, TokenPos p lb_start_block(p, end_block); if (!is_tuple) { - { - // NOTE(bill): Panic on invalid conversion - Type *dst_type = tuple->Tuple.variables[0]->type; + GB_ASSERT((p->state_flags & StateFlag_no_type_assert) == 0); + // NOTE(bill): Panic on invalid conversion + Type *dst_type = tuple->Tuple.variables[0]->type; - lbValue ok = lb_emit_load(p, lb_emit_struct_ep(p, v.addr, 1)); - auto args = array_make(permanent_allocator(), 7); - args[0] = ok; + isize arg_count = 7; + if (build_context.disallow_rtti) { + arg_count = 4; + } - args[1] = lb_const_string(m, get_file_path_string(pos.file_id)); - args[2] = lb_const_int(m, t_i32, pos.line); - args[3] = lb_const_int(m, t_i32, pos.column); + lbValue ok = lb_emit_load(p, lb_emit_struct_ep(p, v.addr, 1)); + auto args = array_make(permanent_allocator(), arg_count); + args[0] = ok; + args[1] = lb_const_string(m, get_file_path_string(pos.file_id)); + args[2] = lb_const_int(m, t_i32, pos.line); + args[3] = lb_const_int(m, t_i32, pos.column); + + if (!build_context.disallow_rtti) { args[4] = lb_typeid(m, src_type); args[5] = lb_typeid(m, dst_type); args[6] = lb_emit_conv(p, value_, t_rawptr); - lb_emit_runtime_call(p, "type_assertion_check2", args); } + lb_emit_runtime_call(p, "type_assertion_check2", args); return lb_emit_load(p, lb_emit_struct_ep(p, v.addr, 0)); } @@ -706,6 +718,13 @@ lbAddr lb_emit_any_cast_addr(lbProcedure *p, lbValue value, Type *type, TokenPos } Type *dst_type = tuple->Tuple.variables[0]->type; + if ((p->state_flags & StateFlag_no_type_assert) != 0 && !is_tuple) { + // just do a bit cast of the data at the front + lbValue ptr = lb_emit_struct_ev(p, value, 0); + ptr = lb_emit_conv(p, ptr, alloc_type_pointer(type)); + return lb_addr(ptr); + } + lbAddr v = lb_add_local_generated(p, tuple, true); lbValue dst_typeid = lb_typeid(m, dst_type); @@ -731,18 +750,24 @@ lbAddr lb_emit_any_cast_addr(lbProcedure *p, lbValue value, Type *type, TokenPos if (!is_tuple) { // NOTE(bill): Panic on invalid conversion - lbValue ok = lb_emit_load(p, lb_emit_struct_ep(p, v.addr, 1)); - auto args = array_make(permanent_allocator(), 7); + + isize arg_count = 7; + if (build_context.disallow_rtti) { + arg_count = 4; + } + auto args = array_make(permanent_allocator(), arg_count); args[0] = ok; args[1] = lb_const_string(m, get_file_path_string(pos.file_id)); args[2] = lb_const_int(m, t_i32, pos.line); args[3] = lb_const_int(m, t_i32, pos.column); - args[4] = any_typeid; - args[5] = dst_typeid; - args[6] = lb_emit_struct_ev(p, value, 0);; + if (!build_context.disallow_rtti) { + args[4] = any_typeid; + args[5] = dst_typeid; + args[6] = lb_emit_struct_ev(p, value, 0); + } lb_emit_runtime_call(p, "type_assertion_check2", args); return lb_addr(lb_emit_struct_ep(p, v.addr, 0)); @@ -1200,7 +1225,7 @@ lbValue lb_emit_array_epi(lbProcedure *p, lbValue s, isize index) { } lbValue lb_emit_ptr_offset(lbProcedure *p, lbValue ptr, lbValue index) { - index = lb_correct_endianness(p, index); + index = lb_emit_conv(p, index, t_int); LLVMValueRef indices[1] = {index.value}; lbValue res = {}; res.type = ptr.type; @@ -1362,7 +1387,7 @@ lbValue lb_slice_elem(lbProcedure *p, lbValue slice) { return lb_emit_struct_ev(p, slice, 0); } lbValue lb_slice_len(lbProcedure *p, lbValue slice) { - GB_ASSERT(is_type_slice(slice.type)); + GB_ASSERT(is_type_slice(slice.type) || is_type_relative_slice(slice.type)); return lb_emit_struct_ev(p, slice, 1); } lbValue lb_dynamic_array_elem(lbProcedure *p, lbValue da) { @@ -1494,7 +1519,7 @@ lbValue lb_emit_mul_add(lbProcedure *p, lbValue a, lbValue b, lbValue c, Type *t case TargetArch_arm64: // possible break; - case TargetArch_386: + case TargetArch_i386: case TargetArch_wasm32: case TargetArch_wasm64: is_possible = false; @@ -1768,7 +1793,7 @@ LLVMValueRef llvm_get_inline_asm(LLVMTypeRef func_type, String const &str, Strin return LLVMGetInlineAsm(func_type, cast(char *)str.text, cast(size_t)str.len, cast(char *)clobbers.text, cast(size_t)clobbers.len, - /*HasSideEffects*/true, /*IsAlignStack*/false, + has_side_effects, is_align_stack, dialect #if LLVM_VERSION_MAJOR >= 13 , /*CanThrow*/false @@ -1808,3 +1833,197 @@ void lb_set_wasm_export_attributes(LLVMValueRef value, String export_name) { LLVMSetVisibility(value, LLVMDefaultVisibility); LLVMAddTargetDependentFunctionAttr(value, "wasm-export-name", alloc_cstring(permanent_allocator(), export_name)); } + + +lbValue lb_lookup_runtime_procedure(lbModule *m, String const &name); + + +lbAddr lb_handle_objc_find_or_register_selector(lbProcedure *p, String const &name) { + lbAddr *found = string_map_get(&p->module->objc_selectors, name); + if (found) { + return *found; + } else { + lbModule *default_module = &p->module->gen->default_module; + Entity *e = nullptr; + lbAddr default_addr = lb_add_global_generated(default_module, t_objc_SEL, {}, &e); + + lbValue ptr = lb_find_value_from_entity(p->module, e); + lbAddr local_addr = lb_addr(ptr); + + string_map_set(&default_module->objc_selectors, name, default_addr); + if (default_module != p->module) { + string_map_set(&p->module->objc_selectors, name, local_addr); + } + return local_addr; + } +} + +lbValue lb_handle_objc_find_selector(lbProcedure *p, Ast *expr) { + ast_node(ce, CallExpr, expr); + + auto tav = ce->args[0]->tav; + GB_ASSERT(tav.value.kind == ExactValue_String); + String name = tav.value.value_string; + return lb_addr_load(p, lb_handle_objc_find_or_register_selector(p, name)); +} + +lbValue lb_handle_objc_register_selector(lbProcedure *p, Ast *expr) { + ast_node(ce, CallExpr, expr); + lbModule *m = p->module; + + auto tav = ce->args[0]->tav; + GB_ASSERT(tav.value.kind == ExactValue_String); + String name = tav.value.value_string; + lbAddr dst = lb_handle_objc_find_or_register_selector(p, name); + + auto args = array_make(permanent_allocator(), 1); + args[0] = lb_const_value(m, t_cstring, exact_value_string(name)); + lbValue ptr = lb_emit_runtime_call(p, "sel_registerName", args); + lb_addr_store(p, dst, ptr); + + return lb_addr_load(p, dst); +} + +lbAddr lb_handle_objc_find_or_register_class(lbProcedure *p, String const &name) { + lbAddr *found = string_map_get(&p->module->objc_classes, name); + if (found) { + return *found; + } else { + lbModule *default_module = &p->module->gen->default_module; + Entity *e = nullptr; + lbAddr default_addr = lb_add_global_generated(default_module, t_objc_SEL, {}, &e); + + lbValue ptr = lb_find_value_from_entity(p->module, e); + lbAddr local_addr = lb_addr(ptr); + + string_map_set(&default_module->objc_classes, name, default_addr); + if (default_module != p->module) { + string_map_set(&p->module->objc_classes, name, local_addr); + } + return local_addr; + } +} + +lbValue lb_handle_objc_find_class(lbProcedure *p, Ast *expr) { + ast_node(ce, CallExpr, expr); + + auto tav = ce->args[0]->tav; + GB_ASSERT(tav.value.kind == ExactValue_String); + String name = tav.value.value_string; + return lb_addr_load(p, lb_handle_objc_find_or_register_class(p, name)); +} + +lbValue lb_handle_objc_register_class(lbProcedure *p, Ast *expr) { + ast_node(ce, CallExpr, expr); + lbModule *m = p->module; + + auto tav = ce->args[0]->tav; + GB_ASSERT(tav.value.kind == ExactValue_String); + String name = tav.value.value_string; + lbAddr dst = lb_handle_objc_find_or_register_class(p, name); + + auto args = array_make(permanent_allocator(), 3); + args[0] = lb_const_nil(m, t_objc_Class); + args[1] = lb_const_nil(m, t_objc_Class); + args[2] = lb_const_int(m, t_uint, 0); + lbValue ptr = lb_emit_runtime_call(p, "objc_allocateClassPair", args); + lb_addr_store(p, dst, ptr); + + return lb_addr_load(p, dst); +} + + +lbValue lb_handle_objc_id(lbProcedure *p, Ast *expr) { + TypeAndValue const &tav = type_and_value_of_expr(expr); + if (tav.mode == Addressing_Type) { + Type *type = tav.type; + GB_ASSERT_MSG(type->kind == Type_Named, "%s", type_to_string(type)); + Entity *e = type->Named.type_name; + GB_ASSERT(e->kind == Entity_TypeName); + String name = e->TypeName.objc_class_name; + + lbAddr *found = string_map_get(&p->module->objc_classes, name); + if (found) { + return lb_addr_load(p, *found); + } else { + lbModule *default_module = &p->module->gen->default_module; + Entity *e = nullptr; + lbAddr default_addr = lb_add_global_generated(default_module, t_objc_Class, {}, &e); + + lbValue ptr = lb_find_value_from_entity(p->module, e); + lbAddr local_addr = lb_addr(ptr); + + string_map_set(&default_module->objc_classes, name, default_addr); + if (default_module != p->module) { + string_map_set(&p->module->objc_classes, name, local_addr); + } + return lb_addr_load(p, local_addr); + } + } + + return lb_build_expr(p, expr); +} + +lbValue lb_handle_objc_send(lbProcedure *p, Ast *expr) { + ast_node(ce, CallExpr, expr); + + lbModule *m = p->module; + CheckerInfo *info = m->info; + ObjcMsgData data = map_must_get(&info->objc_msgSend_types, expr); + GB_ASSERT(data.proc_type != nullptr); + + GB_ASSERT(ce->args.count >= 3); + auto args = array_make(permanent_allocator(), 0, ce->args.count-1); + + lbValue id = lb_handle_objc_id(p, ce->args[1]); + Ast *sel_expr = ce->args[2]; + GB_ASSERT(sel_expr->tav.value.kind == ExactValue_String); + lbValue sel = lb_addr_load(p, lb_handle_objc_find_or_register_selector(p, sel_expr->tav.value.value_string)); + + array_add(&args, id); + array_add(&args, sel); + for (isize i = 3; i < ce->args.count; i++) { + lbValue arg = lb_build_expr(p, ce->args[i]); + array_add(&args, arg); + } + + + lbValue the_proc = {}; + switch (data.kind) { + default: + GB_PANIC("unhandled ObjcMsgKind %u", data.kind); + break; + case ObjcMsg_normal: the_proc = lb_lookup_runtime_procedure(m, str_lit("objc_msgSend")); break; + case ObjcMsg_fpret: the_proc = lb_lookup_runtime_procedure(m, str_lit("objc_msgSend_fpret")); break; + case ObjcMsg_fp2ret: the_proc = lb_lookup_runtime_procedure(m, str_lit("objc_msgSend_fp2ret")); break; + case ObjcMsg_stret: the_proc = lb_lookup_runtime_procedure(m, str_lit("objc_msgSend_stret")); break; + } + + the_proc = lb_emit_conv(p, the_proc, data.proc_type); + + return lb_emit_call(p, the_proc, args); +} + + + + +LLVMAtomicOrdering llvm_atomic_ordering_from_odin(ExactValue const &value) { + GB_ASSERT(value.kind == ExactValue_Integer); + i64 v = exact_value_to_i64(value); + switch (v) { + case OdinAtomicMemoryOrder_relaxed: return LLVMAtomicOrderingUnordered; + case OdinAtomicMemoryOrder_consume: return LLVMAtomicOrderingMonotonic; + case OdinAtomicMemoryOrder_acquire: return LLVMAtomicOrderingAcquire; + case OdinAtomicMemoryOrder_release: return LLVMAtomicOrderingRelease; + case OdinAtomicMemoryOrder_acq_rel: return LLVMAtomicOrderingAcquireRelease; + case OdinAtomicMemoryOrder_seq_cst: return LLVMAtomicOrderingSequentiallyConsistent; + } + GB_PANIC("Unknown atomic ordering"); + return LLVMAtomicOrderingSequentiallyConsistent; +} + + +LLVMAtomicOrdering llvm_atomic_ordering_from_odin(Ast *expr) { + ExactValue value = type_and_value_of_expr(expr).value; + return llvm_atomic_ordering_from_odin(value); +} diff --git a/src/main.cpp b/src/main.cpp index 7b4bc92ee..7b0364149 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,7 +46,6 @@ gb_global Timings global_timings = {0}; #include "checker.cpp" #include "docs.cpp" - #include "llvm_backend.cpp" #if defined(GB_SYSTEM_OSX) @@ -57,16 +56,8 @@ gb_global Timings global_timings = {0}; #endif #include "query_data.cpp" - - -#if defined(GB_SYSTEM_WINDOWS) -// NOTE(IC): In order to find Visual C++ paths without relying on environment variables. -#include "microsoft_craziness.h" -#endif - #include "bug_report.cpp" - // NOTE(bill): 'name' is used in debugging and profiling modes i32 system_exec_command_line_app(char const *name, char const *fmt, ...) { isize const cmd_cap = 64<<20; // 64 MiB should be more than enough @@ -74,16 +65,16 @@ i32 system_exec_command_line_app(char const *name, char const *fmt, ...) { isize cmd_len = 0; va_list va; i32 exit_code = 0; - + va_start(va, fmt); cmd_len = gb_snprintf_va(cmd_line, cmd_cap-1, fmt, va); va_end(va); - + #if defined(GB_SYSTEM_WINDOWS) STARTUPINFOW start_info = {gb_size_of(STARTUPINFOW)}; PROCESS_INFORMATION pi = {0}; String16 wcmd = {}; - + start_info.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; start_info.wShowWindow = SW_SHOW; start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE); @@ -117,44 +108,48 @@ i32 system_exec_command_line_app(char const *name, char const *fmt, ...) { gb_printf_err("%s\n\n", cmd_line); } exit_code = system(cmd_line); + if (WIFEXITED(exit_code)) { + exit_code = WEXITSTATUS(exit_code); + } #endif - + if (exit_code) { exit(exit_code); } - + return exit_code; } - - i32 linker_stage(lbGenerator *gen) { i32 result = 0; Timings *timings = &global_timings; - String output_base = gen->output_base; + String output_filename = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Output]); + debugf("Linking %.*s\n", LIT(output_filename)); + + // TOOD(Jeroen): Make a `build_paths[BuildPath_Object] to avoid `%.*s.o`. if (is_arch_wasm()) { timings_start_section(timings, str_lit("wasm-ld")); - + #if defined(GB_SYSTEM_WINDOWS) result = system_exec_command_line_app("wasm-ld", - "\"%.*s\\bin\\wasm-ld\" \"%.*s.wasm.o\" -o \"%.*s.wasm\" %.*s %.*s", + "\"%.*s\\bin\\wasm-ld\" \"%.*s.o\" -o \"%.*s\" %.*s %.*s", LIT(build_context.ODIN_ROOT), - LIT(output_base), LIT(output_base), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); + LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); #else result = system_exec_command_line_app("wasm-ld", - "wasm-ld \"%.*s.wasm.o\" -o \"%.*s.wasm\" %.*s %.*s", - LIT(output_base), LIT(output_base), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); + "wasm-ld \"%.*s.o\" -o \"%.*s\" %.*s %.*s", + LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); #endif return result; } if (build_context.cross_compiling && selected_target_metrics->metrics == &target_essence_amd64) { -#ifdef GB_SYSTEM_UNIX +#if defined(GB_SYSTEM_UNIX) result = system_exec_command_line_app("linker", "x86_64-essence-gcc \"%.*s.o\" -o \"%.*s\" %.*s %.*s", - LIT(output_base), LIT(output_base), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); + LIT(output_filename), LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags)); #else gb_printf_err("Linking for cross compilation for this platform is not yet supported (%.*s %.*s)\n", LIT(target_os_names[build_context.metrics.os]), @@ -178,28 +173,11 @@ i32 linker_stage(lbGenerator *gen) { gbString lib_str = gb_string_make(heap_allocator(), ""); defer (gb_string_free(lib_str)); - char const *output_ext = "exe"; gbString link_settings = gb_string_make_reserve(heap_allocator(), 256); defer (gb_string_free(link_settings)); - - // NOTE(ic): It would be nice to extend this so that we could specify the Visual Studio version that we want instead of defaulting to the latest. - Find_Result_Utf8 find_result = find_visual_studio_and_windows_sdk_utf8(); - - if (find_result.windows_sdk_version == 0) { - gb_printf_err("Windows SDK not found.\n"); - exit(1); - } - - if (build_context.ignore_microsoft_magic) { - find_result = {}; - } - // Add library search paths. - if (find_result.vs_library_path.len > 0) { - GB_ASSERT(find_result.windows_sdk_um_library_path.len > 0); - GB_ASSERT(find_result.windows_sdk_ucrt_library_path.len > 0); - + if (build_context.build_paths[BuildPath_VS_LIB].basename.len > 0) { String path = {}; auto add_path = [&](String path) { if (path[path.len-1] == '\\') { @@ -207,16 +185,16 @@ i32 linker_stage(lbGenerator *gen) { } link_settings = gb_string_append_fmt(link_settings, " /LIBPATH:\"%.*s\"", LIT(path)); }; - add_path(find_result.windows_sdk_um_library_path); - add_path(find_result.windows_sdk_ucrt_library_path); - add_path(find_result.vs_library_path); + add_path(build_context.build_paths[BuildPath_Win_SDK_UM_Lib].basename); + add_path(build_context.build_paths[BuildPath_Win_SDK_UCRT_Lib].basename); + add_path(build_context.build_paths[BuildPath_VS_LIB].basename); } - - + + StringSet libs = {}; string_set_init(&libs, heap_allocator(), 64); defer (string_set_destroy(&libs)); - + StringSet asm_files = {}; string_set_init(&asm_files, heap_allocator(), 64); defer (string_set_destroy(&asm_files)); @@ -241,22 +219,22 @@ i32 linker_stage(lbGenerator *gen) { string_set_add(&libs, lib); } } - + for_array(i, libs.entries) { String lib = libs.entries[i].value; lib_str = gb_string_append_fmt(lib_str, " \"%.*s\"", LIT(lib)); } - - + + if (build_context.build_mode == BuildMode_DynamicLibrary) { - output_ext = "dll"; link_settings = gb_string_append_fmt(link_settings, " /DLL"); } else { link_settings = gb_string_append_fmt(link_settings, " /ENTRY:mainCRTStartup"); } if (build_context.pdb_filepath != "") { - link_settings = gb_string_append_fmt(link_settings, " /PDB:%.*s", LIT(build_context.pdb_filepath)); + String pdb_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_PDB]); + link_settings = gb_string_append_fmt(link_settings, " /PDB:%.*s", LIT(pdb_path)); } if (build_context.no_crt) { @@ -268,7 +246,7 @@ i32 linker_stage(lbGenerator *gen) { if (build_context.ODIN_DEBUG) { link_settings = gb_string_append_fmt(link_settings, " /DEBUG"); } - + for_array(i, asm_files.entries) { String asm_file = asm_files.entries[i].value; String obj_file = concatenate_strings(permanent_allocator(), asm_file, str_lit(".obj")); @@ -283,7 +261,7 @@ i32 linker_stage(lbGenerator *gen) { LIT(obj_file), LIT(build_context.extra_assembler_flags) ); - + if (result) { return result; } @@ -297,27 +275,35 @@ i32 linker_stage(lbGenerator *gen) { object_files = gb_string_append_fmt(object_files, "\"%.*s\" ", LIT(object_path)); } + String vs_exe_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_VS_EXE]); + defer (gb_free(heap_allocator(), vs_exe_path.text)); + char const *subsystem_str = build_context.use_subsystem_windows ? "WINDOWS" : "CONSOLE"; if (!build_context.use_lld) { // msvc if (build_context.has_resource) { + String rc_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_RC]); + String res_path = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_RES]); + defer (gb_free(heap_allocator(), rc_path.text)); + defer (gb_free(heap_allocator(), res_path.text)); + result = system_exec_command_line_app("msvc-link", - "\"rc.exe\" /nologo /fo \"%.*s.res\" \"%.*s.rc\"", - LIT(output_base), - LIT(build_context.resource_filepath) + "\"rc.exe\" /nologo /fo \"%.*s\" \"%.*s\"", + LIT(res_path), + LIT(rc_path) ); - + if (result) { return result; } result = system_exec_command_line_app("msvc-link", - "\"%.*slink.exe\" %s \"%.*s.res\" -OUT:\"%.*s.%s\" %s " + "\"%.*slink.exe\" %s \"%.*s\" -OUT:\"%.*s\" %s " "/nologo /incremental:no /opt:ref /subsystem:%s " " %.*s " " %.*s " " %s " "", - LIT(find_result.vs_exe_path), object_files, LIT(output_base), LIT(output_base), output_ext, + LIT(vs_exe_path), object_files, LIT(res_path), LIT(output_filename), link_settings, subsystem_str, LIT(build_context.link_flags), @@ -326,13 +312,13 @@ i32 linker_stage(lbGenerator *gen) { ); } else { result = system_exec_command_line_app("msvc-link", - "\"%.*slink.exe\" %s -OUT:\"%.*s.%s\" %s " + "\"%.*slink.exe\" %s -OUT:\"%.*s\" %s " "/nologo /incremental:no /opt:ref /subsystem:%s " " %.*s " " %.*s " " %s " "", - LIT(find_result.vs_exe_path), object_files, LIT(output_base), output_ext, + LIT(vs_exe_path), object_files, LIT(output_filename), link_settings, subsystem_str, LIT(build_context.link_flags), @@ -340,27 +326,27 @@ i32 linker_stage(lbGenerator *gen) { lib_str ); } - + if (result) { return result; } - + } else { // lld result = system_exec_command_line_app("msvc-lld-link", - "\"%.*s\\bin\\lld-link\" %s -OUT:\"%.*s.%s\" %s " + "\"%.*s\\bin\\lld-link\" %s -OUT:\"%.*s\" %s " "/nologo /incremental:no /opt:ref /subsystem:%s " " %.*s " " %.*s " " %s " "", - LIT(build_context.ODIN_ROOT), object_files, LIT(output_base),output_ext, + LIT(build_context.ODIN_ROOT), object_files, LIT(output_filename), link_settings, subsystem_str, LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), lib_str ); - + if (result) { return result; } @@ -384,7 +370,7 @@ i32 linker_stage(lbGenerator *gen) { // NOTE(zangent): Sometimes, you have to use -framework on MacOS. // This allows you to specify '-f' in a #foreign_system_library, // without having to implement any new syntax specifically for MacOS. - #if defined(GB_SYSTEM_OSX) + if (build_context.metrics.os == TargetOs_darwin) { if (string_ends_with(lib, str_lit(".framework"))) { // framework thingie String lib_name = lib; @@ -400,25 +386,25 @@ i32 linker_stage(lbGenerator *gen) { // dynamic or static system lib, just link regularly searching system library paths lib_str = gb_string_append_fmt(lib_str, " -l%.*s ", LIT(lib)); } - #else + } else { // NOTE(vassvik): static libraries (.a files) in linux can be linked to directly using the full path, // since those are statically linked to at link time. shared libraries (.so) has to be // available at runtime wherever the executable is run, so we make require those to be // local to the executable (unless the system collection is used, in which case we search // the system library paths for the library file). - if (string_ends_with(lib, str_lit(".a"))) { - // static libs, absolute full path relative to the file in which the lib was imported from + if (string_ends_with(lib, str_lit(".a")) || string_ends_with(lib, str_lit(".o"))) { + // static libs and object files, absolute full path relative to the file in which the lib was imported from lib_str = gb_string_append_fmt(lib_str, " -l:\"%.*s\" ", LIT(lib)); } else if (string_ends_with(lib, str_lit(".so"))) { // dynamic lib, relative path to executable // NOTE(vassvik): it is the user's responsibility to make sure the shared library files are visible - // at runtimeto the executable + // at runtime to the executable lib_str = gb_string_append_fmt(lib_str, " -l:\"%s/%.*s\" ", cwd, LIT(lib)); } else { // dynamic or static system lib, just link regularly searching system library paths lib_str = gb_string_append_fmt(lib_str, " -l%.*s ", LIT(lib)); } - #endif + } } gbString object_files = gb_string_make(heap_allocator(), ""); @@ -428,80 +414,74 @@ i32 linker_stage(lbGenerator *gen) { object_files = gb_string_append_fmt(object_files, "\"%.*s\" ", LIT(object_path)); } - // Unlike the Win32 linker code, the output_ext includes the dot, because - // typically executable files on *NIX systems don't have extensions. - String output_ext = {}; gbString link_settings = gb_string_make_reserve(heap_allocator(), 32); - char const *linker; - if (build_context.build_mode == BuildMode_DynamicLibrary) { - // NOTE(tetra, 2020-11-06): __$startup_runtime must be called at DLL load time. - // Clang, for some reason, won't let us pass the '-init' flag that lets us do this, - // so use ld instead. - // :UseLDForShared - linker = "ld"; - link_settings = gb_string_appendc(link_settings, "-init '__$startup_runtime' "); - // Shared libraries are .dylib on MacOS and .so on Linux. - #if defined(GB_SYSTEM_OSX) - output_ext = STR_LIT(".dylib"); - link_settings = gb_string_appendc(link_settings, "-dylib -dynamic "); - #else - output_ext = STR_LIT(".so"); - link_settings = gb_string_appendc(link_settings, "-shared "); - #endif - } else { - #if defined(GB_SYSTEM_OSX) - linker = "ld"; - #else - // TODO(zangent): Figure out how to make ld work on Linux. - // It probably has to do with including the entire CRT, but - // that's quite a complicated issue to solve while remaining distro-agnostic. - // Clang can figure out linker flags for us, and that's good enough _for now_. - linker = "clang -Wno-unused-command-line-argument"; - #endif + + if (build_context.no_crt) { + link_settings = gb_string_append_fmt(link_settings, "-nostdlib "); } - if (build_context.metrics.os == TargetOs_linux) { + // NOTE(dweiler): We use clang as a frontend for the linker as there are + // other runtime and compiler support libraries that need to be linked in + // very specific orders such as libgcc_s, ld-linux-so, unwind, etc. + // These are not always typically inside /lib, /lib64, or /usr versions + // of that, e.g libgcc.a is in /usr/lib/gcc/{version}, and can vary on + // the distribution of Linux even. The gcc or clang specs is the only + // reliable way to query this information to call ld directly. + if (build_context.build_mode == BuildMode_DynamicLibrary) { + // NOTE(dweiler): Let the frontend know we're building a shared library + // so it doesn't generate symbols which cannot be relocated. + link_settings = gb_string_appendc(link_settings, "-shared "); + + // NOTE(dweiler): _odin_entry_point must be called at initialization + // time of the shared object, similarly, _odin_exit_point must be called + // at deinitialization. We can pass both -init and -fini to the linker by + // using a comma separated list of arguments to -Wl. + // + // This previously used ld but ld cannot actually build a shared library + // correctly this way since all the other dependencies provided implicitly + // by the compiler frontend are still needed and most of the command + // line arguments prepared previously are incompatible with ld. + link_settings = gb_string_appendc(link_settings, "-Wl,-init,'_odin_entry_point' "); + link_settings = gb_string_appendc(link_settings, "-Wl,-fini,'_odin_exit_point' "); + } else if (build_context.metrics.os != TargetOs_openbsd) { + // OpenBSD defaults to PIE executable. do not pass -no-pie for it. link_settings = gb_string_appendc(link_settings, "-no-pie "); } - - if (build_context.out_filepath.len > 0) { - //NOTE(thebirk): We have a custom -out arguments, so we should use the extension from that - isize pos = string_extension_position(build_context.out_filepath); - if (pos > 0) { - output_ext = substring(build_context.out_filepath, pos, build_context.out_filepath.len); - } + gbString platform_lib_str = gb_string_make(heap_allocator(), ""); + defer (gb_string_free(platform_lib_str)); + if (build_context.metrics.os == TargetOs_darwin) { + platform_lib_str = gb_string_appendc(platform_lib_str, "-lSystem -lm -Wl,-syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib"); + } else { + platform_lib_str = gb_string_appendc(platform_lib_str, "-lc -lm"); } - result = system_exec_command_line_app("ld-link", - "%s %s -o \"%.*s%.*s\" %s " - " %s " - " %.*s " - " %.*s " - " %s " - #if defined(GB_SYSTEM_OSX) - // This sets a requirement of Mountain Lion and up, but the compiler doesn't work without this limit. - // NOTE: If you change this (although this minimum is as low as you can go with Odin working) - // make sure to also change the 'mtriple' param passed to 'opt' - #if defined(GB_CPU_ARM) - " -macosx_version_min 11.0.0 " - #else - " -macosx_version_min 10.8.0 " - #endif - // This points the linker to where the entry point is - " -e _main " - #endif - , linker, object_files, LIT(output_base), LIT(output_ext), - #if defined(GB_SYSTEM_OSX) - "-lSystem -lm -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -L/usr/local/lib", - #else - "-lc -lm", - #endif - lib_str, - LIT(build_context.link_flags), - LIT(build_context.extra_linker_flags), - link_settings); - + if (build_context.metrics.os == TargetOs_darwin) { + // This sets a requirement of Mountain Lion and up, but the compiler doesn't work without this limit. + // NOTE: If you change this (although this minimum is as low as you can go with Odin working) + // make sure to also change the 'mtriple' param passed to 'opt' + if (build_context.metrics.arch == TargetArch_arm64) { + link_settings = gb_string_appendc(link_settings, " -mmacosx-version-min=12.0.0 "); + } else { + link_settings = gb_string_appendc(link_settings, " -mmacosx-version-min=10.8.0 "); + } + // This points the linker to where the entry point is + link_settings = gb_string_appendc(link_settings, " -e _main "); + } + + gbString link_command_line = gb_string_make(heap_allocator(), "clang -Wno-unused-command-line-argument "); + defer (gb_string_free(link_command_line)); + + link_command_line = gb_string_appendc(link_command_line, object_files); + link_command_line = gb_string_append_fmt(link_command_line, " -o \"%.*s\" ", LIT(output_filename)); + link_command_line = gb_string_append_fmt(link_command_line, " %s ", platform_lib_str); + link_command_line = gb_string_append_fmt(link_command_line, " %s ", lib_str); + link_command_line = gb_string_append_fmt(link_command_line, " %.*s ", LIT(build_context.link_flags)); + link_command_line = gb_string_append_fmt(link_command_line, " %.*s ", LIT(build_context.extra_linker_flags)); + link_command_line = gb_string_append_fmt(link_command_line, " %s ", link_settings); + + result = system_exec_command_line_app("ld-link", link_command_line); + if (result) { return result; } @@ -510,10 +490,8 @@ i32 linker_stage(lbGenerator *gen) { if (build_context.ODIN_DEBUG) { // NOTE: macOS links DWARF symbols dynamically. Dsymutil will map the stubs in the exe // to the symbols in the object file - result = system_exec_command_line_app("dsymutil", - "dsymutil %.*s%.*s", LIT(output_base), LIT(output_ext) - ); - + result = system_exec_command_line_app("dsymutil", "dsymutil %.*s", LIT(output_filename)); + if (result) { return result; } @@ -571,54 +549,26 @@ void usage(String argv0) { print_usage_line(0, "Usage:"); print_usage_line(1, "%.*s command [arguments]", LIT(argv0)); print_usage_line(0, "Commands:"); - print_usage_line(1, "build compile .odin file, or directory of .odin files, as an executable."); - print_usage_line(1, " one must contain the program's entry point, all must be in the same package."); - print_usage_line(1, "run same as 'build', but also then runs the newly compiled executable."); - print_usage_line(1, "check parse and type check .odin file"); - print_usage_line(1, "query parse, type check, and output a .json file containing information about the program"); - print_usage_line(1, "doc generate documentation .odin file, or directory of .odin files"); - print_usage_line(1, "version print version"); - print_usage_line(1, "report print information useful to reporting a bug"); + print_usage_line(1, "build compile directory of .odin files, as an executable."); + print_usage_line(1, " one must contain the program's entry point, all must be in the same package."); + print_usage_line(1, "run same as 'build', but also then runs the newly compiled executable."); + print_usage_line(1, "check parse, and type check a directory of .odin files"); + print_usage_line(1, "query parse, type check, and output a .json file containing information about the program"); + print_usage_line(1, "strip-semicolon parse, type check, and remove unneeded semicolons from the entire program"); + print_usage_line(1, "test build ands runs procedures with the attribute @(test) in the initial package"); + print_usage_line(1, "doc generate documentation on a directory of .odin files"); + print_usage_line(1, "version print version"); + print_usage_line(1, "report print information useful to reporting a bug"); print_usage_line(0, ""); print_usage_line(0, "For further details on a command, use -help after the command name"); print_usage_line(1, "e.g. odin build -help"); } - -bool string_is_valid_identifier(String str) { - if (str.len <= 0) return false; - - isize rune_count = 0; - - isize w = 0; - isize offset = 0; - while (offset < str.len) { - Rune r = 0; - w = utf8_decode(str.text, str.len, &r); - if (r == GB_RUNE_INVALID) { - return false; - } - - if (rune_count == 0) { - if (!rune_is_letter(r)) { - return false; - } - } else { - if (!rune_is_letter(r) && !rune_is_digit(r)) { - return false; - } - } - rune_count += 1; - offset += w; - } - - return true; -} - enum BuildFlagKind { BuildFlag_Invalid, BuildFlag_Help, + BuildFlag_SingleFile, BuildFlag_OutFile, BuildFlag_OptimizationLevel, @@ -654,6 +604,10 @@ enum BuildFlagKind { BuildFlag_ExtraLinkerFlags, BuildFlag_ExtraAssemblerFlags, BuildFlag_Microarch, + BuildFlag_TargetFeatures, + + BuildFlag_RelocMode, + BuildFlag_DisableRedZone, BuildFlag_TestName, @@ -662,6 +616,8 @@ enum BuildFlagKind { BuildFlag_InsertSemicolon, BuildFlag_StrictStyle, BuildFlag_StrictStyleInitOnly, + BuildFlag_ForeignErrorProcedures, + BuildFlag_DisallowRTTI, BuildFlag_Compact, BuildFlag_GlobalDefinitions, @@ -674,9 +630,9 @@ enum BuildFlagKind { BuildFlag_IgnoreWarnings, BuildFlag_WarningsAsErrors, BuildFlag_VerboseErrors, - + // internal use only - BuildFlag_InternalIgnoreLazy, + BuildFlag_InternalIgnoreLazy, #if defined(GB_SYSTEM_WINDOWS) BuildFlag_IgnoreVsSearch, @@ -771,69 +727,80 @@ ExactValue build_param_to_exact_value(String name, String param) { bool parse_build_flags(Array args) { auto build_flags = array_make(heap_allocator(), 0, BuildFlag_COUNT); - add_flag(&build_flags, BuildFlag_Help, str_lit("help"), BuildFlagParam_None, Command_all); - add_flag(&build_flags, BuildFlag_OutFile, str_lit("out"), BuildFlagParam_String, Command__does_build &~ Command_test); - add_flag(&build_flags, BuildFlag_OptimizationLevel, str_lit("opt"), BuildFlagParam_Integer, Command__does_build); - add_flag(&build_flags, BuildFlag_OptimizationMode, str_lit("o"), BuildFlagParam_String, Command__does_build); - add_flag(&build_flags, BuildFlag_OptimizationMode, str_lit("O"), BuildFlagParam_String, Command__does_build); - add_flag(&build_flags, BuildFlag_ShowTimings, str_lit("show-timings"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_ShowMoreTimings, str_lit("show-more-timings"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_ExportTimings, str_lit("export-timings"), BuildFlagParam_String, Command__does_check); - add_flag(&build_flags, BuildFlag_ExportTimingsFile, str_lit("export-timings-file"), BuildFlagParam_String, Command__does_check); - add_flag(&build_flags, BuildFlag_ShowUnused, str_lit("show-unused"), BuildFlagParam_None, Command_check); - add_flag(&build_flags, BuildFlag_ShowUnusedWithLocation, str_lit("show-unused-with-location"), BuildFlagParam_None, Command_check); - add_flag(&build_flags, BuildFlag_ShowSystemCalls, str_lit("show-system-calls"), BuildFlagParam_None, Command_all); - add_flag(&build_flags, BuildFlag_ThreadCount, str_lit("thread-count"), BuildFlagParam_Integer, Command_all); - add_flag(&build_flags, BuildFlag_KeepTempFiles, str_lit("keep-temp-files"), BuildFlagParam_None, Command__does_build|Command_strip_semicolon); - add_flag(&build_flags, BuildFlag_Collection, str_lit("collection"), BuildFlagParam_String, Command__does_check); - add_flag(&build_flags, BuildFlag_Define, str_lit("define"), BuildFlagParam_String, Command__does_check, true); - add_flag(&build_flags, BuildFlag_BuildMode, str_lit("build-mode"), BuildFlagParam_String, Command__does_build); // Commands_build is not used to allow for a better error message - add_flag(&build_flags, BuildFlag_Target, str_lit("target"), BuildFlagParam_String, Command__does_check); - add_flag(&build_flags, BuildFlag_Debug, str_lit("debug"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_DisableAssert, str_lit("disable-assert"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_NoBoundsCheck, str_lit("no-bounds-check"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_NoDynamicLiterals, str_lit("no-dynamic-literals"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_NoCRT, str_lit("no-crt"), BuildFlagParam_None, Command__does_build); - add_flag(&build_flags, BuildFlag_NoEntryPoint, str_lit("no-entry-point"), BuildFlagParam_None, Command__does_check &~ Command_test); - add_flag(&build_flags, BuildFlag_UseLLD, str_lit("lld"), BuildFlagParam_None, Command__does_build); - add_flag(&build_flags, BuildFlag_UseSeparateModules,str_lit("use-separate-modules"),BuildFlagParam_None, Command__does_build); - add_flag(&build_flags, BuildFlag_ThreadedChecker, str_lit("threaded-checker"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_NoThreadedChecker, str_lit("no-threaded-checker"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_ShowDebugMessages, str_lit("show-debug-messages"), BuildFlagParam_None, Command_all); - add_flag(&build_flags, BuildFlag_Vet, str_lit("vet"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_VetExtra, str_lit("vet-extra"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_UseLLVMApi, str_lit("llvm-api"), BuildFlagParam_None, Command__does_build); - add_flag(&build_flags, BuildFlag_IgnoreUnknownAttributes, str_lit("ignore-unknown-attributes"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_ExtraLinkerFlags, str_lit("extra-linker-flags"), BuildFlagParam_String, Command__does_build); - add_flag(&build_flags, BuildFlag_ExtraAssemblerFlags, str_lit("extra-assembler-flags"), BuildFlagParam_String, Command__does_build); - add_flag(&build_flags, BuildFlag_Microarch, str_lit("microarch"), BuildFlagParam_String, Command__does_build); + add_flag(&build_flags, BuildFlag_Help, str_lit("help"), BuildFlagParam_None, Command_all); + add_flag(&build_flags, BuildFlag_SingleFile, str_lit("file"), BuildFlagParam_None, Command__does_build | Command__does_check); + add_flag(&build_flags, BuildFlag_OutFile, str_lit("out"), BuildFlagParam_String, Command__does_build &~ Command_test); + add_flag(&build_flags, BuildFlag_OptimizationLevel, str_lit("opt"), BuildFlagParam_Integer, Command__does_build); + add_flag(&build_flags, BuildFlag_OptimizationMode, str_lit("o"), BuildFlagParam_String, Command__does_build); + add_flag(&build_flags, BuildFlag_OptimizationMode, str_lit("O"), BuildFlagParam_String, Command__does_build); + add_flag(&build_flags, BuildFlag_ShowTimings, str_lit("show-timings"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_ShowMoreTimings, str_lit("show-more-timings"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_ExportTimings, str_lit("export-timings"), BuildFlagParam_String, Command__does_check); + add_flag(&build_flags, BuildFlag_ExportTimingsFile, str_lit("export-timings-file"), BuildFlagParam_String, Command__does_check); + add_flag(&build_flags, BuildFlag_ShowUnused, str_lit("show-unused"), BuildFlagParam_None, Command_check); + add_flag(&build_flags, BuildFlag_ShowUnusedWithLocation, str_lit("show-unused-with-location"), BuildFlagParam_None, Command_check); + add_flag(&build_flags, BuildFlag_ShowSystemCalls, str_lit("show-system-calls"), BuildFlagParam_None, Command_all); + add_flag(&build_flags, BuildFlag_ThreadCount, str_lit("thread-count"), BuildFlagParam_Integer, Command_all); + add_flag(&build_flags, BuildFlag_KeepTempFiles, str_lit("keep-temp-files"), BuildFlagParam_None, Command__does_build | Command_strip_semicolon); + add_flag(&build_flags, BuildFlag_Collection, str_lit("collection"), BuildFlagParam_String, Command__does_check); + add_flag(&build_flags, BuildFlag_Define, str_lit("define"), BuildFlagParam_String, Command__does_check, true); + add_flag(&build_flags, BuildFlag_BuildMode, str_lit("build-mode"), BuildFlagParam_String, Command__does_build); // Commands_build is not used to allow for a better error message + add_flag(&build_flags, BuildFlag_Target, str_lit("target"), BuildFlagParam_String, Command__does_check); + add_flag(&build_flags, BuildFlag_Debug, str_lit("debug"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_DisableAssert, str_lit("disable-assert"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_NoBoundsCheck, str_lit("no-bounds-check"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_NoDynamicLiterals, str_lit("no-dynamic-literals"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_NoCRT, str_lit("no-crt"), BuildFlagParam_None, Command__does_build); + add_flag(&build_flags, BuildFlag_NoEntryPoint, str_lit("no-entry-point"), BuildFlagParam_None, Command__does_check &~ Command_test); + add_flag(&build_flags, BuildFlag_UseLLD, str_lit("lld"), BuildFlagParam_None, Command__does_build); + add_flag(&build_flags, BuildFlag_UseSeparateModules, str_lit("use-separate-modules"), BuildFlagParam_None, Command__does_build); + add_flag(&build_flags, BuildFlag_ThreadedChecker, str_lit("threaded-checker"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_NoThreadedChecker, str_lit("no-threaded-checker"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_ShowDebugMessages, str_lit("show-debug-messages"), BuildFlagParam_None, Command_all); + add_flag(&build_flags, BuildFlag_Vet, str_lit("vet"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_VetExtra, str_lit("vet-extra"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_UseLLVMApi, str_lit("llvm-api"), BuildFlagParam_None, Command__does_build); + add_flag(&build_flags, BuildFlag_IgnoreUnknownAttributes, str_lit("ignore-unknown-attributes"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_ExtraLinkerFlags, str_lit("extra-linker-flags"), BuildFlagParam_String, Command__does_build); + add_flag(&build_flags, BuildFlag_ExtraAssemblerFlags, str_lit("extra-assembler-flags"), BuildFlagParam_String, Command__does_build); + add_flag(&build_flags, BuildFlag_Microarch, str_lit("microarch"), BuildFlagParam_String, Command__does_build); + add_flag(&build_flags, BuildFlag_TargetFeatures, str_lit("target-features"), BuildFlagParam_String, Command__does_build); - add_flag(&build_flags, BuildFlag_TestName, str_lit("test-name"), BuildFlagParam_String, Command_test); + add_flag(&build_flags, BuildFlag_RelocMode, str_lit("reloc-mode"), BuildFlagParam_String, Command__does_build); + add_flag(&build_flags, BuildFlag_DisableRedZone, str_lit("disable-red-zone"), BuildFlagParam_None, Command__does_build); - add_flag(&build_flags, BuildFlag_DisallowDo, str_lit("disallow-do"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_DefaultToNilAllocator, str_lit("default-to-nil-allocator"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_InsertSemicolon, str_lit("insert-semicolon"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_StrictStyle, str_lit("strict-style"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_StrictStyleInitOnly, str_lit("strict-style-init-only"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_Compact, str_lit("compact"), BuildFlagParam_None, Command_query); - add_flag(&build_flags, BuildFlag_GlobalDefinitions, str_lit("global-definitions"), BuildFlagParam_None, Command_query); - add_flag(&build_flags, BuildFlag_GoToDefinitions, str_lit("go-to-definitions"), BuildFlagParam_None, Command_query); + add_flag(&build_flags, BuildFlag_TestName, str_lit("test-name"), BuildFlagParam_String, Command_test); - add_flag(&build_flags, BuildFlag_Short, str_lit("short"), BuildFlagParam_None, Command_doc); - add_flag(&build_flags, BuildFlag_AllPackages, str_lit("all-packages"), BuildFlagParam_None, Command_doc); - add_flag(&build_flags, BuildFlag_DocFormat, str_lit("doc-format"), BuildFlagParam_None, Command_doc); + add_flag(&build_flags, BuildFlag_DisallowDo, str_lit("disallow-do"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_DefaultToNilAllocator, str_lit("default-to-nil-allocator"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_InsertSemicolon, str_lit("insert-semicolon"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_StrictStyle, str_lit("strict-style"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_StrictStyleInitOnly, str_lit("strict-style-init-only"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_ForeignErrorProcedures, str_lit("foreign-error-procedures"), BuildFlagParam_None, Command__does_check); - add_flag(&build_flags, BuildFlag_IgnoreWarnings, str_lit("ignore-warnings"), BuildFlagParam_None, Command_all); - add_flag(&build_flags, BuildFlag_WarningsAsErrors, str_lit("warnings-as-errors"), BuildFlagParam_None, Command_all); - add_flag(&build_flags, BuildFlag_VerboseErrors, str_lit("verbose-errors"), BuildFlagParam_None, Command_all); - - add_flag(&build_flags, BuildFlag_InternalIgnoreLazy, str_lit("internal-ignore-lazy"), BuildFlagParam_None, Command_all); + add_flag(&build_flags, BuildFlag_DisallowRTTI, str_lit("disallow-rtti"), BuildFlagParam_None, Command__does_check); + + + add_flag(&build_flags, BuildFlag_Compact, str_lit("compact"), BuildFlagParam_None, Command_query); + add_flag(&build_flags, BuildFlag_GlobalDefinitions, str_lit("global-definitions"), BuildFlagParam_None, Command_query); + add_flag(&build_flags, BuildFlag_GoToDefinitions, str_lit("go-to-definitions"), BuildFlagParam_None, Command_query); + + + add_flag(&build_flags, BuildFlag_Short, str_lit("short"), BuildFlagParam_None, Command_doc); + add_flag(&build_flags, BuildFlag_AllPackages, str_lit("all-packages"), BuildFlagParam_None, Command_doc); + add_flag(&build_flags, BuildFlag_DocFormat, str_lit("doc-format"), BuildFlagParam_None, Command_doc); + + add_flag(&build_flags, BuildFlag_IgnoreWarnings, str_lit("ignore-warnings"), BuildFlagParam_None, Command_all); + add_flag(&build_flags, BuildFlag_WarningsAsErrors, str_lit("warnings-as-errors"), BuildFlagParam_None, Command_all); + add_flag(&build_flags, BuildFlag_VerboseErrors, str_lit("verbose-errors"), BuildFlagParam_None, Command_all); + + add_flag(&build_flags, BuildFlag_InternalIgnoreLazy, str_lit("internal-ignore-lazy"), BuildFlagParam_None, Command_all); #if defined(GB_SYSTEM_WINDOWS) - add_flag(&build_flags, BuildFlag_IgnoreVsSearch, str_lit("ignore-vs-search"), BuildFlagParam_None, Command__does_build); - add_flag(&build_flags, BuildFlag_ResourceFile, str_lit("resource"), BuildFlagParam_String, Command__does_build); - add_flag(&build_flags, BuildFlag_WindowsPdbName, str_lit("pdb-name"), BuildFlagParam_String, Command__does_build); - add_flag(&build_flags, BuildFlag_Subsystem, str_lit("subsystem"), BuildFlagParam_String, Command__does_build); + add_flag(&build_flags, BuildFlag_IgnoreVsSearch, str_lit("ignore-vs-search"), BuildFlagParam_None, Command__does_build); + add_flag(&build_flags, BuildFlag_ResourceFile, str_lit("resource"), BuildFlagParam_String, Command__does_build); + add_flag(&build_flags, BuildFlag_WindowsPdbName, str_lit("pdb-name"), BuildFlagParam_String, Command__does_build); + add_flag(&build_flags, BuildFlag_Subsystem, str_lit("subsystem"), BuildFlagParam_String, Command__does_build); #endif @@ -1280,7 +1247,7 @@ bool parse_build_flags(Array args) { } else { gb_printf_err("Unknown build mode '%.*s'\n", LIT(str)); gb_printf_err("Valid build modes:\n"); - gb_printf_err("\tdll, shared\n"); + gb_printf_err("\tdll, shared, dynamic\n"); gb_printf_err("\tobj, object\n"); gb_printf_err("\texe\n"); gb_printf_err("\tasm, assembly, assembler\n"); @@ -1355,7 +1322,7 @@ bool parse_build_flags(Array args) { GB_ASSERT(value.kind == ExactValue_String); build_context.extra_linker_flags = value.value_string; break; - case BuildFlag_ExtraAssemblerFlags: + case BuildFlag_ExtraAssemblerFlags: GB_ASSERT(value.kind == ExactValue_String); build_context.extra_assembler_flags = value.value_string; break; @@ -1365,6 +1332,37 @@ bool parse_build_flags(Array args) { string_to_lower(&build_context.microarch); break; } + case BuildFlag_TargetFeatures: { + GB_ASSERT(value.kind == ExactValue_String); + build_context.target_features = value.value_string; + string_to_lower(&build_context.target_features); + break; + } + case BuildFlag_RelocMode: { + GB_ASSERT(value.kind == ExactValue_String); + String v = value.value_string; + if (v == "default") { + build_context.reloc_mode = RelocMode_Default; + } else if (v == "static") { + build_context.reloc_mode = RelocMode_Static; + } else if (v == "pic") { + build_context.reloc_mode = RelocMode_PIC; + } else if (v == "dynamic-no-pic") { + build_context.reloc_mode = RelocMode_DynamicNoPIC; + } else { + gb_printf_err("-reloc-mode flag expected one of the following\n"); + gb_printf_err("\tdefault\n"); + gb_printf_err("\tstatic\n"); + gb_printf_err("\tpic\n"); + gb_printf_err("\tdynamic-no-pic\n"); + bad_flags = true; + } + + break; + } + case BuildFlag_DisableRedZone: + build_context.disable_red_zone = true; + break; case BuildFlag_TestName: { GB_ASSERT(value.kind == ExactValue_String); { @@ -1383,9 +1381,15 @@ bool parse_build_flags(Array args) { case BuildFlag_DisallowDo: build_context.disallow_do = true; break; + case BuildFlag_DisallowRTTI: + build_context.disallow_rtti = true; + break; case BuildFlag_DefaultToNilAllocator: build_context.ODIN_DEFAULT_TO_NIL_ALLOCATOR = true; break; + case BuildFlag_ForeignErrorProcedures: + build_context.ODIN_FOREIGN_ERROR_PROCEDURES = true; + break; case BuildFlag_InsertSemicolon: { gb_printf_err("-insert-semicolon flag is not required any more\n"); bad_flags = true; @@ -1486,6 +1490,10 @@ bool parse_build_flags(Array args) { gb_printf_err("Invalid -resource path %.*s, missing .rc\n", LIT(path)); bad_flags = true; break; + } else if (!gb_file_exists((const char *)path.text)) { + gb_printf_err("Invalid -resource path %.*s, file does not exist.\n", LIT(path)); + bad_flags = true; + break; } build_context.resource_filepath = substring(path, 0, string_extension_position(path)); build_context.has_resource = true; @@ -1500,6 +1508,11 @@ bool parse_build_flags(Array args) { String path = value.value_string; path = string_trim_whitespace(path); if (is_build_flag_path_valid(path)) { + if (path_is_directory(path)) { + gb_printf_err("Invalid -pdb-name path. %.*s, is a directory.\n", LIT(path)); + bad_flags = true; + break; + } // #if defined(GB_SYSTEM_WINDOWS) // String ext = path_extension(path); // if (ext != ".pdb") { @@ -1817,7 +1830,7 @@ void show_timings(Checker *c, Timings *t) { void remove_temp_files(lbGenerator *gen) { if (build_context.keep_temp_files) return; - + TIME_SECTION("remove keep temp files"); for_array(i, gen->output_temp_paths) { @@ -1841,32 +1854,47 @@ void remove_temp_files(lbGenerator *gen) { void print_show_help(String const arg0, String const &command) { print_usage_line(0, "%.*s is a tool for managing Odin source code", LIT(arg0)); - print_usage_line(0, "Usage"); + print_usage_line(0, "Usage:"); print_usage_line(1, "%.*s %.*s [arguments]", LIT(arg0), LIT(command)); print_usage_line(0, ""); if (command == "build") { - print_usage_line(1, "build compile .odin file, or directory of .odin files, as an executable."); - print_usage_line(1, " one must contain the program's entry point, all must be in the same package."); - } else if (command == "run") { - print_usage_line(1, "run same as 'build', but also then runs the newly compiled executable."); - } else if (command == "check") { - print_usage_line(1, "check parse and type check .odin file(s)"); - } else if (command == "test") { - print_usage_line(1, "test build ands runs procedures with the attribute @(test) in the initial package"); - } else if (command == "query") { - print_usage_line(1, "query [experimental] parse, type check, and output a .json file containing information about the program"); - } else if (command == "doc") { - print_usage_line(1, "doc generate documentation from a .odin file, or directory of .odin files"); + print_usage_line(1, "build Compile directory of .odin files as an executable."); + print_usage_line(2, "One must contain the program's entry point, all must be in the same package."); + print_usage_line(2, "Use `-file` to build a single file instead."); print_usage_line(2, "Examples:"); - print_usage_line(3, "odin doc core/path"); - print_usage_line(3, "odin doc core/path core/path/filepath"); + print_usage_line(3, "odin build . # Build package in current directory"); + print_usage_line(3, "odin build # Build package in "); + print_usage_line(3, "odin build filename.odin -file # Build single-file package, must contain entry point."); + } else if (command == "run") { + print_usage_line(1, "run Same as 'build', but also then runs the newly compiled executable."); + print_usage_line(2, "Append an empty flag and then the args, '-- ', to specify args for the output."); + print_usage_line(2, "Examples:"); + print_usage_line(3, "odin run . # Build and run package in current directory"); + print_usage_line(3, "odin run # Build and run package in "); + print_usage_line(3, "odin run filename.odin -file # Build and run single-file package, must contain entry point."); + } else if (command == "check") { + print_usage_line(1, "check Parse and type check directory of .odin files"); + print_usage_line(2, "Examples:"); + print_usage_line(3, "odin check . # Type check package in current directory"); + print_usage_line(3, "odin check # Type check package in "); + print_usage_line(3, "odin check filename.odin -file # Type check single-file package, must contain entry point."); + } else if (command == "test") { + print_usage_line(1, "test Build ands runs procedures with the attribute @(test) in the initial package"); + } else if (command == "query") { + print_usage_line(1, "query [experimental] Parse, type check, and output a .json file containing information about the program"); + } else if (command == "doc") { + print_usage_line(1, "doc generate documentation from a directory of .odin files"); + print_usage_line(2, "Examples:"); + print_usage_line(3, "odin doc . # Generate documentation on package in current directory"); + print_usage_line(3, "odin doc # Generate documentation on package in "); + print_usage_line(3, "odin doc filename.odin -file # Generate documentation on single-file package."); } else if (command == "version") { print_usage_line(1, "version print version"); } else if (command == "strip-semicolon") { print_usage_line(1, "strip-semicolon"); - print_usage_line(2, "parse and type check .odin file(s) and then remove unneeded semicolons from the entire project"); - } + print_usage_line(2, "Parse and type check .odin file(s) and then remove unneeded semicolons from the entire project"); + } bool doc = command == "doc"; bool build = command == "build"; @@ -1880,6 +1908,13 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(1, "Flags"); print_usage_line(0, ""); + if (check) { + print_usage_line(1, "-file"); + print_usage_line(2, "Tells `%.*s %.*s` to treat the given file as a self-contained package.", LIT(arg0), LIT(command)); + print_usage_line(2, "This means that `/a.odin` won't have access to `/b.odin`'s contents."); + print_usage_line(0, ""); + } + if (doc) { print_usage_line(1, "-short"); print_usage_line(2, "Show shortened documentation for the packages"); @@ -1970,6 +2005,7 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(1, "-define:="); print_usage_line(2, "Defines a global constant with a value"); print_usage_line(2, "Example: -define:SPAM=123"); + print_usage_line(2, "To use: #config(SPAM, default_value)"); print_usage_line(0, ""); } @@ -2071,7 +2107,7 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(1, "-extra-linker-flags:"); print_usage_line(2, "Adds extra linker specific flags in a string"); print_usage_line(0, ""); - + print_usage_line(1, "-extra-assembler-flags:"); print_usage_line(2, "Adds extra assembler specific flags in a string"); print_usage_line(0, ""); @@ -2083,6 +2119,18 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(3, "-microarch:sandybridge"); print_usage_line(3, "-microarch:native"); print_usage_line(0, ""); + + print_usage_line(1, "-reloc-mode:"); + print_usage_line(2, "Specifies the reloc mode"); + print_usage_line(2, "Options:"); + print_usage_line(3, "default"); + print_usage_line(3, "static"); + print_usage_line(3, "pic"); + print_usage_line(3, "dynamic-no-pic"); + print_usage_line(0, ""); + + print_usage_line(1, "-disable-red-zone"); + print_usage_line(2, "Disable red zone on a supported freestanding target"); } if (check) { @@ -2097,7 +2145,7 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(1, "-strict-style"); print_usage_line(2, "Errs on unneeded tokens, such as unneeded semicolons"); print_usage_line(0, ""); - + print_usage_line(1, "-strict-style-init-only"); print_usage_line(2, "Errs on unneeded tokens, such as unneeded semicolons, only on the initial project"); print_usage_line(0, ""); @@ -2113,6 +2161,11 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(1, "-verbose-errors"); print_usage_line(2, "Prints verbose error messages showing the code on that line and the location in that line"); print_usage_line(0, ""); + + print_usage_line(1, "-foreign-error-procedures"); + print_usage_line(2, "States that the error procedues used in the runtime are defined in a separate translation unit"); + print_usage_line(0, ""); + } if (run_or_build) { @@ -2262,7 +2315,7 @@ gbFileError write_file_with_stripped_tokens(gbFile *f, AstFile *file, i64 *writt } written += to_write; prev_offset = token_pos_end(*token).offset; - } + } if (token->flags & TokenFlag_Replace) { if (token->kind == Token_Ellipsis) { if (!gb_file_write(f, "..=", 3)) { @@ -2281,7 +2334,7 @@ gbFileError write_file_with_stripped_tokens(gbFile *f, AstFile *file, i64 *writt } written += to_write; } - + if (written_) *written_ = written; return err; } @@ -2292,14 +2345,14 @@ int strip_semicolons(Parser *parser) { AstPackage *pkg = parser->packages[i]; file_count += pkg->files.count; } - + auto generated_files = array_make(permanent_allocator(), 0, file_count); - + for_array(i, parser->packages) { AstPackage *pkg = parser->packages[i]; for_array(j, pkg->files) { AstFile *file = pkg->files[j]; - + bool nothing_to_change = true; for_array(i, file->tokens) { Token *token = &file->tokens[i]; @@ -2308,29 +2361,29 @@ int strip_semicolons(Parser *parser) { break; } } - + if (nothing_to_change) { continue; } - + String old_fullpath = copy_string(permanent_allocator(), file->fullpath); - + // assumes .odin extension String fullpath_base = substring(old_fullpath, 0, old_fullpath.len-5); - + String old_fullpath_backup = concatenate_strings(permanent_allocator(), fullpath_base, str_lit("~backup.odin-temp")); String new_fullpath = concatenate_strings(permanent_allocator(), fullpath_base, str_lit("~temp.odin-temp")); - + array_add(&generated_files, StripSemicolonFile{old_fullpath, old_fullpath_backup, new_fullpath, file}); } } - + gb_printf_err("File count to be stripped of unneeded tokens: %td\n", generated_files.count); - - + + isize generated_count = 0; bool failed = false; - + for_array(i, generated_files) { auto *file = &generated_files[i]; char const *filename = cast(char const *)file->new_fullpath.text; @@ -2338,15 +2391,15 @@ int strip_semicolons(Parser *parser) { defer (if (err != gbFileError_None) { failed = true; }); - - gbFile f = {}; + + gbFile f = {}; err = gb_file_create(&f, filename); if (err) { break; } defer (err = gb_file_close(&f)); generated_count += 1; - + i64 written = 0; defer (err = gb_file_truncate(&f, written)); @@ -2367,23 +2420,23 @@ int strip_semicolons(Parser *parser) { } return 1; } - + isize overwritten_files = 0; - + for_array(i, generated_files) { auto *file = &generated_files[i]; - + char const *old_fullpath = cast(char const *)file->old_fullpath.text; char const *old_fullpath_backup = cast(char const *)file->old_fullpath_backup.text; char const *new_fullpath = cast(char const *)file->new_fullpath.text; - + debugf("Copy '%s' to '%s'\n", old_fullpath, old_fullpath_backup); if (!gb_file_copy(old_fullpath, old_fullpath_backup, false)) { gb_printf_err("failed to copy '%s' to '%s'\n", old_fullpath, old_fullpath_backup); failed = true; break; } - + debugf("Copy '%s' to '%s'\n", new_fullpath, old_fullpath); if (!gb_file_copy(new_fullpath, old_fullpath, false)) { @@ -2400,19 +2453,19 @@ int strip_semicolons(Parser *parser) { if (!gb_file_remove(old_fullpath_backup)) { gb_printf_err("failed to remove '%s'\n", old_fullpath_backup); } - + overwritten_files++; } - + if (!build_context.keep_temp_files) { for_array(i, generated_files) { auto *file = &generated_files[i]; char const *filename = nullptr; filename = cast(char const *)file->new_fullpath.text; - + debugf("Remove '%s'\n", filename); GB_ASSERT_MSG(gb_file_remove(filename), "unable to delete file %s", filename); - + filename = cast(char const *)file->old_fullpath_backup.text; debugf("Remove '%s'\n", filename); if (gb_file_exists(filename) && !gb_file_remove(filename)) { @@ -2423,15 +2476,13 @@ int strip_semicolons(Parser *parser) { } } } - + gb_printf_err("Files stripped of unneeded token: %td\n", generated_files.count); - - + + return cast(int)failed; } - - int main(int arg_count, char const **arg_ptr) { if (arg_count < 2) { usage(make_string_c(arg_ptr[0])); @@ -2442,10 +2493,11 @@ int main(int arg_count, char const **arg_ptr) { defer (timings_destroy(&global_timings)); MAIN_TIME_SECTION("initialization"); - + virtual_memory_init(); mutex_init(&fullpath_mutex); mutex_init(&hash_exact_value_mutex); + mutex_init(&global_type_name_objc_metadata_mutex); init_string_buffer_memory(); init_string_interner(); @@ -2471,6 +2523,7 @@ int main(int arg_count, char const **arg_ptr) { String command = args[1]; String init_filename = {}; String run_args_string = {}; + isize last_non_run_arg = args.count; bool run_output = false; if (command == "run" || command == "test") { @@ -2486,7 +2539,6 @@ int main(int arg_count, char const **arg_ptr) { Array run_args = array_make(heap_allocator(), 0, arg_count); defer (array_free(&run_args)); - isize last_non_run_arg = args.count; for_array(i, args) { if (args[i] == "--") { last_non_run_arg = i; @@ -2499,6 +2551,7 @@ int main(int arg_count, char const **arg_ptr) { args = array_slice(args, 0, last_non_run_arg); run_args_string = string_join_and_quote(heap_allocator(), run_args); + init_filename = args[2]; run_output = true; @@ -2586,11 +2639,40 @@ int main(int arg_count, char const **arg_ptr) { return 1; } + init_filename = copy_string(permanent_allocator(), init_filename); + if (init_filename == "-help" || init_filename == "--help") { build_context.show_help = true; } + if (init_filename.len > 0 && !build_context.show_help) { + // The command must be build, run, test, check, or another that takes a directory or filename. + if (!path_is_directory(init_filename)) { + // Input package is a filename. We allow this only if `-file` was given, otherwise we exit with an error message. + bool single_file_package = false; + for_array(i, args) { + if (i >= 3 && i <= last_non_run_arg && args[i] == "-file") { + single_file_package = true; + break; + } + } + + if (!single_file_package) { + gb_printf_err("ERROR: `%.*s %.*s` takes a package as its first argument.\n", LIT(args[0]), LIT(command)); + gb_printf_err("Did you mean `%.*s %.*s %.*s -file`?\n", LIT(args[0]), LIT(command), LIT(init_filename)); + gb_printf_err("The `-file` flag tells it to treat a file as a self-contained package.\n"); + return 1; + } else { + String const ext = str_lit(".odin"); + if (!string_ends_with(init_filename, ext)) { + gb_printf_err("Expected either a directory or a .odin file, got '%.*s'\n", LIT(init_filename)); + return 1; + } + } + } + } + build_context.command = command; if (!parse_build_flags(args)) { @@ -2605,19 +2687,30 @@ int main(int arg_count, char const **arg_ptr) { // NOTE(bill): add 'shared' directory if it is not already set if (!find_library_collection_path(str_lit("shared"), nullptr)) { add_library_collection(str_lit("shared"), - get_fullpath_relative(heap_allocator(), odin_root_dir(), str_lit("shared"))); + get_fullpath_relative(heap_allocator(), odin_root_dir(), str_lit("shared"))); } - init_build_context(selected_target_metrics ? selected_target_metrics->metrics : nullptr); // if (build_context.word_size == 4 && build_context.metrics.os != TargetOs_js) { // print_usage_line(0, "%.*s 32-bit is not yet supported for this platform", LIT(args[0])); // return 1; // } + // Set and check build paths... + if (!init_build_paths(init_filename)) { + return 1; + } + + if (build_context.show_debug_messages) { + for_array(i, build_context.build_paths) { + String build_path = path_to_string(heap_allocator(), build_context.build_paths[i]); + debugf("build_paths[%ld]: %.*s\n", i, LIT(build_path)); + } + } + init_global_thread_pool(); defer (thread_pool_destroy(&global_thread_pool)); - + init_universal(); // TODO(bill): prevent compiling without a linker @@ -2631,6 +2724,8 @@ int main(int arg_count, char const **arg_ptr) { } defer (destroy_parser(parser)); + // TODO(jeroen): Remove the `init_filename` param. + // Let's put that on `build_context.build_paths[0]` instead. if (parse_packages(parser, init_filename) != ParseFile_None) { return 1; } @@ -2649,7 +2744,7 @@ int main(int arg_count, char const **arg_ptr) { if (any_errors()) { return 1; } - + if (build_context.command_kind == Command_strip_semicolon) { return strip_semicolons(parser); } @@ -2703,22 +2798,20 @@ int main(int arg_count, char const **arg_ptr) { } remove_temp_files(gen); - + if (build_context.show_timings) { show_timings(checker, &global_timings); } if (run_output) { + String exe_name = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Output]); + defer (gb_free(heap_allocator(), exe_name.text)); + #if defined(GB_SYSTEM_WINDOWS) - return system_exec_command_line_app("odin run", "%.*s.exe %.*s", LIT(gen->output_base), LIT(run_args_string)); + return system_exec_command_line_app("odin run", "%.*s %.*s", LIT(exe_name), LIT(run_args_string)); #else - //NOTE(thebirk): This whole thing is a little leaky - String output_ext = {}; - String complete_path = concatenate_strings(permanent_allocator(), gen->output_base, output_ext); - complete_path = path_to_full_path(permanent_allocator(), complete_path); - return system_exec_command_line_app("odin run", "\"%.*s\" %.*s", LIT(complete_path), LIT(run_args_string)); + return system_exec_command_line_app("odin run", "\"%.*s\" %.*s", LIT(exe_name), LIT(run_args_string)); #endif } - return 0; } diff --git a/src/microsoft_craziness.h b/src/microsoft_craziness.h index 02f14dda3..b4f815284 100644 --- a/src/microsoft_craziness.h +++ b/src/microsoft_craziness.h @@ -460,7 +460,7 @@ bool find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *res wchar_t *library_path = nullptr; if (build_context.metrics.arch == TargetArch_amd64) { library_path = concat(bstr_inst_path, L"\\VC\\Tools\\MSVC\\", version, L"\\lib\\x64\\"); - } else if (build_context.metrics.arch == TargetArch_386) { + } else if (build_context.metrics.arch == TargetArch_i386) { library_path = concat(bstr_inst_path, L"\\VC\\Tools\\MSVC\\", version, L"\\lib\\x86\\"); } else { continue; @@ -472,7 +472,7 @@ bool find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *res wchar_t *link_exe_path = nullptr; if (build_context.metrics.arch == TargetArch_amd64) { link_exe_path = concat(bstr_inst_path, L"\\VC\\Tools\\MSVC\\", version, L"\\bin\\Hostx64\\x64\\"); - } else if (build_context.metrics.arch == TargetArch_386) { + } else if (build_context.metrics.arch == TargetArch_i386) { link_exe_path = concat(bstr_inst_path, L"\\VC\\Tools\\MSVC\\", version, L"\\bin\\Hostx86\\x86\\"); } else { continue; @@ -529,7 +529,7 @@ bool find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *res if (build_context.metrics.arch == TargetArch_amd64) { lib_path = concat(buffer, L"VC\\Lib\\amd64\\"); - } else if (build_context.metrics.arch == TargetArch_386) { + } else if (build_context.metrics.arch == TargetArch_i386) { lib_path = concat(buffer, L"VC\\Lib\\"); } else { continue; @@ -542,7 +542,7 @@ bool find_visual_studio_by_fighting_through_microsoft_craziness(Find_Result *res if (os_file_exists(vcruntime_filename)) { if (build_context.metrics.arch == TargetArch_amd64) { result->vs_exe_path = concat(buffer, L"VC\\bin\\"); - } else if (build_context.metrics.arch == TargetArch_386) { + } else if (build_context.metrics.arch == TargetArch_i386) { // result->vs_exe_path = concat(buffer, L"VC\\bin\\amd64_x86\\"); result->vs_exe_path = concat(buffer, L"VC\\bin\\x86_amd64\\"); } else { @@ -573,7 +573,7 @@ Find_Result find_visual_studio_and_windows_sdk() { if (build_context.metrics.arch == TargetArch_amd64) { result.windows_sdk_um_library_path = concat(result.windows_sdk_root, L"um\\x64\\"); result.windows_sdk_ucrt_library_path = concat(result.windows_sdk_root, L"ucrt\\x64\\"); - } else if (build_context.metrics.arch == TargetArch_386) { + } else if (build_context.metrics.arch == TargetArch_i386) { result.windows_sdk_um_library_path = concat(result.windows_sdk_root, L"um\\x86\\"); result.windows_sdk_ucrt_library_path = concat(result.windows_sdk_root, L"ucrt\\x86\\"); } diff --git a/src/parser.cpp b/src/parser.cpp index cbd4d61d5..df7f908a6 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -57,6 +57,9 @@ isize ast_node_size(AstKind kind) { return align_formula_isize(gb_size_of(AstCommonStuff) + ast_variant_sizes[kind], gb_align_of(void *)); } + +gb_global std::atomic global_total_node_memory_allocated; + // NOTE(bill): And this below is why is I/we need a new language! Discriminated unions are a pain in C/C++ Ast *alloc_ast_node(AstFile *f, AstKind kind) { gbAllocator a = ast_allocator(f); @@ -66,6 +69,9 @@ Ast *alloc_ast_node(AstFile *f, AstKind kind) { Ast *node = cast(Ast *)gb_alloc(a, size); node->kind = kind; node->file_id = f ? f->id : 0; + + global_total_node_memory_allocated += size; + return node; } @@ -183,6 +189,11 @@ Ast *clone_ast(Ast *node) { n->FieldValue.value = clone_ast(n->FieldValue.value); break; + case Ast_EnumFieldValue: + n->EnumFieldValue.name = clone_ast(n->EnumFieldValue.name); + n->EnumFieldValue.value = clone_ast(n->EnumFieldValue.value); + break; + case Ast_TernaryIfExpr: n->TernaryIfExpr.x = clone_ast(n->TernaryIfExpr.x); n->TernaryIfExpr.cond = clone_ast(n->TernaryIfExpr.cond); @@ -693,6 +704,16 @@ Ast *ast_field_value(AstFile *f, Ast *field, Ast *value, Token eq) { return result; } + +Ast *ast_enum_field_value(AstFile *f, Ast *name, Ast *value, CommentGroup *docs, CommentGroup *comment) { + Ast *result = alloc_ast_node(f, Ast_EnumFieldValue); + result->EnumFieldValue.name = name; + result->EnumFieldValue.value = value; + result->EnumFieldValue.docs = docs; + result->EnumFieldValue.comment = comment; + return result; +} + Ast *ast_compound_lit(AstFile *f, Ast *type, Array const &elems, Token open, Token close) { Ast *result = alloc_ast_node(f, Ast_CompoundLit); result->CompoundLit.type = type; @@ -944,7 +965,7 @@ Ast *ast_field(AstFile *f, Array const &names, Ast *type, Ast *default_va result->Field.default_value = default_value; result->Field.flags = flags; result->Field.tag = tag; - result->Field.docs = docs; + result->Field.docs = docs; result->Field.comment = comment; return result; } @@ -1050,15 +1071,14 @@ Ast *ast_struct_type(AstFile *f, Token token, Slice fields, isize field_c } -Ast *ast_union_type(AstFile *f, Token token, Array const &variants, Ast *polymorphic_params, Ast *align, bool no_nil, bool maybe, +Ast *ast_union_type(AstFile *f, Token token, Array const &variants, Ast *polymorphic_params, Ast *align, UnionTypeKind kind, Token where_token, Array const &where_clauses) { Ast *result = alloc_ast_node(f, Ast_UnionType); result->UnionType.token = token; result->UnionType.variants = slice_from_array(variants); result->UnionType.polymorphic_params = polymorphic_params; result->UnionType.align = align; - result->UnionType.no_nil = no_nil; - result->UnionType.maybe = maybe; + result->UnionType.kind = kind; result->UnionType.where_token = where_token; result->UnionType.where_clauses = slice_from_array(where_clauses); return result; @@ -1234,7 +1254,7 @@ CommentGroup *consume_comment_group(AstFile *f, isize n, isize *end_line_) { return comments; } -void comsume_comment_groups(AstFile *f, Token prev) { +void consume_comment_groups(AstFile *f, Token prev) { if (f->curr_token.kind == Token_Comment) { CommentGroup *comment = nullptr; isize end_line = 0; @@ -1278,7 +1298,7 @@ Token advance_token(AstFile *f) { if (ok) { switch (f->curr_token.kind) { case Token_Comment: - comsume_comment_groups(f, prev); + consume_comment_groups(f, prev); break; case Token_Semicolon: if (ignore_newlines(f) && f->curr_token.string == "\n") { @@ -1517,7 +1537,7 @@ void fix_advance_to_next_stmt(AstFile *f) { Token expect_closing(AstFile *f, TokenKind kind, String context) { if (f->curr_token.kind != kind && f->curr_token.kind == Token_Semicolon && - f->curr_token.string == "\n") { + (f->curr_token.string == "\n" || f->curr_token.kind == Token_EOF)) { Token tok = f->prev_token; tok.pos.column += cast(i32)tok.string.len; syntax_error(tok, "Missing ',' before newline in %.*s", LIT(context)); @@ -1539,6 +1559,7 @@ void assign_removal_flag_to_semicolon(AstFile *f) { switch (curr_token->kind) { case Token_CloseBrace: case Token_CloseParen: + case Token_EOF: ok = true; break; } @@ -1555,7 +1576,7 @@ void assign_removal_flag_to_semicolon(AstFile *f) { } } -void expect_semicolon(AstFile *f, Ast *s) { +void expect_semicolon(AstFile *f) { Token prev_token = {}; if (allow_token(f, Token_Semicolon)) { @@ -1580,17 +1601,17 @@ void expect_semicolon(AstFile *f, Ast *s) { if (f->curr_token.kind == Token_EOF) { return; } - - if (s != nullptr) { - return; - } switch (f->curr_token.kind) { case Token_EOF: return; } - String p = token_to_string(f->curr_token); - syntax_error(prev_token, "Expected ';', got %.*s", LIT(p)); - fix_advance_to_next_stmt(f); + + if (f->curr_token.pos.line == f->prev_token.pos.line) { + String p = token_to_string(f->curr_token); + prev_token.pos = token_pos_end(prev_token); + syntax_error(prev_token, "Expected ';', got %.*s", LIT(p)); + fix_advance_to_next_stmt(f); + } } @@ -1689,6 +1710,46 @@ Array parse_element_list(AstFile *f) { return elems; } +CommentGroup *consume_line_comment(AstFile *f) { + CommentGroup *comment = f->line_comment; + if (f->line_comment == f->lead_comment) { + f->lead_comment = nullptr; + } + f->line_comment = nullptr; + return comment; + +} + +Array parse_enum_field_list(AstFile *f) { + auto elems = array_make(heap_allocator()); + + while (f->curr_token.kind != Token_CloseBrace && + f->curr_token.kind != Token_EOF) { + CommentGroup *docs = f->lead_comment; + CommentGroup *comment = nullptr; + Ast *name = parse_value(f); + Ast *value = nullptr; + if (f->curr_token.kind == Token_Eq) { + Token eq = expect_token(f, Token_Eq); + value = parse_value(f); + } + + comment = consume_line_comment(f); + + Ast *elem = ast_enum_field_value(f, name, value, docs, comment); + array_add(&elems, elem); + + if (!allow_token(f, Token_Comma)) { + break; + } + + if (!elem->EnumFieldValue.comment) { + elem->EnumFieldValue.comment = consume_line_comment(f); + } + } + + return elems; +} Ast *parse_literal_value(AstFile *f, Ast *type) { Array elems = {}; @@ -1793,6 +1854,8 @@ void parse_proc_tags(AstFile *f, u64 *tags) { ELSE_IF_ADD_TAG(require_results) ELSE_IF_ADD_TAG(bounds_check) ELSE_IF_ADD_TAG(no_bounds_check) + ELSE_IF_ADD_TAG(type_assert) + ELSE_IF_ADD_TAG(no_type_assert) else { syntax_error(tag_expr, "Unknown procedure type tag #%.*s", LIT(tag_name)); } @@ -1803,6 +1866,10 @@ void parse_proc_tags(AstFile *f, u64 *tags) { if ((*tags & ProcTag_bounds_check) && (*tags & ProcTag_no_bounds_check)) { syntax_error(f->curr_token, "You cannot apply both #bounds_check and #no_bounds_check to a procedure"); } + + if ((*tags & ProcTag_type_assert) && (*tags & ProcTag_no_type_assert)) { + syntax_error(f->curr_token, "You cannot apply both #type_assert and #no_type_assert to a procedure"); + } } @@ -1950,11 +2017,23 @@ Ast *parse_check_directive_for_statement(Ast *s, Token const &tag_token, u16 sta syntax_error(tag_token, "#bounds_check and #no_bounds_check cannot be applied together"); } break; + case StateFlag_type_assert: + if ((s->state_flags & StateFlag_no_type_assert) != 0) { + syntax_error(tag_token, "#type_assert and #no_type_assert cannot be applied together"); + } + break; + case StateFlag_no_type_assert: + if ((s->state_flags & StateFlag_type_assert) != 0) { + syntax_error(tag_token, "#type_assert and #no_type_assert cannot be applied together"); + } + break; } switch (state_flag) { case StateFlag_bounds_check: case StateFlag_no_bounds_check: + case StateFlag_type_assert: + case StateFlag_no_type_assert: switch (s->kind) { case Ast_BlockStmt: case Ast_IfStmt: @@ -2062,6 +2141,22 @@ Ast *parse_operand(AstFile *f, bool lhs) { } return original_type; } else if (name.string == "partial") { + Ast *tag = ast_basic_directive(f, token, name); + Ast *original_expr = parse_expr(f, lhs); + Ast *expr = unparen_expr(original_expr); + switch (expr->kind) { + case Ast_ArrayType: + syntax_error(expr, "#partial has been replaced with #sparse for non-contiguous enumerated array types"); + break; + case Ast_CompoundLit: + expr->CompoundLit.tag = tag; + break; + default: + syntax_error(expr, "Expected a compound literal after #%.*s, got %.*s", LIT(name.string), LIT(ast_strings[expr->kind])); + break; + } + return original_expr; + } else if (name.string == "sparse") { Ast *tag = ast_basic_directive(f, token, name); Ast *original_type = parse_type(f); Ast *type = unparen_expr(original_type); @@ -2078,6 +2173,12 @@ Ast *parse_operand(AstFile *f, bool lhs) { } else if (name.string == "no_bounds_check") { Ast *operand = parse_expr(f, lhs); return parse_check_directive_for_statement(operand, name, StateFlag_no_bounds_check); + } else if (name.string == "type_assert") { + Ast *operand = parse_expr(f, lhs); + return parse_check_directive_for_statement(operand, name, StateFlag_type_assert); + } else if (name.string == "no_type_assert") { + Ast *operand = parse_expr(f, lhs); + return parse_check_directive_for_statement(operand, name, StateFlag_no_type_assert); } else if (name.string == "relative") { Ast *tag = ast_basic_directive(f, token, name); tag = parse_call_expr(f, tag); @@ -2174,6 +2275,12 @@ Ast *parse_operand(AstFile *f, bool lhs) { if (tags & ProcTag_bounds_check) { body->state_flags |= StateFlag_bounds_check; } + if (tags & ProcTag_no_type_assert) { + body->state_flags |= StateFlag_no_type_assert; + } + if (tags & ProcTag_type_assert) { + body->state_flags |= StateFlag_type_assert; + } return ast_proc_lit(f, type, body, tags, where_token, where_clauses); } else if (allow_token(f, Token_do)) { @@ -2367,6 +2474,9 @@ Ast *parse_operand(AstFile *f, bool lhs) { Ast *align = nullptr; bool no_nil = false; bool maybe = false; + bool shared_nil = false; + + UnionTypeKind union_kind = UnionType_Normal; Token start_token = f->curr_token; @@ -2393,6 +2503,11 @@ Ast *parse_operand(AstFile *f, bool lhs) { syntax_error(tag, "Duplicate union tag '#%.*s'", LIT(tag.string)); } no_nil = true; + } else if (tag.string == "shared_nil") { + if (shared_nil) { + syntax_error(tag, "Duplicate union tag '#%.*s'", LIT(tag.string)); + } + shared_nil = true; } else if (tag.string == "maybe") { if (maybe) { syntax_error(tag, "Duplicate union tag '#%.*s'", LIT(tag.string)); @@ -2405,6 +2520,21 @@ Ast *parse_operand(AstFile *f, bool lhs) { if (no_nil && maybe) { syntax_error(f->curr_token, "#maybe and #no_nil cannot be applied together"); } + if (no_nil && shared_nil) { + syntax_error(f->curr_token, "#shared_nil and #no_nil cannot be applied together"); + } + if (shared_nil && maybe) { + syntax_error(f->curr_token, "#maybe and #shared_nil cannot be applied together"); + } + + + if (maybe) { + union_kind = UnionType_maybe; + } else if (no_nil) { + union_kind = UnionType_no_nil; + } else if (shared_nil) { + union_kind = UnionType_shared_nil; + } skip_possible_newline_for_literal(f); @@ -2436,7 +2566,7 @@ Ast *parse_operand(AstFile *f, bool lhs) { Token close = expect_closing_brace_of_field_list(f); - return ast_union_type(f, token, variants, polymorphic_params, align, no_nil, maybe, where_token, where_clauses); + return ast_union_type(f, token, variants, polymorphic_params, align, union_kind, where_token, where_clauses); } break; case Token_enum: { @@ -2449,7 +2579,7 @@ Ast *parse_operand(AstFile *f, bool lhs) { skip_possible_newline_for_literal(f); Token open = expect_token(f, Token_OpenBrace); - Array values = parse_element_list(f); + Array values = parse_enum_field_list(f); Token close = expect_closing_brace_of_field_list(f); return ast_enum_type(f, token, base_type, values); @@ -2908,64 +3038,62 @@ i32 token_precedence(AstFile *f, TokenKind t) { Ast *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) { Ast *expr = parse_unary_expr(f, lhs); - for (i32 prec = token_precedence(f, f->curr_token.kind); prec >= prec_in; prec--) { - for (;;) { - Token op = f->curr_token; - i32 op_prec = token_precedence(f, op.kind); - if (op_prec != prec) { - // NOTE(bill): This will also catch operators that are not valid "binary" operators - break; + for (;;) { + Token op = f->curr_token; + i32 op_prec = token_precedence(f, op.kind); + if (op_prec < prec_in) { + // NOTE(bill): This will also catch operators that are not valid "binary" operators + break; + } + Token prev = f->prev_token; + switch (op.kind) { + case Token_if: + case Token_when: + if (prev.pos.line < op.pos.line) { + // NOTE(bill): Check to see if the `if` or `when` is on the same line of the `lhs` condition + goto loop_end; } - Token prev = f->prev_token; + break; + } + expect_operator(f); // NOTE(bill): error checks too + + if (op.kind == Token_Question) { + Ast *cond = expr; + // Token_Question + Ast *x = parse_expr(f, lhs); + Token token_c = expect_token(f, Token_Colon); + Ast *y = parse_expr(f, lhs); + expr = ast_ternary_if_expr(f, x, cond, y); + } else if (op.kind == Token_if || op.kind == Token_when) { + Ast *x = expr; + Ast *cond = parse_expr(f, lhs); + Token tok_else = expect_token(f, Token_else); + Ast *y = parse_expr(f, lhs); + switch (op.kind) { case Token_if: + expr = ast_ternary_if_expr(f, x, cond, y); + break; case Token_when: - if (prev.pos.line < op.pos.line) { - // NOTE(bill): Check to see if the `if` or `when` is on the same line of the `lhs` condition - goto loop_end; - } + expr = ast_ternary_when_expr(f, x, cond, y); break; } - expect_operator(f); // NOTE(bill): error checks too - - if (op.kind == Token_Question) { - Ast *cond = expr; - // Token_Question - Ast *x = parse_expr(f, lhs); - Token token_c = expect_token(f, Token_Colon); - Ast *y = parse_expr(f, lhs); - expr = ast_ternary_if_expr(f, x, cond, y); - } else if (op.kind == Token_if || op.kind == Token_when) { - Ast *x = expr; - Ast *cond = parse_expr(f, lhs); - Token tok_else = expect_token(f, Token_else); - Ast *y = parse_expr(f, lhs); - - switch (op.kind) { - case Token_if: - expr = ast_ternary_if_expr(f, x, cond, y); - break; - case Token_when: - expr = ast_ternary_when_expr(f, x, cond, y); - break; - } - } else { - Ast *right = parse_binary_expr(f, false, prec+1); - if (right == nullptr) { - syntax_error(op, "Expected expression on the right-hand side of the binary operator '%.*s'", LIT(op.string)); - } - if (op.kind == Token_or_else) { - // NOTE(bill): easier to handle its logic different with its own AST kind - expr = ast_or_else_expr(f, expr, op, right); - } else { - expr = ast_binary_expr(f, op, expr, right); - } + } else { + Ast *right = parse_binary_expr(f, false, op_prec+1); + if (right == nullptr) { + syntax_error(op, "Expected expression on the right-hand side of the binary operator '%.*s'", LIT(op.string)); + } + if (op.kind == Token_or_else) { + // NOTE(bill): easier to handle its logic different with its own AST kind + expr = ast_or_else_expr(f, expr, op, right); + } else { + expr = ast_binary_expr(f, op, expr, right); } - - lhs = false; } - loop_end:; + + lhs = false; } + loop_end:; return expr; } @@ -3075,7 +3203,7 @@ Ast *parse_foreign_block(AstFile *f, Token token) { Ast *body = ast_block_stmt(f, decls, open, close); Ast *decl = ast_foreign_block_decl(f, token, foreign_library, body, docs); - expect_semicolon(f, decl); + expect_semicolon(f); return decl; } @@ -3121,15 +3249,11 @@ Ast *parse_value_decl(AstFile *f, Array names, CommentGroup *docs) { } if (f->expr_level >= 0) { - Ast *end = nullptr; - if (!is_mutable && values.count > 0) { - end = values[values.count-1]; - } if (f->curr_token.kind == Token_CloseBrace && f->curr_token.pos.line == f->prev_token.pos.line) { } else { - expect_semicolon(f, end); + expect_semicolon(f); } } @@ -3311,12 +3435,18 @@ ProcCallingConvention string_to_calling_convention(String s) { if (s == "fast") return ProcCC_FastCall; if (s == "none") return ProcCC_None; if (s == "naked") return ProcCC_Naked; + + if (s == "win64") return ProcCC_Win64; + if (s == "sysv") return ProcCC_SysV; + if (s == "system") { if (build_context.metrics.os == TargetOs_windows) { return ProcCC_StdCall; } return ProcCC_CDecl; } + + return ProcCC_Invalid; } @@ -3403,12 +3533,13 @@ enum FieldPrefixKind : i32 { FieldPrefix_Unknown = -1, FieldPrefix_Invalid = 0, - FieldPrefix_using, + FieldPrefix_using, // implies #subtype FieldPrefix_const, FieldPrefix_no_alias, FieldPrefix_c_vararg, FieldPrefix_auto_cast, FieldPrefix_any_int, + FieldPrefix_subtype, // does not imply `using` semantics }; struct ParseFieldPrefixMapping { @@ -3425,6 +3556,7 @@ gb_global ParseFieldPrefixMapping parse_field_prefix_mappings[] = { {str_lit("c_vararg"), Token_Hash, FieldPrefix_c_vararg, FieldFlag_c_vararg}, {str_lit("const"), Token_Hash, FieldPrefix_const, FieldFlag_const}, {str_lit("any_int"), Token_Hash, FieldPrefix_any_int, FieldFlag_any_int}, + {str_lit("subtype"), Token_Hash, FieldPrefix_subtype, FieldFlag_subtype}, }; @@ -4029,11 +4161,7 @@ Ast *parse_return_stmt(AstFile *f) { advance_token(f); } - Ast *end = nullptr; - if (results.count > 0) { - end = results[results.count-1]; - } - expect_semicolon(f, end); + expect_semicolon(f); return ast_return_stmt(f, token, results); } @@ -4284,7 +4412,7 @@ Ast *parse_import_decl(AstFile *f, ImportDeclKind kind) { syntax_error(import_name, "'using import' is not allowed, please use the import name explicitly"); } - expect_semicolon(f, s); + expect_semicolon(f); return s; } @@ -4342,7 +4470,7 @@ Ast *parse_foreign_decl(AstFile *f) { } else { s = ast_foreign_import_decl(f, token, filepaths, lib_name, docs, f->line_comment); } - expect_semicolon(f, s); + expect_semicolon(f); return s; } } @@ -4481,7 +4609,7 @@ Ast *parse_stmt(AstFile *f) { case Token_Not: case Token_And: s = parse_simple_stmt(f, StmtAllowFlag_Label); - expect_semicolon(f, s); + expect_semicolon(f); return s; @@ -4509,7 +4637,7 @@ Ast *parse_stmt(AstFile *f) { label = parse_ident(f); } s = ast_branch_stmt(f, token, label); - expect_semicolon(f, s); + expect_semicolon(f); return s; } @@ -4524,12 +4652,12 @@ Ast *parse_stmt(AstFile *f) { Array list = parse_lhs_expr_list(f); if (list.count == 0) { syntax_error(token, "Illegal use of 'using' statement"); - expect_semicolon(f, nullptr); + expect_semicolon(f); return ast_bad_stmt(f, token, f->curr_token); } if (f->curr_token.kind != Token_Colon) { - expect_semicolon(f, list[list.count-1]); + expect_semicolon(f); return ast_using_stmt(f, token, list); } expect_token_after(f, Token_Colon, "identifier list"); @@ -4561,6 +4689,12 @@ Ast *parse_stmt(AstFile *f) { } else if (tag == "no_bounds_check") { s = parse_stmt(f); return parse_check_directive_for_statement(s, name, StateFlag_no_bounds_check); + } else if (tag == "type_assert") { + s = parse_stmt(f); + return parse_check_directive_for_statement(s, name, StateFlag_type_assert); + } else if (tag == "no_type_assert") { + s = parse_stmt(f); + return parse_check_directive_for_statement(s, name, StateFlag_no_type_assert); } else if (tag == "partial") { s = parse_stmt(f); switch (s->kind) { @@ -4580,13 +4714,13 @@ Ast *parse_stmt(AstFile *f) { } else if (tag == "assert" || tag == "panic") { Ast *t = ast_basic_directive(f, hash_token, name); Ast *stmt = ast_expr_stmt(f, parse_call_expr(f, t)); - expect_semicolon(f, stmt); + expect_semicolon(f); return stmt; } else if (name.string == "force_inline" || name.string == "force_no_inline") { Ast *expr = parse_force_inlining_operand(f, name); Ast *stmt = ast_expr_stmt(f, expr); - expect_semicolon(f, stmt); + expect_semicolon(f); return stmt; } else if (tag == "unroll") { return parse_unrolled_for_loop(f, name); @@ -4608,7 +4742,7 @@ Ast *parse_stmt(AstFile *f) { case Token_Semicolon: s = ast_empty_stmt(f, token); - expect_semicolon(f, nullptr); + expect_semicolon(f); return s; } @@ -4736,12 +4870,6 @@ ParseFileError init_ast_file(AstFile *f, String fullpath, TokenPos *err_pos) { f->prev_token = f->tokens[f->prev_token_index]; f->curr_token = f->tokens[f->curr_token_index]; - isize const page_size = 4*1024; - isize block_size = 2*f->tokens.count*gb_size_of(Ast); - block_size = ((block_size + page_size-1)/page_size) * page_size; - block_size = gb_clamp(block_size, page_size, DEFAULT_MINIMUM_BLOCK_SIZE); - f->arena.minimum_block_size = block_size; - array_init(&f->comments, heap_allocator(), 0, 0); array_init(&f->imports, heap_allocator(), 0, 0); @@ -5362,6 +5490,15 @@ isize calc_decl_count(Ast *decl) { count += calc_decl_count(decl->BlockStmt.stmts.data[i]); } break; + case Ast_WhenStmt: + { + isize inner_count = calc_decl_count(decl->WhenStmt.body); + if (decl->WhenStmt.else_stmt) { + inner_count = gb_max(inner_count, calc_decl_count(decl->WhenStmt.else_stmt)); + } + count += inner_count; + } + break; case Ast_ValueDecl: count = decl->ValueDecl.names.count; break; @@ -5389,7 +5526,7 @@ bool parse_file(Parser *p, AstFile *f) { String filepath = f->tokenizer.fullpath; String base_dir = dir_from_path(filepath); if (f->curr_token.kind == Token_Comment) { - comsume_comment_groups(f, f->prev_token); + consume_comment_groups(f, f->prev_token); } CommentGroup *docs = f->lead_comment; @@ -5403,6 +5540,15 @@ bool parse_file(Parser *p, AstFile *f) { if (f->package_token.kind != Token_package) { return false; } + if (docs != nullptr) { + TokenPos end = token_pos_end(docs->list[docs->list.count-1]); + if (end.line == f->package_token.pos.line || end.line+1 == f->package_token.pos.line) { + // Okay + } else { + docs = nullptr; + } + } + Token package_name = expect_token_after(f, Token_Ident, "package"); if (package_name.kind == Token_Ident) { if (package_name.string == "_") { @@ -5426,8 +5572,17 @@ bool parse_file(Parser *p, AstFile *f) { if (!parse_build_tag(tok, lc)) { return false; } - } else if (lc == "+private") { - f->flags |= AstFile_IsPrivate; + } else if (string_starts_with(lc, str_lit("+private"))) { + f->flags |= AstFile_IsPrivatePkg; + String command = string_trim_starts_with(lc, str_lit("+private ")); + command = string_trim_whitespace(command); + if (lc == "+private") { + f->flags |= AstFile_IsPrivatePkg; + } else if (command == "package") { + f->flags |= AstFile_IsPrivatePkg; + } else if (command == "file") { + f->flags |= AstFile_IsPrivateFile; + } } else if (lc == "+lazy") { if (build_context.ignore_lazy) { // Ignore @@ -5445,7 +5600,7 @@ bool parse_file(Parser *p, AstFile *f) { } Ast *pd = ast_package_decl(f, f->package_token, package_name, docs, f->line_comment); - expect_semicolon(f, pd); + expect_semicolon(f); f->pkg_decl = pd; if (f->error_count == 0) { @@ -5579,8 +5734,24 @@ ParseFileError parse_packages(Parser *p, String init_filename) { error_line("Expected either a directory or a .odin file, got '%.*s'\n", LIT(init_filename)); return ParseFile_WrongExtension; } + } else if (init_fullpath.len != 0) { + String path = init_fullpath; + if (path[path.len-1] == '/') { + path.len -= 1; + } + if ((build_context.command_kind & Command__does_build) && + build_context.build_mode == BuildMode_Executable) { + String short_path = filename_from_path(path); + char *cpath = alloc_cstring(heap_allocator(), short_path); + defer (gb_free(heap_allocator(), cpath)); + + if (gb_file_exists(cpath)) { + error_line("Please specify the executable name with -out: as a directory exists with the same name in the current working directory"); + return ParseFile_DirectoryAlreadyExists; + } + } } - + { // Add these packages serially and then process them parallel mutex_lock(&p->wait_mutex); diff --git a/src/parser.hpp b/src/parser.hpp index b83822cbf..c7b4fd0d8 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -46,6 +46,7 @@ enum ParseFileError { ParseFile_InvalidToken, ParseFile_GeneralError, ParseFile_FileTooLarge, + ParseFile_DirectoryAlreadyExists, ParseFile_Count, }; @@ -78,9 +79,11 @@ struct ImportedFile { }; enum AstFileFlag : u32 { - AstFile_IsPrivate = 1<<0, - AstFile_IsTest = 1<<1, - AstFile_IsLazy = 1<<2, + AstFile_IsPrivatePkg = 1<<0, + AstFile_IsPrivateFile = 1<<1, + + AstFile_IsTest = 1<<3, + AstFile_IsLazy = 1<<4, }; enum AstDelayQueueKind { @@ -95,8 +98,6 @@ struct AstFile { AstPackage * pkg; Scope * scope; - Arena arena; - Ast * pkg_decl; String fullpath; Tokenizer tokenizer; @@ -226,6 +227,8 @@ enum ProcInlining { enum ProcTag { ProcTag_bounds_check = 1<<0, ProcTag_no_bounds_check = 1<<1, + ProcTag_type_assert = 1<<2, + ProcTag_no_type_assert = 1<<3, ProcTag_require_results = 1<<4, ProcTag_optional_ok = 1<<5, @@ -245,12 +248,30 @@ enum ProcCallingConvention : i32 { ProcCC_InlineAsm = 8, + ProcCC_Win64 = 9, + ProcCC_SysV = 10, + + ProcCC_MAX, ProcCC_ForeignBlockDefault = -1, }; +char const *proc_calling_convention_strings[ProcCC_MAX] = { + "", + "odin", + "contextless", + "cdecl", + "stdcall", + "fastcall", + "none", + "naked", + "inlineasm", + "win64", + "sysv", +}; + ProcCallingConvention default_calling_convention(void) { return ProcCC_Odin; } @@ -258,6 +279,8 @@ ProcCallingConvention default_calling_convention(void) { enum StateFlag : u8 { StateFlag_bounds_check = 1<<0, StateFlag_no_bounds_check = 1<<1, + StateFlag_type_assert = 1<<2, + StateFlag_no_type_assert = 1<<3, StateFlag_BeenHandled = 1<<7, }; @@ -276,6 +299,7 @@ enum FieldFlag : u32 { FieldFlag_auto_cast = 1<<4, FieldFlag_const = 1<<5, FieldFlag_any_int = 1<<6, + FieldFlag_subtype = 1<<7, // Internal use by the parser only FieldFlag_Tags = 1<<10, @@ -283,7 +307,7 @@ enum FieldFlag : u32 { // Parameter List Restrictions FieldFlag_Signature = FieldFlag_ellipsis|FieldFlag_using|FieldFlag_no_alias|FieldFlag_c_vararg|FieldFlag_auto_cast|FieldFlag_const|FieldFlag_any_int, - FieldFlag_Struct = FieldFlag_using|FieldFlag_Tags, + FieldFlag_Struct = FieldFlag_using|FieldFlag_subtype|FieldFlag_Tags, }; enum StmtAllowFlag { @@ -306,6 +330,13 @@ char const *inline_asm_dialect_strings[InlineAsmDialect_COUNT] = { "intel", }; +enum UnionTypeKind : u8 { + UnionType_Normal = 0, + UnionType_maybe = 1, + UnionType_no_nil = 2, + UnionType_shared_nil = 3, +}; + #define AST_KINDS \ AST_KIND(Ident, "identifier", struct { \ Token token; \ @@ -344,6 +375,7 @@ char const *inline_asm_dialect_strings[InlineAsmDialect_COUNT] = { Slice elems; \ Token open, close; \ i64 max_count; \ + Ast *tag; \ }) \ AST_KIND(_ExprBegin, "", bool) \ AST_KIND(BadExpr, "bad expression", struct { Token begin, end; }) \ @@ -383,6 +415,12 @@ AST_KIND(_ExprBegin, "", bool) \ void *sce_temp_data; \ }) \ AST_KIND(FieldValue, "field value", struct { Token eq; Ast *field, *value; }) \ + AST_KIND(EnumFieldValue, "enum field value", struct { \ + Ast *name; \ + Ast *value; \ + CommentGroup *docs; \ + CommentGroup *comment; \ + }) \ AST_KIND(TernaryIfExpr, "ternary if expression", struct { Ast *x, *cond, *y; }) \ AST_KIND(TernaryWhenExpr, "ternary when expression", struct { Ast *x, *cond, *y; }) \ AST_KIND(OrElseExpr, "or_else expression", struct { Ast *x; Token token; Ast *y; }) \ @@ -647,8 +685,7 @@ AST_KIND(_TypeBegin, "", bool) \ Slice variants; \ Ast *polymorphic_params; \ Ast * align; \ - bool maybe; \ - bool no_nil; \ + UnionTypeKind kind; \ Token where_token; \ Slice where_clauses; \ }) \ @@ -769,10 +806,10 @@ gb_inline bool is_ast_when_stmt(Ast *node) { return node->kind == Ast_WhenStmt; } -gb_global gb_thread_local Arena global_ast_arena = {}; +gb_global gb_thread_local Arena global_thread_local_ast_arena = {}; gbAllocator ast_allocator(AstFile *f) { - Arena *arena = f ? &f->arena : &global_ast_arena; + Arena *arena = &global_thread_local_ast_arena; return arena_allocator(arena); } diff --git a/src/parser_pos.cpp b/src/parser_pos.cpp index 6ef0db215..54c3ec1f1 100644 --- a/src/parser_pos.cpp +++ b/src/parser_pos.cpp @@ -39,6 +39,7 @@ Token ast_token(Ast *node) { case Ast_SliceExpr: return node->SliceExpr.open; case Ast_Ellipsis: return node->Ellipsis.token; case Ast_FieldValue: return node->FieldValue.eq; + case Ast_EnumFieldValue: return ast_token(node->EnumFieldValue.name); case Ast_DerefExpr: return node->DerefExpr.op; case Ast_TernaryIfExpr: return ast_token(node->TernaryIfExpr.x); case Ast_TernaryWhenExpr: return ast_token(node->TernaryWhenExpr.x); @@ -178,6 +179,11 @@ Token ast_end_token(Ast *node) { } return node->Ellipsis.token; case Ast_FieldValue: return ast_end_token(node->FieldValue.value); + case Ast_EnumFieldValue: + if (node->EnumFieldValue.value) { + return ast_end_token(node->EnumFieldValue.value); + } + return ast_end_token(node->EnumFieldValue.name); case Ast_DerefExpr: return node->DerefExpr.op; case Ast_TernaryIfExpr: return ast_end_token(node->TernaryIfExpr.y); case Ast_TernaryWhenExpr: return ast_end_token(node->TernaryWhenExpr.y); diff --git a/src/path.cpp b/src/path.cpp new file mode 100644 index 000000000..6f83c39ea --- /dev/null +++ b/src/path.cpp @@ -0,0 +1,394 @@ +/* + Path handling utilities. +*/ +String remove_extension_from_path(String const &s) { + for (isize i = s.len-1; i >= 0; i--) { + if (s[i] == '.') { + return substring(s, 0, i); + } + } + return s; +} + +String remove_directory_from_path(String const &s) { + isize len = 0; + for (isize i = s.len-1; i >= 0; i--) { + if (s[i] == '/' || + s[i] == '\\') { + break; + } + len += 1; + } + return substring(s, s.len-len, s.len); +} + +bool path_is_directory(String path); + +String directory_from_path(String const &s) { + if (path_is_directory(s)) { + return s; + } + + isize i = s.len-1; + for (; i >= 0; i--) { + if (s[i] == '/' || + s[i] == '\\') { + break; + } + } + if (i >= 0) { + return substring(s, 0, i); + } + return substring(s, 0, 0); +} + +#if defined(GB_SYSTEM_WINDOWS) + bool path_is_directory(String path) { + gbAllocator a = heap_allocator(); + String16 wstr = string_to_string16(a, path); + defer (gb_free(a, wstr.text)); + + i32 attribs = GetFileAttributesW(wstr.text); + if (attribs < 0) return false; + + return (attribs & FILE_ATTRIBUTE_DIRECTORY) != 0; + } + +#else + bool path_is_directory(String path) { + gbAllocator a = heap_allocator(); + char *copy = cast(char *)copy_string(a, path).text; + defer (gb_free(a, copy)); + + struct stat s; + if (stat(copy, &s) == 0) { + return (s.st_mode & S_IFDIR) != 0; + } + return false; + } +#endif + + +String path_to_full_path(gbAllocator a, String path) { + gbAllocator ha = heap_allocator(); + char *path_c = gb_alloc_str_len(ha, cast(char *)path.text, path.len); + defer (gb_free(ha, path_c)); + + char *fullpath = gb_path_get_full_name(a, path_c); + String res = string_trim_whitespace(make_string_c(fullpath)); +#if defined(GB_SYSTEM_WINDOWS) + for (isize i = 0; i < res.len; i++) { + if (res.text[i] == '\\') { + res.text[i] = '/'; + } + } +#endif + return copy_string(a, res); +} + +struct Path { + String basename; + String name; + String ext; +}; + +// NOTE(Jeroen): Naively turns a Path into a string. +String path_to_string(gbAllocator a, Path path) { + if (path.basename.len + path.name.len + path.ext.len == 0) { + return make_string(nullptr, 0); + } + + isize len = path.basename.len + 1 + path.name.len + 1; + if (path.ext.len > 0) { + len += path.ext.len + 1; + } + + u8 *str = gb_alloc_array(a, u8, len); + + isize i = 0; + gb_memmove(str+i, path.basename.text, path.basename.len); i += path.basename.len; + gb_memmove(str+i, "/", 1); i += 1; + gb_memmove(str+i, path.name.text, path.name.len); i += path.name.len; + if (path.ext.len > 0) { + gb_memmove(str+i, ".", 1); i += 1; + gb_memmove(str+i, path.ext.text, path.ext.len); i += path.ext.len; + } + str[i] = 0; + + String res = make_string(str, i); + res = string_trim_whitespace(res); + return res; +} + +// NOTE(Jeroen): Naively turns a Path into a string, then normalizes it using `path_to_full_path`. +String path_to_full_path(gbAllocator a, Path path) { + String temp = path_to_string(heap_allocator(), path); + defer (gb_free(heap_allocator(), temp.text)); + + return path_to_full_path(a, temp); +} + +// NOTE(Jeroen): Takes a path like "odin" or "W:\Odin", turns it into a full path, +// and then breaks it into its components to make a Path. +Path path_from_string(gbAllocator a, String const &path) { + Path res = {}; + + if (path.len == 0) return res; + + String fullpath = path_to_full_path(a, path); + defer (gb_free(heap_allocator(), fullpath.text)); + + res.basename = directory_from_path(fullpath); + res.basename = copy_string(a, res.basename); + + if (path_is_directory(fullpath)) { + // It's a directory. We don't need to tinker with the name and extension. + // It could have a superfluous trailing `/`. Remove it if so. + if (res.basename.len > 0 && res.basename.text[res.basename.len - 1] == '/') { + res.basename.len--; + } + return res; + } + + isize name_start = (res.basename.len > 0) ? res.basename.len + 1 : res.basename.len; + res.name = substring(fullpath, name_start, fullpath.len); + res.name = remove_extension_from_path(res.name); + res.name = copy_string(a, res.name); + + res.ext = path_extension(fullpath, false); // false says not to include the dot. + res.ext = copy_string(a, res.ext); + return res; +} + +// NOTE(Jeroen): Takes a path String and returns the last path element. +String last_path_element(String const &path) { + isize count = 0; + u8 * start = (u8 *)(&path.text[path.len - 1]); + for (isize length = path.len; length > 0 && path.text[length - 1] != '/'; length--) { + count++; + start--; + } + if (count > 0) { + start++; // Advance past the `/` and return the substring. + String res = make_string(start, count); + return res; + } + // Must be a root path like `/` or `C:/`, return empty String. + return STR_LIT(""); +} + +bool path_is_directory(Path path) { + String path_string = path_to_full_path(heap_allocator(), path); + defer (gb_free(heap_allocator(), path_string.text)); + + return path_is_directory(path_string); +} + +struct FileInfo { + String name; + String fullpath; + i64 size; + bool is_dir; +}; + +enum ReadDirectoryError { + ReadDirectory_None, + + ReadDirectory_InvalidPath, + ReadDirectory_NotExists, + ReadDirectory_Permission, + ReadDirectory_NotDir, + ReadDirectory_Empty, + ReadDirectory_Unknown, + + ReadDirectory_COUNT, +}; + +i64 get_file_size(String path) { + char *c_str = alloc_cstring(heap_allocator(), path); + defer (gb_free(heap_allocator(), c_str)); + + gbFile f = {}; + gbFileError err = gb_file_open(&f, c_str); + defer (gb_file_close(&f)); + if (err != gbFileError_None) { + return -1; + } + return gb_file_size(&f); +} + + +#if defined(GB_SYSTEM_WINDOWS) +ReadDirectoryError read_directory(String path, Array *fi) { + GB_ASSERT(fi != nullptr); + + gbAllocator a = heap_allocator(); + + while (path.len > 0) { + Rune end = path[path.len-1]; + if (end == '/') { + path.len -= 1; + } else if (end == '\\') { + path.len -= 1; + } else { + break; + } + } + + if (path.len == 0) { + return ReadDirectory_InvalidPath; + } + { + char *c_str = alloc_cstring(a, path); + defer (gb_free(a, c_str)); + + gbFile f = {}; + gbFileError file_err = gb_file_open(&f, c_str); + defer (gb_file_close(&f)); + + switch (file_err) { + case gbFileError_Invalid: return ReadDirectory_InvalidPath; + case gbFileError_NotExists: return ReadDirectory_NotExists; + // case gbFileError_Permission: return ReadDirectory_Permission; + } + } + + if (!path_is_directory(path)) { + return ReadDirectory_NotDir; + } + + + char *new_path = gb_alloc_array(a, char, path.len+3); + defer (gb_free(a, new_path)); + + gb_memmove(new_path, path.text, path.len); + gb_memmove(new_path+path.len, "/*", 2); + new_path[path.len+2] = 0; + + String np = make_string(cast(u8 *)new_path, path.len+2); + String16 wstr = string_to_string16(a, np); + defer (gb_free(a, wstr.text)); + + WIN32_FIND_DATAW file_data = {}; + HANDLE find_file = FindFirstFileW(wstr.text, &file_data); + if (find_file == INVALID_HANDLE_VALUE) { + return ReadDirectory_Unknown; + } + defer (FindClose(find_file)); + + array_init(fi, a, 0, 100); + + do { + wchar_t *filename_w = file_data.cFileName; + i64 size = cast(i64)file_data.nFileSizeLow; + size |= (cast(i64)file_data.nFileSizeHigh) << 32; + String name = string16_to_string(a, make_string16_c(filename_w)); + if (name == "." || name == "..") { + gb_free(a, name.text); + continue; + } + + String filepath = {}; + filepath.len = path.len+1+name.len; + filepath.text = gb_alloc_array(a, u8, filepath.len+1); + defer (gb_free(a, filepath.text)); + gb_memmove(filepath.text, path.text, path.len); + gb_memmove(filepath.text+path.len, "/", 1); + gb_memmove(filepath.text+path.len+1, name.text, name.len); + + FileInfo info = {}; + info.name = name; + info.fullpath = path_to_full_path(a, filepath); + info.size = size; + info.is_dir = (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; + array_add(fi, info); + } while (FindNextFileW(find_file, &file_data)); + + if (fi->count == 0) { + return ReadDirectory_Empty; + } + + return ReadDirectory_None; +} +#elif defined(GB_SYSTEM_LINUX) || defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_FREEBSD) || defined(GB_SYSTEM_OPENBSD) + +#include + +ReadDirectoryError read_directory(String path, Array *fi) { + GB_ASSERT(fi != nullptr); + + gbAllocator a = heap_allocator(); + + char *c_path = alloc_cstring(a, path); + defer (gb_free(a, c_path)); + + DIR *dir = opendir(c_path); + if (!dir) { + switch (errno) { + case ENOENT: + return ReadDirectory_NotExists; + case EACCES: + return ReadDirectory_Permission; + case ENOTDIR: + return ReadDirectory_NotDir; + default: + // ENOMEM: out of memory + // EMFILE: per-process limit on open fds reached + // ENFILE: system-wide limit on total open files reached + return ReadDirectory_Unknown; + } + GB_PANIC("unreachable"); + } + + array_init(fi, a, 0, 100); + + for (;;) { + struct dirent *entry = readdir(dir); + if (entry == nullptr) { + break; + } + + String name = make_string_c(entry->d_name); + if (name == "." || name == "..") { + continue; + } + + String filepath = {}; + filepath.len = path.len+1+name.len; + filepath.text = gb_alloc_array(a, u8, filepath.len+1); + defer (gb_free(a, filepath.text)); + gb_memmove(filepath.text, path.text, path.len); + gb_memmove(filepath.text+path.len, "/", 1); + gb_memmove(filepath.text+path.len+1, name.text, name.len); + filepath.text[filepath.len] = 0; + + + struct stat dir_stat = {}; + + if (stat((char *)filepath.text, &dir_stat)) { + continue; + } + + if (S_ISDIR(dir_stat.st_mode)) { + continue; + } + + i64 size = dir_stat.st_size; + + FileInfo info = {}; + info.name = name; + info.fullpath = path_to_full_path(a, filepath); + info.size = size; + array_add(fi, info); + } + + if (fi->count == 0) { + return ReadDirectory_Empty; + } + + return ReadDirectory_None; +} +#else +#error Implement read_directory +#endif + diff --git a/src/ptr_set.cpp b/src/ptr_set.cpp index ca7df3b53..b45997916 100644 --- a/src/ptr_set.cpp +++ b/src/ptr_set.cpp @@ -138,6 +138,15 @@ gb_inline bool ptr_set_exists(PtrSet *s, T ptr) { return index != MAP_SENTINEL; } +template +gb_inline isize ptr_entry_index(PtrSet *s, T ptr) { + isize index = ptr_set__find(s, ptr).entry_index; + if (index != MAP_SENTINEL) { + return index; + } + return -1; +} + // Returns true if it already exists template T ptr_set_add(PtrSet *s, T ptr) { diff --git a/src/queue.cpp b/src/queue.cpp index d69a2845c..ee8b1b086 100644 --- a/src/queue.cpp +++ b/src/queue.cpp @@ -71,6 +71,29 @@ void mpmc_destroy(MPMCQueue *q) { } +template +bool mpmc_internal_grow(MPMCQueue *q) { + mutex_lock(&q->mutex); + i32 old_size = q->mask+1; + i32 new_size = old_size*2; + resize_array_raw(&q->nodes, q->allocator, old_size, new_size); + if (q->nodes == nullptr) { + GB_PANIC("Unable to resize enqueue: %td -> %td", old_size, new_size); + mutex_unlock(&q->mutex); + return false; + } + resize_array_raw(&q->indices, q->allocator, old_size, new_size); + if (q->indices == nullptr) { + GB_PANIC("Unable to resize enqueue: %td -> %td", old_size, new_size); + mutex_unlock(&q->mutex); + return false; + } + mpmc_internal_init_indices(q->indices, old_size, new_size); + q->mask = new_size-1; + mutex_unlock(&q->mutex); + return true; +} + template i32 mpmc_enqueue(MPMCQueue *q, T const &data) { GB_ASSERT(q->mask != 0); @@ -78,8 +101,9 @@ i32 mpmc_enqueue(MPMCQueue *q, T const &data) { i32 head_idx = q->head_idx.load(std::memory_order_relaxed); for (;;) { - auto node = &q->nodes[head_idx & q->mask]; - auto node_idx_ptr = &q->indices[head_idx & q->mask]; + i32 index = head_idx & q->mask; + auto node = &q->nodes[index]; + auto node_idx_ptr = &q->indices[index]; i32 node_idx = node_idx_ptr->load(std::memory_order_acquire); i32 diff = node_idx - head_idx; @@ -91,24 +115,9 @@ i32 mpmc_enqueue(MPMCQueue *q, T const &data) { return q->count.fetch_add(1, std::memory_order_release); } } else if (diff < 0) { - mutex_lock(&q->mutex); - i32 old_size = q->mask+1; - i32 new_size = old_size*2; - resize_array_raw(&q->nodes, q->allocator, old_size, new_size); - if (q->nodes == nullptr) { - GB_PANIC("Unable to resize enqueue: %td -> %td", old_size, new_size); - mutex_unlock(&q->mutex); + if (!mpmc_internal_grow(q)) { return -1; } - resize_array_raw(&q->indices, q->allocator, old_size, new_size); - if (q->indices == nullptr) { - GB_PANIC("Unable to resize enqueue: %td -> %td", old_size, new_size); - mutex_unlock(&q->mutex); - return -1; - } - mpmc_internal_init_indices(q->indices, old_size, new_size); - q->mask = new_size-1; - mutex_unlock(&q->mutex); } else { head_idx = q->head_idx.load(std::memory_order_relaxed); } diff --git a/src/string.cpp b/src/string.cpp index 800378689..616761265 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -10,10 +10,6 @@ struct String { u8 * text; isize len; - // u8 &operator[](isize i) { - // GB_ASSERT_MSG(0 <= i && i < len, "[%td]", i); - // return text[i]; - // } u8 const &operator[](isize i) const { GB_ASSERT_MSG(0 <= i && i < len, "[%td]", i); return text[i]; @@ -33,10 +29,6 @@ struct String { struct String16 { wchar_t *text; isize len; - wchar_t &operator[](isize i) { - GB_ASSERT_MSG(0 <= i && i < len, "[%td]", i); - return text[i]; - } wchar_t const &operator[](isize i) const { GB_ASSERT_MSG(0 <= i && i < len, "[%td]", i); return text[i]; @@ -195,8 +187,6 @@ template bool operator > (String const &a, char const (&b)[N]) { retu template bool operator <= (String const &a, char const (&b)[N]) { return str_le(a, make_string(cast(u8 *)b, N-1)); } template bool operator >= (String const &a, char const (&b)[N]) { return str_ge(a, make_string(cast(u8 *)b, N-1)); } - - gb_inline bool string_starts_with(String const &s, String const &prefix) { if (prefix.len > s.len) { return false; @@ -230,6 +220,16 @@ gb_inline bool string_ends_with(String const &s, u8 suffix) { return s[s.len-1] == suffix; } + + +gb_inline String string_trim_starts_with(String const &s, String const &prefix) { + if (string_starts_with(s, prefix)) { + return substring(s, prefix.len, s.len); + } + return s; +} + + gb_inline isize string_extension_position(String const &str) { isize dot_pos = -1; isize i = str.len; @@ -245,15 +245,14 @@ gb_inline isize string_extension_position(String const &str) { return dot_pos; } -String path_extension(String const &str) { +String path_extension(String const &str, bool include_dot = true) { isize pos = string_extension_position(str); if (pos < 0) { return make_string(nullptr, 0); } - return substring(str, pos, str.len); + return substring(str, include_dot ? pos : pos + 1, str.len); } - String string_trim_whitespace(String str) { while (str.len > 0 && rune_is_whitespace(str[str.len-1])) { str.len--; @@ -299,38 +298,6 @@ String filename_from_path(String s) { return make_string(nullptr, 0); } -String remove_extension_from_path(String const &s) { - for (isize i = s.len-1; i >= 0; i--) { - if (s[i] == '.') { - return substring(s, 0, i); - } - } - return s; -} - -String remove_directory_from_path(String const &s) { - isize len = 0; - for (isize i = s.len-1; i >= 0; i--) { - if (s[i] == '/' || - s[i] == '\\') { - break; - } - len += 1; - } - return substring(s, s.len-len, s.len); -} - -String directory_from_path(String const &s) { - isize i = s.len-1; - for (; i >= 0; i--) { - if (s[i] == '/' || - s[i] == '\\') { - break; - } - } - return substring(s, 0, i); -} - String concatenate_strings(gbAllocator a, String const &x, String const &y) { isize len = x.len+y.len; u8 *data = gb_alloc_array(a, u8, len+1); @@ -773,3 +740,34 @@ i32 unquote_string(gbAllocator a, String *s_, u8 quote=0, bool has_carriage_retu return 2; } + + +bool string_is_valid_identifier(String str) { + if (str.len <= 0) return false; + + isize rune_count = 0; + + isize w = 0; + isize offset = 0; + while (offset < str.len) { + Rune r = 0; + w = utf8_decode(str.text, str.len, &r); + if (r == GB_RUNE_INVALID) { + return false; + } + + if (rune_count == 0) { + if (!rune_is_letter(r)) { + return false; + } + } else { + if (!rune_is_letter(r) && !rune_is_digit(r)) { + return false; + } + } + rune_count += 1; + offset += w; + } + + return true; +} diff --git a/src/threading.cpp b/src/threading.cpp index e9412b411..63e3415b2 100644 --- a/src/threading.cpp +++ b/src/threading.cpp @@ -68,6 +68,40 @@ void yield_thread(void); void yield_process(void); +struct MutexGuard { + MutexGuard() = delete; + MutexGuard(MutexGuard const &) = delete; + + MutexGuard(BlockingMutex *bm) : bm{bm} { + mutex_lock(this->bm); + } + MutexGuard(RecursiveMutex *rm) : rm{rm} { + mutex_lock(this->rm); + } + MutexGuard(BlockingMutex &bm) : bm{&bm} { + mutex_lock(this->bm); + } + MutexGuard(RecursiveMutex &rm) : rm{&rm} { + mutex_lock(this->rm); + } + ~MutexGuard() { + if (this->bm) { + mutex_unlock(this->bm); + } else if (this->rm) { + mutex_unlock(this->rm); + } + } + + operator bool() const { return true; } + + BlockingMutex *bm; + RecursiveMutex *rm; +}; + +#define MUTEX_GUARD_BLOCK(m) if (MutexGuard GB_DEFER_3(_mutex_guard_){m}) +#define MUTEX_GUARD(m) MutexGuard GB_DEFER_3(_mutex_guard_){m} + + #if defined(GB_SYSTEM_WINDOWS) struct BlockingMutex { SRWLOCK srwlock; @@ -296,6 +330,8 @@ u32 thread_current_id(void) { __asm__("mov %%gs:0x08,%0" : "=r"(thread_id)); #elif defined(GB_ARCH_64_BIT) && defined(GB_CPU_X86) __asm__("mov %%fs:0x10,%0" : "=r"(thread_id)); +#elif defined(GB_SYSTEM_LINUX) + thread_id = gettid(); #else #error Unsupported architecture for thread_current_id() #endif @@ -315,6 +351,8 @@ gb_inline void yield_thread(void) { #endif #elif defined(GB_CPU_X86) _mm_pause(); +#elif defined(GB_CPU_ARM) + __asm__ volatile ("yield" : : : "memory"); #else #error Unknown architecture #endif @@ -448,7 +486,7 @@ void thread_set_name(Thread *t, char const *name) { #elif defined(GB_SYSTEM_OSX) // TODO(bill): Test if this works pthread_setname_np(name); -#elif defined(GB_SYSTEM_FREEBSD) +#elif defined(GB_SYSTEM_FREEBSD) || defined(GB_SYSTEM_OPENBSD) pthread_set_name_np(t->posix_handle, name); #else // TODO(bill): Test if this works diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 624aea2aa..40bc5c220 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -201,14 +201,6 @@ struct TokenPos { i32 column; // starting at 1 }; -// temporary -char *token_pos_to_string(TokenPos const &pos) { - gbString s = gb_string_make_reserve(temporary_allocator(), 128); - String file = get_file_path_string(pos.file_id); - s = gb_string_append_fmt(s, "%.*s(%d:%d)", LIT(file), pos.line, pos.column); - return s; -} - i32 token_pos_cmp(TokenPos const &a, TokenPos const &b) { if (a.offset != b.offset) { return (a.offset < b.offset) ? -1 : +1; @@ -264,419 +256,6 @@ bool token_is_newline(Token const &tok) { return tok.kind == Token_Semicolon && tok.string == "\n"; } - -struct ErrorCollector { - TokenPos prev; - std::atomic count; - std::atomic warning_count; - std::atomic in_block; - BlockingMutex mutex; - BlockingMutex error_out_mutex; - BlockingMutex string_mutex; - RecursiveMutex block_mutex; - - Array error_buffer; - Array errors; -}; - -gb_global ErrorCollector global_error_collector; - -#define MAX_ERROR_COLLECTOR_COUNT (36) - - -bool any_errors(void) { - return global_error_collector.count.load() != 0; -} - -void init_global_error_collector(void) { - mutex_init(&global_error_collector.mutex); - mutex_init(&global_error_collector.block_mutex); - mutex_init(&global_error_collector.error_out_mutex); - mutex_init(&global_error_collector.string_mutex); - array_init(&global_error_collector.errors, heap_allocator()); - array_init(&global_error_collector.error_buffer, heap_allocator()); - array_init(&global_file_path_strings, heap_allocator(), 1, 4096); - array_init(&global_files, heap_allocator(), 1, 4096); -} - - -bool set_file_path_string(i32 index, String const &path) { - bool ok = false; - GB_ASSERT(index >= 0); - mutex_lock(&global_error_collector.string_mutex); - - if (index >= global_file_path_strings.count) { - array_resize(&global_file_path_strings, index+1); - } - String prev = global_file_path_strings[index]; - if (prev.len == 0) { - global_file_path_strings[index] = path; - ok = true; - } - - mutex_unlock(&global_error_collector.string_mutex); - return ok; -} - -bool thread_safe_set_ast_file_from_id(i32 index, AstFile *file) { - bool ok = false; - GB_ASSERT(index >= 0); - mutex_lock(&global_error_collector.string_mutex); - - if (index >= global_files.count) { - array_resize(&global_files, index+1); - } - AstFile *prev = global_files[index]; - if (prev == nullptr) { - global_files[index] = file; - ok = true; - } - - mutex_unlock(&global_error_collector.string_mutex); - return ok; -} - -String get_file_path_string(i32 index) { - GB_ASSERT(index >= 0); - mutex_lock(&global_error_collector.string_mutex); - - String path = {}; - if (index < global_file_path_strings.count) { - path = global_file_path_strings[index]; - } - - mutex_unlock(&global_error_collector.string_mutex); - return path; -} - -AstFile *thread_safe_get_ast_file_from_id(i32 index) { - GB_ASSERT(index >= 0); - mutex_lock(&global_error_collector.string_mutex); - - AstFile *file = nullptr; - if (index < global_files.count) { - file = global_files[index]; - } - - mutex_unlock(&global_error_collector.string_mutex); - return file; -} - - - -void begin_error_block(void) { - mutex_lock(&global_error_collector.block_mutex); - global_error_collector.in_block.store(true); -} - -void end_error_block(void) { - if (global_error_collector.error_buffer.count > 0) { - isize n = global_error_collector.error_buffer.count; - u8 *text = gb_alloc_array(permanent_allocator(), u8, n+1); - gb_memmove(text, global_error_collector.error_buffer.data, n); - text[n] = 0; - String s = {text, n}; - array_add(&global_error_collector.errors, s); - global_error_collector.error_buffer.count = 0; - } - - global_error_collector.in_block.store(false); - mutex_unlock(&global_error_collector.block_mutex); -} - -#define ERROR_BLOCK() begin_error_block(); defer (end_error_block()) - - -#define ERROR_OUT_PROC(name) void name(char const *fmt, va_list va) -typedef ERROR_OUT_PROC(ErrorOutProc); - -ERROR_OUT_PROC(default_error_out_va) { - gbFile *f = gb_file_get_standard(gbFileStandard_Error); - - char buf[4096] = {}; - isize len = gb_snprintf_va(buf, gb_size_of(buf), fmt, va); - isize n = len-1; - if (global_error_collector.in_block) { - isize cap = global_error_collector.error_buffer.count + n; - array_reserve(&global_error_collector.error_buffer, cap); - u8 *data = global_error_collector.error_buffer.data + global_error_collector.error_buffer.count; - gb_memmove(data, buf, n); - global_error_collector.error_buffer.count += n; - } else { - mutex_lock(&global_error_collector.error_out_mutex); - { - u8 *text = gb_alloc_array(permanent_allocator(), u8, n+1); - gb_memmove(text, buf, n); - text[n] = 0; - array_add(&global_error_collector.errors, make_string(text, n)); - } - mutex_unlock(&global_error_collector.error_out_mutex); - - } - gb_file_write(f, buf, n); -} - - -ErrorOutProc *error_out_va = default_error_out_va; - -// NOTE: defined in build_settings.cpp -bool global_warnings_as_errors(void); -bool global_ignore_warnings(void); -bool show_error_line(void); -gbString get_file_line_as_string(TokenPos const &pos, i32 *offset); - -void error_out(char const *fmt, ...) { - va_list va; - va_start(va, fmt); - error_out_va(fmt, va); - va_end(va); -} - - -bool show_error_on_line(TokenPos const &pos, TokenPos end) { - if (!show_error_line()) { - return false; - } - - i32 offset = 0; - gbString the_line = get_file_line_as_string(pos, &offset); - defer (gb_string_free(the_line)); - - if (the_line != nullptr) { - String line = make_string(cast(u8 const *)the_line, gb_string_length(the_line)); - - // TODO(bill): This assumes ASCII - - enum { - MAX_LINE_LENGTH = 76, - MAX_TAB_WIDTH = 8, - ELLIPSIS_PADDING = 8 - }; - - error_out("\n\t"); - if (line.len+MAX_TAB_WIDTH+ELLIPSIS_PADDING > MAX_LINE_LENGTH) { - i32 const half_width = MAX_LINE_LENGTH/2; - i32 left = cast(i32)(offset); - i32 right = cast(i32)(line.len - offset); - left = gb_min(left, half_width); - right = gb_min(right, half_width); - - line.text += offset-left; - line.len -= offset+right-left; - - line = string_trim_whitespace(line); - - offset = left + ELLIPSIS_PADDING/2; - - error_out("... %.*s ...", LIT(line)); - } else { - error_out("%.*s", LIT(line)); - } - error_out("\n\t"); - - for (i32 i = 0; i < offset; i++) { - error_out(" "); - } - error_out("^"); - if (end.file_id == pos.file_id) { - if (end.line > pos.line) { - for (i32 i = offset; i < line.len; i++) { - error_out("~"); - } - } else if (end.line == pos.line && end.column > pos.column) { - i32 length = gb_min(end.offset - pos.offset, cast(i32)(line.len-offset)); - for (i32 i = 1; i < length-1; i++) { - error_out("~"); - } - if (length > 1) { - error_out("^"); - } - } - } - - error_out("\n\n"); - return true; - } - return false; -} - -void error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) { - global_error_collector.count.fetch_add(1); - - mutex_lock(&global_error_collector.mutex); - // NOTE(bill): Duplicate error, skip it - if (pos.line == 0) { - error_out("Error: %s\n", gb_bprintf_va(fmt, va)); - } else if (global_error_collector.prev != pos) { - global_error_collector.prev = pos; - error_out("%s %s\n", - token_pos_to_string(pos), - gb_bprintf_va(fmt, va)); - show_error_on_line(pos, end); - } - mutex_unlock(&global_error_collector.mutex); - if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT) { - gb_exit(1); - } -} - -void warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) { - if (global_warnings_as_errors()) { - error_va(pos, end, fmt, va); - return; - } - global_error_collector.warning_count.fetch_add(1); - mutex_lock(&global_error_collector.mutex); - if (!global_ignore_warnings()) { - // NOTE(bill): Duplicate error, skip it - if (pos.line == 0) { - error_out("Warning: %s\n", gb_bprintf_va(fmt, va)); - } else if (global_error_collector.prev != pos) { - global_error_collector.prev = pos; - error_out("%s Warning: %s\n", - token_pos_to_string(pos), - gb_bprintf_va(fmt, va)); - show_error_on_line(pos, end); - } - } - mutex_unlock(&global_error_collector.mutex); -} - - -void error_line_va(char const *fmt, va_list va) { - error_out_va(fmt, va); -} - -void error_no_newline_va(TokenPos const &pos, char const *fmt, va_list va) { - mutex_lock(&global_error_collector.mutex); - global_error_collector.count++; - // NOTE(bill): Duplicate error, skip it - if (pos.line == 0) { - error_out("Error: %s", gb_bprintf_va(fmt, va)); - } else if (global_error_collector.prev != pos) { - global_error_collector.prev = pos; - error_out("%s %s", - token_pos_to_string(pos), - gb_bprintf_va(fmt, va)); - } - mutex_unlock(&global_error_collector.mutex); - if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT) { - gb_exit(1); - } -} - - -void syntax_error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) { - mutex_lock(&global_error_collector.mutex); - global_error_collector.count++; - // NOTE(bill): Duplicate error, skip it - if (global_error_collector.prev != pos) { - global_error_collector.prev = pos; - error_out("%s Syntax Error: %s\n", - token_pos_to_string(pos), - gb_bprintf_va(fmt, va)); - show_error_on_line(pos, end); - } else if (pos.line == 0) { - error_out("Syntax Error: %s\n", gb_bprintf_va(fmt, va)); - } - - mutex_unlock(&global_error_collector.mutex); - if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT) { - gb_exit(1); - } -} - -void syntax_warning_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) { - if (global_warnings_as_errors()) { - syntax_error_va(pos, end, fmt, va); - return; - } - mutex_lock(&global_error_collector.mutex); - global_error_collector.warning_count++; - if (!global_ignore_warnings()) { - // NOTE(bill): Duplicate error, skip it - if (global_error_collector.prev != pos) { - global_error_collector.prev = pos; - error_out("%s Syntax Warning: %s\n", - token_pos_to_string(pos), - gb_bprintf_va(fmt, va)); - show_error_on_line(pos, end); - } else if (pos.line == 0) { - error_out("Warning: %s\n", gb_bprintf_va(fmt, va)); - } - } - mutex_unlock(&global_error_collector.mutex); -} - - - -void warning(Token const &token, char const *fmt, ...) { - va_list va; - va_start(va, fmt); - warning_va(token.pos, {}, fmt, va); - va_end(va); -} - -void error(Token const &token, char const *fmt, ...) { - va_list va; - va_start(va, fmt); - error_va(token.pos, {}, fmt, va); - va_end(va); -} - -void error(TokenPos pos, char const *fmt, ...) { - va_list va; - va_start(va, fmt); - Token token = {}; - token.pos = pos; - error_va(pos, {}, fmt, va); - va_end(va); -} - -void error_line(char const *fmt, ...) { - va_list va; - va_start(va, fmt); - error_line_va(fmt, va); - va_end(va); -} - - -void syntax_error(Token const &token, char const *fmt, ...) { - va_list va; - va_start(va, fmt); - syntax_error_va(token.pos, {}, fmt, va); - va_end(va); -} - -void syntax_error(TokenPos pos, char const *fmt, ...) { - va_list va; - va_start(va, fmt); - syntax_error_va(pos, {}, fmt, va); - va_end(va); -} - -void syntax_warning(Token const &token, char const *fmt, ...) { - va_list va; - va_start(va, fmt); - syntax_warning_va(token.pos, {}, fmt, va); - va_end(va); -} - - -void compiler_error(char const *fmt, ...) { - va_list va; - - va_start(va, fmt); - gb_printf_err("Internal Compiler Error: %s\n", - gb_bprintf_va(fmt, va)); - va_end(va); - gb_exit(1); -} - - - - - gb_inline bool token_is_literal(TokenKind t) { return gb_is_between(t, Token__LiteralBegin+1, Token__LiteralEnd-1); } @@ -695,6 +274,8 @@ gb_inline bool token_is_shift(TokenKind t) { gb_inline void print_token(Token t) { gb_printf("%.*s\n", LIT(t.string)); } +#include "error.cpp" + enum TokenizerInitError { TokenizerInit_None, diff --git a/src/types.cpp b/src/types.cpp index 2b7ea93dc..b4dc17256 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -165,9 +165,8 @@ struct TypeUnion { i16 tag_size; bool is_polymorphic; - bool is_poly_specialized : 1; - bool no_nil : 1; - bool maybe : 1; + bool is_poly_specialized; + UnionTypeKind kind; }; struct TypeProc { @@ -186,7 +185,6 @@ struct TypeProc { bool c_vararg; bool is_polymorphic; bool is_poly_specialized; - bool has_proc_default_values; bool has_named_results; bool diverging; // no return bool return_by_pointer; @@ -221,6 +219,7 @@ struct TypeProc { ExactValue *max_value; \ i64 count; \ TokenKind op; \ + bool is_sparse; \ }) \ TYPE_KIND(Slice, struct { Type *elem; }) \ TYPE_KIND(DynamicArray, struct { Type *elem; }) \ @@ -362,6 +361,7 @@ enum TypeInfoFlag : u32 { enum : int { MATRIX_ELEMENT_COUNT_MIN = 1, MATRIX_ELEMENT_COUNT_MAX = 16, + MATRIX_ELEMENT_MAX_SIZE = MATRIX_ELEMENT_COUNT_MAX * (2 * 8), // complex128 }; @@ -391,6 +391,7 @@ struct Selection { bool indirect; // Set if there was a pointer deref anywhere down the line u8 swizzle_count; // maximum components = 4 u8 swizzle_indices; // 2 bits per component, representing which swizzle index + bool pseudo_field; }; Selection empty_selection = {0}; @@ -683,6 +684,38 @@ gb_global Type *t_map_header = nullptr; gb_global Type *t_equal_proc = nullptr; gb_global Type *t_hasher_proc = nullptr; +gb_global Type *t_objc_object = nullptr; +gb_global Type *t_objc_selector = nullptr; +gb_global Type *t_objc_class = nullptr; + +gb_global Type *t_objc_id = nullptr; +gb_global Type *t_objc_SEL = nullptr; +gb_global Type *t_objc_Class = nullptr; + +enum OdinAtomicMemoryOrder : i32 { + OdinAtomicMemoryOrder_relaxed = 0, // unordered + OdinAtomicMemoryOrder_consume = 1, // monotonic + OdinAtomicMemoryOrder_acquire = 2, + OdinAtomicMemoryOrder_release = 3, + OdinAtomicMemoryOrder_acq_rel = 4, + OdinAtomicMemoryOrder_seq_cst = 5, + OdinAtomicMemoryOrder_COUNT, +}; + +char const *OdinAtomicMemoryOrder_strings[OdinAtomicMemoryOrder_COUNT] = { + "Relaxed", + "Consume", + "Acquire", + "Release", + "Acq_Rel", + "Seq_Cst", +}; + +gb_global Type *t_atomic_memory_order = nullptr; + + + + gb_global RecursiveMutex g_type_mutex; struct TypePath; @@ -690,7 +723,7 @@ struct TypePath; i64 type_size_of (Type *t); i64 type_align_of (Type *t); i64 type_offset_of (Type *t, i32 index); -gbString type_to_string (Type *type); +gbString type_to_string (Type *type, bool shorthand=false); i64 type_size_of_internal(Type *t, TypePath *path); void init_map_internal_types(Type *type); Type * bit_set_to_int(Type *t); @@ -1253,6 +1286,13 @@ bool is_type_quaternion(Type *t) { } return false; } +bool is_type_complex_or_quaternion(Type *t) { + t = core_type(t); + if (t->kind == Type_Basic) { + return (t->Basic.flags & (BasicFlag_Complex|BasicFlag_Quaternion)) != 0; + } + return false; +} bool is_type_f16(Type *t) { t = core_type(t); if (t->kind == Type_Basic) { @@ -1575,6 +1615,24 @@ Type *core_array_type(Type *t) { } } +i32 type_math_rank(Type *t) { + i32 rank = 0; + for (;;) { + t = base_type(t); + switch (t->kind) { + case Type_Array: + rank += 1; + t = t->Array.elem; + break; + case Type_Matrix: + rank += 2; + t = t->Matrix.elem; + break; + default: + return rank; + } + } +} Type *base_complex_elem_type(Type *t) { @@ -1627,7 +1685,7 @@ bool is_type_map(Type *t) { bool is_type_union_maybe_pointer(Type *t) { t = base_type(t); - if (t->kind == Type_Union && t->Union.maybe) { + if (t->kind == Type_Union && t->Union.kind == UnionType_maybe) { if (t->Union.variants.count == 1) { Type *v = t->Union.variants[0]; return is_type_pointer(v) || is_type_multi_pointer(v); @@ -1639,7 +1697,7 @@ bool is_type_union_maybe_pointer(Type *t) { bool is_type_union_maybe_pointer_original_alignment(Type *t) { t = base_type(t); - if (t->kind == Type_Union && t->Union.maybe) { + if (t->kind == Type_Union && t->Union.kind == UnionType_maybe) { if (t->Union.variants.count == 1) { Type *v = t->Union.variants[0]; if (is_type_pointer(v) || is_type_multi_pointer(v)) { @@ -2131,7 +2189,7 @@ bool type_has_nil(Type *t) { case Type_Map: return true; case Type_Union: - return !t->Union.no_nil; + return t->Union.kind != UnionType_no_nil; case Type_Struct: if (is_type_soa_struct(t)) { switch (t->Struct.soa_kind) { @@ -2160,6 +2218,17 @@ bool elem_type_can_be_constant(Type *t) { return true; } +bool is_type_lock_free(Type *t) { + t = core_type(t); + if (t == t_invalid) { + return false; + } + i64 sz = type_size_of(t); + // TODO(bill): Figure this out correctly + return sz <= build_context.max_align; +} + + bool is_type_comparable(Type *t) { t = base_type(t); @@ -2296,7 +2365,7 @@ String lookup_subtype_polymorphic_field(Type *dst, Type *src) { GB_ASSERT(is_type_struct(src) || is_type_union(src)); for_array(i, src->Struct.fields) { Entity *f = src->Struct.fields[i]; - if (f->kind == Entity_Variable && f->flags & EntityFlag_Using) { + if (f->kind == Entity_Variable && f->flags & EntityFlags_IsSubtype) { if (are_types_identical(dst, f->type)) { return f->token.string; } @@ -2305,7 +2374,7 @@ String lookup_subtype_polymorphic_field(Type *dst, Type *src) { return f->token.string; } } - if (is_type_struct(f->type)) { + if ((f->flags & EntityFlag_Using) != 0 && is_type_struct(f->type)) { String name = lookup_subtype_polymorphic_field(dst, f->type); if (name.len > 0) { return name; @@ -2331,7 +2400,17 @@ Type *strip_type_aliasing(Type *x) { return x; } +bool are_types_identical_internal(Type *x, Type *y, bool check_tuple_names); + bool are_types_identical(Type *x, Type *y) { + return are_types_identical_internal(x, y, false); +} +bool are_types_identical_unique_tuples(Type *x, Type *y) { + return are_types_identical_internal(x, y, true); +} + + +bool are_types_identical_internal(Type *x, Type *y, bool check_tuple_names) { if (x == y) { return true; } @@ -2407,7 +2486,7 @@ bool are_types_identical(Type *x, Type *y) { if (y->kind == Type_Union) { if (x->Union.variants.count == y->Union.variants.count && x->Union.custom_align == y->Union.custom_align && - x->Union.no_nil == y->Union.no_nil) { + x->Union.kind == y->Union.kind) { // NOTE(bill): zeroth variant is nullptr for_array(i, x->Union.variants) { if (!are_types_identical(x->Union.variants[i], y->Union.variants[i])) { @@ -2441,9 +2520,9 @@ bool are_types_identical(Type *x, Type *y) { if (xf->token.string != yf->token.string) { return false; } - bool xf_is_using = (xf->flags&EntityFlag_Using) != 0; - bool yf_is_using = (yf->flags&EntityFlag_Using) != 0; - if (xf_is_using ^ yf_is_using) { + u64 xf_flags = (xf->flags&EntityFlags_IsSubtype); + u64 yf_flags = (yf->flags&EntityFlags_IsSubtype); + if (xf_flags != yf_flags) { return false; } } @@ -2480,6 +2559,11 @@ bool are_types_identical(Type *x, Type *y) { if (xe->kind != ye->kind || !are_types_identical(xe->type, ye->type)) { return false; } + if (check_tuple_names) { + if (xe->token.string != ye->token.string) { + return false; + } + } if (xe->kind == Entity_Constant && !compare_exact_values(Token_CmpEq, xe->Constant.value, ye->Constant.value)) { // NOTE(bill): This is needed for polymorphic procedures return false; @@ -2546,7 +2630,7 @@ i64 union_variant_index(Type *u, Type *v) { for_array(i, u->Union.variants) { Type *vt = u->Union.variants[i]; if (are_types_identical(v, vt)) { - if (u->Union.no_nil) { + if (u->Union.kind == UnionType_no_nil) { return cast(i64)(i+0); } else { return cast(i64)(i+1); @@ -2570,6 +2654,17 @@ i64 union_tag_size(Type *u) { // TODO(bill): Is this an okay approach? i64 max_align = 1; + + if (u->Union.variants.count < 1ull<<8) { + max_align = 1; + } else if (u->Union.variants.count < 1ull<<16) { + max_align = 2; + } else if (u->Union.variants.count < 1ull<<32) { + max_align = 4; + } else { + GB_PANIC("how many variants do you have?!"); + } + for_array(i, u->Union.variants) { Type *variant_type = u->Union.variants[i]; i64 align = type_align_of(variant_type); @@ -2730,6 +2825,7 @@ Selection lookup_field_from_index(Type *type, i64 index) { } Entity *scope_lookup_current(Scope *s, String const &name); +bool has_type_got_objc_class_attribute(Type *t); Selection lookup_field_with_selection(Type *type_, String field_name, bool is_type, Selection sel, bool allow_blank_ident) { GB_ASSERT(type_ != nullptr); @@ -2742,9 +2838,40 @@ Selection lookup_field_with_selection(Type *type_, String field_name, bool is_ty bool is_ptr = type != type_; sel.indirect = sel.indirect || is_ptr; + Type *original_type = type; + type = base_type(type); if (is_type) { + if (has_type_got_objc_class_attribute(original_type) && original_type->kind == Type_Named) { + Entity *e = original_type->Named.type_name; + GB_ASSERT(e->kind == Entity_TypeName); + if (e->TypeName.objc_metadata) { + auto *md = e->TypeName.objc_metadata; + mutex_lock(md->mutex); + defer (mutex_unlock(md->mutex)); + for (TypeNameObjCMetadataEntry const &entry : md->type_entries) { + GB_ASSERT(entry.entity->kind == Entity_Procedure); + if (entry.name == field_name) { + sel.entity = entry.entity; + sel.pseudo_field = true; + return sel; + } + } + } + if (type->kind == Type_Struct) { + for_array(i, type->Struct.fields) { + Entity *f = type->Struct.fields[i]; + if (f->flags&EntityFlag_Using) { + sel = lookup_field_with_selection(f->type, field_name, is_type, sel, allow_blank_ident); + if (sel.entity) { + return sel; + } + } + } + } + } + if (is_type_enum(type)) { // NOTE(bill): These may not have been added yet, so check in case for_array(i, type->Enum.fields) { @@ -2791,6 +2918,24 @@ Selection lookup_field_with_selection(Type *type_, String field_name, bool is_ty } else if (type->kind == Type_Union) { } else if (type->kind == Type_Struct) { + if (has_type_got_objc_class_attribute(original_type) && original_type->kind == Type_Named) { + Entity *e = original_type->Named.type_name; + GB_ASSERT(e->kind == Entity_TypeName); + if (e->TypeName.objc_metadata) { + auto *md = e->TypeName.objc_metadata; + mutex_lock(md->mutex); + defer (mutex_unlock(md->mutex)); + for (TypeNameObjCMetadataEntry const &entry : md->value_entries) { + GB_ASSERT(entry.entity->kind == Entity_Procedure); + if (entry.name == field_name) { + sel.entity = entry.entity; + sel.pseudo_field = true; + return sel; + } + } + } + } + for_array(i, type->Struct.fields) { Entity *f = type->Struct.fields[i]; if (f->kind != Entity_Variable || (f->flags & EntityFlag_Field) == 0) { @@ -3696,6 +3841,61 @@ i64 type_offset_of_from_selection(Type *type, Selection sel) { return offset; } +isize check_is_assignable_to_using_subtype(Type *src, Type *dst, isize level = 0, bool src_is_ptr = false) { + Type *prev_src = src; + src = type_deref(src); + if (!src_is_ptr) { + src_is_ptr = src != prev_src; + } + src = base_type(src); + + if (!is_type_struct(src)) { + return 0; + } + + for_array(i, src->Struct.fields) { + Entity *f = src->Struct.fields[i]; + if (f->kind != Entity_Variable || (f->flags&EntityFlags_IsSubtype) == 0) { + continue; + } + + if (are_types_identical(f->type, dst)) { + return level+1; + } + if (src_is_ptr && is_type_pointer(dst)) { + if (are_types_identical(f->type, type_deref(dst))) { + return level+1; + } + } + isize nested_level = check_is_assignable_to_using_subtype(f->type, dst, level+1, src_is_ptr); + if (nested_level > 0) { + return nested_level; + } + } + + return 0; +} + +bool is_type_subtype_of(Type *src, Type *dst) { + if (are_types_identical(src, dst)) { + return true; + } + + return 0 < check_is_assignable_to_using_subtype(src, dst, 0, is_type_pointer(src)); +} + + +bool has_type_got_objc_class_attribute(Type *t) { + return t->kind == Type_Named && t->Named.type_name != nullptr && t->Named.type_name->TypeName.objc_class_name != ""; +} + + + +bool is_type_objc_object(Type *t) { + bool internal_check_is_assignable_to(Type *src, Type *dst); + + return internal_check_is_assignable_to(t, t_objc_object); +} Type *get_struct_field_type(Type *t, isize index) { t = base_type(type_deref(t)); @@ -3767,7 +3967,7 @@ Type *alloc_type_proc_from_types(Type **param_types, unsigned param_count, Type -gbString write_type_to_string(gbString str, Type *type) { +gbString write_type_to_string(gbString str, Type *type, bool shorthand=false) { if (type == nullptr) { return gb_string_appendc(str, ""); } @@ -3808,6 +4008,9 @@ gbString write_type_to_string(gbString str, Type *type) { break; case Type_EnumeratedArray: + if (type->EnumeratedArray.is_sparse) { + str = gb_string_appendc(str, "#sparse"); + } str = gb_string_append_rune(str, '['); str = write_type_to_string(str, type->EnumeratedArray.index); str = gb_string_append_rune(str, ']'); @@ -3850,8 +4053,11 @@ gbString write_type_to_string(gbString str, Type *type) { case Type_Union: str = gb_string_appendc(str, "union"); - if (type->Union.no_nil != 0) str = gb_string_appendc(str, " #no_nil"); - if (type->Union.maybe != 0) str = gb_string_appendc(str, " #maybe"); + switch (type->Union.kind) { + case UnionType_maybe: str = gb_string_appendc(str, " #maybe"); break; + case UnionType_no_nil: str = gb_string_appendc(str, " #no_nil"); break; + case UnionType_shared_nil: str = gb_string_appendc(str, " #shared_nil"); break; + } if (type->Union.custom_align != 0) str = gb_string_append_fmt(str, " #align %d", cast(int)type->Union.custom_align); str = gb_string_appendc(str, " {"); for_array(i, type->Union.variants) { @@ -3879,15 +4085,21 @@ gbString write_type_to_string(gbString str, Type *type) { if (type->Struct.is_raw_union) str = gb_string_appendc(str, " #raw_union"); if (type->Struct.custom_align != 0) str = gb_string_append_fmt(str, " #align %d", cast(int)type->Struct.custom_align); str = gb_string_appendc(str, " {"); - for_array(i, type->Struct.fields) { - Entity *f = type->Struct.fields[i]; - GB_ASSERT(f->kind == Entity_Variable); - if (i > 0) { - str = gb_string_appendc(str, ", "); + + + if (shorthand && type->Struct.fields.count > 16) { + str = gb_string_append_fmt(str, "%lld fields...", cast(long long)type->Struct.fields.count); + } else { + for_array(i, type->Struct.fields) { + Entity *f = type->Struct.fields[i]; + GB_ASSERT(f->kind == Entity_Variable); + if (i > 0) { + str = gb_string_appendc(str, ", "); + } + str = gb_string_append_length(str, f->token.string.text, f->token.string.len); + str = gb_string_appendc(str, ": "); + str = write_type_to_string(str, f->type); } - str = gb_string_append_length(str, f->token.string.text, f->token.string.len); - str = gb_string_appendc(str, ": "); - str = write_type_to_string(str, f->type); } str = gb_string_append_rune(str, '}'); } break; @@ -3926,7 +4138,7 @@ gbString write_type_to_string(gbString str, Type *type) { str = gb_string_appendc(str, " = "); str = write_exact_value_to_string(str, var->Constant.value); } else { - str = gb_string_appendc(str, "="); + str = gb_string_appendc(str, " := "); str = write_exact_value_to_string(str, var->Constant.value); } continue; @@ -3954,14 +4166,10 @@ gbString write_type_to_string(gbString str, Type *type) { str = gb_string_appendc(str, "typeid/"); str = write_type_to_string(str, var->type); } else { - if (var->kind == Entity_TypeName) { - str = gb_string_appendc(str, "$"); - str = gb_string_append_length(str, name.text, name.len); - str = gb_string_appendc(str, "="); - str = write_type_to_string(str, var->type); - } else { - str = gb_string_appendc(str, "typeid"); - } + str = gb_string_appendc(str, "$"); + str = gb_string_append_length(str, name.text, name.len); + str = gb_string_appendc(str, "="); + str = write_type_to_string(str, var->type); } } } @@ -4066,13 +4274,16 @@ gbString write_type_to_string(gbString str, Type *type) { } -gbString type_to_string(Type *type, gbAllocator allocator) { - return write_type_to_string(gb_string_make(allocator, ""), type); +gbString type_to_string(Type *type, gbAllocator allocator, bool shorthand=false) { + return write_type_to_string(gb_string_make(allocator, ""), type, shorthand); } -gbString type_to_string(Type *type) { - return write_type_to_string(gb_string_make(heap_allocator(), ""), type); +gbString type_to_string(Type *type, bool shorthand) { + return write_type_to_string(gb_string_make(heap_allocator(), ""), type, shorthand); +} + +gbString type_to_string_shorthand(Type *type) { + return type_to_string(type, true); } - diff --git a/tests/common/common.odin b/tests/common/common.odin new file mode 100644 index 000000000..07b6afef9 --- /dev/null +++ b/tests/common/common.odin @@ -0,0 +1,75 @@ +// Boilerplate for tests +package common + +import "core:testing" +import "core:fmt" +import "core:os" +import "core:strings" + +TEST_count := 0 +TEST_fail := 0 + +when ODIN_TEST { + expect :: testing.expect + log :: testing.log +} else { + expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { + TEST_count += 1 + if !condition { + TEST_fail += 1 + fmt.printf("[%v] FAIL %v\n", loc, message) + return + } + } + log :: proc(t: ^testing.T, v: any, loc := #caller_location) { + fmt.printf("[%v] ", loc) + fmt.printf("log: %v\n", v) + } +} + +report :: proc(t: ^testing.T) { + if TEST_fail > 0 { + if TEST_fail > 1 { + fmt.printf("%v/%v tests successful, %v tests failed.\n", TEST_count - TEST_fail, TEST_count, TEST_fail) + } else { + fmt.printf("%v/%v tests successful, 1 test failed.\n", TEST_count - TEST_fail, TEST_count) + } + os.exit(1) + } else { + fmt.printf("%v/%v tests successful.\n", TEST_count, TEST_count) + } +} + +// Returns absolute path to `sub_path` where `sub_path` is within the "tests/" sub-directory of the Odin project root +// and we're being run from the Odin project root or from a sub-directory of "tests/" +// e.g. get_data_path("assets/blah") will return "/Odin_root/tests/assets/blah" if run within "/Odin_root", +// "/Odin_root/tests" or "/Odin_root/tests/subdir" etc +get_data_path :: proc(t: ^testing.T, sub_path: string) -> (data_path: string) { + + cwd := os.get_current_directory() + defer delete(cwd) + + when ODIN_OS == .Windows { + norm, was_allocation := strings.replace_all(cwd, "\\", "/") + if !was_allocation { + norm = strings.clone(norm) + } + defer delete(norm) + } else { + norm := cwd + } + + last_index := strings.last_index(norm, "/tests/") + if last_index == -1 { + len := len(norm) + if len >= 6 && norm[len-6:] == "/tests" { + data_path = fmt.tprintf("%s/%s", norm, sub_path) + } else { + data_path = fmt.tprintf("%s/tests/%s", norm, sub_path) + } + } else { + data_path = fmt.tprintf("%s/tests/%s", norm[:last_index], sub_path) + } + + return data_path +} diff --git a/tests/core/Makefile b/tests/core/Makefile index e17dede90..2c24fef75 100644 --- a/tests/core/Makefile +++ b/tests/core/Makefile @@ -1,29 +1,46 @@ ODIN=../../odin PYTHON=$(shell which python3) -all: download_test_assets image_test compress_test strings_test hash_test crypto_test encoding_test +all: download_test_assets image_test compress_test strings_test hash_test crypto_test noise_test encoding_test \ + math_test linalg_glsl_math_test filepath_test reflect_test os_exit_test download_test_assets: $(PYTHON) download_assets.py image_test: - $(ODIN) run image/test_core_image.odin -out=test_image -o:speed -no-bounds-check + $(ODIN) run image/test_core_image.odin -file -out:test_core_image compress_test: - $(ODIN) run compress/test_core_compress.odin -out=test_compress -o:speed -no-bounds-check + $(ODIN) run compress/test_core_compress.odin -file -out:test_core_compress strings_test: - $(ODIN) run strings/test_core_strings.odin -out=test_strings -o:speed -no-bounds-check - -odin_test: - $(ODIN) run odin -out=test_odin -o:speed -no-bounds-check + $(ODIN) run strings/test_core_strings.odin -file -out:test_core_strings hash_test: - $(ODIN) run hash -out=test_hash -o:speed -no-bounds-check + $(ODIN) run hash -o:speed -no-bounds-check -out:test_hash crypto_test: - $(ODIN) run crypto -out=crypto_hash -o:speed -no-bounds-check + $(ODIN) run crypto -o:speed -no-bounds-check -out:test_crypto_hash + +noise_test: + $(ODIN) run math/noise -out:test_noise encoding_test: - $(ODIN) run encoding/json -out=test_encoding_json -o:speed -no-bounds-check - $(ODIN) run encoding/xml -out=test_encoding_xml -o:speed -no-bounds-check + $(ODIN) run encoding/hxa -collection:tests=.. -out:test_hxa + $(ODIN) run encoding/json -out:test_json + $(ODIN) run encoding/varint -out:test_varint + +math_test: + $(ODIN) run math/test_core_math.odin -file -collection:tests=.. -out:test_core_math + +linalg_glsl_math_test: + $(ODIN) run math/linalg/glsl/test_linalg_glsl_math.odin -file -collection:tests=.. -out:test_linalg_glsl_math + +filepath_test: + $(ODIN) run path/filepath/test_core_filepath.odin -file -collection:tests=.. -out:test_core_filepath + +reflect_test: + $(ODIN) run reflect/test_core_reflect.odin -file -collection:tests=.. -out:test_core_reflect + +os_exit_test: + $(ODIN) run os/test_core_os_exit.odin -file -out:test_core_os_exit && exit 1 || exit 0 \ No newline at end of file diff --git a/tests/core/assets/HXA/teapot.hxa b/tests/core/assets/HXA/teapot.hxa new file mode 100644 index 000000000..954ab5a10 Binary files /dev/null and b/tests/core/assets/HXA/teapot.hxa differ diff --git a/tests/core/assets/Shoco/LICENSE b/tests/core/assets/Shoco/LICENSE new file mode 100644 index 000000000..9ca94bcdf --- /dev/null +++ b/tests/core/assets/Shoco/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2016-2021 Ginger Bill. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/tests/core/assets/Shoco/LICENSE.shoco b/tests/core/assets/Shoco/LICENSE.shoco new file mode 100644 index 000000000..5d5e4d623 Binary files /dev/null and b/tests/core/assets/Shoco/LICENSE.shoco differ diff --git a/tests/core/assets/Shoco/README.md b/tests/core/assets/Shoco/README.md new file mode 100644 index 000000000..9e46f80d0 --- /dev/null +++ b/tests/core/assets/Shoco/README.md @@ -0,0 +1,95 @@ +

+ Odin logo +
+ The Data-Oriented Language for Sane Software Development. +
+
+ + + +
+ + +
+ + + + + + +

+ +# The Odin Programming Language + + +Odin is a general-purpose programming language with distinct typing, built for high performance, modern systems, and built-in data-oriented data types. The Odin Programming Language, the C alternative for the joy of programming. + +Website: [https://odin-lang.org/](https://odin-lang.org/) + +```odin +package main + +import "core:fmt" + +main :: proc() { + program := "+ + * 😃 - /" + accumulator := 0 + + for token in program { + switch token { + case '+': accumulator += 1 + case '-': accumulator -= 1 + case '*': accumulator *= 2 + case '/': accumulator /= 2 + case '😃': accumulator *= accumulator + case: // Ignore everything else + } + } + + fmt.printf("The program \"%s\" calculates the value %d\n", + program, accumulator) +} + +``` + +## Documentation + +#### [Getting Started](https://odin-lang.org/docs/install) + +Instructions for downloading and installing the Odin compiler and libraries. + +#### [Nightly Builds](https://odin-lang.org/docs/nightly/) + +Get the latest nightly builds of Odin. + +### Learning Odin + +#### [Overview of Odin](https://odin-lang.org/docs/overview) + +An overview of the Odin programming language. + +#### [Frequently Asked Questions (FAQ)](https://odin-lang.org/docs/faq) + +Answers to common questions about Odin. + +#### [Packages](https://pkg.odin-lang.org/) + +Documentation for all the official packages part of the [core](https://pkg.odin-lang.org/core/) and [vendor](https://pkg.odin-lang.org/vendor/) library collections. + +#### [The Odin Wiki](https://github.com/odin-lang/Odin/wiki) + +A wiki maintained by the Odin community. + +#### [Odin Discord](https://discord.gg/sVBPHEv) + +Get live support and talk with other odiners on the Odin Discord. + +### Articles + +#### [The Odin Blog](https://odin-lang.org/news/) + +The official blog of the Odin programming language, featuring announcements, news, and in-depth articles by the Odin team and guests. + +## Warnings + +* The Odin compiler is still in development. diff --git a/tests/core/assets/Shoco/README.md.shoco b/tests/core/assets/Shoco/README.md.shoco new file mode 100644 index 000000000..013f4f469 Binary files /dev/null and b/tests/core/assets/Shoco/README.md.shoco differ diff --git a/tests/core/build.bat b/tests/core/build.bat index 7a214acc9..b03fef4bb 100644 --- a/tests/core/build.bat +++ b/tests/core/build.bat @@ -1,39 +1,65 @@ @echo off -set COMMON=-show-timings -no-bounds-check -vet -strict-style +set COMMON=-show-timings -no-bounds-check -vet -strict-style -collection:tests=.. set PATH_TO_ODIN==..\..\odin python3 download_assets.py echo --- echo Running core:image tests echo --- -%PATH_TO_ODIN% run image %COMMON% -out:test_image.exe +%PATH_TO_ODIN% run image %COMMON% -out:test_core_image.exe echo --- echo Running core:compress tests echo --- -%PATH_TO_ODIN% run compress %COMMON% -out:test_compress.exe +%PATH_TO_ODIN% run compress %COMMON% -out:test_core_compress.exe echo --- echo Running core:strings tests echo --- -%PATH_TO_ODIN% run strings %COMMON% -out:test_strings.exe +%PATH_TO_ODIN% run strings %COMMON% -out:test_core_strings.exe echo --- echo Running core:hash tests echo --- -%PATH_TO_ODIN% run hash %COMMON% -o:size -out:test_hash.exe +%PATH_TO_ODIN% run hash %COMMON% -o:size -out:test_core_hash.exe echo --- echo Running core:odin tests echo --- -%PATH_TO_ODIN% run odin %COMMON% -o:size -out:test_odin.exe +%PATH_TO_ODIN% run odin %COMMON% -o:size -out:test_core_odin.exe echo --- echo Running core:crypto hash tests echo --- -%PATH_TO_ODIN% run crypto %COMMON% -o:speed -out:test_crypto.exe +%PATH_TO_ODIN% run crypto %COMMON% -out:test_crypto_hash.exe echo --- echo Running core:encoding tests echo --- -%PATH_TO_ODIN% run encoding\json %COMMON% -out:test_json.exe -%PATH_TO_ODIN% run encoding\xml %COMMON% -out:test_xml.exe \ No newline at end of file +%PATH_TO_ODIN% run encoding/hxa %COMMON% -out:test_hxa.exe +%PATH_TO_ODIN% run encoding/json %COMMON% -out:test_json.exe +%PATH_TO_ODIN% run encoding/varint %COMMON% -out:test_varint.exe + +echo --- +echo Running core:math/noise tests +echo --- +%PATH_TO_ODIN% run math/noise %COMMON% -out:test_noise.exe + +echo --- +echo Running core:math tests +echo --- +%PATH_TO_ODIN% run math %COMMON% -out:test_core_math.exe + +echo --- +echo Running core:math/linalg/glsl tests +echo --- +%PATH_TO_ODIN% run math/linalg/glsl %COMMON% -out:test_linalg_glsl.exe + +echo --- +echo Running core:path/filepath tests +echo --- +%PATH_TO_ODIN% run path/filepath %COMMON% -out:test_core_filepath.exe + +echo --- +echo Running core:reflect tests +echo --- +%PATH_TO_ODIN% run reflect %COMMON% -out:test_core_reflect.exe \ No newline at end of file diff --git a/tests/core/compress/test_core_compress.odin b/tests/core/compress/test_core_compress.odin index 908ef12e4..ee7233e52 100644 --- a/tests/core/compress/test_core_compress.odin +++ b/tests/core/compress/test_core_compress.odin @@ -7,13 +7,14 @@ package test_core_compress List of contributors: Jeroen van Rijn: Initial implementation. - A test suite for ZLIB, GZIP. + A test suite for ZLIB, GZIP and Shoco. */ import "core:testing" import "core:compress/zlib" import "core:compress/gzip" +import "core:compress/shoco" import "core:bytes" import "core:fmt" @@ -38,7 +39,8 @@ when ODIN_TEST { } } log :: proc(t: ^testing.T, v: any, loc := #caller_location) { - fmt.printf("[%v] LOG:\n\t%v\n", loc, v) + fmt.printf("[%v] ", loc) + fmt.printf("log: %v\n", v) } } @@ -47,8 +49,12 @@ main :: proc() { t := testing.T{w=w} zlib_test(&t) gzip_test(&t) + shoco_test(&t) - fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + if TEST_fail > 0 { + os.exit(1) + } } @test @@ -130,3 +136,56 @@ gzip_test :: proc(t: ^testing.T) { expect(t, false, error) } } + +@test +shoco_test :: proc(t: ^testing.T) { + + Shoco_Tests :: []struct{ + compressed: []u8, + raw: []u8, + short_pack: int, + short_sentinel: int, + }{ + { #load("../assets/Shoco/README.md.shoco"), #load("../assets/Shoco/README.md"), 10, 1006 }, + { #load("../assets/Shoco/LICENSE.shoco"), #load("../assets/Shoco/LICENSE"), 25, 68 }, + } + + for v in Shoco_Tests { + expected_raw := len(v.raw) + expected_compressed := len(v.compressed) + + biggest_unpacked := shoco.decompress_bound(expected_compressed) + biggest_packed := shoco.compress_bound(expected_raw) + + buffer := make([]u8, max(biggest_packed, biggest_unpacked)) + defer delete(buffer) + + size, err := shoco.decompress(v.compressed, buffer[:]) + msg := fmt.tprintf("Expected `decompress` to return `nil`, got %v", err) + expect(t, err == nil, msg) + + msg = fmt.tprintf("Decompressed %v bytes into %v. Expected to decompress into %v bytes.", len(v.compressed), size, expected_raw) + expect(t, size == expected_raw, msg) + expect(t, string(buffer[:size]) == string(v.raw), "Decompressed contents don't match.") + + size, err = shoco.compress(string(v.raw), buffer[:]) + expect(t, err == nil, "Expected `compress` to return `nil`.") + + msg = fmt.tprintf("Compressed %v bytes into %v. Expected to compress into %v bytes.", expected_raw, size, expected_compressed) + expect(t, size == expected_compressed, msg) + + size, err = shoco.decompress(v.compressed, buffer[:expected_raw - 10]) + msg = fmt.tprintf("Decompressing into too small a buffer returned %v, expected `.Output_Too_Short`", err) + expect(t, err == .Output_Too_Short, msg) + + size, err = shoco.compress(string(v.raw), buffer[:expected_compressed - 10]) + msg = fmt.tprintf("Compressing into too small a buffer returned %v, expected `.Output_Too_Short`", err) + expect(t, err == .Output_Too_Short, msg) + + size, err = shoco.decompress(v.compressed[:v.short_pack], buffer[:]) + expect(t, err == .Stream_Too_Short, "Expected `decompress` to return `Stream_Too_Short` because there was no more data after selecting a pack.") + + size, err = shoco.decompress(v.compressed[:v.short_sentinel], buffer[:]) + expect(t, err == .Stream_Too_Short, "Expected `decompress` to return `Stream_Too_Short` because there was no more data after non-ASCII sentinel.") + } +} \ No newline at end of file diff --git a/tests/core/crypto/test_core_crypto.odin b/tests/core/crypto/test_core_crypto.odin index 6d3a9f8e4..636632d71 100644 --- a/tests/core/crypto/test_core_crypto.odin +++ b/tests/core/crypto/test_core_crypto.odin @@ -36,6 +36,8 @@ import "core:crypto/sm3" import "core:crypto/jh" import "core:crypto/groestl" import "core:crypto/haval" +import "core:crypto/siphash" +import "core:os" TEST_count := 0 TEST_fail := 0 @@ -52,8 +54,9 @@ when ODIN_TEST { return } } - log :: proc(t: ^testing.T, v: any, loc := #caller_location) { - fmt.printf("[%v] LOG:\n\t%v\n", loc, v) + log :: proc(t: ^testing.T, v: any, loc := #caller_location) { + fmt.printf("[%v] ", loc) + fmt.printf("log: %v\n", v) } } @@ -111,6 +114,7 @@ main :: proc() { test_haval_192(&t) test_haval_224(&t) test_haval_256(&t) + test_siphash_2_4(&t) // "modern" crypto tests test_chacha20(&t) @@ -121,7 +125,10 @@ main :: proc() { bench_modern(&t) - fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + if TEST_fail > 0 { + os.exit(1) + } } TestHash :: struct { @@ -198,7 +205,7 @@ test_md5 :: proc(t: ^testing.T) { @(test) test_sha1 :: proc(t: ^testing.T) { - // Test vectors from + // Test vectors from // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf // https://www.di-mgt.com.au/sha_testvectors.html test_vectors := [?]TestHash { @@ -220,7 +227,7 @@ test_sha1 :: proc(t: ^testing.T) { @(test) test_sha224 :: proc(t: ^testing.T) { - // Test vectors from + // Test vectors from // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf // https://www.di-mgt.com.au/sha_testvectors.html test_vectors := [?]TestHash { @@ -238,7 +245,7 @@ test_sha224 :: proc(t: ^testing.T) { @(test) test_sha256 :: proc(t: ^testing.T) { - // Test vectors from + // Test vectors from // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf // https://www.di-mgt.com.au/sha_testvectors.html test_vectors := [?]TestHash { @@ -256,7 +263,7 @@ test_sha256 :: proc(t: ^testing.T) { @(test) test_sha384 :: proc(t: ^testing.T) { - // Test vectors from + // Test vectors from // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf // https://www.di-mgt.com.au/sha_testvectors.html test_vectors := [?]TestHash { @@ -274,7 +281,7 @@ test_sha384 :: proc(t: ^testing.T) { @(test) test_sha512 :: proc(t: ^testing.T) { - // Test vectors from + // Test vectors from // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf // https://www.di-mgt.com.au/sha_testvectors.html test_vectors := [?]TestHash { @@ -292,7 +299,7 @@ test_sha512 :: proc(t: ^testing.T) { @(test) test_sha3_224 :: proc(t: ^testing.T) { - // Test vectors from + // Test vectors from // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf // https://www.di-mgt.com.au/sha_testvectors.html test_vectors := [?]TestHash { @@ -314,7 +321,7 @@ test_sha3_224 :: proc(t: ^testing.T) { @(test) test_sha3_256 :: proc(t: ^testing.T) { - // Test vectors from + // Test vectors from // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf // https://www.di-mgt.com.au/sha_testvectors.html test_vectors := [?]TestHash { @@ -336,7 +343,7 @@ test_sha3_256 :: proc(t: ^testing.T) { @(test) test_sha3_384 :: proc(t: ^testing.T) { - // Test vectors from + // Test vectors from // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf // https://www.di-mgt.com.au/sha_testvectors.html test_vectors := [?]TestHash { @@ -358,7 +365,7 @@ test_sha3_384 :: proc(t: ^testing.T) { @(test) test_sha3_512 :: proc(t: ^testing.T) { - // Test vectors from + // Test vectors from // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf // https://www.di-mgt.com.au/sha_testvectors.html test_vectors := [?]TestHash { @@ -408,7 +415,7 @@ test_shake_256 :: proc(t: ^testing.T) { @(test) test_keccak_224 :: proc(t: ^testing.T) { - // Test vectors from + // Test vectors from // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf // https://www.di-mgt.com.au/sha_testvectors.html test_vectors := [?]TestHash { @@ -424,7 +431,7 @@ test_keccak_224 :: proc(t: ^testing.T) { @(test) test_keccak_256 :: proc(t: ^testing.T) { - // Test vectors from + // Test vectors from // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf // https://www.di-mgt.com.au/sha_testvectors.html test_vectors := [?]TestHash { @@ -440,7 +447,7 @@ test_keccak_256 :: proc(t: ^testing.T) { @(test) test_keccak_384 :: proc(t: ^testing.T) { - // Test vectors from + // Test vectors from // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf // https://www.di-mgt.com.au/sha_testvectors.html test_vectors := [?]TestHash { @@ -456,7 +463,7 @@ test_keccak_384 :: proc(t: ^testing.T) { @(test) test_keccak_512 :: proc(t: ^testing.T) { - // Test vectors from + // Test vectors from // https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/examples/sha_all.pdf // https://www.di-mgt.com.au/sha_testvectors.html test_vectors := [?]TestHash { @@ -472,7 +479,7 @@ test_keccak_512 :: proc(t: ^testing.T) { @(test) test_whirlpool :: proc(t: ^testing.T) { - // Test vectors from + // Test vectors from // https://web.archive.org/web/20171129084214/http://www.larc.usp.br/~pbarreto/WhirlpoolPage.html test_vectors := [?]TestHash { TestHash{"19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3", ""}, @@ -628,7 +635,7 @@ test_blake2s :: proc(t: ^testing.T) { @(test) test_ripemd_128 :: proc(t: ^testing.T) { - // Test vectors from + // Test vectors from // https://homes.esat.kuleuven.be/~bosselae/ripemd160.html test_vectors := [?]TestHash { TestHash{"cdf26213a150dc3ecb610f18f6b38b46", ""}, @@ -648,7 +655,7 @@ test_ripemd_128 :: proc(t: ^testing.T) { @(test) test_ripemd_160 :: proc(t: ^testing.T) { - // Test vectors from + // Test vectors from // https://homes.esat.kuleuven.be/~bosselae/ripemd160.html test_vectors := [?]TestHash { TestHash{"9c1185a5c5e9fc54612808977ee8f548b2258d31", ""}, @@ -668,7 +675,7 @@ test_ripemd_160 :: proc(t: ^testing.T) { @(test) test_ripemd_256 :: proc(t: ^testing.T) { - // Test vectors from + // Test vectors from // https://homes.esat.kuleuven.be/~bosselae/ripemd160.html test_vectors := [?]TestHash { TestHash{"02ba4c4e5f8ecd1877fc52d64d30e37a2d9774fb1e5d026380ae0168e3c5522d", ""}, @@ -677,7 +684,7 @@ test_ripemd_256 :: proc(t: ^testing.T) { TestHash{"87e971759a1ce47a514d5c914c392c9018c7c46bc14465554afcdf54a5070c0e", "message digest"}, TestHash{"649d3034751ea216776bf9a18acc81bc7896118a5197968782dd1fd97d8d5133", "abcdefghijklmnopqrstuvwxyz"}, TestHash{"3843045583aac6c8c8d9128573e7a9809afb2a0f34ccc36ea9e72f16f6368e3f", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - TestHash{"5740a408ac16b720b84424ae931cbb1fe363d1d0bf4017f1a89f7ea6de77a0b8", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, + TestHash{"5740a408ac16b720b84424ae931cbb1fe363d1d0bf4017f1a89f7ea6de77a0b8", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, } for v, _ in test_vectors { computed := ripemd.hash_256(v.str) @@ -688,7 +695,7 @@ test_ripemd_256 :: proc(t: ^testing.T) { @(test) test_ripemd_320 :: proc(t: ^testing.T) { - // Test vectors from + // Test vectors from // https://homes.esat.kuleuven.be/~bosselae/ripemd160.html test_vectors := [?]TestHash { TestHash{"22d65d5661536cdc75c1fdf5c6de7b41b9f27325ebc61e8557177d705a0ec880151c3a32a00899b8", ""}, @@ -813,7 +820,7 @@ test_sm3 :: proc(t: ^testing.T) { test_vectors := [?]TestHash { TestHash{"1ab21d8355cfa17f8e61194831e81a8f22bec8c728fefb747ed035eb5082aa2b", ""}, TestHash{"66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0", "abc"}, - TestHash{"debe9ff92275b8a138604889c18e5a4d6fdb70e5387e5765293dcba39c0c5732", "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"}, + TestHash{"debe9ff92275b8a138604889c18e5a4d6fdb70e5387e5765293dcba39c0c5732", "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"}, TestHash{"5fdfe814b8573ca021983970fc79b2218c9570369b4859684e2e4c3fc76cb8ea", "The quick brown fox jumps over the lazy dog"}, TestHash{"ca27d14a42fc04c1e5ecf574a95a8c2d70ecb5805e9b429026ccac8f28b20098", "The quick brown fox jumps over the lazy cog"}, } @@ -945,7 +952,7 @@ test_haval_128 :: proc(t: ^testing.T) { TestHash{"3caf4a79e81adcd6d1716bcc1cef4573", "message digest"}, TestHash{"dc502247fb3eb8376109eda32d361d82", "abcdefghijklmnopqrstuvwxyz"}, TestHash{"44068770868768964d1f2c3bff4aa3d8", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - TestHash{"de5eb3f7d9eb08fae7a07d68e3047ec6", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, + TestHash{"de5eb3f7d9eb08fae7a07d68e3047ec6", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, } for v, _ in test_vectors_3 { computed := haval.hash_128_3(v.str) @@ -981,7 +988,7 @@ test_haval_160 :: proc(t: ^testing.T) { TestHash{"43a47f6f1c016207f08be8115c0977bf155346da", "message digest"}, TestHash{"eba9fa6050f24c07c29d1834a60900ea4e32e61b", "abcdefghijklmnopqrstuvwxyz"}, TestHash{"c30bce448cf8cfe957c141e90c0a063497cdfeeb", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - TestHash{"97dc988d97caae757be7523c4e8d4ea63007a4b9", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, + TestHash{"97dc988d97caae757be7523c4e8d4ea63007a4b9", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, } for v, _ in test_vectors_3 { computed := haval.hash_160_3(v.str) @@ -1100,3 +1107,44 @@ test_haval_256 :: proc(t: ^testing.T) { expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) } } + +@(test) +test_siphash_2_4 :: proc(t: ^testing.T) { + // Test vectors from + // https://github.com/veorq/SipHash/blob/master/vectors.h + test_vectors := [?]u64 { + 0x726fdb47dd0e0e31, 0x74f839c593dc67fd, 0x0d6c8009d9a94f5a, 0x85676696d7fb7e2d, + 0xcf2794e0277187b7, 0x18765564cd99a68d, 0xcbc9466e58fee3ce, 0xab0200f58b01d137, + 0x93f5f5799a932462, 0x9e0082df0ba9e4b0, 0x7a5dbbc594ddb9f3, 0xf4b32f46226bada7, + 0x751e8fbc860ee5fb, 0x14ea5627c0843d90, 0xf723ca908e7af2ee, 0xa129ca6149be45e5, + 0x3f2acc7f57c29bdb, 0x699ae9f52cbe4794, 0x4bc1b3f0968dd39c, 0xbb6dc91da77961bd, + 0xbed65cf21aa2ee98, 0xd0f2cbb02e3b67c7, 0x93536795e3a33e88, 0xa80c038ccd5ccec8, + 0xb8ad50c6f649af94, 0xbce192de8a85b8ea, 0x17d835b85bbb15f3, 0x2f2e6163076bcfad, + 0xde4daaaca71dc9a5, 0xa6a2506687956571, 0xad87a3535c49ef28, 0x32d892fad841c342, + 0x7127512f72f27cce, 0xa7f32346f95978e3, 0x12e0b01abb051238, 0x15e034d40fa197ae, + 0x314dffbe0815a3b4, 0x027990f029623981, 0xcadcd4e59ef40c4d, 0x9abfd8766a33735c, + 0x0e3ea96b5304a7d0, 0xad0c42d6fc585992, 0x187306c89bc215a9, 0xd4a60abcf3792b95, + 0xf935451de4f21df2, 0xa9538f0419755787, 0xdb9acddff56ca510, 0xd06c98cd5c0975eb, + 0xe612a3cb9ecba951, 0xc766e62cfcadaf96, 0xee64435a9752fe72, 0xa192d576b245165a, + 0x0a8787bf8ecb74b2, 0x81b3e73d20b49b6f, 0x7fa8220ba3b2ecea, 0x245731c13ca42499, + 0xb78dbfaf3a8d83bd, 0xea1ad565322a1a0b, 0x60e61c23a3795013, 0x6606d7e446282b93, + 0x6ca4ecb15c5f91e1, 0x9f626da15c9625f3, 0xe51b38608ef25f57, 0x958a324ceb064572, + } + + key: [16]byte + for i in 0..<16 { + key[i] = byte(i) + } + + for i in 0.. %v != %v", #procedure, filename, err, e)) + defer file_destroy(file) + + /* Header */ + tc.expect(t, file.magic_number == 0x417848, fmt.tprintf("%v: file.magic_number %v != %v", + #procedure, file.magic_number, 0x417848)) + tc.expect(t, file.version == 1, fmt.tprintf("%v: file.version %v != %v", + #procedure, file.version, 1)) + tc.expect(t, file.internal_node_count == 1, fmt.tprintf("%v: file.internal_node_count %v != %v", + #procedure, file.internal_node_count, 1)) + + /* Nodes (only one) */ + tc.expect(t, len(file.nodes) == 1, fmt.tprintf("%v: len(file.nodes) %v != %v", #procedure, len(file.nodes), 1)) + + m := &file.nodes[0].meta_data + tc.expect(t, len(m^) == 38, fmt.tprintf("%v: len(m^) %v != %v", #procedure, len(m^), 38)) + { + e :: "Texture resolution" + tc.expect(t, m[0].name == e, fmt.tprintf("%v: m[0].name %v != %v", #procedure, m[0].name, e)) + + m_v, m_v_ok := m[0].value.([]i64le) + tc.expect(t, m_v_ok, fmt.tprintf("%v: m_v_ok %v != %v", #procedure, m_v_ok, true)) + tc.expect(t, len(m_v) == 1, fmt.tprintf("%v: len(m_v) %v != %v", #procedure, len(m_v), 1)) + tc.expect(t, m_v[0] == 1024, fmt.tprintf("%v: m_v[0] %v != %v", #procedure, len(m_v), 1024)) + } + { + e :: "Validate" + tc.expect(t, m[37].name == e, fmt.tprintf("%v: m[37].name %v != %v", #procedure, m[37].name, e)) + + m_v, m_v_ok := m[37].value.([]i64le) + tc.expect(t, m_v_ok, fmt.tprintf("%v: m_v_ok %v != %v", #procedure, m_v_ok, true)) + tc.expect(t, len(m_v) == 1, fmt.tprintf("%v: len(m_v) %v != %v", #procedure, len(m_v), 1)) + tc.expect(t, m_v[0] == -2054847231, fmt.tprintf("%v: m_v[0] %v != %v", #procedure, len(m_v), -2054847231)) + } + + /* Node content */ + v, v_ok := file.nodes[0].content.(hxa.Node_Geometry) + tc.expect(t, v_ok, fmt.tprintf("%v: v_ok %v != %v", #procedure, v_ok, true)) + + tc.expect(t, v.vertex_count == 530, fmt.tprintf("%v: v.vertex_count %v != %v", #procedure, v.vertex_count, 530)) + tc.expect(t, v.edge_corner_count == 2026, fmt.tprintf("%v: v.edge_corner_count %v != %v", + #procedure, v.edge_corner_count, 2026)) + tc.expect(t, v.face_count == 517, fmt.tprintf("%v: v.face_count %v != %v", #procedure, v.face_count, 517)) + + /* Vertex stack */ + tc.expect(t, len(v.vertex_stack) == 1, fmt.tprintf("%v: len(v.vertex_stack) %v != %v", + #procedure, len(v.vertex_stack), 1)) + { + e := "vertex" + tc.expect(t, v.vertex_stack[0].name == e, fmt.tprintf("%v: v.vertex_stack[0].name %v != %v", + #procedure, v.vertex_stack[0].name, e)) + } + tc.expect(t, v.vertex_stack[0].components == 3, fmt.tprintf("%v: v.vertex_stack[0].components %v != %v", + #procedure, v.vertex_stack[0].components, 3)) + + /* Vertex stack data */ + vs_d, vs_d_ok := v.vertex_stack[0].data.([]f64le) + tc.expect(t, vs_d_ok, fmt.tprintf("%v: vs_d_ok %v != %v", #procedure, vs_d_ok, true)) + tc.expect(t, len(vs_d) == 1590, fmt.tprintf("%v: len(vs_d) %v != %v", #procedure, len(vs_d), 1590)) + + tc.expect(t, vs_d[0] == 4.06266, fmt.tprintf("%v: vs_d[0] %v (%h) != %v (%h)", + #procedure, vs_d[0], vs_d[0], 4.06266, 4.06266)) + tc.expect(t, vs_d[1] == 2.83457, fmt.tprintf("%v: vs_d[1] %v (%h) != %v (%h)", + #procedure, vs_d[1], vs_d[1], 2.83457, 2.83457)) + tc.expect(t, vs_d[2] == 0hbfbc5da6a4441787, fmt.tprintf("%v: vs_d[2] %v (%h) != %v (%h)", + #procedure, vs_d[2], vs_d[2], + 0hbfbc5da6a4441787, 0hbfbc5da6a4441787)) + tc.expect(t, vs_d[3] == 0h4010074fb549f948, fmt.tprintf("%v: vs_d[3] %v (%h) != %v (%h)", + #procedure, vs_d[3], vs_d[3], + 0h4010074fb549f948, 0h4010074fb549f948)) + tc.expect(t, vs_d[1587] == 0h400befa82e87d2c7, fmt.tprintf("%v: vs_d[1587] %v (%h) != %v (%h)", + #procedure, vs_d[1587], vs_d[1587], + 0h400befa82e87d2c7, 0h400befa82e87d2c7)) + tc.expect(t, vs_d[1588] == 2.83457, fmt.tprintf("%v: vs_d[1588] %v (%h) != %v (%h)", + #procedure, vs_d[1588], vs_d[1588], 2.83457, 2.83457)) + tc.expect(t, vs_d[1589] == -1.56121, fmt.tprintf("%v: vs_d[1589] %v (%h) != %v (%h)", + #procedure, vs_d[1589], vs_d[1589], -1.56121, -1.56121)) + + /* Corner stack */ + tc.expect(t, len(v.corner_stack) == 1, + fmt.tprintf("%v: len(v.corner_stack) %v != %v", #procedure, len(v.corner_stack), 1)) + { + e := "reference" + tc.expect(t, v.corner_stack[0].name == e, fmt.tprintf("%v: v.corner_stack[0].name %v != %v", + #procedure, v.corner_stack[0].name, e)) + } + tc.expect(t, v.corner_stack[0].components == 1, fmt.tprintf("%v: v.corner_stack[0].components %v != %v", + #procedure, v.corner_stack[0].components, 1)) + + /* Corner stack data */ + cs_d, cs_d_ok := v.corner_stack[0].data.([]i32le) + tc.expect(t, cs_d_ok, fmt.tprintf("%v: cs_d_ok %v != %v", #procedure, cs_d_ok, true)) + tc.expect(t, len(cs_d) == 2026, fmt.tprintf("%v: len(cs_d) %v != %v", #procedure, len(cs_d), 2026)) + tc.expect(t, cs_d[0] == 6, fmt.tprintf("%v: cs_d[0] %v != %v", #procedure, cs_d[0], 6)) + tc.expect(t, cs_d[2025] == -32, fmt.tprintf("%v: cs_d[2025] %v != %v", #procedure, cs_d[2025], -32)) + + /* Edge and face stacks (empty) */ + tc.expect(t, len(v.edge_stack) == 0, fmt.tprintf("%v: len(v.edge_stack) %v != %v", + #procedure, len(v.edge_stack), 0)) + tc.expect(t, len(v.face_stack) == 0, fmt.tprintf("%v: len(v.face_stack) %v != %v", + #procedure, len(v.face_stack), 0)) +} + +@test +test_write :: proc(t: ^testing.T) { + + using hxa + + n1 :Node + + n1_m1_value := []f64le{0.4, -1.23, 2341.6, -333.333} + n1_m1 := Meta{"m1", n1_m1_value} + + n1.meta_data = []Meta{n1_m1} + + n1_l1 := Layer{"l1", 2, []f32le{32.1, -41.3}} + n1_l2 := Layer{"l2", 3, []f64le{0.64, 1.64, -2.64}} + + n1_content := Node_Image{Image_Type.Image_1D, [3]u32le{1, 1, 2}, Layer_Stack{n1_l1, n1_l2}} + + n1.content = n1_content + + w_file :File + w_file.nodes = []Node{n1} + + required_size := required_write_size(w_file) + buf := make([]u8, required_size) + + n, write_err := write(buf, w_file) + write_e :: hxa.Write_Error.None + tc.expect(t, write_err == write_e, fmt.tprintf("%v: write_err %v != %v", #procedure, write_err, write_e)) + tc.expect(t, n == required_size, fmt.tprintf("%v: n %v != %v", #procedure, n, required_size)) + + file, read_err := read(buf) + read_e :: hxa.Read_Error.None + tc.expect(t, read_err == read_e, fmt.tprintf("%v: read_err %v != %v", #procedure, read_err, read_e)) + defer file_destroy(file) + + delete(buf) + + tc.expect(t, file.magic_number == 0x417848, fmt.tprintf("%v: file.magic_number %v != %v", + #procedure, file.magic_number, 0x417848)) + tc.expect(t, file.version == 3, fmt.tprintf("%v: file.version %v != %v", #procedure, file.version, 3)) + tc.expect(t, file.internal_node_count == 1, fmt.tprintf("%v: file.internal_node_count %v != %v", + #procedure, file.internal_node_count, 1)) + + tc.expect(t, len(file.nodes) == len(w_file.nodes), fmt.tprintf("%v: len(file.nodes) %v != %v", + #procedure, len(file.nodes), len(w_file.nodes))) + + m := &file.nodes[0].meta_data + w_m := &w_file.nodes[0].meta_data + tc.expect(t, len(m^) == len(w_m^), fmt.tprintf("%v: len(m^) %v != %v", #procedure, len(m^), len(w_m^))) + tc.expect(t, m[0].name == w_m[0].name, fmt.tprintf("%v: m[0].name %v != %v", #procedure, m[0].name, w_m[0].name)) + + m_v, m_v_ok := m[0].value.([]f64le) + tc.expect(t, m_v_ok, fmt.tprintf("%v: m_v_ok %v != %v", #procedure, m_v_ok, true)) + tc.expect(t, len(m_v) == len(n1_m1_value), fmt.tprintf("%v: %v != len(m_v) %v", + #procedure, len(m_v), len(n1_m1_value))) + for i := 0; i < len(m_v); i += 1 { + tc.expect(t, m_v[i] == n1_m1_value[i], fmt.tprintf("%v: m_v[%d] %v != %v", + #procedure, i, m_v[i], n1_m1_value[i])) + } + + v, v_ok := file.nodes[0].content.(hxa.Node_Image) + tc.expect(t, v_ok, fmt.tprintf("%v: v_ok %v != %v", #procedure, v_ok, true)) + tc.expect(t, v.type == n1_content.type, fmt.tprintf("%v: v.type %v != %v", #procedure, v.type, n1_content.type)) + tc.expect(t, len(v.resolution) == 3, fmt.tprintf("%v: len(v.resolution) %v != %v", + #procedure, len(v.resolution), 3)) + tc.expect(t, len(v.image_stack) == len(n1_content.image_stack), fmt.tprintf("%v: len(v.image_stack) %v != %v", + #procedure, len(v.image_stack), len(n1_content.image_stack))) + for i := 0; i < len(v.image_stack); i += 1 { + tc.expect(t, v.image_stack[i].name == n1_content.image_stack[i].name, + fmt.tprintf("%v: v.image_stack[%d].name %v != %v", + #procedure, i, v.image_stack[i].name, n1_content.image_stack[i].name)) + tc.expect(t, v.image_stack[i].components == n1_content.image_stack[i].components, + fmt.tprintf("%v: v.image_stack[%d].components %v != %v", + #procedure, i, v.image_stack[i].components, n1_content.image_stack[i].components)) + + switch n1_t in n1_content.image_stack[i].data { + case []u8: + tc.expect(t, false, fmt.tprintf("%v: n1_content.image_stack[i].data []u8", #procedure)) + case []i32le: + tc.expect(t, false, fmt.tprintf("%v: n1_content.image_stack[i].data []i32le", #procedure)) + case []f32le: + l, l_ok := v.image_stack[i].data.([]f32le) + tc.expect(t, l_ok, fmt.tprintf("%v: l_ok %v != %v", #procedure, l_ok, true)) + tc.expect(t, len(l) == len(n1_t), fmt.tprintf("%v: len(l) %v != %v", #procedure, len(l), len(n1_t))) + for j := 0; j < len(l); j += 1 { + tc.expect(t, l[j] == n1_t[j], fmt.tprintf("%v: l[%d] %v (%h) != %v (%h)", + #procedure, j, l[j], l[j], n1_t[j], n1_t[j])) + } + case []f64le: + l, l_ok := v.image_stack[i].data.([]f64le) + tc.expect(t, l_ok, fmt.tprintf("%v: l_ok %v != %v", #procedure, l_ok, true)) + tc.expect(t, len(l) == len(n1_t), fmt.tprintf("%v: len(l) %v != %v", #procedure, len(l), len(n1_t))) + for j := 0; j < len(l); j += 1 { + tc.expect(t, l[j] == n1_t[j], fmt.tprintf("%v: l[%d] %v != %v", #procedure, j, l[j], n1_t[j])) + } + } + } +} diff --git a/tests/core/encoding/json/test_core_json.odin b/tests/core/encoding/json/test_core_json.odin index 6f2e8c35a..0e6a6412f 100644 --- a/tests/core/encoding/json/test_core_json.odin +++ b/tests/core/encoding/json/test_core_json.odin @@ -3,6 +3,7 @@ package test_core_json import "core:encoding/json" import "core:testing" import "core:fmt" +import "core:os" TEST_count := 0 TEST_fail := 0 @@ -20,17 +21,22 @@ when ODIN_TEST { } } log :: proc(t: ^testing.T, v: any, loc := #caller_location) { - fmt.printf("[%v] LOG:\n\t%v\n", loc, v) + fmt.printf("[%v] ", loc) + fmt.printf("log: %v\n", v) } } main :: proc() { t := testing.T{} - + parse_json(&t) marshal_json(&t) + unmarshal_json(&t) - fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + if TEST_fail > 0 { + os.exit(1) + } } @test @@ -65,7 +71,8 @@ parse_json :: proc(t: ^testing.T) { _, err := json.parse(transmute([]u8)json_data) - expect(t, err == .None, "expected json error to be none") + msg := fmt.tprintf("Expected `json.parse` to return nil, got %v", err) + expect(t, err == nil, msg) } @test @@ -82,6 +89,259 @@ marshal_json :: proc(t: ^testing.T) { } _, err := json.marshal(my_struct) - - expect(t, err == .None, "expected json error to be none") + msg := fmt.tprintf("Expected `json.marshal` to return nil, got %v", err) + expect(t, err == nil, msg) } + +PRODUCTS := ` +{ + "cash": "0", + "products": [ + { + "name": "Cog\nCola", + "cost": "3", + "owned": "1", + + "profit": "4", + "seconds": 3, + "multiplier": 1, + "auto_click": false + }, + { + "name": "gingerBeer", + "cost": "9", + "owned": "0", + + "profit": "16", + "seconds": 5, + "multiplier": 1, + "auto_click": false + }, + { + "name": "Coffee", + "cost": "27", + "owned": "0", + + "profit": "64", + "seconds": 7, + "multiplier": 1, + "auto_click": false + }, + { + "name": "Haggis", + "cost": "81", + "owned": "0", + + "profit": "256", + "seconds": 11, + "multiplier": 1, + "auto_click": false + }, + { + "name": "Lasagna", + "cost": "243", + "owned": "0", + + "profit": "1024", + "seconds": 13, + "multiplier": 1, + "auto_click": false + }, + { + "name": "Asparagus", + "cost": "729", + "owned": "0", + + "profit": "4096", + "seconds": 17, + "multiplier": 1, + "auto_click": false + }, + { + "name": "Yorkshire Pudding", + "cost": "2187", + "owned": "0", + + "profit": "16384", + "seconds": 19, + "multiplier": 1, + "auto_click": false + }, + { + "name": "Salmon Wrap", + "cost": "6561", + "owned": "0", + + "profit": "65536", + "seconds": 23, + "multiplier": 1, + "auto_click": false + }, + { + "name": "Poke Bowl", + "cost": "19683", + "owned": "0", + + "profit": "262144", + "seconds": 29, + "multiplier": 1, + "auto_click": false + }, + { + "name": "Chili Con Carne", + "cost": "59049", + "owned": "0", + + "profit": "1048576", + "seconds": 59, + "multiplier": 1, + "auto_click": false + }, + ], +} +` + +original_data := Game_Marshal{ + cash = "0", + products = { + { + name = "Cog\nCola", + cost = "3", + owned = "1", + profit = "4", + seconds = 3, + multiplier = 1, + auto_click = false, + }, + { + name = "gingerBeer", + cost = "9", + owned = "0", + profit = "16", + seconds = 5, + multiplier = 1, + auto_click = false, + }, + { + name = "Coffee", + cost = "27", + owned = "0", + profit = "64", + seconds = 7, + multiplier = 1, + auto_click = false, + }, + { + name = "Haggis", + cost = "81", + owned = "0", + profit = "256", + seconds = 11, + multiplier = 1, + auto_click = false, + }, + { + name = "Lasagna", + cost = "243", + owned = "0", + profit = "1024", + seconds = 13, + multiplier = 1, + auto_click = false, + }, + { + name = "Asparagus", + cost = "729", + owned = "0", + profit = "4096", + seconds = 17, + multiplier = 1, + auto_click = false, + }, + { + name = "Yorkshire Pudding", + cost = "2187", + owned = "0", + profit = "16384", + seconds = 19, + multiplier = 1, + auto_click = false, + }, + { + name = "Salmon Wrap", + cost = "6561", + owned = "0", + profit = "65536", + seconds = 23, + multiplier = 1, + auto_click = false, + }, + { + name = "Poke Bowl", + cost = "19683", + owned = "0", + profit = "262144", + seconds = 29, + multiplier = 1, + auto_click = false, + }, + { + name = "Chili Con Carne", + cost = "59049", + owned = "0", + profit = "1048576", + seconds = 59, + multiplier = 1, + auto_click = false, + }, + }, +} + +Product_Marshal :: struct { + name: cstring, + owned: string, + + cost: string, + + profit: string, + seconds: int, + multiplier: int, + + auto_click: bool, +} + +Game_Marshal :: struct { + cash: string, + products: []Product_Marshal, +} + +cleanup :: proc(g: Game_Marshal) { + for p in g.products { + delete(p.name) + delete(p.owned) + delete(p.cost) + delete(p.profit) + } + delete(g.products) + delete(g.cash) +} + +@test +unmarshal_json :: proc(t: ^testing.T) { + g: Game_Marshal + err := json.unmarshal(transmute([]u8)PRODUCTS, &g, json.DEFAULT_SPECIFICATION) + defer cleanup(g) + + msg := fmt.tprintf("Expected `json.unmarshal` to return nil, got %v", err) + expect(t, err == nil, msg) + + msg = fmt.tprintf("Expected %v products to have been unmarshaled, got %v", len(original_data.products), len(g.products)) + expect(t, len(g.products) == len(original_data.products), msg) + + msg = fmt.tprintf("Expected cash to have been unmarshaled as %v, got %v", original_data.cash, g.cash) + expect(t, original_data.cash == g.cash, msg) + + for p, i in g.products { + expect(t, p == original_data.products[i], "Producted unmarshaled improperly") + } +} \ No newline at end of file diff --git a/tests/core/encoding/varint/test_core_varint.odin b/tests/core/encoding/varint/test_core_varint.odin new file mode 100644 index 000000000..2c3669afa --- /dev/null +++ b/tests/core/encoding/varint/test_core_varint.odin @@ -0,0 +1,156 @@ +package test_core_varint + +import "core:encoding/varint" +import "core:testing" +import "core:fmt" +import "core:os" +import "core:slice" +import "core:math/rand" + +TEST_count := 0 +TEST_fail := 0 + +RANDOM_TESTS :: 100 + +when ODIN_TEST { + expect :: testing.expect + log :: testing.log +} else { + expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { + TEST_count += 1 + if !condition { + TEST_fail += 1 + fmt.printf("[%v] %v\n", loc, message) + return + } + } + log :: proc(t: ^testing.T, v: any, loc := #caller_location) { + fmt.printf("[%v] ", loc) + fmt.printf("log: %v\n", v) + } +} + +main :: proc() { + t := testing.T{} + + test_leb128(&t) + + fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + if TEST_fail > 0 { + os.exit(1) + } +} + +@(test) +test_leb128 :: proc(t: ^testing.T) { + buf: [varint.LEB128_MAX_BYTES]u8 + + for vector in ULEB_Vectors { + val, size, err := varint.decode_uleb128(vector.encoded) + + msg := fmt.tprintf("Expected %02x to decode to %v consuming %v bytes, got %v and %v", vector.encoded, vector.value, vector.size, val, size) + expect(t, size == vector.size && val == vector.value, msg) + + msg = fmt.tprintf("Expected decoder to return error %v, got %v for vector %v", vector.error, err, vector) + expect(t, err == vector.error, msg) + + if err == .None { // Try to roundtrip + size, err = varint.encode_uleb128(buf[:], vector.value) + + msg = fmt.tprintf("Expected %v to encode to %02x, got %02x", vector.value, vector.encoded, buf[:size]) + expect(t, size == vector.size && slice.simple_equal(vector.encoded, buf[:size]), msg) + } + } + + for vector in ILEB_Vectors { + val, size, err := varint.decode_ileb128(vector.encoded) + + msg := fmt.tprintf("Expected %02x to decode to %v consuming %v bytes, got %v and %v", vector.encoded, vector.value, vector.size, val, size) + expect(t, size == vector.size && val == vector.value, msg) + + msg = fmt.tprintf("Expected decoder to return error %v, got %v", vector.error, err) + expect(t, err == vector.error, msg) + + if err == .None { // Try to roundtrip + size, err = varint.encode_ileb128(buf[:], vector.value) + + msg = fmt.tprintf("Expected %v to encode to %02x, got %02x", vector.value, vector.encoded, buf[:size]) + expect(t, size == vector.size && slice.simple_equal(vector.encoded, buf[:size]), msg) + } + } + + for num_bytes in 1..uint(16) { + for _ in 0..RANDOM_TESTS { + unsigned, signed := get_random(num_bytes) + + { + encode_size, encode_err := varint.encode_uleb128(buf[:], unsigned) + msg := fmt.tprintf("%v failed to encode as an unsigned LEB128 value, got %v", unsigned, encode_err) + expect(t, encode_err == .None, msg) + + decoded, decode_size, decode_err := varint.decode_uleb128(buf[:]) + msg = fmt.tprintf("Expected %02x to decode as %v, got %v", buf[:encode_size], unsigned, decoded) + expect(t, decode_err == .None && decode_size == encode_size && decoded == unsigned, msg) + } + + { + encode_size, encode_err := varint.encode_ileb128(buf[:], signed) + msg := fmt.tprintf("%v failed to encode as a signed LEB128 value, got %v", signed, encode_err) + expect(t, encode_err == .None, msg) + + decoded, decode_size, decode_err := varint.decode_ileb128(buf[:]) + msg = fmt.tprintf("Expected %02x to decode as %v, got %v, err: %v", buf[:encode_size], signed, decoded, decode_err) + expect(t, decode_err == .None && decode_size == encode_size && decoded == signed, msg) + } + } + } +} + +get_random :: proc(byte_count: uint) -> (u: u128, i: i128) { + assert(byte_count >= 0 && byte_count <= size_of(u128)) + + for _ in 1..byte_count { + u <<= 8 + u |= u128(rand.uint32() & 0xff) + } + + bias := i128(1 << (byte_count * 7)) - 1 + i = i128(u) - bias + + return +} + +ULEB_Test_Vector :: struct { + encoded: []u8, + value: u128, + size: int, + error: varint.Error, +} + +ULEB_Vectors :: []ULEB_Test_Vector{ + { []u8{0x00}, 0, 1, .None }, + { []u8{0x7f}, 127, 1, .None }, + { []u8{0xE5, 0x8E, 0x26}, 624485, 3, .None }, + { []u8{0x80}, 0, 0, .Buffer_Too_Small }, + { []u8{}, 0, 0, .Buffer_Too_Small }, + + { []u8{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03}, max(u128), 19, .None }, +} + +ILEB_Test_Vector :: struct { + encoded: []u8, + value: i128, + size: int, + error: varint.Error, +} + +ILEB_Vectors :: []ILEB_Test_Vector{ + { []u8{0x00}, 0, 1, .None }, + { []u8{0x3f}, 63, 1, .None }, + { []u8{0x40}, -64, 1, .None }, + { []u8{0xC0, 0xBB, 0x78}, -123456, 3, .None }, + { []u8{}, 0, 0, .Buffer_Too_Small }, + + { []u8{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7e}, min(i128), 19, .None }, + { []u8{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01}, max(i128), 19, .None }, +} \ No newline at end of file diff --git a/tests/core/hash/test_core_hash.odin b/tests/core/hash/test_core_hash.odin index b81af01a5..607642339 100644 --- a/tests/core/hash/test_core_hash.odin +++ b/tests/core/hash/test_core_hash.odin @@ -5,6 +5,7 @@ import "core:hash" import "core:time" import "core:testing" import "core:fmt" +import "core:os" TEST_count := 0 TEST_fail := 0 @@ -17,12 +18,13 @@ when ODIN_TEST { TEST_count += 1 if !condition { TEST_fail += 1 - fmt.printf("[%v] %v", loc, message) + fmt.printf("[%v] %v\n", loc, message) return } } log :: proc(t: ^testing.T, v: any, loc := #caller_location) { - fmt.printf("[%v] LOG:\n\t%v\n", loc, v) + fmt.printf("[%v] ", loc) + fmt.printf("log: %v\n", v) } } @@ -31,7 +33,10 @@ main :: proc() { test_benchmark_runner(&t) test_xxhash_vectors(&t) test_crc64_vectors(&t) - fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + if TEST_fail > 0 { + os.exit(1) + } } /* diff --git a/tests/core/image/test_core_image.odin b/tests/core/image/test_core_image.odin index 48d9ca1d2..0c11ca5ae 100644 --- a/tests/core/image/test_core_image.odin +++ b/tests/core/image/test_core_image.odin @@ -5,7 +5,7 @@ List of contributors: Jeroen van Rijn: Initial implementation. - A test suite for PNG. + A test suite for PNG + QOI. */ package test_core_image @@ -14,6 +14,7 @@ import "core:testing" import "core:compress" import "core:image" import "core:image/png" +import "core:image/qoi" import "core:bytes" import "core:hash" @@ -25,8 +26,8 @@ import "core:time" import "core:runtime" -WRITE_PPM_ON_FAIL :: #config(WRITE_PPM_ON_FAIL, false) -TEST_FILE_PATH_PREFIX :: "tests/core/assets/PNG" +WRITE_PPM_ON_FAIL :: #config(WRITE_PPM_ON_FAIL, false) +TEST_SUITE_PATH :: "assets/PNG" TEST_count := 0 TEST_fail := 0 @@ -44,30 +45,20 @@ when ODIN_TEST { } } log :: proc(t: ^testing.T, v: any, loc := #caller_location) { - fmt.printf("[%v] LOG:\n\t%v\n", loc, v) + fmt.printf("[%v] ", loc) + fmt.printf("log: %v\n", v) } } - I_Error :: image.Error main :: proc() { t := testing.T{} png_test(&t) - fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) -} - -test_file_path :: proc(filename: string, extension := "png") -> (path: string) { - - path = fmt.tprintf("%v%v/%v.%v", ODIN_ROOT, TEST_FILE_PATH_PREFIX, filename, extension) - temp := transmute([]u8)path - - for r, i in path { - if r == '\\' { - temp[i] = '/' - } + fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + if TEST_fail > 0 { + os.exit(1) } - return path } PNG_Test :: struct { @@ -1472,7 +1463,7 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) { context = runtime.default_context() for file in suite { - test_file := test_file_path(file.file) + test_file := fmt.tprintf("%v/%v.png", TEST_SUITE_PATH, file.file) img: ^png.Image err: png.Error @@ -1509,11 +1500,34 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) { passed &= dims_pass - hash := hash.crc32(pixels) - error = fmt.tprintf("%v test %v hash is %08x, expected %08x.", file.file, count, hash, test.hash) - expect(t, test.hash == hash, error) + png_hash := hash.crc32(pixels) + error = fmt.tprintf("%v test %v hash is %08x, expected %08x with %v.", file.file, count, png_hash, test.hash, test.options) + expect(t, test.hash == png_hash, error) + + passed &= test.hash == png_hash + + // Roundtrip through QOI to test the QOI encoder and decoder. + if passed && img.depth == 8 && (img.channels == 3 || img.channels == 4) { + qoi_buffer: bytes.Buffer + defer bytes.buffer_destroy(&qoi_buffer) + qoi_save_err := qoi.save(&qoi_buffer, img) + + error = fmt.tprintf("%v test %v QOI save failed with %v.", file.file, count, qoi_save_err) + expect(t, qoi_save_err == nil, error) + + if qoi_save_err == nil { + qoi_img, qoi_load_err := qoi.load(qoi_buffer.buf[:]) + defer qoi.destroy(qoi_img) + + error = fmt.tprintf("%v test %v QOI load failed with %v.", file.file, count, qoi_load_err) + expect(t, qoi_load_err == nil, error) + + qoi_hash := hash.crc32(qoi_img.pixels.buf[:]) + error = fmt.tprintf("%v test %v QOI load hash is %08x, expected it match PNG's %08x with %v.", file.file, count, qoi_hash, png_hash, test.options) + expect(t, qoi_hash == png_hash, error) + } + } - passed &= test.hash == hash if .return_metadata in test.options { if v, ok := img.metadata.(^image.PNG_Info); ok { @@ -1778,7 +1792,7 @@ write_image_as_ppm :: proc(filename: string, image: ^image.Image) -> (success: b img := image // PBM 16-bit images are big endian - when ODIN_ENDIAN == "little" { + when ODIN_ENDIAN == .Little { if img.depth == 16 { // The pixel components are in Big Endian. Let's byteswap back. input := mem.slice_data_cast([]u16, img.pixels.buf[:]) @@ -1796,7 +1810,7 @@ write_image_as_ppm :: proc(filename: string, image: ^image.Image) -> (success: b } mode: int = 0 - when ODIN_OS == "linux" || ODIN_OS == "darwin" { + when ODIN_OS == .Linux || ODIN_OS == .Darwin { // NOTE(justasd): 644 (owner read, write; group read; others read) mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH } diff --git a/tests/core/math/big/build.bat b/tests/core/math/big/build.bat index e383cdfc1..ad199d775 100644 --- a/tests/core/math/big/build.bat +++ b/tests/core/math/big/build.bat @@ -4,14 +4,11 @@ set PATH_TO_ODIN==..\..\..\..\odin set TEST_ARGS=-fast-tests set TEST_ARGS=-no-random set TEST_ARGS= -set OUT_NAME=math_big_test_library +set OUT_NAME=math_big_test_library.dll set COMMON=-build-mode:shared -show-timings -no-bounds-check -define:MATH_BIG_EXE=false -vet -strict-style echo --- echo Running core:math/big tests echo --- -rem Fails -:%PATH_TO_ODIN% build . %COMMON% -o:speed -out:%OUT_NAME% -rem Passes -%PATH_TO_ODIN% build . %COMMON% -o:size -out:%OUT_NAME% +%PATH_TO_ODIN% build . %COMMON% -o:speed -out:%OUT_NAME% python3 test.py %TEST_ARGS% \ No newline at end of file diff --git a/tests/core/math/big/test.odin b/tests/core/math/big/test.odin index 07fa0364b..a289c89dd 100644 --- a/tests/core/math/big/test.odin +++ b/tests/core/math/big/test.odin @@ -32,9 +32,9 @@ print_to_buffer :: proc(val: ^big.Int) -> cstring { @export test_initialize_constants :: proc "c" () -> (res: u64) { context = runtime.default_context() - res = u64(big.initialize_constants()) - //assert(MUL_KARATSUBA_CUTOFF >= 40); - return res + _ = big.initialize_constants() + + return u64(big._DIGIT_NAILS) } @export test_error_string :: proc "c" (err: big.Error) -> (res: cstring) { @@ -208,7 +208,7 @@ print_to_buffer :: proc(val: ^big.Int) -> cstring { /* dest = shr_digit(src, digits) */ -@export test_shr_digit :: proc "c" (source: cstring, digits: int) -> (res: PyRes) { +@export test_shr_leg :: proc "c" (source: cstring, digits: int) -> (res: PyRes) { context = runtime.default_context() err: big.Error @@ -216,7 +216,7 @@ print_to_buffer :: proc(val: ^big.Int) -> cstring { defer big.internal_destroy(src) if err = big.atoi(src, string(source), 16); err != nil { return PyRes{res=":shr_digit:atoi(src):", err=err} } - if err = #force_inline big.internal_shr_digit(src, digits); err != nil { return PyRes{res=":shr_digit:shr_digit(src):", err=err} } + if err = #force_inline big._private_int_shr_leg(src, digits); err != nil { return PyRes{res=":shr_digit:shr_digit(src):", err=err} } r := print_to_buffer(src) return PyRes{res = r, err = nil} @@ -225,7 +225,7 @@ print_to_buffer :: proc(val: ^big.Int) -> cstring { /* dest = shl_digit(src, digits) */ -@export test_shl_digit :: proc "c" (source: cstring, digits: int) -> (res: PyRes) { +@export test_shl_leg :: proc "c" (source: cstring, digits: int) -> (res: PyRes) { context = runtime.default_context() err: big.Error @@ -233,7 +233,7 @@ print_to_buffer :: proc(val: ^big.Int) -> cstring { defer big.internal_destroy(src) if err = big.atoi(src, string(source), 16); err != nil { return PyRes{res=":shl_digit:atoi(src):", err=err} } - if err = #force_inline big.internal_shl_digit(src, digits); err != nil { return PyRes{res=":shl_digit:shr_digit(src):", err=err} } + if err = #force_inline big._private_int_shl_leg(src, digits); err != nil { return PyRes{res=":shl_digit:shr_digit(src):", err=err} } r := print_to_buffer(src) return PyRes{res = r, err = nil} diff --git a/tests/core/math/big/test.py b/tests/core/math/big/test.py index 6b17336bc..d4724edb8 100644 --- a/tests/core/math/big/test.py +++ b/tests/core/math/big/test.py @@ -17,7 +17,6 @@ import gc from enum import Enum import argparse - parser = argparse.ArgumentParser( description = "Odin core:math/big test suite", epilog = "By default we run regression and random tests with preset parameters.", @@ -127,17 +126,22 @@ def we_iterate(): # Error enum values # class Error(Enum): - Okay = 0 - Out_Of_Memory = 1 - Invalid_Pointer = 2 - Invalid_Argument = 3 - Unknown_Error = 4 - Max_Iterations_Reached = 5 - Buffer_Overflow = 6 - Integer_Overflow = 7 - Division_by_Zero = 8 - Math_Domain_Error = 9 - Unimplemented = 127 + Okay = 0 + Out_Of_Memory = 1 + Invalid_Pointer = 2 + Invalid_Argument = 3 + Unknown_Error = 4 + Assignment_To_Immutable = 10 + Max_Iterations_Reached = 11 + Buffer_Overflow = 12 + Integer_Overflow = 13 + Integer_Underflow = 14 + Division_by_Zero = 30 + Math_Domain_Error = 31 + Cannot_Open_File = 50 + Cannot_Read_File = 51 + Cannot_Write_File = 52 + Unimplemented = 127 # # Disable garbage collection @@ -158,6 +162,8 @@ def load(export_name, args, res): export_name.restype = res return export_name + + # # Result values will be passed in a struct { res: cstring, err: Error } # @@ -165,7 +171,11 @@ class Res(Structure): _fields_ = [("res", c_char_p), ("err", c_uint64)] initialize_constants = load(l.test_initialize_constants, [], c_uint64) -print("initialize_constants: ", initialize_constants()) + +NAILS = initialize_constants() +LEG_BITS = 64 - NAILS + +print("LEG BITS: ", LEG_BITS) error_string = load(l.test_error_string, [c_byte], c_char_p) @@ -182,8 +192,8 @@ int_sqrt = load(l.test_sqrt, [c_char_p ], Res) int_root_n = load(l.test_root_n, [c_char_p, c_longlong], Res) # Logical operations -int_shl_digit = load(l.test_shl_digit, [c_char_p, c_longlong], Res) -int_shr_digit = load(l.test_shr_digit, [c_char_p, c_longlong], Res) +int_shl_leg = load(l.test_shl_leg, [c_char_p, c_longlong], Res) +int_shr_leg = load(l.test_shr_leg, [c_char_p, c_longlong], Res) int_shl = load(l.test_shl, [c_char_p, c_longlong], Res) int_shr = load(l.test_shr, [c_char_p, c_longlong], Res) int_shr_signed = load(l.test_shr_signed, [c_char_p, c_longlong], Res) @@ -397,26 +407,26 @@ def test_root_n(number = 0, root = 0, expected_error = Error.Okay): return test("test_root_n", res, [number, root], expected_error, expected_result) -def test_shl_digit(a = 0, digits = 0, expected_error = Error.Okay): +def test_shl_leg(a = 0, digits = 0, expected_error = Error.Okay): args = [arg_to_odin(a), digits] - res = int_shl_digit(*args) + res = int_shl_leg(*args) expected_result = None if expected_error == Error.Okay: - expected_result = a << (digits * 60) - return test("test_shl_digit", res, [a, digits], expected_error, expected_result) + expected_result = a << (digits * LEG_BITS) + return test("test_shl_leg", res, [a, digits], expected_error, expected_result) -def test_shr_digit(a = 0, digits = 0, expected_error = Error.Okay): +def test_shr_leg(a = 0, digits = 0, expected_error = Error.Okay): args = [arg_to_odin(a), digits] - res = int_shr_digit(*args) + res = int_shr_leg(*args) expected_result = None if expected_error == Error.Okay: if a < 0: # Don't pass negative numbers. We have a shr_signed. return False else: - expected_result = a >> (digits * 60) + expected_result = a >> (digits * LEG_BITS) - return test("test_shr_digit", res, [a, digits], expected_error, expected_result) + return test("test_shr_leg", res, [a, digits], expected_error, expected_result) def test_shl(a = 0, bits = 0, expected_error = Error.Okay): args = [arg_to_odin(a), bits] @@ -551,12 +561,12 @@ TESTS = { test_root_n: [ [ 1298074214633706907132624082305024, 2, Error.Okay, ], ], - test_shl_digit: [ + test_shl_leg: [ [ 3192, 1 ], [ 1298074214633706907132624082305024, 2 ], [ 1024, 3 ], ], - test_shr_digit: [ + test_shr_leg: [ [ 3680125442705055547392, 1 ], [ 1725436586697640946858688965569256363112777243042596638790631055949824, 2 ], [ 219504133884436710204395031992179571, 2 ], @@ -614,10 +624,10 @@ total_failures = 0 # test_shr_signed also tests shr, so we're not going to test shr randomly. # RANDOM_TESTS = [ - test_add, test_sub, test_mul, test_sqr, test_div, - test_log, test_pow, test_sqrt, test_root_n, - test_shl_digit, test_shr_digit, test_shl, test_shr_signed, - test_gcd, test_lcm, test_is_square, + test_add, test_sub, test_mul, test_sqr, + test_log, test_pow, test_sqrt, test_root_n, + test_shl_leg, test_shr_leg, test_shl, test_shr_signed, + test_gcd, test_lcm, test_is_square, test_div, ] SKIP_LARGE = [ test_pow, test_root_n, # test_gcd, @@ -714,9 +724,9 @@ if __name__ == '__main__': a = randint(1, 1 << BITS) b = TEST_ROOT_N_PARAMS[index] index = (index + 1) % len(TEST_ROOT_N_PARAMS) - elif test_proc == test_shl_digit: + elif test_proc == test_shl_leg: b = randint(0, 10); - elif test_proc == test_shr_digit: + elif test_proc == test_shr_leg: a = abs(a) b = randint(0, 10); elif test_proc == test_shl: diff --git a/tests/core/math/linalg/glsl/test_linalg_glsl_math.odin b/tests/core/math/linalg/glsl/test_linalg_glsl_math.odin new file mode 100644 index 000000000..e0b4f5145 --- /dev/null +++ b/tests/core/math/linalg/glsl/test_linalg_glsl_math.odin @@ -0,0 +1,85 @@ +// Tests "linalg_glsl_math.odin" in "core:math/linalg/glsl". +// Must be run with `-collection:tests=` flag, e.g. +// ./odin run tests/core/math/linalg/glsl/test_linalg_glsl_math.odin -collection:tests=./tests +package test_core_math_linalg_glsl_math + +import glsl "core:math/linalg/glsl" + +import "core:fmt" +import "core:math" +import "core:testing" +import tc "tests:common" + +main :: proc() { + + t := testing.T{} + + test_fract_f32(&t) + test_fract_f64(&t) + + tc.report(&t) +} + +@test +test_fract_f32 :: proc(t: ^testing.T) { + + using math + + r: f32 + + Datum :: struct { + i: int, + v: f32, + e: f32, + } + @static data := []Datum{ + { 0, 10.5, 0.5 }, // Issue #1574 fract in linalg/glm is broken + { 1, -10.5, -0.5 }, + { 2, F32_MIN, F32_MIN }, // 0x1p-126 + { 3, -F32_MIN, -F32_MIN }, + { 4, 0.0, 0.0 }, + { 5, -0.0, -0.0 }, + { 6, 1, 0.0 }, + { 7, -1, -0.0 }, + { 8, 0h3F80_0001, 0h3400_0000 }, // 0x1.000002p+0, 0x1p-23 + { 9, -0h3F80_0001, -0h3400_0000 }, + } + + for d, i in data { + assert(i == d.i) + r = glsl.fract(d.v) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%v (%h)) -> %v (%h) != %v", i, #procedure, d.v, d.v, r, r, d.e)) + } +} + +@test +test_fract_f64 :: proc(t: ^testing.T) { + + using math + + r: f64 + + Datum :: struct { + i: int, + v: f64, + e: f64, + } + @static data := []Datum{ + { 0, 10.5, 0.5 }, // Issue #1574 fract in linalg/glm is broken + { 1, -10.5, -0.5 }, + { 2, F64_MIN, F64_MIN }, // 0x1p-1022 + { 3, -F64_MIN, -F64_MIN }, + { 4, 0.0, 0.0 }, + { 5, -0.0, -0.0 }, + { 6, 1, 0.0 }, + { 7, -1, -0.0 }, + { 8, 0h3FF0_0000_0000_0001, 0h3CB0_0000_0000_0000 }, // 0x1.0000000000001p+0, 0x1p-52 + { 9, -0h3FF0_0000_0000_0001, -0h3CB0_0000_0000_0000 }, + } + + for d, i in data { + assert(i == d.i) + r = glsl.fract(d.v) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%v (%h)) -> %v (%h) != %v", i, #procedure, d.v, d.v, r, r, d.e)) + } +} diff --git a/tests/core/math/noise/test_core_math_noise.odin b/tests/core/math/noise/test_core_math_noise.odin new file mode 100644 index 000000000..a0360e695 --- /dev/null +++ b/tests/core/math/noise/test_core_math_noise.odin @@ -0,0 +1,151 @@ +package test_core_math_noise + +import "core:testing" +import "core:math/noise" +import "core:fmt" +import "core:os" + +TEST_count := 0 +TEST_fail := 0 + +V2 :: noise.Vec2 +V3 :: noise.Vec3 +V4 :: noise.Vec4 + +when ODIN_TEST { + expect :: testing.expect + log :: testing.log +} else { + expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { + TEST_count += 1 + if !condition { + TEST_fail += 1 + fmt.printf("[%v] %v\n", loc, message) + return + } + } + log :: proc(t: ^testing.T, v: any, loc := #caller_location) { + fmt.printf("[%v] ", loc) + fmt.printf("log: %v\n", v) + } +} + +main :: proc() { + t := testing.T{} + noise_test(&t) + fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + if TEST_fail > 0 { + os.exit(1) + } +} + +Test_Vector :: struct { + seed: i64, + coord: union {V2, V3, V4}, + expected: f32, + + test_proc: union { + proc(_: i64, _: V2) -> f32, + proc(_: i64, _: V3) -> f32, + proc(_: i64, _: V4) -> f32, + }, +} + +SEED_1 :: 2324223232 +SEED_2 :: 932466901 +SEED_3 :: 9321 + +COORD_1 :: V4{ 242.0, 3433.0, 920.0, 222312.0} +COORD_2 :: V4{ 590.0, 9411.0, 5201.0, 942124256.0} +COORD_3 :: V4{12090.0, 19411.0, 81950901.0, 4224219.0} + +Noise_Tests := []Test_Vector{ + /* + `noise_2d` tests. + */ + {SEED_1, COORD_1.xy, 0.25010583, noise.noise_2d}, + {SEED_2, COORD_2.xy, -0.92513955, noise.noise_2d}, + {SEED_3, COORD_3.xy, 0.67327416, noise.noise_2d}, + + /* + `noise_2d_improve_x` tests. + */ + {SEED_1, COORD_1.xy, 0.17074019, noise.noise_2d_improve_x}, + {SEED_2, COORD_2.xy, 0.72330487, noise.noise_2d_improve_x}, + {SEED_3, COORD_3.xy, -0.032076947, noise.noise_2d_improve_x}, + + /* + `noise_3d_improve_xy` tests. + */ + {SEED_1, COORD_1.xyz, 0.14819577, noise.noise_3d_improve_xy}, + {SEED_2, COORD_2.xyz, -0.065345764, noise.noise_3d_improve_xy}, + {SEED_3, COORD_3.xyz, -0.37761918, noise.noise_3d_improve_xy}, + + /* + `noise_3d_improve_xz` tests. + */ + {SEED_1, COORD_1.xyz, -0.50075006, noise.noise_3d_improve_xz}, + {SEED_2, COORD_2.xyz, -0.36039603, noise.noise_3d_improve_xz}, + {SEED_3, COORD_3.xyz, -0.3479203, noise.noise_3d_improve_xz}, + + /* + `noise_3d_fallback` tests. + */ + {SEED_1, COORD_1.xyz, 0.6557345, noise.noise_3d_fallback}, + {SEED_2, COORD_2.xyz, 0.55452216, noise.noise_3d_fallback}, + {SEED_3, COORD_3.xyz, -0.26408964, noise.noise_3d_fallback}, + + /* + `noise_3d_fallback` tests. + */ + {SEED_1, COORD_1.xyz, 0.6557345, noise.noise_3d_fallback}, + {SEED_2, COORD_2.xyz, 0.55452216, noise.noise_3d_fallback}, + {SEED_3, COORD_3.xyz, -0.26408964, noise.noise_3d_fallback}, + + /* + `noise_4d_improve_xyz_improve_xy` tests. + */ + {SEED_1, COORD_1, 0.44929826, noise.noise_4d_improve_xyz_improve_xy}, + {SEED_2, COORD_2, -0.13270882, noise.noise_4d_improve_xyz_improve_xy}, + {SEED_3, COORD_3, 0.10298563, noise.noise_4d_improve_xyz_improve_xy}, + + /* + `noise_4d_improve_xyz_improve_xz` tests. + */ + {SEED_1, COORD_1, -0.078514606, noise.noise_4d_improve_xyz_improve_xz}, + {SEED_2, COORD_2, -0.032157656, noise.noise_4d_improve_xyz_improve_xz}, + {SEED_3, COORD_3, -0.38607058, noise.noise_4d_improve_xyz_improve_xz}, + + /* + `noise_4d_improve_xyz` tests. + */ + {SEED_1, COORD_1, -0.4442258, noise.noise_4d_improve_xyz}, + {SEED_2, COORD_2, 0.36822623, noise.noise_4d_improve_xyz}, + {SEED_3, COORD_3, 0.22628775, noise.noise_4d_improve_xyz}, + + /* + `noise_4d_fallback` tests. + */ + {SEED_1, COORD_1, -0.14233987, noise.noise_4d_fallback}, + {SEED_2, COORD_2, 0.1354035, noise.noise_4d_fallback}, + {SEED_3, COORD_3, 0.14565045, noise.noise_4d_fallback}, + +} + +noise_test :: proc(t: ^testing.T) { + for test in Noise_Tests { + output: f32 + + switch coord in test.coord { + case V2: + output = test.test_proc.(proc(_: i64, _: V2) -> f32)(test.seed, test.coord.(V2)) + case V3: + output = test.test_proc.(proc(_: i64, _: V3) -> f32)(test.seed, test.coord.(V3)) + case V4: + output = test.test_proc.(proc(_: i64, _: V4) -> f32)(test.seed, test.coord.(V4)) + } + + error := fmt.tprintf("Seed %v, Coord: %v, Expected: %3.8f. Got %3.8f", test.seed, test.coord, test.expected, output) + expect(t, test.expected == output, error) + } +} \ No newline at end of file diff --git a/tests/core/math/test_core_math.odin b/tests/core/math/test_core_math.odin new file mode 100644 index 000000000..57da27002 --- /dev/null +++ b/tests/core/math/test_core_math.odin @@ -0,0 +1,310 @@ +// Tests "math.odin" in "core:math". +// Must be run with `-collection:tests=` flag, e.g. +// ./odin run tests/core/math/test_core_math.odin -collection:tests=./tests +package test_core_math + +import "core:fmt" +import "core:math" +import "core:testing" +import tc "tests:common" + +main :: proc() { + t := testing.T{} + + test_classify_f16(&t) + test_classify_f32(&t) + test_classify_f64(&t) + + test_trunc_f16(&t) + test_trunc_f32(&t) + test_trunc_f64(&t) + + tc.report(&t) +} + +@test +test_classify_f16 :: proc(t: ^testing.T) { + + using math + using Float_Class + + r: Float_Class + + Datum :: struct { + i: int, + v: f16, + e: math.Float_Class, + } + @static data := []Datum{ + { 0, 1.2, Normal }, + { 1, 0h0001, Subnormal }, + { 2, 0.0, Zero }, + { 3, -0.0, Neg_Zero }, + { 4, SNAN_F16, NaN }, + { 5, QNAN_F16, NaN }, + { 6, INF_F16, Inf }, + { 7, NEG_INF_F16, Neg_Inf }, + } + + for d, i in data { + assert(i == d.i) + r = classify_f16(d.v) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %v != %v", i, #procedure, d.v, r, d.e)) + } + + /* Check all subnormals (exponent 0, 10-bit significand non-zero) */ + for i :u16 = 1; i < 0x400; i += 1 { + v :f16 = transmute(f16)i + r = classify_f16(v) + e :Float_Class: Subnormal + tc.expect(t, r == e, fmt.tprintf("i:%d %s(%h) -> %v != %v", i, #procedure, v, r, e)) + } +} + +@test +test_classify_f32 :: proc(t: ^testing.T) { + + using math + using Float_Class + + r: Float_Class + + Datum :: struct { + i: int, + v: f32, + e: math.Float_Class, + } + @static data := []Datum{ + { 0, 1.2, Normal }, + { 1, 0h0000_0001, Subnormal }, + { 2, 0.0, Zero }, + { 3, -0.0, Neg_Zero }, + { 4, SNAN_F32, NaN }, + { 5, QNAN_F32, NaN }, + { 6, INF_F32, Inf }, + { 7, NEG_INF_F32, Neg_Inf }, + } + + for d, i in data { + assert(i == d.i) + r = classify_f32(d.v) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %v != %v", i, #procedure, d.v, r, d.e)) + } +} + +@test +test_classify_f64 :: proc(t: ^testing.T) { + + using math + using Float_Class + + r: Float_Class + + Datum :: struct { + i: int, + v: f64, + e: math.Float_Class, + } + @static data := []Datum{ + { 0, 1.2, Normal }, + { 1, 0h0000_0000_0000_0001, Subnormal }, + { 2, 0.0, Zero }, + { 3, -0.0, Neg_Zero }, + { 4, SNAN_F64, NaN }, + { 5, QNAN_F64, NaN }, + { 6, INF_F64, Inf }, + { 7, NEG_INF_F64, Neg_Inf }, + } + + for d, i in data { + assert(i == d.i) + r = classify_f64(d.v) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %v != %v", i, #procedure, d.v, r, d.e)) + } +} + +@test +test_trunc_f16 :: proc(t: ^testing.T) { + + using math + + r, v: f16 + + Datum :: struct { + i: int, + v: f16, + e: f16, + } + @static data := []Datum{ + { 0, 10.5, 10 }, // Issue #1574 fract in linalg/glm is broken + { 1, -10.5, -10 }, + + { 2, F16_MAX, F16_MAX }, + { 3, -F16_MAX, -F16_MAX }, + { 4, F16_MIN, 0.0 }, + { 5, -F16_MIN, -0.0 }, + { 6, 0.0, 0.0 }, + { 7, -0.0, -0.0 }, + { 8, 1, 1 }, + { 9, -1, -1 }, + { 10, INF_F16, INF_F16 }, + { 11, NEG_INF_F16, NEG_INF_F16 }, + + /* From https://en.wikipedia.org/wiki/Half-precision_floating-point_format */ + { 12, 0h3C01, 1 }, // 0x1.004p+0 (smallest > 1) + { 13, -0h3C01, -1 }, + { 14, 0h3BFF, 0.0 }, // 0x1.ffcp-1 (largest < 1) + { 15, -0h3BFF, -0.0 }, + { 16, 0h0001, 0.0 }, // 0x0.004p-14 (smallest subnormal) + { 17, -0h0001, -0.0 }, + { 18, 0h03FF, 0.0 }, // 0x0.ffcp-14 (largest subnormal) + { 19, -0h03FF, -0.0 }, + + { 20, 0hC809, -8 }, // -0x1.024p+3 + { 21, 0h4458, 4 }, // 0x1.16p+2 + } + + for d, i in data { + assert(i == d.i) + r = trunc_f16(d.v) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %h != %h", i, #procedure, d.v, r, d.e)) + } + + v = SNAN_F16 + r = trunc_f16(v) + tc.expect(t, is_nan_f16(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r)) + + v = QNAN_F16 + r = trunc_f16(v) + tc.expect(t, is_nan_f16(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r)) +} + +@test +test_trunc_f32 :: proc(t: ^testing.T) { + + using math + + r, v: f32 + + Datum :: struct { + i: int, + v: f32, + e: f32, + } + @static data := []Datum{ + { 0, 10.5, 10 }, // Issue #1574 fract in linalg/glm is broken + { 1, -10.5, -10 }, + + { 2, F32_MAX, F32_MAX }, + { 3, -F32_MAX, -F32_MAX }, + { 4, F32_MIN, 0.0 }, + { 5, -F32_MIN, -0.0 }, + { 6, 0.0, 0.0 }, + { 7, -0.0, -0.0 }, + { 8, 1, 1 }, + { 9, -1, -1 }, + { 10, INF_F32, INF_F32 }, + { 11, NEG_INF_F32, NEG_INF_F32 }, + + /* From https://en.wikipedia.org/wiki/Single-precision_floating-point_format */ + { 12, 0h3F80_0001, 1 }, // 0x1.000002p+0 (smallest > 1) + { 13, -0h3F80_0001, -1 }, + { 14, 0h3F7F_FFFF, 0.0 }, // 0x1.fffffep-1 (largest < 1) + { 15, -0h3F7F_FFFF, -0.0 }, + { 16, 0h0000_0001, 0.0 }, // 0x0.000002p-126 (smallest subnormal) + { 17, -0h0000_0001, -0.0 }, + { 18, 0h007F_FFFF, 0.0 }, // 0x0.fffffep-126 (largest subnormal) + { 19, -0h007F_FFFF, -0.0 }, + + /* From libc-test src/math/sanity/truncf.h */ + { 20, 0hC101_11D0, -8 }, // -0x1.0223ap+3 + { 21, 0h408B_0C34, 4 }, // 0x1.161868p+2 + { 22, 0hC106_1A5A, -8 }, // -0x1.0c34b4p+3 + { 23, 0hC0D1_0378, -6 }, // -0x1.a206fp+2 + { 24, 0h4114_45DE, 9 }, // 0x1.288bbcp+3 + { 25, 0h3F29_77E8, 0.0 }, // 0x1.52efdp-1 + { 26, 0hBED0_2E64, -0.0 }, // -0x1.a05cc8p-2 + { 27, 0h3F0F_CF7D, 0.0 }, // 0x1.1f9efap-1 + { 28, 0h3F46_2ED8, 0.0 }, // 0x1.8c5dbp-1 + { 29, 0hBF2D_C375, -0.0 }, // -0x1.5b86eap-1 + } + + for d, i in data { + assert(i == d.i) + r = trunc_f32(d.v) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %h != %h", i, #procedure, d.v, r, d.e)) + } + + v = SNAN_F32 + r = trunc_f32(v) + tc.expect(t, is_nan_f32(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r)) + + v = QNAN_F32 + r = trunc_f32(v) + tc.expect(t, is_nan_f32(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r)) +} + +@test +test_trunc_f64 :: proc(t: ^testing.T) { + + using math + + r, v: f64 + + Datum :: struct { + i: int, + v: f64, + e: f64, + } + data := []Datum{ + { 0, 10.5, 10 }, // Issue #1574 fract in linalg/glm is broken + { 1, -10.5, -10 }, + + { 2, F64_MAX, F64_MAX }, + { 3, -F64_MAX, -F64_MAX }, + { 4, F64_MIN, 0.0 }, + { 5, -F64_MIN, -0.0 }, + { 6, 0.0, 0.0 }, + { 7, -0.0, -0.0 }, + { 8, 1, 1 }, + { 9, -1, -1 }, + { 10, INF_F64, INF_F64 }, + { 11, NEG_INF_F64, NEG_INF_F64 }, + + /* From https://en.wikipedia.org/wiki/Double-precision_floating-point_format */ + { 12, 0h3FF0_0000_0000_0001, 1 }, // 0x1.0000000000001p+0 (smallest > 1) + { 13, -0h3FF0_0000_0000_0001, -1 }, + { 14, 0h3FEF_FFFF_FFFF_FFFF, 0.0 }, // 0x1.fffffffffffffp-1 (largest < 1) + { 15, -0h3FEF_FFFF_FFFF_FFFF, -0.0 }, + { 16, 0h0000_0000_0000_0001, 0.0 }, // 0x0.0000000000001p-1022 (smallest subnormal) + { 17, -0h0000_0000_0000_0001, -0.0 }, + { 18, 0h000F_FFFF_FFFF_FFFF, 0.0 }, // 0x0.fffffffffffffp-1022 (largest subnormal) + { 19, -0h000F_FFFF_FFFF_FFFF, -0.0 }, + + /* From libc-test src/math/sanity/trunc.h */ + { 20, 0hC020_2239_F3C6_A8F1, -8 }, // -0x1.02239f3c6a8f1p+3 + { 21, 0h4011_6186_8E18_BC67, 4 }, // 0x1.161868e18bc67p+2 + { 22, 0hC020_C34B_3E01_E6E7, -8 }, // -0x1.0c34b3e01e6e7p+3 + { 23, 0hC01A_206F_0A19_DCC4, -6 }, // -0x1.a206f0a19dcc4p+2 + { 24, 0h4022_88BB_B0D6_A1E6, 9 }, // 0x1.288bbb0d6a1e6p+3 + { 25, 0h3FE5_2EFD_0CD8_0497, 0.0 }, // 0x1.52efd0cd80497p-1 + { 26, 0hBFDA_05CC_7544_81D1, -0.0 }, // -0x1.a05cc754481d1p-2 + { 27, 0h3FE1_F9EF_9347_45CB, 0.0 }, // 0x1.1f9ef934745cbp-1 + { 28, 0h3FE8_C5DB_097F_7442, 0.0 }, // 0x1.8c5db097f7442p-1 + { 29, 0hBFE5_B86E_A811_8A0E, -0.0 }, // -0x1.5b86ea8118a0ep-1 + } + + for d, i in data { + assert(i == d.i) + r = trunc_f64(d.v) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(%h) -> %h != %h", i, #procedure, d.v, r, d.e)) + } + + v = SNAN_F64 + r = trunc_f64(v) + tc.expect(t, is_nan_f64(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r)) + + v = QNAN_F64 + r = trunc_f64(v) + tc.expect(t, is_nan_f64(r), fmt.tprintf("%s(%f) -> %f != NaN", #procedure, v, r)) +} diff --git a/tests/core/odin/test_parser.odin b/tests/core/odin/test_parser.odin index 53711d3ec..3837436bc 100644 --- a/tests/core/odin/test_parser.odin +++ b/tests/core/odin/test_parser.odin @@ -2,7 +2,7 @@ package test_core_odin_parser import "core:testing" import "core:fmt" - +import "core:os" import "core:odin/parser" @@ -22,7 +22,8 @@ when ODIN_TEST { } } log :: proc(t: ^testing.T, v: any, loc := #caller_location) { - fmt.printf("[%v] LOG:\n\t%v\n", loc, v) + fmt.printf("[%v] ", loc) + fmt.printf("log: %v\n", v) } } @@ -30,9 +31,13 @@ main :: proc() { t := testing.T{} test_parse_demo(&t) - fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + if TEST_fail > 0 { + os.exit(1) + } } + @test test_parse_demo :: proc(t: ^testing.T) { pkg, ok := parser.parse_package_from_path("examples/demo") @@ -42,4 +47,4 @@ test_parse_demo :: proc(t: ^testing.T) { for key, value in pkg.files { expect(t, value.syntax_error_count == 0, fmt.tprintf("%v should contain zero errors", key)) } -} +} \ No newline at end of file diff --git a/tests/core/os/test_core_os_exit.odin b/tests/core/os/test_core_os_exit.odin new file mode 100644 index 000000000..2ab274f5e --- /dev/null +++ b/tests/core/os/test_core_os_exit.odin @@ -0,0 +1,10 @@ +// Tests that Odin run returns exit code of built executable on Unix +// Needs exit status to be inverted to return 0 on success, e.g. +// $(./odin run tests/core/os/test_core_os_exit.odin && exit 1 || exit 0) +package test_core_os_exit + +import "core:os" + +main :: proc() { + os.exit(1) +} diff --git a/tests/core/path/filepath/test_core_filepath.odin b/tests/core/path/filepath/test_core_filepath.odin new file mode 100644 index 000000000..0268fb62c --- /dev/null +++ b/tests/core/path/filepath/test_core_filepath.odin @@ -0,0 +1,123 @@ +// Tests "path.odin" in "core:path/filepath". +// Must be run with `-collection:tests=` flag, e.g. +// ./odin run tests/core/path/filepath/test_core_filepath.odin -collection:tests=tests +package test_core_filepath + +import "core:fmt" +import "core:path/filepath" +import "core:testing" +import tc "tests:common" + +main :: proc() { + t := testing.T{} + + when ODIN_OS == .Windows { + test_split_list_windows(&t) + } else { + test_split_list_unix(&t) + } + + tc.report(&t) +} + +@test +test_split_list_windows :: proc(t: ^testing.T) { + + using filepath + + Datum :: struct { + i: int, + v: string, + e: [3]string, + } + @static data := []Datum{ + { 0, "C:\\Odin;C:\\Visual Studio;\"C:\\Some Other\"", + [3]string{"C:\\Odin", "C:\\Visual Studio", "C:\\Some Other"} }, // Issue #1537 + { 1, "a;;b", [3]string{"a", "", "b"} }, + { 2, "a;b;", [3]string{"a", "b", ""} }, + { 3, ";a;b", [3]string{"", "a", "b"} }, + { 4, ";;", [3]string{"", "", ""} }, + { 5, "\"a;b\"c;d;\"f\"", [3]string{"a;bc", "d", "f"} }, + { 6, "\"a;b;c\";d\";e\";f", [3]string{"a;b;c", "d;e", "f"} }, + } + + for d, i in data { + assert(i == d.i, fmt.tprintf("wrong data index: i %d != d.i %d\n", i, d.i)) + r := split_list(d.v) + defer delete(r) + tc.expect(t, len(r) == len(d.e), fmt.tprintf("i:%d %s(%s) len(r) %d != len(d.e) %d", + i, #procedure, d.v, len(r), len(d.e))) + if len(r) == len(d.e) { + for _, j in r { + tc.expect(t, r[j] == d.e[j], fmt.tprintf("i:%d %s(%v) -> %v[%d] != %v", + i, #procedure, d.v, r[j], j, d.e[j])) + } + } + } + + { + v := "" + r := split_list(v) + tc.expect(t, r == nil, fmt.tprintf("%s(%s) -> %v != nil", #procedure, v, r)) + } + { + v := "a" + r := split_list(v) + defer delete(r) + tc.expect(t, len(r) == 1, fmt.tprintf("%s(%s) len(r) %d != 1", #procedure, v, len(r))) + if len(r) == 1 { + tc.expect(t, r[0] == "a", fmt.tprintf("%s(%v) -> %v[0] != a", #procedure, v, r[0])) + } + } +} + +@test +test_split_list_unix :: proc(t: ^testing.T) { + + using filepath + + Datum :: struct { + i: int, + v: string, + e: [3]string, + } + @static data := []Datum{ + { 0, "/opt/butler:/home/fancykillerpanda/Projects/Odin/Odin:/usr/local/sbin", + [3]string{"/opt/butler", "/home/fancykillerpanda/Projects/Odin/Odin", "/usr/local/sbin"} }, // Issue #1537 + { 1, "a::b", [3]string{"a", "", "b"} }, + { 2, "a:b:", [3]string{"a", "b", ""} }, + { 3, ":a:b", [3]string{"", "a", "b"} }, + { 4, "::", [3]string{"", "", ""} }, + { 5, "\"a:b\"c:d:\"f\"", [3]string{"a:bc", "d", "f"} }, + { 6, "\"a:b:c\":d\":e\":f", [3]string{"a:b:c", "d:e", "f"} }, + } + + for d, i in data { + assert(i == d.i, fmt.tprintf("wrong data index: i %d != d.i %d\n", i, d.i)) + r := split_list(d.v) + defer delete(r) + tc.expect(t, len(r) == len(d.e), fmt.tprintf("i:%d %s(%s) len(r) %d != len(d.e) %d", + i, #procedure, d.v, len(r), len(d.e))) + if len(r) == len(d.e) { + for _, j in r { + tc.expect(t, r[j] == d.e[j], fmt.tprintf("i:%d %s(%v) -> %v[%d] != %v", + i, #procedure, d.v, r[j], j, d.e[j])) + } + } + } + + { + v := "" + r := split_list(v) + tc.expect(t, r == nil, fmt.tprintf("%s(%s) -> %v != nil", #procedure, v, r)) + } + { + v := "a" + r := split_list(v) + defer delete(r) + tc.expect(t, len(r) == 1, fmt.tprintf("%s(%s) len(r) %d != 1", #procedure, v, len(r))) + if len(r) == 1 { + tc.expect(t, r[0] == "a", fmt.tprintf("%s(%v) -> %v[0] != a", #procedure, v, r[0])) + } + } +} diff --git a/tests/core/reflect/test_core_reflect.odin b/tests/core/reflect/test_core_reflect.odin new file mode 100644 index 000000000..039501735 --- /dev/null +++ b/tests/core/reflect/test_core_reflect.odin @@ -0,0 +1,288 @@ +// Tests "core:reflect/reflect". +// Must be run with `-collection:tests=` flag, e.g. +// ./odin run tests/core/reflect/test_core_reflect.odin -out=tests/core/test_core_reflect -collection:tests=./tests +package test_core_reflect + +import "core:fmt" +import "core:reflect" +import "core:testing" +import tc "tests:common" + +main :: proc() { + t := testing.T{} + + test_as_u64(&t) + test_as_f64(&t) + + tc.report(&t) +} + +@test +test_as_u64 :: proc(t: ^testing.T) { + using reflect + + { + /* i8 */ + Datum :: struct { i: int, v: i8, e: u64 } + @static data := []Datum{ + { 0, 0x7F, 0x7F }, + { 1, -1, 0xFFFF_FFFF_FFFF_FFFF }, + { 2, -0x80, 0xFFFF_FFFF_FFFF_FF80 }, + } + + for d, i in data { + assert(i == d.i) + r, valid := as_u64(d.v) + tc.expect(t, valid, fmt.tprintf("i:%d %s(i8 %v) !valid\n", i, #procedure, d.v)) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(i8 %v) -> %v (0x%X) != %v (0x%X)\n", + i, #procedure, d.v, r, r, d.e, d.e)) + } + } + { + /* i16 */ + Datum :: struct { i: int, v: i16, e: u64 } + @static data := []Datum{ + { 0, 0x7FFF, 0x7FFF }, + { 1, -1, 0xFFFF_FFFF_FFFF_FFFF }, + { 2, -0x8000, 0xFFFF_FFFF_FFFF_8000 }, + } + + for d, i in data { + assert(i == d.i) + r, valid := as_u64(d.v) + tc.expect(t, valid, fmt.tprintf("i:%d %s(i16 %v) !valid\n", i, #procedure, d.v)) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(i16 %v) -> %v (0x%X) != %v (0x%X)\n", + i, #procedure, d.v, r, r, d.e, d.e)) + } + } + { + /* i32 */ + Datum :: struct { i: int, v: i32, e: u64 } + @static data := []Datum{ + { 0, 0x7FFF_FFFF, 0x7FFF_FFFF }, + { 1, -1, 0xFFFF_FFFF_FFFF_FFFF }, + { 2, -0x8000_0000, 0xFFFF_FFFF_8000_0000 }, + } + + for d, i in data { + assert(i == d.i) + r, valid := as_u64(d.v) + tc.expect(t, valid, fmt.tprintf("i:%d %s(i32 %v) !valid\n", i, #procedure, d.v)) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(i32 %v) -> %v (0x%X) != %v (0x%X)\n", + i, #procedure, d.v, r, r, d.e, d.e)) + } + } + { + /* i64 */ + Datum :: struct { i: int, v: i64, e: u64 } + @static data := []Datum{ + { 0, 0x7FFF_FFFF_FFFF_FFFF, 0x7FFF_FFFF_FFFF_FFFF }, + { 1, -1, 0xFFFF_FFFF_FFFF_FFFF }, + { 2, -0x8000_0000_0000_0000, 0x8000_0000_0000_0000 }, + } + + for d, i in data { + assert(i == d.i) + r, valid := as_u64(d.v) + tc.expect(t, valid, fmt.tprintf("i:%d %s(i64 %v) !valid\n", i, #procedure, d.v)) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(i64 %v) -> %v (0x%X) != %v (0x%X)\n", + i, #procedure, d.v, r, r, d.e, d.e)) + } + } + { + /* i128 */ + Datum :: struct { i: int, v: i128, e: u64 } + @static data := []Datum{ + { 0, 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF }, + { 1, -1, 0xFFFF_FFFF_FFFF_FFFF }, + { 2, 0x8000_0000_0000_0000, 0x8000_0000_0000_0000 }, + { 3, -0x8000_0000_0000_0000, 0x8000_0000_0000_0000 }, + { 4, 0x0001_0000_0000_0000_0000, 0 }, + { 5, -0x8000_0000_0000_0000_0000_0000_0000_0000, 0 }, + } + + for d, i in data { + assert(i == d.i) + r, valid := as_u64(d.v) + tc.expect(t, valid, fmt.tprintf("i:%d %s(i128 %v) !valid\n", i, #procedure, d.v)) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(i128 %v) -> %v (0x%X) != %v (0x%X)\n", + i, #procedure, d.v, r, r, d.e, d.e)) + } + } + { + /* f16 */ + Datum :: struct { i: int, v: f16, e: u64 } + @static data := []Datum{ + { 0, 1.2, 1 }, + { 1, 123.12, 123 }, + } + + for d, i in data { + assert(i == d.i) + r, valid := as_u64(d.v) + tc.expect(t, valid, fmt.tprintf("i:%d %s(f16 %v) !valid\n", i, #procedure, d.v)) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(f16 %v) -> %v != %v\n", i, #procedure, d.v, r, d.e)) + } + } + { + /* f32 */ + Datum :: struct { i: int, v: f32, e: u64 } + @static data := []Datum{ + { 0, 123.3415, 123 }, + } + + for d, i in data { + assert(i == d.i) + r, valid := as_u64(d.v) + tc.expect(t, valid, fmt.tprintf("i:%d %s(f32 %v) !valid\n", i, #procedure, d.v)) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(f32 %v) -> %v != %v\n", i, #procedure, d.v, r, d.e)) + } + } + { + /* f64 */ + Datum :: struct { i: int, v: f64, e: u64 } + @static data := []Datum{ + { 0, 12345345345.3415234234, 12345345345 }, + } + + for d, i in data { + assert(i == d.i) + r, valid := as_u64(d.v) + tc.expect(t, valid, fmt.tprintf("i:%d %s(f64 %v) !valid\n", i, #procedure, d.v)) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(f64 %v) -> %v != %v\n", i, #procedure, d.v, r, d.e)) + } + } +} + +@test +test_as_f64 :: proc(t: ^testing.T) { + using reflect + + { + /* i8 */ + Datum :: struct { i: int, v: i8, e: f64 } + @static data := []Datum{ + { 0, 0x7F, 0x7F }, + { 1, -1, -1 }, + { 2, -0x80, -0x80 }, + } + + for d, i in data { + assert(i == d.i) + r, valid := as_f64(d.v) + tc.expect(t, valid, fmt.tprintf("i:%d %s(i8 %v) !valid\n", i, #procedure, d.v)) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(i8 %v) -> %v != %v\n", i, #procedure, d.v, r, d.e)) + } + } + { + /* i16 */ + Datum :: struct { i: int, v: i16, e: f64 } + @static data := []Datum{ + { 0, 0x7FFF, 0x7FFF }, + { 1, -1, -1 }, + { 2, -0x8000, -0x8000 }, + } + + for d, i in data { + assert(i == d.i) + r, valid := as_f64(d.v) + tc.expect(t, valid, fmt.tprintf("i:%d %s(i16 %v) !valid\n", i, #procedure, d.v)) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(i16 %v) -> %v != %v\n", i, #procedure, d.v, r, d.e)) + } + } + { + /* i32 */ + Datum :: struct { i: int, v: i32, e: f64 } + @static data := []Datum{ + { 0, 0x7FFF_FFFF, 0x7FFF_FFFF }, + { 1, -1, -1 }, + { 2, -0x8000_0000, -0x8000_0000 }, + } + + for d, i in data { + assert(i == d.i) + r, valid := as_f64(d.v) + tc.expect(t, valid, fmt.tprintf("i:%d %s(i32 %v) !valid\n", i, #procedure, d.v)) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(i32 %v) -> %v != %v\n", i, #procedure, d.v, r, d.e)) + } + } + { + /* i64 */ + Datum :: struct { i: int, v: i64, e: f64 } + @static data := []Datum{ + { 0, 0x7FFF_FFFF_FFFF_FFFF, 0x7FFF_FFFF_FFFF_FFFF }, + { 1, -1, -1 }, + { 2, -0x8000_0000_0000_0000, -0x8000_0000_0000_0000 }, + } + + for d, i in data { + assert(i == d.i) + r, valid := as_f64(d.v) + tc.expect(t, valid, fmt.tprintf("i:%d %s(i64 %v) !valid\n", i, #procedure, d.v)) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(i64 %v) -> %v != %v\n", i, #procedure, d.v, r, d.e)) + } + } + { + /* i128 */ + Datum :: struct { i: int, v: i128, e: f64 } + @static data := []Datum{ + { 0, 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF, 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF }, + { 1, -1, -1 }, + { 2, 0x8000_0000_0000_0000_0000_0000_0000, 0x8000_0000_0000_0000_0000_0000_0000 }, + { 3, -0x8000_0000_0000_0000_0000_0000_0000_0000, -0x8000_0000_0000_0000_0000_0000_0000_0000 }, + } + + for d, i in data { + assert(i == d.i) + r, valid := as_f64(d.v) + tc.expect(t, valid, fmt.tprintf("i:%d %s(i128 %v) !valid\n", i, #procedure, d.v)) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(i128 %v) -> %v (%H) != %v (%H)\n", + i, #procedure, d.v, r, r, d.e, d.e)) + } + } + { + /* f16 */ + Datum :: struct { i: int, v: f16, e: f64 } + @static data := []Datum{ + { 0, 1.2, 0h3FF3_3400_0000_0000 }, // Precision difference TODO: check + { 1, 123.12, 0h405E_C800_0000_0000 }, // Precision difference TODO: check + } + + for d, i in data { + assert(i == d.i) + r, valid := as_f64(d.v) + tc.expect(t, valid, fmt.tprintf("i:%d %s(f16 %v) !valid\n", i, #procedure, d.v)) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(f16 %v (%H)) -> %v (%H) != %v (%H)\n", + i, #procedure, d.v, d.v, r, r, d.e, d.e)) + } + } + { + /* f32 */ + Datum :: struct { i: int, v: f32, e: f64 } + @static data := []Datum{ + { 0, 123.3415, 0h405E_D5DB_2000_0000 }, // Precision difference TODO: check + } + + for d, i in data { + assert(i == d.i) + r, valid := as_f64(d.v) + tc.expect(t, valid, fmt.tprintf("i:%d %s(f32 %v) !valid\n", i, #procedure, d.v)) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(f32 %v (%H)) -> %v (%H) != %v (%H)\n", + i, #procedure, d.v, d.v, r, r, d.e, d.e)) + } + } + { + /* f64 */ + Datum :: struct { i: int, v: f64, e: f64 } + @static data := []Datum{ + { 0, 12345345345.3415234234, 12345345345.3415234234 }, + } + + for d, i in data { + assert(i == d.i) + r, valid := as_f64(d.v) + tc.expect(t, valid, fmt.tprintf("i:%d %s(f64 %v) !valid\n", i, #procedure, d.v)) + tc.expect(t, r == d.e, fmt.tprintf("i:%d %s(f64 %v) -> %v != %v\n", i, #procedure, d.v, r, d.e)) + } + } +} diff --git a/tests/core/strings/test_core_strings.odin b/tests/core/strings/test_core_strings.odin index c5436f5c1..e97734dda 100644 --- a/tests/core/strings/test_core_strings.odin +++ b/tests/core/strings/test_core_strings.odin @@ -1,8 +1,9 @@ -package test_core_image +package test_core_strings import "core:strings" import "core:testing" import "core:fmt" +import "core:os" TEST_count := 0 TEST_fail := 0 @@ -20,7 +21,8 @@ when ODIN_TEST { } } log :: proc(t: ^testing.T, v: any, loc := #caller_location) { - fmt.printf("[%v] LOG:\n\t%v\n", loc, v) + fmt.printf("[%v] ", loc) + fmt.printf("log: %v\n", v) } } @@ -30,14 +32,17 @@ main :: proc() { test_index_any_larger_string_not_found(&t) test_index_any_small_string_found(&t) test_index_any_larger_string_found(&t) + test_cut(&t) - fmt.printf("\n%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + if TEST_fail > 0 { + os.exit(1) + } } @test test_index_any_small_string_not_found :: proc(t: ^testing.T) { index := strings.index_any(".", "/:\"") - log(t, index) expect(t, index == -1, "index_any should be negative") } @@ -58,3 +63,30 @@ test_index_any_larger_string_found :: proc(t: ^testing.T) { index := strings.index_any("aaaaaaaa:aaaaaaaa", "/:\"") expect(t, index == 8, "index_any should be 8") } + +Cut_Test :: struct { + input: string, + offset: int, + length: int, + output: string, +} + +cut_tests :: []Cut_Test{ + {"some example text", 0, 4, "some" }, + {"some example text", 2, 2, "me" }, + {"some example text", 5, 7, "example" }, + {"some example text", 5, 0, "example text"}, + {"恥ずべきフクロウ", 4, 0, "フクロウ" }, +} + +@test +test_cut :: proc(t: ^testing.T) { + for test in cut_tests { + res := strings.cut(test.input, test.offset, test.length) + defer delete(res) + + msg := fmt.tprintf("cut(\"%v\", %v, %v) expected to return \"%v\", got \"%v\"", + test.input, test.offset, test.length, test.output, res) + expect(t, res == test.output, msg) + } +} \ No newline at end of file diff --git a/tests/issues/run.bat b/tests/issues/run.bat new file mode 100644 index 000000000..a7078ae0f --- /dev/null +++ b/tests/issues/run.bat @@ -0,0 +1,17 @@ +@echo off + +if not exist "build\" mkdir build + +set COMMON=-collection:tests=.. -out:build\test_issue.exe + +@echo on + +..\..\odin build test_issue_829.odin %COMMON% -file +build\test_issue + +..\..\odin build test_issue_1592.odin %COMMON% -file +build\test_issue + +@echo off + +rmdir /S /Q build diff --git a/tests/issues/run.sh b/tests/issues/run.sh new file mode 100755 index 000000000..ec0804bac --- /dev/null +++ b/tests/issues/run.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -eu + +mkdir -p build +ODIN=../../odin +COMMON="-collection:tests=.. -out:build/test_issue" + +set -x + +$ODIN build test_issue_829.odin $COMMON -file +./build/test_issue + +$ODIN build test_issue_1592.odin $COMMON -file +./build/test_issue + +set +x + +rm -rf build diff --git a/tests/issues/test_issue_1592.odin b/tests/issues/test_issue_1592.odin new file mode 100644 index 000000000..bb350a30b --- /dev/null +++ b/tests/issues/test_issue_1592.odin @@ -0,0 +1,489 @@ +// Tests issue #1592 https://github.com/odin-lang/Odin/issues/1592 +package test_issues + +import "core:fmt" +import "core:testing" +import tc "tests:common" + +main :: proc() { + t := testing.T{} + + /* This won't short-circuit */ + test_orig() + + /* These will short-circuit */ + test_simple_const_false(&t) + test_simple_const_true(&t) + + /* These won't short-circuit */ + test_simple_proc_false(&t) + test_simple_proc_true(&t) + + /* These won't short-circuit */ + test_const_false_const_false(&t) + test_const_false_const_true(&t) + test_const_true_const_false(&t) + test_const_true_const_true(&t) + + /* These won't short-circuit */ + test_proc_false_const_false(&t) + test_proc_false_const_true(&t) + test_proc_true_const_false(&t) + test_proc_true_const_true(&t) + + tc.report(&t) +} + +/* Original issue #1592 example */ + +// I get a LLVM code gen error when this constant is false, but it works when it is true +CONSTANT_BOOL :: false + +bool_result :: proc() -> bool { + return false +} + +@test +test_orig :: proc() { + if bool_result() || CONSTANT_BOOL { + } +} + +CONSTANT_FALSE :: false +CONSTANT_TRUE :: true + +false_result :: proc() -> bool { + return false +} +true_result :: proc() -> bool { + return true +} + +@test +test_simple_const_false :: proc(t: ^testing.T) { + if CONSTANT_FALSE { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + if (CONSTANT_FALSE) { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + if !CONSTANT_FALSE { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if (!CONSTANT_FALSE) { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if !(CONSTANT_FALSE) { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if !!CONSTANT_FALSE { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + if CONSTANT_FALSE == true { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + if CONSTANT_FALSE == false { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if !(CONSTANT_FALSE == true) { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if !(CONSTANT_FALSE == false) { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } +} + +@test +test_simple_const_true :: proc(t: ^testing.T) { + if CONSTANT_TRUE { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if (CONSTANT_TRUE) { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if !CONSTANT_TRUE { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + if (!CONSTANT_TRUE) { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + if (!CONSTANT_TRUE) { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + if !(CONSTANT_TRUE) { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + if !!CONSTANT_TRUE { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if CONSTANT_TRUE == true { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if CONSTANT_TRUE == false { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + if !(CONSTANT_TRUE == true) { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + if !(CONSTANT_TRUE == false) { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } +} + +@test +test_simple_proc_false :: proc(t: ^testing.T) { + if false_result() { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + if !false_result() { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } +} + +@test +test_simple_proc_true :: proc(t: ^testing.T) { + if true_result() { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if !true_result() { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } +} + +@test +test_const_false_const_false :: proc(t: ^testing.T) { + if CONSTANT_FALSE || CONSTANT_FALSE { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + if CONSTANT_FALSE && CONSTANT_FALSE { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + + if !CONSTANT_FALSE || CONSTANT_FALSE { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if !CONSTANT_FALSE && CONSTANT_FALSE { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + + if CONSTANT_FALSE || !CONSTANT_FALSE { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if CONSTANT_FALSE && !CONSTANT_FALSE { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + + if !(CONSTANT_FALSE || CONSTANT_FALSE) { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if !(CONSTANT_FALSE && CONSTANT_FALSE) { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } +} + +@test +test_const_false_const_true :: proc(t: ^testing.T) { + if CONSTANT_FALSE || CONSTANT_TRUE { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if CONSTANT_FALSE && CONSTANT_TRUE { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + + if !CONSTANT_FALSE || CONSTANT_TRUE { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if !CONSTANT_FALSE && CONSTANT_TRUE { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + + if CONSTANT_FALSE || !CONSTANT_TRUE { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + if CONSTANT_FALSE && !CONSTANT_TRUE { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + + if !(CONSTANT_FALSE || CONSTANT_TRUE) { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + if !(CONSTANT_FALSE && CONSTANT_TRUE) { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } +} + +@test +test_const_true_const_false :: proc(t: ^testing.T) { + if CONSTANT_TRUE || CONSTANT_FALSE { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if CONSTANT_TRUE && CONSTANT_FALSE { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + + if !CONSTANT_TRUE || CONSTANT_FALSE { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + if !CONSTANT_TRUE && CONSTANT_FALSE { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + + if CONSTANT_TRUE || !CONSTANT_FALSE { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if CONSTANT_TRUE && !CONSTANT_FALSE { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + + if !(CONSTANT_TRUE || CONSTANT_FALSE) { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + if !(CONSTANT_TRUE && CONSTANT_FALSE) { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } +} + +@test +test_const_true_const_true :: proc(t: ^testing.T) { + if CONSTANT_TRUE || CONSTANT_TRUE { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if CONSTANT_TRUE && CONSTANT_TRUE { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + + if !CONSTANT_TRUE || CONSTANT_TRUE { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if !CONSTANT_TRUE && CONSTANT_TRUE { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + + if CONSTANT_TRUE || !CONSTANT_TRUE { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if CONSTANT_TRUE && !CONSTANT_TRUE { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + + if !(CONSTANT_TRUE || CONSTANT_TRUE) { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + if !(CONSTANT_TRUE && CONSTANT_TRUE) { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } +} + +@test +test_proc_false_const_false :: proc(t: ^testing.T) { + if false_result() || CONSTANT_FALSE { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + if false_result() && CONSTANT_FALSE { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + + if !(false_result() || CONSTANT_FALSE) { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if !(false_result() && CONSTANT_FALSE) { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } +} + +@test +test_proc_false_const_true :: proc(t: ^testing.T) { + if false_result() || CONSTANT_TRUE { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if false_result() && CONSTANT_TRUE { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + + if !(false_result() || CONSTANT_TRUE) { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + if !(false_result() && CONSTANT_TRUE) { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } +} + +@test +test_proc_true_const_false :: proc(t: ^testing.T) { + if true_result() || CONSTANT_FALSE { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if true_result() && CONSTANT_FALSE { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + + if !(true_result() || CONSTANT_FALSE) { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + if !(true_result() && CONSTANT_FALSE) { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } +} + +@test +test_proc_true_const_true :: proc(t: ^testing.T) { + if true_result() || CONSTANT_TRUE { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + if true_result() && CONSTANT_TRUE { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } else { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } + + if !(true_result() || CONSTANT_TRUE) { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } + if !(true_result() && CONSTANT_TRUE) { + tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure)) + } else { + tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure)) + } +} diff --git a/tests/issues/test_issue_829.odin b/tests/issues/test_issue_829.odin new file mode 100644 index 000000000..4ff3d71f1 --- /dev/null +++ b/tests/issues/test_issue_829.odin @@ -0,0 +1,33 @@ +// Tests issue #829 https://github.com/odin-lang/Odin/issues/829 +package test_issues + +import "core:fmt" +import "core:testing" +import tc "tests:common" + +/* Original issue #829 example */ + +env : map[string]proc(a, b : int) -> int = { + "+" = proc(a, b : int) -> int { + return a + b + }, +} + +test_orig :: proc() { + fmt.println(env["+"](1, 2)) +} + +main :: proc() { + t := testing.T{} + + test_orig() + + test_orig_ret(&t) + + tc.report(&t) +} + +test_orig_ret :: proc(t: ^testing.T) { + r := fmt.tprint(env["+"](1, 2)) + tc.expect(t, r == "3", fmt.tprintf("%s: \"%s\" != \"3\"\n", #procedure, r)) +} diff --git a/tests/vendor/Makefile b/tests/vendor/Makefile index f0a456bae..6c68d7908 100644 --- a/tests/vendor/Makefile +++ b/tests/vendor/Makefile @@ -1,6 +1,13 @@ ODIN=../../odin +ODINFLAGS= + +OS=$(shell uname) + +ifeq ($(OS), OpenBSD) + ODINFLAGS:=$(ODINFLAGS) -extra-linker-flags:-L/usr/local/lib +endif all: botan_test botan_test: - $(ODIN) run botan -out=botan_hash -o:speed -no-bounds-check \ No newline at end of file + $(ODIN) run botan -o:speed -no-bounds-check $(ODINFLAGS) -out=vendor_botan diff --git a/tests/vendor/botan/test_vendor_botan.odin b/tests/vendor/botan/test_vendor_botan.odin index e92410621..f0ff44ac9 100644 --- a/tests/vendor/botan/test_vendor_botan.odin +++ b/tests/vendor/botan/test_vendor_botan.odin @@ -14,6 +14,7 @@ package test_vendor_botan import "core:testing" import "core:fmt" +import "core:os" import "vendor:botan/md4" import "vendor:botan/md5" @@ -30,6 +31,7 @@ import "vendor:botan/gost" import "vendor:botan/streebog" import "vendor:botan/sm3" import "vendor:botan/skein512" +import "vendor:botan/siphash" TEST_count := 0 TEST_fail := 0 @@ -82,8 +84,12 @@ main :: proc() { test_sm3(&t) test_skein512_256(&t) test_skein512_512(&t) + test_siphash_2_4(&t) fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + if TEST_fail > 0 { + os.exit(1) + } } TestHash :: struct { @@ -575,3 +581,44 @@ test_skein512_512 :: proc(t: ^testing.T) { expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str)) } } + +@(test) +test_siphash_2_4 :: proc(t: ^testing.T) { + // Test vectors from + // https://github.com/veorq/SipHash/blob/master/vectors.h + test_vectors := [?]u64 { + 0x726fdb47dd0e0e31, 0x74f839c593dc67fd, 0x0d6c8009d9a94f5a, 0x85676696d7fb7e2d, + 0xcf2794e0277187b7, 0x18765564cd99a68d, 0xcbc9466e58fee3ce, 0xab0200f58b01d137, + 0x93f5f5799a932462, 0x9e0082df0ba9e4b0, 0x7a5dbbc594ddb9f3, 0xf4b32f46226bada7, + 0x751e8fbc860ee5fb, 0x14ea5627c0843d90, 0xf723ca908e7af2ee, 0xa129ca6149be45e5, + 0x3f2acc7f57c29bdb, 0x699ae9f52cbe4794, 0x4bc1b3f0968dd39c, 0xbb6dc91da77961bd, + 0xbed65cf21aa2ee98, 0xd0f2cbb02e3b67c7, 0x93536795e3a33e88, 0xa80c038ccd5ccec8, + 0xb8ad50c6f649af94, 0xbce192de8a85b8ea, 0x17d835b85bbb15f3, 0x2f2e6163076bcfad, + 0xde4daaaca71dc9a5, 0xa6a2506687956571, 0xad87a3535c49ef28, 0x32d892fad841c342, + 0x7127512f72f27cce, 0xa7f32346f95978e3, 0x12e0b01abb051238, 0x15e034d40fa197ae, + 0x314dffbe0815a3b4, 0x027990f029623981, 0xcadcd4e59ef40c4d, 0x9abfd8766a33735c, + 0x0e3ea96b5304a7d0, 0xad0c42d6fc585992, 0x187306c89bc215a9, 0xd4a60abcf3792b95, + 0xf935451de4f21df2, 0xa9538f0419755787, 0xdb9acddff56ca510, 0xd06c98cd5c0975eb, + 0xe612a3cb9ecba951, 0xc766e62cfcadaf96, 0xee64435a9752fe72, 0xa192d576b245165a, + 0x0a8787bf8ecb74b2, 0x81b3e73d20b49b6f, 0x7fa8220ba3b2ecea, 0x245731c13ca42499, + 0xb78dbfaf3a8d83bd, 0xea1ad565322a1a0b, 0x60e61c23a3795013, 0x6606d7e446282b93, + 0x6ca4ecb15c5f91e1, 0x9f626da15c9625f3, 0xe51b38608ef25f57, 0x958a324ceb064572, + } + + key: [16]byte + for i in 0..<16 { + key[i] = byte(i) + } + + for i in 0.. 0 { + os.exit(1) + } } @(test) diff --git a/tools/odinfmt/main.odin b/tools/odinfmt/main.odin index bc1b521ca..cebb20888 100644 --- a/tools/odinfmt/main.odin +++ b/tools/odinfmt/main.odin @@ -114,7 +114,6 @@ main :: proc() { filepath.walk(path, walk_files); for file in files { - fmt.println(file); backup_path := strings.concatenate({file, "_bk"}); defer delete(backup_path); diff --git a/vendor/ENet/enet.odin b/vendor/ENet/enet.odin index 8d068fbfc..37e65b497 100644 --- a/vendor/ENet/enet.odin +++ b/vendor/ENet/enet.odin @@ -1,7 +1,7 @@ package ENet -when ODIN_OS == "windows" { - when ODIN_ARCH == "amd64" { +when ODIN_OS == .Windows { + when ODIN_ARCH == .amd64 { foreign import ENet { "lib/enet64.lib", "system:Ws2_32.lib", diff --git a/vendor/ENet/unix.odin b/vendor/ENet/unix.odin index ea6b84199..05ce41e05 100644 --- a/vendor/ENet/unix.odin +++ b/vendor/ENet/unix.odin @@ -1,4 +1,4 @@ -//+build linux, darwin, freebsd +//+build linux, darwin, freebsd, openbsd package ENet // When we implement the appropriate bindings for Unix, the section separated @@ -14,7 +14,7 @@ import "core:c" @(private="file") FD_ZERO :: #force_inline proc(s: ^fd_set) { for i := size_of(fd_set) / size_of(c.long); i != 0; i -= 1 { - s.fds_bits[i] = 0; + s.fds_bits[i] = 0 } } @@ -56,4 +56,4 @@ SOCKETSET_REMOVE :: #force_inline proc(sockset: ^SocketSet, socket: Socket) { SOCKSET_CHECK :: #force_inline proc(sockset: ^SocketSet, socket: Socket) -> bool { return FD_ISSET(i32(socket), cast(^fd_set)sockset) -} \ No newline at end of file +} diff --git a/vendor/OpenGL/README.md b/vendor/OpenGL/README.md index 9e7a7bbbc..928d5eb5d 100644 --- a/vendor/OpenGL/README.md +++ b/vendor/OpenGL/README.md @@ -9,7 +9,7 @@ gl.load_up_to(4, 5, proc(p: rawptr, name: cstring) do (cast(^rawptr)p)^ = glfw.G ``` [odin-glfw](https://github.com/vassvik/odin-glfw) also provides a useful helper you can pass straight to `gl.load_up_to`: ```go -gl.load_up_to(4, 5, glfw.set_proc_address); +gl.load_up_to(4, 5, glfw.gl_set_proc_address); ``` #### NOTE: It is recommended to put this into the shared collection: diff --git a/vendor/OpenGL/helpers.odin b/vendor/OpenGL/helpers.odin index 0a9cffefa..661de318c 100644 --- a/vendor/OpenGL/helpers.odin +++ b/vendor/OpenGL/helpers.odin @@ -188,7 +188,7 @@ load_shaders_source :: proc(vs_source, fs_source: string, binary_retrievable := load_shaders :: proc{load_shaders_file} -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { update_shader_if_changed :: proc( vertex_name, fragment_name: string, program: u32, diff --git a/vendor/botan/README.md b/vendor/botan/README.md index 057aed422..b7d4d01a1 100644 --- a/vendor/botan/README.md +++ b/vendor/botan/README.md @@ -26,9 +26,11 @@ Wrappers for hashing algorithms have been added to match the API within the Odin #### High level API Each hash algorithm contains a procedure group named `hash`, or if the algorithm provides more than one digest size `hash_`. -Included in these groups are four procedures. +Included in these groups are six procedures. * `hash_string` - Hash a given string and return the computed hash. Just calls `hash_bytes` internally * `hash_bytes` - Hash a given byte slice and return the computed hash +* `hash_string_to_buffer` - Hash a given string and put the computed hash in the second proc parameter. Just calls `hash_bytes_to_buffer` internally +* `hash_bytes_to_buffer` - Hash a given string and put the computed hash in the second proc parameter. The destination buffer has to be at least as big as the digest size of the hash * `hash_stream` - Takes a stream from io.Stream and returns the computed hash from it * `hash_file` - Takes a file handle and returns the computed hash from it. A second optional boolean parameter controls if the file is streamed (this is the default) or read at once (set to true) @@ -49,6 +51,10 @@ main :: proc() { // Compute the hash, using the high level API computed_hash := md4.hash(input) + // Variant that takes a destination buffer, instead of returning the computed hash + hash := make([]byte, md4.DIGEST_SIZE) // @note: Destination buffer has to be at least as big as the digest size of the hash + md4.hash(input, hash[:]) + // Compute the hash, using the low level API // @note: Botan's structs are opaque by design, they don't expose any fields ctx: md4.Md4_Context diff --git a/vendor/botan/bindings/botan.odin b/vendor/botan/bindings/botan.odin index d1d88cda0..a12706e95 100644 --- a/vendor/botan/bindings/botan.odin +++ b/vendor/botan/bindings/botan.odin @@ -99,6 +99,10 @@ MAC_HMAC_SHA_384 :: "HMAC(SHA-384)" MAC_HMAC_SHA_512 :: "HMAC(SHA-512)" MAC_HMAC_MD5 :: "HMAC(MD5)" +MAC_SIPHASH_1_3 :: "SipHash(1,3)" +MAC_SIPHASH_2_4 :: "SipHash(2,4)" +MAC_SIPHASH_4_8 :: "SipHash(4,8)" + hash_struct :: struct{} hash_t :: ^hash_struct rng_struct :: struct{} @@ -136,11 +140,9 @@ totp_t :: ^totp_struct fpe_struct :: struct{} fpe_t :: ^fpe_struct -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import botan_lib "botan.lib" -} else when ODIN_OS == "linux" { - foreign import botan_lib "system:botan-2" -} else when ODIN_OS == "darwin" { +} else { foreign import botan_lib "system:botan-2" } @@ -467,4 +469,4 @@ foreign botan_lib { fpe_destroy :: proc(fpe: fpe_t) -> c.int --- fpe_encrypt :: proc(fpe: fpe_t, x: mp_t, tweak: ^c.char, tweak_len: c.size_t) -> c.int --- fpe_decrypt :: proc(fpe: fpe_t, x: mp_t, tweak: ^c.char, tweak_len: c.size_t) -> c.int --- -} \ No newline at end of file +} diff --git a/vendor/botan/blake2b/blake2b.odin b/vendor/botan/blake2b/blake2b.odin index efd4f464b..67238ec74 100644 --- a/vendor/botan/blake2b/blake2b.odin +++ b/vendor/botan/blake2b/blake2b.odin @@ -20,16 +20,18 @@ import botan "../bindings" High level API */ +DIGEST_SIZE :: 64 + // hash_string will hash the given input and return the // computed hash -hash_string :: proc "contextless" (data: string) -> [64]byte { +hash_string :: proc "contextless" (data: string) -> [DIGEST_SIZE]byte { return hash_bytes(transmute([]byte)(data)) } // hash_bytes will hash the given input and return the // computed hash -hash_bytes :: proc "contextless" (data: []byte) -> [64]byte { - hash: [64]byte +hash_bytes :: proc "contextless" (data: []byte) -> [DIGEST_SIZE]byte { + hash: [DIGEST_SIZE]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_BLAKE2B, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -38,10 +40,29 @@ hash_bytes :: proc "contextless" (data: []byte) -> [64]byte { return hash } +// hash_string_to_buffer will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_BLAKE2B, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream will read the stream in chunks and compute a // hash from its contents -hash_stream :: proc(s: io.Stream) -> ([64]byte, bool) { - hash: [64]byte +hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { + hash: [DIGEST_SIZE]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_BLAKE2B, 0) buf := make([]byte, 512) @@ -60,7 +81,7 @@ hash_stream :: proc(s: io.Stream) -> ([64]byte, bool) { // hash_file will read the file provided by the given handle // and compute a hash -hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) { +hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE]byte, bool) { if !load_at_once { return hash_stream(os.stream_from_handle(hd)) } else { @@ -68,7 +89,7 @@ hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) { return hash_bytes(buf[:]), ok } } - return [64]byte{}, false + return [DIGEST_SIZE]byte{}, false } hash :: proc { @@ -76,6 +97,8 @@ hash :: proc { hash_file, hash_bytes, hash_string, + hash_bytes_to_buffer, + hash_string_to_buffer, } /* diff --git a/vendor/botan/gost/gost.odin b/vendor/botan/gost/gost.odin index 266078c7d..6bf1c5b97 100644 --- a/vendor/botan/gost/gost.odin +++ b/vendor/botan/gost/gost.odin @@ -20,16 +20,18 @@ import botan "../bindings" High level API */ +DIGEST_SIZE :: 32 + // hash_string will hash the given input and return the // computed hash -hash_string :: proc "contextless" (data: string) -> [32]byte { +hash_string :: proc "contextless" (data: string) -> [DIGEST_SIZE]byte { return hash_bytes(transmute([]byte)(data)) } // hash_bytes will hash the given input and return the // computed hash -hash_bytes :: proc "contextless" (data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes :: proc "contextless" (data: []byte) -> [DIGEST_SIZE]byte { + hash: [DIGEST_SIZE]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_GOST, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -38,10 +40,29 @@ hash_bytes :: proc "contextless" (data: []byte) -> [32]byte { return hash } +// hash_string_to_buffer will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_GOST, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream will read the stream in chunks and compute a // hash from its contents -hash_stream :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { + hash: [DIGEST_SIZE]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_GOST, 0) buf := make([]byte, 512) @@ -60,7 +81,7 @@ hash_stream :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file will read the file provided by the given handle // and compute a hash -hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE]byte, bool) { if !load_at_once { return hash_stream(os.stream_from_handle(hd)) } else { @@ -68,7 +89,7 @@ hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { return hash_bytes(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE]byte{}, false } hash :: proc { @@ -76,6 +97,8 @@ hash :: proc { hash_file, hash_bytes, hash_string, + hash_bytes_to_buffer, + hash_string_to_buffer, } /* diff --git a/vendor/botan/keccak/keccak.odin b/vendor/botan/keccak/keccak.odin index c2f52bfdc..28e7374ba 100644 --- a/vendor/botan/keccak/keccak.odin +++ b/vendor/botan/keccak/keccak.odin @@ -20,16 +20,18 @@ import botan "../bindings" High level API */ +DIGEST_SIZE_512 :: 64 + // hash_string_512 will hash the given input and return the // computed hash -hash_string_512 :: proc(data: string) -> [64]byte { +hash_string_512 :: proc(data: string) -> [DIGEST_SIZE_512]byte { return hash_bytes_512(transmute([]byte)(data)) } // hash_bytes_512 will hash the given input and return the // computed hash -hash_bytes_512 :: proc(data: []byte) -> [64]byte { - hash: [64]byte +hash_bytes_512 :: proc(data: []byte) -> [DIGEST_SIZE_512]byte { + hash: [DIGEST_SIZE_512]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_KECCAK_512, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -38,10 +40,29 @@ hash_bytes_512 :: proc(data: []byte) -> [64]byte { return hash } +// hash_string_to_buffer_512 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_512 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_512(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_512 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_512 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_512, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_KECCAK_512, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream_512 will read the stream in chunks and compute a // hash from its contents -hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { - hash: [64]byte +hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { + hash: [DIGEST_SIZE_512]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_KECCAK_512, 0) buf := make([]byte, 512) @@ -60,7 +81,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { // hash_file_512 will read the file provided by the given handle // and compute a hash -hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) { +hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_512]byte, bool) { if !load_at_once { return hash_stream_512(os.stream_from_handle(hd)) } else { @@ -68,7 +89,7 @@ hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) return hash_bytes_512(buf[:]), ok } } - return [64]byte{}, false + return [DIGEST_SIZE_512]byte{}, false } hash_512 :: proc { @@ -76,6 +97,8 @@ hash_512 :: proc { hash_file_512, hash_bytes_512, hash_string_512, + hash_bytes_to_buffer_512, + hash_string_to_buffer_512, } /* diff --git a/vendor/botan/md4/md4.odin b/vendor/botan/md4/md4.odin index 47a77c0fb..174676a82 100644 --- a/vendor/botan/md4/md4.odin +++ b/vendor/botan/md4/md4.odin @@ -20,16 +20,18 @@ import botan "../bindings" High level API */ +DIGEST_SIZE :: 16 + // hash_string will hash the given input and return the // computed hash -hash_string :: proc "contextless" (data: string) -> [16]byte { +hash_string :: proc "contextless" (data: string) -> [DIGEST_SIZE]byte { return hash_bytes(transmute([]byte)(data)) } // hash_bytes will hash the given input and return the // computed hash -hash_bytes :: proc "contextless" (data: []byte) -> [16]byte { - hash: [16]byte +hash_bytes :: proc "contextless" (data: []byte) -> [DIGEST_SIZE]byte { + hash: [DIGEST_SIZE]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_MD4, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -38,10 +40,29 @@ hash_bytes :: proc "contextless" (data: []byte) -> [16]byte { return hash } +// hash_string_to_buffer will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_MD4, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream will read the stream in chunks and compute a // hash from its contents -hash_stream :: proc(s: io.Stream) -> ([16]byte, bool) { - hash: [16]byte +hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { + hash: [DIGEST_SIZE]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_MD4, 0) buf := make([]byte, 512) @@ -60,7 +81,7 @@ hash_stream :: proc(s: io.Stream) -> ([16]byte, bool) { // hash_file will read the file provided by the given handle // and compute a hash -hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) { +hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE]byte, bool) { if !load_at_once { return hash_stream(os.stream_from_handle(hd)) } else { @@ -68,7 +89,7 @@ hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) { return hash_bytes(buf[:]), ok } } - return [16]byte{}, false + return [DIGEST_SIZE]byte{}, false } hash :: proc { @@ -76,6 +97,8 @@ hash :: proc { hash_file, hash_bytes, hash_string, + hash_bytes_to_buffer, + hash_string_to_buffer, } /* diff --git a/vendor/botan/md5/md5.odin b/vendor/botan/md5/md5.odin index 15ad1e05a..01e099062 100644 --- a/vendor/botan/md5/md5.odin +++ b/vendor/botan/md5/md5.odin @@ -20,16 +20,18 @@ import botan "../bindings" High level API */ +DIGEST_SIZE :: 16 + // hash_string will hash the given input and return the // computed hash -hash_string :: proc "contextless" (data: string) -> [16]byte { +hash_string :: proc "contextless" (data: string) -> [DIGEST_SIZE]byte { return hash_bytes(transmute([]byte)(data)) } // hash_bytes will hash the given input and return the // computed hash -hash_bytes :: proc "contextless" (data: []byte) -> [16]byte { - hash: [16]byte +hash_bytes :: proc "contextless" (data: []byte) -> [DIGEST_SIZE]byte { + hash: [DIGEST_SIZE]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_MD5, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -38,10 +40,29 @@ hash_bytes :: proc "contextless" (data: []byte) -> [16]byte { return hash } +// hash_string_to_buffer will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_MD5, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream will read the stream in chunks and compute a // hash from its contents -hash_stream :: proc(s: io.Stream) -> ([16]byte, bool) { - hash: [16]byte +hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { + hash: [DIGEST_SIZE]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_MD5, 0) buf := make([]byte, 512) @@ -60,7 +81,7 @@ hash_stream :: proc(s: io.Stream) -> ([16]byte, bool) { // hash_file will read the file provided by the given handle // and compute a hash -hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) { +hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE]byte, bool) { if !load_at_once { return hash_stream(os.stream_from_handle(hd)) } else { @@ -68,7 +89,7 @@ hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) { return hash_bytes(buf[:]), ok } } - return [16]byte{}, false + return [DIGEST_SIZE]byte{}, false } hash :: proc { @@ -76,6 +97,8 @@ hash :: proc { hash_file, hash_bytes, hash_string, + hash_bytes_to_buffer, + hash_string_to_buffer, } /* diff --git a/vendor/botan/ripemd/ripemd.odin b/vendor/botan/ripemd/ripemd.odin index 66260e520..230e4c0d9 100644 --- a/vendor/botan/ripemd/ripemd.odin +++ b/vendor/botan/ripemd/ripemd.odin @@ -20,16 +20,18 @@ import botan "../bindings" High level API */ +DIGEST_SIZE_160 :: 20 + // hash_string_160 will hash the given input and return the // computed hash -hash_string_160 :: proc(data: string) -> [20]byte { +hash_string_160 :: proc(data: string) -> [DIGEST_SIZE_160]byte { return hash_bytes_160(transmute([]byte)(data)) } // hash_bytes_160 will hash the given input and return the // computed hash -hash_bytes_160 :: proc(data: []byte) -> [20]byte { - hash: [20]byte +hash_bytes_160 :: proc(data: []byte) -> [DIGEST_SIZE_160]byte { + hash: [DIGEST_SIZE_160]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_RIPEMD_160, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -38,10 +40,29 @@ hash_bytes_160 :: proc(data: []byte) -> [20]byte { return hash } +// hash_string_to_buffer_160 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_160 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_160(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_160 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_160 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_160, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_RIPEMD_160, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream_160 will read the stream in chunks and compute a // hash from its contents -hash_stream_160 :: proc(s: io.Stream) -> ([20]byte, bool) { - hash: [20]byte +hash_stream_160 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) { + hash: [DIGEST_SIZE_160]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_RIPEMD_160, 0) buf := make([]byte, 512) @@ -60,7 +81,7 @@ hash_stream_160 :: proc(s: io.Stream) -> ([20]byte, bool) { // hash_file_160 will read the file provided by the given handle // and compute a hash -hash_file_160 :: proc(hd: os.Handle, load_at_once := false) -> ([20]byte, bool) { +hash_file_160 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_160]byte, bool) { if !load_at_once { return hash_stream_160(os.stream_from_handle(hd)) } else { @@ -68,7 +89,7 @@ hash_file_160 :: proc(hd: os.Handle, load_at_once := false) -> ([20]byte, bool) return hash_bytes_160(buf[:]), ok } } - return [20]byte{}, false + return [DIGEST_SIZE_160]byte{}, false } hash_160 :: proc { @@ -76,6 +97,8 @@ hash_160 :: proc { hash_file_160, hash_bytes_160, hash_string_160, + hash_bytes_to_buffer_160, + hash_string_to_buffer_160, } /* diff --git a/vendor/botan/sha1/sha1.odin b/vendor/botan/sha1/sha1.odin index 2eb799cb6..1f74c8fc2 100644 --- a/vendor/botan/sha1/sha1.odin +++ b/vendor/botan/sha1/sha1.odin @@ -20,16 +20,18 @@ import botan "../bindings" High level API */ +DIGEST_SIZE :: 20 + // hash_string will hash the given input and return the // computed hash -hash_string :: proc "contextless" (data: string) -> [20]byte { +hash_string :: proc "contextless" (data: string) -> [DIGEST_SIZE]byte { return hash_bytes(transmute([]byte)(data)) } // hash_bytes will hash the given input and return the // computed hash -hash_bytes :: proc "contextless" (data: []byte) -> [20]byte { - hash: [20]byte +hash_bytes :: proc "contextless" (data: []byte) -> [DIGEST_SIZE]byte { + hash: [DIGEST_SIZE]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHA1, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -38,10 +40,29 @@ hash_bytes :: proc "contextless" (data: []byte) -> [20]byte { return hash } +// hash_string_to_buffer will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_SHA1, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream will read the stream in chunks and compute a // hash from its contents -hash_stream :: proc(s: io.Stream) -> ([20]byte, bool) { - hash: [20]byte +hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { + hash: [DIGEST_SIZE]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHA1, 0) buf := make([]byte, 512) @@ -60,7 +81,7 @@ hash_stream :: proc(s: io.Stream) -> ([20]byte, bool) { // hash_file will read the file provided by the given handle // and compute a hash -hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([20]byte, bool) { +hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE]byte, bool) { if !load_at_once { return hash_stream(os.stream_from_handle(hd)) } else { @@ -68,7 +89,7 @@ hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([20]byte, bool) { return hash_bytes(buf[:]), ok } } - return [20]byte{}, false + return [DIGEST_SIZE]byte{}, false } hash :: proc { @@ -76,6 +97,8 @@ hash :: proc { hash_file, hash_bytes, hash_string, + hash_bytes_to_buffer, + hash_string_to_buffer, } /* diff --git a/vendor/botan/sha2/sha2.odin b/vendor/botan/sha2/sha2.odin index cc5cd1d65..4c201cc26 100644 --- a/vendor/botan/sha2/sha2.odin +++ b/vendor/botan/sha2/sha2.odin @@ -20,16 +20,21 @@ import botan "../bindings" High level API */ +DIGEST_SIZE_224 :: 28 +DIGEST_SIZE_256 :: 32 +DIGEST_SIZE_384 :: 48 +DIGEST_SIZE_512 :: 64 + // hash_string_224 will hash the given input and return the // computed hash -hash_string_224 :: proc(data: string) -> [28]byte { +hash_string_224 :: proc(data: string) -> [DIGEST_SIZE_224]byte { return hash_bytes_224(transmute([]byte)(data)) } // hash_bytes_224 will hash the given input and return the // computed hash -hash_bytes_224 :: proc(data: []byte) -> [28]byte { - hash: [28]byte +hash_bytes_224 :: proc(data: []byte) -> [DIGEST_SIZE_224]byte { + hash: [DIGEST_SIZE_224]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHA_224, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -38,10 +43,29 @@ hash_bytes_224 :: proc(data: []byte) -> [28]byte { return hash } +// hash_string_to_buffer_224 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_224 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_224(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_224 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_224 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_224, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_SHA_224, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream_224 will read the stream in chunks and compute a // hash from its contents -hash_stream_224 :: proc(s: io.Stream) -> ([28]byte, bool) { - hash: [28]byte +hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { + hash: [DIGEST_SIZE_224]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHA_224, 0) buf := make([]byte, 512) @@ -60,7 +84,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([28]byte, bool) { // hash_file_224 will read the file provided by the given handle // and compute a hash -hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool) { +hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_224]byte, bool) { if !load_at_once { return hash_stream_224(os.stream_from_handle(hd)) } else { @@ -68,7 +92,7 @@ hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool) return hash_bytes_224(buf[:]), ok } } - return [28]byte{}, false + return [DIGEST_SIZE_224]byte{}, false } hash_224 :: proc { @@ -76,18 +100,20 @@ hash_224 :: proc { hash_file_224, hash_bytes_224, hash_string_224, + hash_bytes_to_buffer_224, + hash_string_to_buffer_224, } // hash_string_256 will hash the given input and return the // computed hash -hash_string_256 :: proc(data: string) -> [32]byte { +hash_string_256 :: proc(data: string) -> [DIGEST_SIZE_256]byte { return hash_bytes_256(transmute([]byte)(data)) } // hash_bytes_256 will hash the given input and return the // computed hash -hash_bytes_256 :: proc(data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes_256 :: proc(data: []byte) -> [DIGEST_SIZE_256]byte { + hash: [DIGEST_SIZE_256]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHA_256, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -96,10 +122,29 @@ hash_bytes_256 :: proc(data: []byte) -> [32]byte { return hash } +// hash_string_to_buffer_256 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_256 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_256(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_256 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_256 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_256, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_SHA_256, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream_256 will read the stream in chunks and compute a // hash from its contents -hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { + hash: [DIGEST_SIZE_256]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHA_256, 0) buf := make([]byte, 512) @@ -118,7 +163,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file_256 will read the file provided by the given handle // and compute a hash -hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_256]byte, bool) { if !load_at_once { return hash_stream_256(os.stream_from_handle(hd)) } else { @@ -126,7 +171,7 @@ hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) return hash_bytes_256(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE_256]byte{}, false } hash_256 :: proc { @@ -134,18 +179,20 @@ hash_256 :: proc { hash_file_256, hash_bytes_256, hash_string_256, + hash_bytes_to_buffer_256, + hash_string_to_buffer_256, } // hash_string_384 will hash the given input and return the // computed hash -hash_string_384 :: proc(data: string) -> [48]byte { +hash_string_384 :: proc(data: string) -> [DIGEST_SIZE_384]byte { return hash_bytes_384(transmute([]byte)(data)) } // hash_bytes_384 will hash the given input and return the // computed hash -hash_bytes_384 :: proc(data: []byte) -> [48]byte { - hash: [48]byte +hash_bytes_384 :: proc(data: []byte) -> [DIGEST_SIZE_384]byte { + hash: [DIGEST_SIZE_384]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHA_384, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -154,10 +201,29 @@ hash_bytes_384 :: proc(data: []byte) -> [48]byte { return hash } +// hash_string_to_buffer_384 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_384 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_384(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_384 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_384 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_384, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_SHA_384, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream_384 will read the stream in chunks and compute a // hash from its contents -hash_stream_384 :: proc(s: io.Stream) -> ([48]byte, bool) { - hash: [48]byte +hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) { + hash: [DIGEST_SIZE_384]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHA_384, 0) buf := make([]byte, 512) @@ -176,7 +242,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([48]byte, bool) { // hash_file_384 will read the file provided by the given handle // and compute a hash -hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([48]byte, bool) { +hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_384]byte, bool) { if !load_at_once { return hash_stream_384(os.stream_from_handle(hd)) } else { @@ -184,7 +250,7 @@ hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([48]byte, bool) return hash_bytes_384(buf[:]), ok } } - return [48]byte{}, false + return [DIGEST_SIZE_384]byte{}, false } hash_384 :: proc { @@ -192,18 +258,20 @@ hash_384 :: proc { hash_file_384, hash_bytes_384, hash_string_384, + hash_bytes_to_buffer_384, + hash_string_to_buffer_384, } // hash_string_512 will hash the given input and return the // computed hash -hash_string_512 :: proc(data: string) -> [64]byte { +hash_string_512 :: proc(data: string) -> [DIGEST_SIZE_512]byte { return hash_bytes_512(transmute([]byte)(data)) } // hash_bytes_512 will hash the given input and return the // computed hash -hash_bytes_512 :: proc(data: []byte) -> [64]byte { - hash: [64]byte +hash_bytes_512 :: proc(data: []byte) -> [DIGEST_SIZE_512]byte { + hash: [DIGEST_SIZE_512]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHA_512, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -212,10 +280,29 @@ hash_bytes_512 :: proc(data: []byte) -> [64]byte { return hash } +// hash_string_to_buffer_512 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_512 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_512(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_512 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_512 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_512, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_SHA_512, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream_512 will read the stream in chunks and compute a // hash from its contents -hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { - hash: [64]byte +hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { + hash: [DIGEST_SIZE_512]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHA_512, 0) buf := make([]byte, 512) @@ -234,7 +321,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { // hash_file_512 will read the file provided by the given handle // and compute a hash -hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) { +hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_512]byte, bool) { if !load_at_once { return hash_stream_512(os.stream_from_handle(hd)) } else { @@ -242,7 +329,7 @@ hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) return hash_bytes_512(buf[:]), ok } } - return [64]byte{}, false + return [DIGEST_SIZE_512]byte{}, false } hash_512 :: proc { @@ -250,6 +337,8 @@ hash_512 :: proc { hash_file_512, hash_bytes_512, hash_string_512, + hash_bytes_to_buffer_512, + hash_string_to_buffer_512, } /* diff --git a/vendor/botan/sha3/sha3.odin b/vendor/botan/sha3/sha3.odin index 1211d836a..4c1b87dda 100644 --- a/vendor/botan/sha3/sha3.odin +++ b/vendor/botan/sha3/sha3.odin @@ -20,16 +20,21 @@ import botan "../bindings" High level API */ +DIGEST_SIZE_224 :: 28 +DIGEST_SIZE_256 :: 32 +DIGEST_SIZE_384 :: 48 +DIGEST_SIZE_512 :: 64 + // hash_string_224 will hash the given input and return the // computed hash -hash_string_224 :: proc(data: string) -> [28]byte { +hash_string_224 :: proc(data: string) -> [DIGEST_SIZE_224]byte { return hash_bytes_224(transmute([]byte)(data)) } // hash_bytes_224 will hash the given input and return the // computed hash -hash_bytes_224 :: proc(data: []byte) -> [28]byte { - hash: [28]byte +hash_bytes_224 :: proc(data: []byte) -> [DIGEST_SIZE_224]byte { + hash: [DIGEST_SIZE_224]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHA3_224, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -38,10 +43,29 @@ hash_bytes_224 :: proc(data: []byte) -> [28]byte { return hash } +// hash_string_to_buffer_224 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_224 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_224(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_224 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_224 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_224, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_SHA3_224, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream_224 will read the stream in chunks and compute a // hash from its contents -hash_stream_224 :: proc(s: io.Stream) -> ([28]byte, bool) { - hash: [28]byte +hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) { + hash: [DIGEST_SIZE_224]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHA3_224, 0) buf := make([]byte, 512) @@ -60,7 +84,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([28]byte, bool) { // hash_file_224 will read the file provided by the given handle // and compute a hash -hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool) { +hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_224]byte, bool) { if !load_at_once { return hash_stream_224(os.stream_from_handle(hd)) } else { @@ -68,7 +92,7 @@ hash_file_224 :: proc(hd: os.Handle, load_at_once := false) -> ([28]byte, bool) return hash_bytes_224(buf[:]), ok } } - return [28]byte{}, false + return [DIGEST_SIZE_224]byte{}, false } hash_224 :: proc { @@ -76,18 +100,20 @@ hash_224 :: proc { hash_file_224, hash_bytes_224, hash_string_224, + hash_bytes_to_buffer_224, + hash_string_to_buffer_224, } // hash_string_256 will hash the given input and return the // computed hash -hash_string_256 :: proc(data: string) -> [32]byte { +hash_string_256 :: proc(data: string) -> [DIGEST_SIZE_256]byte { return hash_bytes_256(transmute([]byte)(data)) } // hash_bytes_256 will hash the given input and return the // computed hash -hash_bytes_256 :: proc(data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes_256 :: proc(data: []byte) -> [DIGEST_SIZE_256]byte { + hash: [DIGEST_SIZE_256]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHA3_256, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -96,10 +122,29 @@ hash_bytes_256 :: proc(data: []byte) -> [32]byte { return hash } +// hash_string_to_buffer_256 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_256 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_256(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_256 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_256 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_256, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_SHA3_256, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream_256 will read the stream in chunks and compute a // hash from its contents -hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { + hash: [DIGEST_SIZE_256]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHA3_256, 0) buf := make([]byte, 512) @@ -118,7 +163,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file_256 will read the file provided by the given handle // and compute a hash -hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_256]byte, bool) { if !load_at_once { return hash_stream_256(os.stream_from_handle(hd)) } else { @@ -126,7 +171,7 @@ hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) return hash_bytes_256(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE_256]byte{}, false } hash_256 :: proc { @@ -134,18 +179,20 @@ hash_256 :: proc { hash_file_256, hash_bytes_256, hash_string_256, + hash_bytes_to_buffer_256, + hash_string_to_buffer_256, } // hash_string_384 will hash the given input and return the // computed hash -hash_string_384 :: proc(data: string) -> [48]byte { +hash_string_384 :: proc(data: string) -> [DIGEST_SIZE_384]byte { return hash_bytes_384(transmute([]byte)(data)) } // hash_bytes_384 will hash the given input and return the // computed hash -hash_bytes_384 :: proc(data: []byte) -> [48]byte { - hash: [48]byte +hash_bytes_384 :: proc(data: []byte) -> [DIGEST_SIZE_384]byte { + hash: [DIGEST_SIZE_384]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHA3_384, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -154,10 +201,29 @@ hash_bytes_384 :: proc(data: []byte) -> [48]byte { return hash } +// hash_string_to_buffer_384 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_384 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_384(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_384 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_384 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_384, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_SHA3_384, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream_384 will read the stream in chunks and compute a // hash from its contents -hash_stream_384 :: proc(s: io.Stream) -> ([48]byte, bool) { - hash: [48]byte +hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) { + hash: [DIGEST_SIZE_384]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHA3_384, 0) buf := make([]byte, 512) @@ -176,7 +242,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([48]byte, bool) { // hash_file_384 will read the file provided by the given handle // and compute a hash -hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([48]byte, bool) { +hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_384]byte, bool) { if !load_at_once { return hash_stream_384(os.stream_from_handle(hd)) } else { @@ -184,7 +250,7 @@ hash_file_384 :: proc(hd: os.Handle, load_at_once := false) -> ([48]byte, bool) return hash_bytes_384(buf[:]), ok } } - return [48]byte{}, false + return [DIGEST_SIZE_384]byte{}, false } hash_384 :: proc { @@ -192,18 +258,20 @@ hash_384 :: proc { hash_file_384, hash_bytes_384, hash_string_384, + hash_bytes_to_buffer_384, + hash_string_to_buffer_384, } // hash_string_512 will hash the given input and return the // computed hash -hash_string_512 :: proc(data: string) -> [64]byte { +hash_string_512 :: proc(data: string) -> [DIGEST_SIZE_512]byte { return hash_bytes_512(transmute([]byte)(data)) } // hash_bytes_512 will hash the given input and return the // computed hash -hash_bytes_512 :: proc(data: []byte) -> [64]byte { - hash: [64]byte +hash_bytes_512 :: proc(data: []byte) -> [DIGEST_SIZE_512]byte { + hash: [DIGEST_SIZE_512]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHA3_512, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -212,10 +280,29 @@ hash_bytes_512 :: proc(data: []byte) -> [64]byte { return hash } +// hash_string_to_buffer_512 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_512 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_512(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_512 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_512 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_512, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_SHA3_512, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream_512 will read the stream in chunks and compute a // hash from its contents -hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { - hash: [64]byte +hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { + hash: [DIGEST_SIZE_512]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHA3_512, 0) buf := make([]byte, 512) @@ -234,7 +321,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { // hash_file_512 will read the file provided by the given handle // and compute a hash -hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) { +hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_512]byte, bool) { if !load_at_once { return hash_stream_512(os.stream_from_handle(hd)) } else { @@ -242,7 +329,7 @@ hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) return hash_bytes_512(buf[:]), ok } } - return [64]byte{}, false + return [DIGEST_SIZE_512]byte{}, false } hash_512 :: proc { @@ -250,6 +337,8 @@ hash_512 :: proc { hash_file_512, hash_bytes_512, hash_string_512, + hash_bytes_to_buffer_512, + hash_string_to_buffer_512, } /* diff --git a/vendor/botan/shake/shake.odin b/vendor/botan/shake/shake.odin index 82bf7ad15..f1023b90e 100644 --- a/vendor/botan/shake/shake.odin +++ b/vendor/botan/shake/shake.odin @@ -20,16 +20,19 @@ import botan "../bindings" High level API */ +DIGEST_SIZE_128 :: 16 +DIGEST_SIZE_256 :: 32 + // hash_string_128 will hash the given input and return the // computed hash -hash_string_128 :: proc(data: string) -> [16]byte { +hash_string_128 :: proc(data: string) -> [DIGEST_SIZE_128]byte { return hash_bytes_128(transmute([]byte)(data)) } // hash_bytes_128 will hash the given input and return the // computed hash -hash_bytes_128 :: proc(data: []byte) -> [16]byte { - hash: [16]byte +hash_bytes_128 :: proc(data: []byte) -> [DIGEST_SIZE_128]byte { + hash: [DIGEST_SIZE_128]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHAKE_128, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -38,10 +41,29 @@ hash_bytes_128 :: proc(data: []byte) -> [16]byte { return hash } +// hash_string_to_buffer_128 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_128 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_128(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_128 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_128 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_128, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_SHAKE_128, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream_128 will read the stream in chunks and compute a // hash from its contents -hash_stream_128 :: proc(s: io.Stream) -> ([16]byte, bool) { - hash: [16]byte +hash_stream_128 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) { + hash: [DIGEST_SIZE_128]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHAKE_128, 0) buf := make([]byte, 512) @@ -60,7 +82,7 @@ hash_stream_128 :: proc(s: io.Stream) -> ([16]byte, bool) { // hash_file_128 will read the file provided by the given handle // and compute a hash -hash_file_128 :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) { +hash_file_128 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_128]byte, bool) { if !load_at_once { return hash_stream_128(os.stream_from_handle(hd)) } else { @@ -68,7 +90,7 @@ hash_file_128 :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) return hash_bytes_128(buf[:]), ok } } - return [16]byte{}, false + return [DIGEST_SIZE_128]byte{}, false } hash_128 :: proc { @@ -76,18 +98,20 @@ hash_128 :: proc { hash_file_128, hash_bytes_128, hash_string_128, + hash_bytes_to_buffer_128, + hash_string_to_buffer_128, } // hash_string_256 will hash the given input and return the // computed hash -hash_string_256 :: proc(data: string) -> [32]byte { +hash_string_256 :: proc(data: string) -> [DIGEST_SIZE_256]byte { return hash_bytes_256(transmute([]byte)(data)) } // hash_bytes_256 will hash the given input and return the // computed hash -hash_bytes_256 :: proc(data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes_256 :: proc(data: []byte) -> [DIGEST_SIZE_256]byte { + hash: [DIGEST_SIZE_256]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHAKE_256, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -96,10 +120,29 @@ hash_bytes_256 :: proc(data: []byte) -> [32]byte { return hash } +// hash_string_to_buffer_256 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_256 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_256(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_256 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_256 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_256, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_SHAKE_256, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream_256 will read the stream in chunks and compute a // hash from its contents -hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { + hash: [DIGEST_SIZE_256]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SHAKE_256, 0) buf := make([]byte, 512) @@ -118,7 +161,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file_256 will read the file provided by the given handle // and compute a hash -hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_256]byte, bool) { if !load_at_once { return hash_stream_256(os.stream_from_handle(hd)) } else { @@ -126,7 +169,7 @@ hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) return hash_bytes_256(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE_256]byte{}, false } hash_256 :: proc { @@ -134,6 +177,8 @@ hash_256 :: proc { hash_file_256, hash_bytes_256, hash_string_256, + hash_bytes_to_buffer_256, + hash_string_to_buffer_256, } /* diff --git a/vendor/botan/siphash/siphash.odin b/vendor/botan/siphash/siphash.odin new file mode 100644 index 000000000..c2b7b64f4 --- /dev/null +++ b/vendor/botan/siphash/siphash.odin @@ -0,0 +1,253 @@ +package siphash + +/* + Copyright 2022 zhibog + Made available under the BSD-3 license. + + List of contributors: + zhibog: Initial implementation. + + Interface for the SipHash hashing algorithm. + The hash will be computed via bindings to the Botan crypto library + + Use the specific procedures for a certain setup. The generic procdedures will default to Siphash 2-4 +*/ + +import "core:crypto" +import "core:crypto/util" + +import botan "../bindings" + +KEY_SIZE :: 16 +DIGEST_SIZE :: 8 + +// sum_string_1_3 will hash the given message with the key and return +// the computed hash as a u64 +sum_string_1_3 :: proc(msg, key: string) -> u64 { + return sum_bytes_1_3(transmute([]byte)(msg), transmute([]byte)(key)) +} + +// sum_bytes_1_3 will hash the given message with the key and return +// the computed hash as a u64 +sum_bytes_1_3 :: proc (msg, key: []byte) -> u64 { + dst: [8]byte + ctx: botan.mac_t + init(&ctx, key[:], 1, 3) + update(&ctx, msg[:]) + final(&ctx, dst[:]) + return util.U64_LE(dst[:]) +} + +// sum_string_to_buffer_1_3 will hash the given message with the key and write +// the computed hash into the provided destination buffer +sum_string_to_buffer_1_3 :: proc(msg, key: string, dst: []byte) { + sum_bytes_to_buffer_1_3(transmute([]byte)(msg), transmute([]byte)(key), dst) +} + +// sum_bytes_to_buffer_1_3 will hash the given message with the key and write +// the computed hash into the provided destination buffer +sum_bytes_to_buffer_1_3 :: proc(msg, key, dst: []byte) { + assert(len(dst) >= DIGEST_SIZE, "vendor/botan: Destination buffer needs to be at least of size 8") + ctx: botan.mac_t + init(&ctx, key[:], 1, 3) + update(&ctx, msg[:]) + final(&ctx, dst[:]) +} + +sum_1_3 :: proc { + sum_string_1_3, + sum_bytes_1_3, + sum_string_to_buffer_1_3, + sum_bytes_to_buffer_1_3, +} + +// verify_u64_1_3 will check if the supplied tag matches with the output you +// will get from the provided message and key +verify_u64_1_3 :: proc (tag: u64 msg, key: []byte) -> bool { + return sum_bytes_1_3(msg, key) == tag +} + +// verify_bytes_1_3 will check if the supplied tag matches with the output you +// will get from the provided message and key +verify_bytes_1_3 :: proc (tag, msg, key: []byte) -> bool { + derived_tag: [8]byte + sum_bytes_to_buffer_1_3(msg, key, derived_tag[:]) + return crypto.compare_constant_time(derived_tag[:], tag) == 1 +} + +verify_1_3 :: proc { + verify_bytes_1_3, + verify_u64_1_3, +} + +// sum_string_2_4 will hash the given message with the key and return +// the computed hash as a u64 +sum_string_2_4 :: proc(msg, key: string) -> u64 { + return sum_bytes_2_4(transmute([]byte)(msg), transmute([]byte)(key)) +} + +// sum_bytes_2_4 will hash the given message with the key and return +// the computed hash as a u64 +sum_bytes_2_4 :: proc (msg, key: []byte) -> u64 { + dst: [8]byte + ctx: botan.mac_t + init(&ctx, key[:]) + update(&ctx, msg[:]) + final(&ctx, dst[:]) + return util.U64_LE(dst[:]) +} + +// sum_string_to_buffer_2_4 will hash the given message with the key and write +// the computed hash into the provided destination buffer +sum_string_to_buffer_2_4 :: proc(msg, key: string, dst: []byte) { + sum_bytes_to_buffer_2_4(transmute([]byte)(msg), transmute([]byte)(key), dst) +} + +// sum_bytes_to_buffer_2_4 will hash the given message with the key and write +// the computed hash into the provided destination buffer +sum_bytes_to_buffer_2_4 :: proc(msg, key, dst: []byte) { + assert(len(dst) >= DIGEST_SIZE, "vendor/botan: Destination buffer needs to be at least of size 8") + ctx: botan.mac_t + init(&ctx, key[:]) + update(&ctx, msg[:]) + final(&ctx, dst[:]) +} + +sum_2_4 :: proc { + sum_string_2_4, + sum_bytes_2_4, + sum_string_to_buffer_2_4, + sum_bytes_to_buffer_2_4, +} + +sum_string :: sum_string_2_4 +sum_bytes :: sum_bytes_2_4 +sum_string_to_buffer :: sum_string_to_buffer_2_4 +sum_bytes_to_buffer :: sum_bytes_to_buffer_2_4 +sum :: proc { + sum_string, + sum_bytes, + sum_string_to_buffer, + sum_bytes_to_buffer, +} + + +// verify_u64_2_4 will check if the supplied tag matches with the output you +// will get from the provided message and key +verify_u64_2_4 :: proc (tag: u64 msg, key: []byte) -> bool { + return sum_bytes_2_4(msg, key) == tag +} + +// verify_bytes_2_4 will check if the supplied tag matches with the output you +// will get from the provided message and key +verify_bytes_2_4 :: proc (tag, msg, key: []byte) -> bool { + derived_tag: [8]byte + sum_bytes_to_buffer_2_4(msg, key, derived_tag[:]) + return crypto.compare_constant_time(derived_tag[:], tag) == 1 +} + +verify_2_4 :: proc { + verify_bytes_2_4, + verify_u64_2_4, +} + +verify_bytes :: verify_bytes_2_4 +verify_u64 :: verify_u64_2_4 +verify :: proc { + verify_bytes, + verify_u64, +} + +// sum_string_4_8 will hash the given message with the key and return +// the computed hash as a u64 +sum_string_4_8 :: proc(msg, key: string) -> u64 { + return sum_bytes_4_8(transmute([]byte)(msg), transmute([]byte)(key)) +} + +// sum_bytes_4_8 will hash the given message with the key and return +// the computed hash as a u64 +sum_bytes_4_8 :: proc (msg, key: []byte) -> u64 { + dst: [8]byte + ctx: botan.mac_t + init(&ctx, key[:], 4, 8) + update(&ctx, msg[:]) + final(&ctx, dst[:]) + return util.U64_LE(dst[:]) +} + +// sum_string_to_buffer_4_8 will hash the given message with the key and write +// the computed hash into the provided destination buffer +sum_string_to_buffer_4_8 :: proc(msg, key: string, dst: []byte) { + sum_bytes_to_buffer_2_4(transmute([]byte)(msg), transmute([]byte)(key), dst) +} + +// sum_bytes_to_buffer_4_8 will hash the given message with the key and write +// the computed hash into the provided destination buffer +sum_bytes_to_buffer_4_8 :: proc(msg, key, dst: []byte) { + assert(len(dst) >= DIGEST_SIZE, "vendor/botan: Destination buffer needs to be at least of size 8") + ctx: botan.mac_t + init(&ctx, key[:], 4, 8) + update(&ctx, msg[:]) + final(&ctx, dst[:]) +} + +sum_4_8 :: proc { + sum_string_4_8, + sum_bytes_4_8, + sum_string_to_buffer_4_8, + sum_bytes_to_buffer_4_8, +} + +// verify_u64_4_8 will check if the supplied tag matches with the output you +// will get from the provided message and key +verify_u64_4_8 :: proc (tag: u64 msg, key: []byte) -> bool { + return sum_bytes_4_8(msg, key) == tag +} + +// verify_bytes_4_8 will check if the supplied tag matches with the output you +// will get from the provided message and key +verify_bytes_4_8 :: proc (tag, msg, key: []byte) -> bool { + derived_tag: [8]byte + sum_bytes_to_buffer_4_8(msg, key, derived_tag[:]) + return crypto.compare_constant_time(derived_tag[:], tag) == 1 +} + +verify_4_8 :: proc { + verify_bytes_4_8, + verify_u64_4_8, +} + +/* + Low level API +*/ + +Context :: botan.mac_t + +init :: proc(ctx: ^botan.mac_t, key: []byte, c_rounds := 2, d_rounds := 4) { + assert(len(key) == KEY_SIZE, "vendor/botan: Invalid key size, want 16") + is_valid_setting := (c_rounds == 1 && d_rounds == 3) || + (c_rounds == 2 && d_rounds == 4) || + (c_rounds == 4 && d_rounds == 8) + assert(is_valid_setting, "vendor/botan: Incorrect rounds set up. Valid pairs are (1,3), (2,4) and (4,8)") + if c_rounds == 1 && d_rounds == 3 { + botan.mac_init(ctx, botan.MAC_SIPHASH_1_3, 0) + } else if c_rounds == 2 && d_rounds == 4 { + botan.mac_init(ctx, botan.MAC_SIPHASH_2_4, 0) + } else if c_rounds == 4 && d_rounds == 8 { + botan.mac_init(ctx, botan.MAC_SIPHASH_4_8, 0) + } + botan.mac_set_key(ctx^, len(key) == 0 ? nil : &key[0], uint(len(key))) +} + +update :: proc "contextless" (ctx: ^botan.mac_t, data: []byte) { + botan.mac_update(ctx^, len(data) == 0 ? nil : &data[0], uint(len(data))) +} + +final :: proc(ctx: ^botan.mac_t, dst: []byte) { + botan.mac_final(ctx^, &dst[0]) + reset(ctx) +} + +reset :: proc(ctx: ^botan.mac_t) { + botan.mac_destroy(ctx^) +} \ No newline at end of file diff --git a/vendor/botan/skein512/skein512.odin b/vendor/botan/skein512/skein512.odin index dc808edb9..4fed07853 100644 --- a/vendor/botan/skein512/skein512.odin +++ b/vendor/botan/skein512/skein512.odin @@ -22,16 +22,19 @@ import botan "../bindings" High level API */ +DIGEST_SIZE_256 :: 32 +DIGEST_SIZE_512 :: 64 + // hash_string_256 will hash the given input and return the // computed hash -hash_string_256 :: proc(data: string) -> [32]byte { +hash_string_256 :: proc(data: string) -> [DIGEST_SIZE_256]byte { return hash_bytes_256(transmute([]byte)(data)) } // hash_bytes_256 will hash the given input and return the // computed hash -hash_bytes_256 :: proc(data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes_256 :: proc(data: []byte) -> [DIGEST_SIZE_256]byte { + hash: [DIGEST_SIZE_256]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SKEIN_512_256, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -40,10 +43,29 @@ hash_bytes_256 :: proc(data: []byte) -> [32]byte { return hash } +// hash_string_to_buffer_256 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_256 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_256(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_256 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_256 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_256, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_SKEIN_512_256, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream_256 will read the stream in chunks and compute a // hash from its contents -hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { + hash: [DIGEST_SIZE_256]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SKEIN_512_256, 0) buf := make([]byte, 512) @@ -62,7 +84,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file_256 will read the file provided by the given handle // and compute a hash -hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_256]byte, bool) { if !load_at_once { return hash_stream_256(os.stream_from_handle(hd)) } else { @@ -70,7 +92,7 @@ hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) return hash_bytes_256(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE_256]byte{}, false } hash_256 :: proc { @@ -78,18 +100,20 @@ hash_256 :: proc { hash_file_256, hash_bytes_256, hash_string_256, + hash_bytes_to_buffer_256, + hash_string_to_buffer_256, } // hash_string_512 will hash the given input and return the // computed hash -hash_string_512 :: proc(data: string) -> [64]byte { +hash_string_512 :: proc(data: string) -> [DIGEST_SIZE_512]byte { return hash_bytes_512(transmute([]byte)(data)) } // hash_bytes_512 will hash the given input and return the // computed hash -hash_bytes_512 :: proc(data: []byte) -> [64]byte { - hash: [64]byte +hash_bytes_512 :: proc(data: []byte) -> [DIGEST_SIZE_512]byte { + hash: [DIGEST_SIZE_512]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SKEIN_512_512, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -98,10 +122,29 @@ hash_bytes_512 :: proc(data: []byte) -> [64]byte { return hash } +// hash_string_to_buffer_512 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_512 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_512(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_512 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_512 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_512, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_SKEIN_512_512, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream_512 will read the stream in chunks and compute a // hash from its contents -hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { - hash: [64]byte +hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { + hash: [DIGEST_SIZE_512]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SKEIN_512_512, 0) buf := make([]byte, 512) @@ -120,7 +163,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { // hash_file_512 will read the file provided by the given handle // and compute a hash -hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) { +hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_512]byte, bool) { if !load_at_once { return hash_stream_512(os.stream_from_handle(hd)) } else { @@ -128,7 +171,7 @@ hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) return hash_bytes_512(buf[:]), ok } } - return [64]byte{}, false + return [DIGEST_SIZE_512]byte{}, false } hash_512 :: proc { @@ -136,6 +179,8 @@ hash_512 :: proc { hash_file_512, hash_bytes_512, hash_string_512, + hash_bytes_to_buffer_512, + hash_string_to_buffer_512, } // hash_string_slice will hash the given input and return the @@ -156,6 +201,25 @@ hash_bytes_slice :: proc(data: []byte, bit_size: int, allocator := context.alloc return hash } +// hash_string_to_buffer_512 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_slice :: proc(data: string, hash: []byte, bit_size: int, allocator := context.allocator) { + hash_bytes_to_buffer_slice(transmute([]byte)(data), hash, bit_size, allocator) +} + +// hash_bytes_to_buffer_slice will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_slice :: proc(data, hash: []byte, bit_size: int, allocator := context.allocator) { + assert(len(hash) >= bit_size, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, strings.unsafe_string_to_cstring(fmt.tprintf("Skein-512(%d)", bit_size * 8)), 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream_slice will read the stream in chunks and compute a // hash from its contents hash_stream_slice :: proc(s: io.Stream, bit_size: int, allocator := context.allocator) -> ([]byte, bool) { @@ -194,6 +258,8 @@ hash_slice :: proc { hash_file_slice, hash_bytes_slice, hash_string_slice, + hash_bytes_to_buffer_slice, + hash_string_to_buffer_slice, } /* diff --git a/vendor/botan/sm3/sm3.odin b/vendor/botan/sm3/sm3.odin index eada2a5b3..75cf40679 100644 --- a/vendor/botan/sm3/sm3.odin +++ b/vendor/botan/sm3/sm3.odin @@ -20,16 +20,18 @@ import botan "../bindings" High level API */ +DIGEST_SIZE :: 32 + // hash_string will hash the given input and return the // computed hash -hash_string :: proc "contextless" (data: string) -> [32]byte { +hash_string :: proc "contextless" (data: string) -> [DIGEST_SIZE]byte { return hash_bytes(transmute([]byte)(data)) } // hash_bytes will hash the given input and return the // computed hash -hash_bytes :: proc "contextless" (data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes :: proc "contextless" (data: []byte) -> [DIGEST_SIZE]byte { + hash: [DIGEST_SIZE]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SM3, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -38,10 +40,29 @@ hash_bytes :: proc "contextless" (data: []byte) -> [32]byte { return hash } +// hash_string_to_buffer will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_SM3, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream will read the stream in chunks and compute a // hash from its contents -hash_stream :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { + hash: [DIGEST_SIZE]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_SM3, 0) buf := make([]byte, 512) @@ -60,7 +81,7 @@ hash_stream :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file will read the file provided by the given handle // and compute a hash -hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE]byte, bool) { if !load_at_once { return hash_stream(os.stream_from_handle(hd)) } else { @@ -68,7 +89,7 @@ hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { return hash_bytes(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE]byte{}, false } hash :: proc { @@ -76,6 +97,8 @@ hash :: proc { hash_file, hash_bytes, hash_string, + hash_bytes_to_buffer, + hash_string_to_buffer, } /* diff --git a/vendor/botan/streebog/streebog.odin b/vendor/botan/streebog/streebog.odin index acee1a78a..20b4e6adb 100644 --- a/vendor/botan/streebog/streebog.odin +++ b/vendor/botan/streebog/streebog.odin @@ -20,16 +20,19 @@ import botan "../bindings" High level API */ +DIGEST_SIZE_256 :: 32 +DIGEST_SIZE_512 :: 64 + // hash_string_256 will hash the given input and return the // computed hash -hash_string_256 :: proc(data: string) -> [32]byte { +hash_string_256 :: proc(data: string) -> [DIGEST_SIZE_256]byte { return hash_bytes_256(transmute([]byte)(data)) } // hash_bytes_256 will hash the given input and return the // computed hash -hash_bytes_256 :: proc(data: []byte) -> [32]byte { - hash: [32]byte +hash_bytes_256 :: proc(data: []byte) -> [DIGEST_SIZE_256]byte { + hash: [DIGEST_SIZE_256]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_STREEBOG_256, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -38,10 +41,29 @@ hash_bytes_256 :: proc(data: []byte) -> [32]byte { return hash } +// hash_string_to_buffer_256 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_256 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_256(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_256 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_256 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_256, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_STREEBOG_256, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream_256 will read the stream in chunks and compute a // hash from its contents -hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { - hash: [32]byte +hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) { + hash: [DIGEST_SIZE_256]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_STREEBOG_256, 0) buf := make([]byte, 512) @@ -60,7 +82,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([32]byte, bool) { // hash_file_256 will read the file provided by the given handle // and compute a hash -hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) { +hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_256]byte, bool) { if !load_at_once { return hash_stream_256(os.stream_from_handle(hd)) } else { @@ -68,7 +90,7 @@ hash_file_256 :: proc(hd: os.Handle, load_at_once := false) -> ([32]byte, bool) return hash_bytes_256(buf[:]), ok } } - return [32]byte{}, false + return [DIGEST_SIZE_256]byte{}, false } hash_256 :: proc { @@ -76,18 +98,20 @@ hash_256 :: proc { hash_file_256, hash_bytes_256, hash_string_256, + hash_bytes_to_buffer_256, + hash_string_to_buffer_256, } // hash_string_512 will hash the given input and return the // computed hash -hash_string_512 :: proc(data: string) -> [64]byte { +hash_string_512 :: proc(data: string) -> [DIGEST_SIZE_512]byte { return hash_bytes_512(transmute([]byte)(data)) } // hash_bytes_512 will hash the given input and return the // computed hash -hash_bytes_512 :: proc(data: []byte) -> [64]byte { - hash: [64]byte +hash_bytes_512 :: proc(data: []byte) -> [DIGEST_SIZE_512]byte { + hash: [DIGEST_SIZE_512]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_STREEBOG_512, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -96,10 +120,29 @@ hash_bytes_512 :: proc(data: []byte) -> [64]byte { return hash } +// hash_string_to_buffer_512 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_512 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_512(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_512 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_512 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_512, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_STREEBOG_512, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream_512 will read the stream in chunks and compute a // hash from its contents -hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { - hash: [64]byte +hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) { + hash: [DIGEST_SIZE_512]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_STREEBOG_512, 0) buf := make([]byte, 512) @@ -118,7 +161,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([64]byte, bool) { // hash_file_512 will read the file provided by the given handle // and compute a hash -hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) { +hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_512]byte, bool) { if !load_at_once { return hash_stream_512(os.stream_from_handle(hd)) } else { @@ -126,7 +169,7 @@ hash_file_512 :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) return hash_bytes_512(buf[:]), ok } } - return [64]byte{}, false + return [DIGEST_SIZE_512]byte{}, false } hash_512 :: proc { @@ -134,6 +177,8 @@ hash_512 :: proc { hash_file_512, hash_bytes_512, hash_string_512, + hash_bytes_to_buffer_512, + hash_string_to_buffer_512, } /* diff --git a/vendor/botan/tiger/tiger.odin b/vendor/botan/tiger/tiger.odin index b240457a6..f24dc7019 100644 --- a/vendor/botan/tiger/tiger.odin +++ b/vendor/botan/tiger/tiger.odin @@ -20,16 +20,20 @@ import botan "../bindings" High level API */ +DIGEST_SIZE_128 :: 16 +DIGEST_SIZE_160 :: 20 +DIGEST_SIZE_192 :: 24 + // hash_string_128 will hash the given input and return the // computed hash -hash_string_128 :: proc(data: string) -> [16]byte { +hash_string_128 :: proc(data: string) -> [DIGEST_SIZE_128]byte { return hash_bytes_128(transmute([]byte)(data)) } // hash_bytes_128 will hash the given input and return the // computed hash -hash_bytes_128 :: proc(data: []byte) -> [16]byte { - hash: [16]byte +hash_bytes_128 :: proc(data: []byte) -> [DIGEST_SIZE_128]byte { + hash: [DIGEST_SIZE_128]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_TIGER_128, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -38,10 +42,29 @@ hash_bytes_128 :: proc(data: []byte) -> [16]byte { return hash } +// hash_string_to_buffer_128 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_128 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_128(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_128 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_128 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_128, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_TIGER_128, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream_128 will read the stream in chunks and compute a // hash from its contents -hash_stream_128 :: proc(s: io.Stream) -> ([16]byte, bool) { - hash: [16]byte +hash_stream_128 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) { + hash: [DIGEST_SIZE_128]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_TIGER_128, 0) buf := make([]byte, 512) @@ -60,7 +83,7 @@ hash_stream_128 :: proc(s: io.Stream) -> ([16]byte, bool) { // hash_file_128 will read the file provided by the given handle // and compute a hash -hash_file_128 :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) { +hash_file_128 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_128]byte, bool) { if !load_at_once { return hash_stream_128(os.stream_from_handle(hd)) } else { @@ -68,7 +91,7 @@ hash_file_128 :: proc(hd: os.Handle, load_at_once := false) -> ([16]byte, bool) return hash_bytes_128(buf[:]), ok } } - return [16]byte{}, false + return [DIGEST_SIZE_128]byte{}, false } hash_128 :: proc { @@ -76,18 +99,20 @@ hash_128 :: proc { hash_file_128, hash_bytes_128, hash_string_128, + hash_bytes_to_buffer_128, + hash_string_to_buffer_128, } // hash_string_160 will hash the given input and return the // computed hash -hash_string_160 :: proc(data: string) -> [20]byte { +hash_string_160 :: proc(data: string) -> [DIGEST_SIZE_160]byte { return hash_bytes_160(transmute([]byte)(data)) } // hash_bytes_160 will hash the given input and return the // computed hash -hash_bytes_160 :: proc(data: []byte) -> [20]byte { - hash: [20]byte +hash_bytes_160 :: proc(data: []byte) -> [DIGEST_SIZE_160]byte { + hash: [DIGEST_SIZE_160]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_TIGER_160, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -96,10 +121,29 @@ hash_bytes_160 :: proc(data: []byte) -> [20]byte { return hash } +// hash_string_to_buffer_160 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_160 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_160(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_160 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_160 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_160, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_TIGER_160, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream_160 will read the stream in chunks and compute a // hash from its contents -hash_stream_160 :: proc(s: io.Stream) -> ([20]byte, bool) { - hash: [20]byte +hash_stream_160 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) { + hash: [DIGEST_SIZE_160]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_TIGER_160, 0) buf := make([]byte, 512) @@ -118,7 +162,7 @@ hash_stream_160 :: proc(s: io.Stream) -> ([20]byte, bool) { // hash_file_160 will read the file provided by the given handle // and compute a hash -hash_file_160 :: proc(hd: os.Handle, load_at_once := false) -> ([20]byte, bool) { +hash_file_160 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_160]byte, bool) { if !load_at_once { return hash_stream_160(os.stream_from_handle(hd)) } else { @@ -126,7 +170,7 @@ hash_file_160 :: proc(hd: os.Handle, load_at_once := false) -> ([20]byte, bool) return hash_bytes_160(buf[:]), ok } } - return [20]byte{}, false + return [DIGEST_SIZE_160]byte{}, false } hash_160 :: proc { @@ -134,18 +178,20 @@ hash_160 :: proc { hash_file_160, hash_bytes_160, hash_string_160, + hash_bytes_to_buffer_160, + hash_string_to_buffer_160, } // hash_string_192 will hash the given input and return the // computed hash -hash_string_192 :: proc(data: string) -> [24]byte { +hash_string_192 :: proc(data: string) -> [DIGEST_SIZE_192]byte { return hash_bytes_192(transmute([]byte)(data)) } // hash_bytes_192 will hash the given input and return the // computed hash -hash_bytes_192 :: proc(data: []byte) -> [24]byte { - hash: [24]byte +hash_bytes_192 :: proc(data: []byte) -> [DIGEST_SIZE_192]byte { + hash: [DIGEST_SIZE_192]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_TIGER_192, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -154,10 +200,29 @@ hash_bytes_192 :: proc(data: []byte) -> [24]byte { return hash } +// hash_string_to_buffer_192 will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer_192 :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer_192(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer_192 will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer_192 :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE_192, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_TIGER_192, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream_192 will read the stream in chunks and compute a // hash from its contents -hash_stream_192 :: proc(s: io.Stream) -> ([24]byte, bool) { - hash: [24]byte +hash_stream_192 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) { + hash: [DIGEST_SIZE_192]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_TIGER_192, 0) buf := make([]byte, 512) @@ -176,7 +241,7 @@ hash_stream_192 :: proc(s: io.Stream) -> ([24]byte, bool) { // hash_file_192 will read the file provided by the given handle // and compute a hash -hash_file_192 :: proc(hd: os.Handle, load_at_once := false) -> ([24]byte, bool) { +hash_file_192 :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE_192]byte, bool) { if !load_at_once { return hash_stream_192(os.stream_from_handle(hd)) } else { @@ -184,7 +249,7 @@ hash_file_192 :: proc(hd: os.Handle, load_at_once := false) -> ([24]byte, bool) return hash_bytes_192(buf[:]), ok } } - return [24]byte{}, false + return [DIGEST_SIZE_192]byte{}, false } hash_192 :: proc { @@ -192,6 +257,8 @@ hash_192 :: proc { hash_file_192, hash_bytes_192, hash_string_192, + hash_bytes_to_buffer_192, + hash_string_to_buffer_192, } /* diff --git a/vendor/botan/whirlpool/whirlpool.odin b/vendor/botan/whirlpool/whirlpool.odin index 130386ff3..a7c1abbe8 100644 --- a/vendor/botan/whirlpool/whirlpool.odin +++ b/vendor/botan/whirlpool/whirlpool.odin @@ -20,16 +20,18 @@ import botan "../bindings" High level API */ +DIGEST_SIZE :: 64 + // hash_string will hash the given input and return the // computed hash -hash_string :: proc "contextless" (data: string) -> [64]byte { +hash_string :: proc "contextless" (data: string) -> [DIGEST_SIZE]byte { return hash_bytes(transmute([]byte)(data)) } // hash_bytes will hash the given input and return the // computed hash -hash_bytes :: proc "contextless" (data: []byte) -> [64]byte { - hash: [64]byte +hash_bytes :: proc "contextless" (data: []byte) -> [DIGEST_SIZE]byte { + hash: [DIGEST_SIZE]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_WHIRLPOOL, 0) botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) @@ -38,10 +40,29 @@ hash_bytes :: proc "contextless" (data: []byte) -> [64]byte { return hash } +// hash_string_to_buffer will hash the given input and assign the +// computed hash to the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_string_to_buffer :: proc(data: string, hash: []byte) { + hash_bytes_to_buffer(transmute([]byte)(data), hash) +} + +// hash_bytes_to_buffer will hash the given input and write the +// computed hash into the second parameter. +// It requires that the destination buffer is at least as big as the digest size +hash_bytes_to_buffer :: proc(data, hash: []byte) { + assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") + ctx: botan.hash_t + botan.hash_init(&ctx, botan.HASH_WHIRLPOOL, 0) + botan.hash_update(ctx, len(data) == 0 ? nil : &data[0], uint(len(data))) + botan.hash_final(ctx, &hash[0]) + botan.hash_destroy(ctx) +} + // hash_stream will read the stream in chunks and compute a // hash from its contents -hash_stream :: proc(s: io.Stream) -> ([64]byte, bool) { - hash: [64]byte +hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) { + hash: [DIGEST_SIZE]byte ctx: botan.hash_t botan.hash_init(&ctx, botan.HASH_WHIRLPOOL, 0) buf := make([]byte, 512) @@ -60,7 +81,7 @@ hash_stream :: proc(s: io.Stream) -> ([64]byte, bool) { // hash_file will read the file provided by the given handle // and compute a hash -hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) { +hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([DIGEST_SIZE]byte, bool) { if !load_at_once { return hash_stream(os.stream_from_handle(hd)) } else { @@ -68,7 +89,7 @@ hash_file :: proc(hd: os.Handle, load_at_once := false) -> ([64]byte, bool) { return hash_bytes(buf[:]), ok } } - return [64]byte{}, false + return [DIGEST_SIZE]byte{}, false } hash :: proc { @@ -76,6 +97,8 @@ hash :: proc { hash_file, hash_bytes, hash_string, + hash_bytes_to_buffer, + hash_string_to_buffer, } /* diff --git a/vendor/darwin/Foundation/NSApplication.odin b/vendor/darwin/Foundation/NSApplication.odin new file mode 100644 index 000000000..2fc4e6356 --- /dev/null +++ b/vendor/darwin/Foundation/NSApplication.odin @@ -0,0 +1,95 @@ +package objc_Foundation + +import "core:intrinsics" + +ActivationPolicy :: enum UInteger { + Regular = 0, + Accessory = 1, + Prohibited = 2, +} + +ApplicationDelegate :: struct { + willFinishLaunching: proc "c" (self: ^ApplicationDelegate, notification: ^Notification), + didFinishLaunching: proc "c" (self: ^ApplicationDelegate, notification: ^Notification), + shouldTerminateAfterLastWindowClosed: proc "c" (self: ^ApplicationDelegate, sender: ^Application), + + user_data: rawptr, +} + +@(objc_class="NSApplication") +Application :: struct {using _: Object} + +@(objc_type=Application, objc_name="sharedApplication", objc_is_class_method=true) +Application_sharedApplication :: proc() -> ^Application { + return msgSend(^Application, Application, "sharedApplication") +} + +@(objc_type=Application, objc_name="setDelegate") +Application_setDelegate :: proc(self: ^Application, delegate: ^ApplicationDelegate) { + willFinishLaunching :: proc "c" (self: ^Value, _: SEL, notification: ^Notification) { + del := (^ApplicationDelegate)(self->pointerValue()) + del->willFinishLaunching(notification) + } + didFinishLaunching :: proc "c" (self: ^Value, _: SEL, notification: ^Notification) { + del := (^ApplicationDelegate)(self->pointerValue()) + del->didFinishLaunching(notification) + } + shouldTerminateAfterLastWindowClosed :: proc "c" (self: ^Value, _: SEL, application: ^Application) { + del := (^ApplicationDelegate)(self->pointerValue()) + del->shouldTerminateAfterLastWindowClosed(application) + } + + wrapper := Value.valueWithPointer(delegate) + + class_addMethod(intrinsics.objc_find_class("NSValue"), intrinsics.objc_find_selector("applicationWillFinishLaunching:"), auto_cast willFinishLaunching, "v@:@") + class_addMethod(intrinsics.objc_find_class("NSValue"), intrinsics.objc_find_selector("applicationDidFinishLaunching:"), auto_cast didFinishLaunching, "v@:@") + class_addMethod(intrinsics.objc_find_class("NSValue"), intrinsics.objc_find_selector("applicationShouldTerminateAfterLastWindowClosed:"), auto_cast shouldTerminateAfterLastWindowClosed, "B@:@") + + msgSend(nil, self, "setDelegate:", wrapper) +} + +@(objc_type=Application, objc_name="setActivationPolicy") +Application_setActivationPolicy :: proc(self: ^Application, activationPolicy: ActivationPolicy) -> BOOL { + return msgSend(BOOL, self, "setActivationPolicy:", activationPolicy) +} + +@(objc_type=Application, objc_name="activateIgnoringOtherApps") +Application_activateIgnoringOtherApps :: proc(self: ^Application, ignoreOtherApps: BOOL) { + msgSend(nil, self, "activateIgnoringOtherApps:", ignoreOtherApps) +} + +@(objc_type=Application, objc_name="setMainMenu") +Application_setMainMenu :: proc(self: ^Application, menu: ^Menu) { + msgSend(nil, self, "setMainMenu:", menu) +} + +@(objc_type=Application, objc_name="windows") +Application_windows :: proc(self: ^Application) -> ^Array { + return msgSend(^Array, self, "windows") +} + +@(objc_type=Application, objc_name="run") +Application_run :: proc(self: ^Application) { + msgSend(nil, self, "run") +} + + +@(objc_type=Application, objc_name="terminate") +Application_terminate :: proc(self: ^Application, sender: ^Object) { + msgSend(nil, self, "terminate:", sender) +} + + + +@(objc_class="NSRunningApplication") +RunningApplication :: struct {using _: Object} + +@(objc_type=RunningApplication, objc_name="currentApplication", objc_is_class_method=true) +RunningApplication_currentApplication :: proc() -> ^RunningApplication { + return msgSend(^RunningApplication, RunningApplication, "currentApplication") +} + +@(objc_type=RunningApplication, objc_name="localizedName") +RunningApplication_localizedName :: proc(self: ^RunningApplication) -> ^String { + return msgSend(^String, self, "localizedName") +} \ No newline at end of file diff --git a/vendor/darwin/Foundation/NSArray.odin b/vendor/darwin/Foundation/NSArray.odin new file mode 100644 index 000000000..d6021838b --- /dev/null +++ b/vendor/darwin/Foundation/NSArray.odin @@ -0,0 +1,42 @@ +package objc_Foundation + +import "core:intrinsics" + +@(objc_class="NSArray") +Array :: struct { + using _: Copying(Array), +} + +@(objc_type=Array, objc_name="alloc", objc_is_class_method=true) +Array_alloc :: proc() -> ^Array { + return msgSend(^Array, Array, "alloc") +} + +@(objc_type=Array, objc_name="init") +Array_init :: proc(self: ^Array) -> ^Array { + return msgSend(^Array, self, "init") +} + +@(objc_type=Array, objc_name="initWithObjects") +Array_initWithObjects :: proc(self: ^Array, objects: [^]^Object, count: UInteger) -> ^Array { + return msgSend(^Array, self, "initWithObjects:count:", objects, count) +} + +@(objc_type=Array, objc_name="initWithCoder") +Array_initWithCoder :: proc(self: ^Array, coder: ^Coder) -> ^Array { + return msgSend(^Array, self, "initWithCoder:", coder) +} + +@(objc_type=Array, objc_name="object") +Array_object :: proc(self: ^Array, index: UInteger) -> ^Object { + return msgSend(^Object, self, "objectAtIndex:", index) +} +@(objc_type=Array, objc_name="objectAs") +Array_objectAs :: proc(self: ^Array, index: UInteger, $T: typeid) -> T where intrinsics.type_is_pointer(T), intrinsics.type_is_subtype_of(T, ^Object) { + return (T)(Array_object(self, index)) +} + +@(objc_type=Array, objc_name="count") +Array_count :: proc(self: ^Array) -> UInteger { + return msgSend(UInteger, self, "count") +} diff --git a/vendor/darwin/Foundation/NSAutoreleasePool.odin b/vendor/darwin/Foundation/NSAutoreleasePool.odin new file mode 100644 index 000000000..a388a7146 --- /dev/null +++ b/vendor/darwin/Foundation/NSAutoreleasePool.odin @@ -0,0 +1,33 @@ +package objc_Foundation + +@(objc_class="NSAutoreleasePool") +AutoreleasePool :: struct {using _: Object} + +@(objc_type=AutoreleasePool, objc_name="alloc", objc_is_class_method=true) +AutoreleasePool_alloc :: proc() -> ^AutoreleasePool { + return msgSend(^AutoreleasePool, AutoreleasePool, "alloc") +} + +@(objc_type=AutoreleasePool, objc_name="init") +AutoreleasePool_init :: proc(self: ^AutoreleasePool) -> ^AutoreleasePool { + return msgSend(^AutoreleasePool, self, "init") +} + +@(objc_type=AutoreleasePool, objc_name="drain") +AutoreleasePool_drain :: proc(self: ^AutoreleasePool) { + msgSend(nil, self, "drain") +} +@(objc_type=AutoreleasePool, objc_name="addObject") +AutoreleasePool_addObject :: proc(self: ^AutoreleasePool, obj: ^Object) { + msgSend(nil, self, "addObject:", obj) +} +@(objc_type=AutoreleasePool, objc_name="showPools") +AutoreleasePool_showPools :: proc(self: ^AutoreleasePool, obj: ^Object) { + msgSend(nil, self, "showPools") +} + + +@(deferred_out=AutoreleasePool_drain) +scoped_autoreleasepool :: proc() -> ^AutoreleasePool { + return AutoreleasePool.alloc()->init() +} \ No newline at end of file diff --git a/vendor/darwin/Foundation/NSBlock.odin b/vendor/darwin/Foundation/NSBlock.odin new file mode 100644 index 000000000..7fa061484 --- /dev/null +++ b/vendor/darwin/Foundation/NSBlock.odin @@ -0,0 +1,81 @@ +package objc_Foundation + +import "core:intrinsics" + +@(objc_class="NSConcreteGlobalBlock") +Block :: struct {using _: Object} + +@(objc_type=Block, objc_name="createGlobal", objc_is_class_method=true) +Block_createGlobal :: proc "c" (user_data: rawptr, user_proc: proc "c" (user_data: rawptr)) -> ^Block { + return Block_createInternal(true, user_data, user_proc) +} + +@(objc_type=Block, objc_name="createLocal", objc_is_class_method=true) +Block_createLocal :: proc "c" (user_data: rawptr, user_proc: proc "c" (user_data: rawptr)) -> ^Block { + return Block_createInternal(false, user_data, user_proc) +} + + +@(private) +Internal_Block_Literal_Base :: struct { + isa: ^intrinsics.objc_class, + flags: u32, + reserved: u32, + invoke: proc "c" (^Internal_Block_Literal), + descriptor: ^Block_Descriptor, +} + +@(private) +Internal_Block_Literal :: struct { + using base: Internal_Block_Literal_Base, + // Imported Variables + user_proc: proc "c" (user_data: rawptr), + user_data: rawptr, +} + +@(private) +Block_Descriptor :: struct { + reserved: uint, + size: uint, + copy_helper: proc "c" (dst, src: rawptr), + dispose_helper: proc "c" (src: rawptr), + signature: cstring, +} + +@(private) +global_block_descriptor := Block_Descriptor{ + reserved = 0, + size = size_of(Internal_Block_Literal), +} + +@(private="file") +Block_createInternal :: proc "c" (is_global: bool, user_data: rawptr, user_proc: proc "c" (user_data: rawptr)) -> ^Block { + // Set to true on blocks that have captures (and thus are not true + // global blocks) but are known not to escape for various other + // reasons. For backward compatibility with old runtimes, whenever + // BLOCK_IS_NOESCAPE is set, BLOCK_IS_GLOBAL is set too. Copying a + // non-escaping block returns the original block and releasing such a + // block is a no-op, which is exactly how global blocks are handled. + BLOCK_IS_NOESCAPE :: (1 << 23)|BLOCK_IS_GLOBAL + + BLOCK_HAS_COPY_DISPOSE :: 1 << 25 + BLOCK_HAS_CTOR :: 1 << 26 // helpers have C++ code + BLOCK_IS_GLOBAL :: 1 << 28 + BLOCK_HAS_STRET :: 1 << 29 // IFF BLOCK_HAS_SIGNATURE + BLOCK_HAS_SIGNATURE :: 1 << 30 + + extraBytes :: size_of(Internal_Block_Literal) - size_of(Internal_Block_Literal_Base) + + cls := intrinsics.objc_find_class("NSConcreteGlobalBlock") + bl := (^Internal_Block_Literal)(AllocateObject(cls, extraBytes, nil)) + bl.isa = cls + bl.flags = BLOCK_IS_GLOBAL if is_global else 0 + bl.invoke = proc "c" (bl: ^Internal_Block_Literal) { + bl.user_proc(bl.user_data) + } + bl.descriptor = &global_block_descriptor + bl.user_proc = user_proc + bl.user_data = user_data + + return auto_cast bl +} diff --git a/vendor/darwin/Foundation/NSBundle.odin b/vendor/darwin/Foundation/NSBundle.odin new file mode 100644 index 000000000..5e136378b --- /dev/null +++ b/vendor/darwin/Foundation/NSBundle.odin @@ -0,0 +1,191 @@ +package objc_Foundation + +@(objc_class="NSBundle") +Bundle :: struct { using _: Object } + +@(objc_type=Bundle, objc_name="mainBundle", objc_is_class_method=true) +Bundle_mainBundle :: proc() -> ^Bundle { + return msgSend(^Bundle, Bundle, "mainBundle") +} + +@(objc_type=Bundle, objc_name="bundleWithPath", objc_is_class_method=true) +Bundle_bundleWithPath :: proc(path: ^String) -> ^Bundle { + return msgSend(^Bundle, Bundle, "bundleWithPath:", path) +} + +@(objc_type=Bundle, objc_name="bundleWithURL", objc_is_class_method=true) +Bundle_bundleWithURL :: proc(url: ^URL) -> ^Bundle { + return msgSend(^Bundle, Bundle, "bundleWithUrl:", url) +} + + +@(objc_type=Bundle, objc_name="alloc", objc_is_class_method=true) +Bundle_alloc :: proc() -> ^Bundle { + return msgSend(^Bundle, Bundle, "alloc") +} + +@(objc_type=Bundle, objc_name="init") +Bundle_init :: proc(self: ^Bundle) -> ^Bundle { + return msgSend(^Bundle, self, "init") +} + +@(objc_type=Bundle, objc_name="initWithPath") +Bundle_initWithPath :: proc(self: ^Bundle, path: ^String) -> ^Bundle { + return msgSend(^Bundle, self, "initWithPath:", path) +} + +@(objc_type=Bundle, objc_name="initWithURL") +Bundle_initWithURL :: proc(self: ^Bundle, url: ^URL) -> ^Bundle { + return msgSend(^Bundle, self, "initWithUrl:", url) +} + +@(objc_type=Bundle, objc_name="allBundles") +Bundle_allBundles :: proc() -> (all: ^Array) { + return msgSend(type_of(all), Bundle, "allBundles") +} + +@(objc_type=Bundle, objc_name="allFrameworks") +Bundle_allFrameworks :: proc() -> (all: ^Array) { + return msgSend(type_of(all), Bundle, "allFrameworks") +} + +@(objc_type=Bundle, objc_name="load") +Bundle_load :: proc(self: ^Bundle) -> BOOL { + return msgSend(BOOL, self, "load") +} +@(objc_type=Bundle, objc_name="unload") +Bundle_unload :: proc(self: ^Bundle) -> BOOL { + return msgSend(BOOL, self, "unload") +} + +@(objc_type=Bundle, objc_name="isLoaded") +Bundle_isLoaded :: proc(self: ^Bundle) -> BOOL { + return msgSend(BOOL, self, "isLoaded") +} + +@(objc_type=Bundle, objc_name="preflightAndReturnError") +Bundle_preflightAndReturnError :: proc(self: ^Bundle) -> (ok: BOOL, error: ^Error) { + ok = msgSend(BOOL, self, "preflightAndReturnError:", &error) + return +} + +@(objc_type=Bundle, objc_name="loadAndReturnError") +Bundle_loadAndReturnError :: proc(self: ^Bundle) -> (ok: BOOL, error: ^Error) { + ok = msgSend(BOOL, self, "loadAndReturnError:", &error) + return +} + +@(objc_type=Bundle, objc_name="bundleURL") +Bundle_bundleURL :: proc(self: ^Bundle) -> ^URL { + return msgSend(^URL, self, "bundleURL") +} + +@(objc_type=Bundle, objc_name="resourceURL") +Bundle_resourceURL :: proc(self: ^Bundle) -> ^URL { + return msgSend(^URL, self, "resourceURL") +} + +@(objc_type=Bundle, objc_name="executableURL") +Bundle_executableURL :: proc(self: ^Bundle) -> ^URL { + return msgSend(^URL, self, "executableURL") +} + +@(objc_type=Bundle, objc_name="URLForAuxiliaryExecutable") +Bundle_URLForAuxiliaryExecutable :: proc(self: ^Bundle, executableName: ^String) -> ^URL { + return msgSend(^URL, self, "URLForAuxiliaryExecutable:", executableName) +} + +@(objc_type=Bundle, objc_name="privateFrameworksURL") +Bundle_privateFrameworksURL :: proc(self: ^Bundle) -> ^URL { + return msgSend(^URL, self, "privateFrameworksURL") +} + +@(objc_type=Bundle, objc_name="sharedFrameworksURL") +Bundle_sharedFrameworksURL :: proc(self: ^Bundle) -> ^URL { + return msgSend(^URL, self, "sharedFrameworksURL") +} + +@(objc_type=Bundle, objc_name="sharedSupportURL") +Bundle_sharedSupportURL :: proc(self: ^Bundle) -> ^URL { + return msgSend(^URL, self, "sharedSupportURL") +} + +@(objc_type=Bundle, objc_name="builtInPlugInsURL") +Bundle_builtInPlugInsURL :: proc(self: ^Bundle) -> ^URL { + return msgSend(^URL, self, "builtInPlugInsURL") +} + +@(objc_type=Bundle, objc_name="appStoreReceiptURL") +Bundle_appStoreReceiptURL :: proc(self: ^Bundle) -> ^URL { + return msgSend(^URL, self, "appStoreReceiptURL") +} + +@(objc_type=Bundle, objc_name="bundlePath") +Bundle_bundlePath :: proc(self: ^Bundle) -> ^String { + return msgSend(^String, self, "bundlePath") +} + +@(objc_type=Bundle, objc_name="resourcePath") +Bundle_resourcePath :: proc(self: ^Bundle) -> ^String { + return msgSend(^String, self, "resourcePath") +} + +@(objc_type=Bundle, objc_name="executablePath") +Bundle_executablePath :: proc(self: ^Bundle) -> ^String { + return msgSend(^String, self, "executablePath") +} + +@(objc_type=Bundle, objc_name="PathForAuxiliaryExecutable") +Bundle_PathForAuxiliaryExecutable :: proc(self: ^Bundle, executableName: ^String) -> ^String { + return msgSend(^String, self, "PathForAuxiliaryExecutable:", executableName) +} + +@(objc_type=Bundle, objc_name="privateFrameworksPath") +Bundle_privateFrameworksPath :: proc(self: ^Bundle) -> ^String { + return msgSend(^String, self, "privateFrameworksPath") +} + +@(objc_type=Bundle, objc_name="sharedFrameworksPath") +Bundle_sharedFrameworksPath :: proc(self: ^Bundle) -> ^String { + return msgSend(^String, self, "sharedFrameworksPath") +} + +@(objc_type=Bundle, objc_name="sharedSupportPath") +Bundle_sharedSupportPath :: proc(self: ^Bundle) -> ^String { + return msgSend(^String, self, "sharedSupportPath") +} + +@(objc_type=Bundle, objc_name="builtInPlugInsPath") +Bundle_builtInPlugInsPath :: proc(self: ^Bundle) -> ^String { + return msgSend(^String, self, "builtInPlugInsPath") +} + +@(objc_type=Bundle, objc_name="appStoreReceiptPath") +Bundle_appStoreReceiptPath :: proc(self: ^Bundle) -> ^String { + return msgSend(^String, self, "appStoreReceiptPath") +} + +@(objc_type=Bundle, objc_name="bundleIdentifier") +Bundle_bundleIdentifier :: proc(self: ^Bundle) -> ^String { + return msgSend(^String, self, "bundleIdentifier") +} + +@(objc_type=Bundle, objc_name="infoDictionary") +Bundle_infoDictionary :: proc(self: ^Bundle) -> ^Dictionary { + return msgSend(^Dictionary, self, "infoDictionary") +} + +@(objc_type=Bundle, objc_name="localizedInfoDictionary") +Bundle_localizedInfoDictionary :: proc(self: ^Bundle) -> ^Dictionary { + return msgSend(^Dictionary, self, "localizedInfoDictionary") +} + +@(objc_type=Bundle, objc_name="objectForInfoDictionaryKey") +Bundle_objectForInfoDictionaryKey :: proc(self: ^Bundle, key: ^String) -> ^Object { + return msgSend(^Object, self, "objectForInfoDictionaryKey:", key) +} + +@(objc_type=Bundle, objc_name="localizedStringForKey") +Bundle_localizedStringForKey :: proc(self: ^Bundle, key: ^String, value: ^String = nil, tableName: ^String = nil) -> ^String { + return msgSend(^String, self, "localizedStringForKey:value:table:", key, value, tableName) +} diff --git a/vendor/darwin/Foundation/NSData.odin b/vendor/darwin/Foundation/NSData.odin new file mode 100644 index 000000000..3c6369e86 --- /dev/null +++ b/vendor/darwin/Foundation/NSData.odin @@ -0,0 +1,24 @@ +package objc_Foundation + +@(objc_class="NSData") +Data :: struct {using _: Copying(Data)} + +@(objc_type=Data, objc_name="alloc", objc_is_class_method=true) +Data_alloc :: proc() -> ^Data { + return msgSend(^Data, Data, "alloc") +} + +@(objc_type=Data, objc_name="init") +Data_init :: proc(self: ^Data) -> ^Data { + return msgSend(^Data, self, "init") +} + +@(objc_type=Data, objc_name="mutableBytes") +Data_mutableBytes :: proc(self: ^Data) -> rawptr { + return msgSend(rawptr, self, "mutableBytes") +} + +@(objc_type=Data, objc_name="length") +Data_length :: proc(self: ^Data) -> UInteger { + return msgSend(UInteger, self, "length") +} \ No newline at end of file diff --git a/vendor/darwin/Foundation/NSDate.odin b/vendor/darwin/Foundation/NSDate.odin new file mode 100644 index 000000000..e30cb07d0 --- /dev/null +++ b/vendor/darwin/Foundation/NSDate.odin @@ -0,0 +1,19 @@ +package objc_Foundation + +@(objc_class="NSDate") +Date :: struct {using _: Copying(Date)} + +@(objc_type=Date, objc_name="alloc", objc_is_class_method=true) +Date_alloc :: proc() -> ^Date { + return msgSend(^Date, Date, "alloc") +} + +@(objc_type=Date, objc_name="init") +Date_init :: proc(self: ^Date) -> ^Date { + return msgSend(^Date, self, "init") +} + +@(objc_type=Date, objc_name="dateWithTimeIntervalSinceNow") +Date_dateWithTimeIntervalSinceNow :: proc(secs: TimeInterval) -> ^Date { + return msgSend(^Date, Date, "dateWithTimeIntervalSinceNow:", secs) +} \ No newline at end of file diff --git a/vendor/darwin/Foundation/NSDictionary.odin b/vendor/darwin/Foundation/NSDictionary.odin new file mode 100644 index 000000000..3832c05f1 --- /dev/null +++ b/vendor/darwin/Foundation/NSDictionary.odin @@ -0,0 +1,50 @@ +package objc_Foundation + +@(objc_class="NSDictionary") +Dictionary :: struct {using _: Copying(Dictionary)} + +@(objc_type=Dictionary, objc_name="dictionary", objc_is_class_method=true) +Dictionary_dictionary :: proc() -> ^Dictionary { + return msgSend(^Dictionary, Dictionary, "dictionary") +} + +@(objc_type=Dictionary, objc_name="dictionaryWithObject", objc_is_class_method=true) +Dictionary_dictionaryWithObject :: proc(object: ^Object, forKey: ^Object) -> ^Dictionary { + return msgSend(^Dictionary, Dictionary, "dictionaryWithObject:forKey:", object, forKey) +} + +@(objc_type=Dictionary, objc_name="dictionaryWithObjects", objc_is_class_method=true) +Dictionary_dictionaryWithObjects :: proc(objects: [^]^Object, forKeys: [^]^Object, count: UInteger) -> ^Dictionary { + return msgSend(^Dictionary, Dictionary, "dictionaryWithObjects:forKeys:count", objects, forKeys, count) +} + + +@(objc_type=Dictionary, objc_name="alloc", objc_is_class_method=true) +Dictionary_alloc :: proc() -> ^Dictionary { + return msgSend(^Dictionary, Dictionary, "alloc") +} + +@(objc_type=Dictionary, objc_name="init") +Dictionary_init :: proc(self: ^Dictionary) -> ^Dictionary { + return msgSend(^Dictionary, self, "init") +} + +@(objc_type=Dictionary, objc_name="initWithObjects") +Dictionary_initWithObjects :: proc(self: ^Dictionary, objects: [^]^Object, forKeys: [^]^Object, count: UInteger) -> ^Dictionary { + return msgSend(^Dictionary, self, "initWithObjects:forKeys:count", objects, forKeys, count) +} + +@(objc_type=Dictionary, objc_name="objectForKey") +Dictionary_objectForKey :: proc(self: ^Dictionary, key: ^Object) -> ^Object { + return msgSend(^Dictionary, self, "objectForKey:", key) +} + +@(objc_type=Dictionary, objc_name="count") +Dictionary_count :: proc(self: ^Dictionary) -> UInteger { + return msgSend(UInteger, self, "count") +} + +@(objc_type=Dictionary, objc_name="keyEnumerator") +Dictionary_keyEnumerator :: proc(self: ^Dictionary, $KeyType: typeid) -> (enumerator: ^Enumerator(KeyType)) { + return msgSend(type_of(enumerator), self, "keyEnumerator") +} diff --git a/vendor/darwin/Foundation/NSEnumerator.odin b/vendor/darwin/Foundation/NSEnumerator.odin new file mode 100644 index 000000000..1c7ddeed2 --- /dev/null +++ b/vendor/darwin/Foundation/NSEnumerator.odin @@ -0,0 +1,50 @@ +package objc_Foundation + +import "core:c" +import "core:intrinsics" + +FastEnumerationState :: struct #packed { + state: c.ulong, + itemsPtr: [^]^Object, + mutationsPtr: [^]c.ulong, + extra: [5]c.ulong, +} + +@(objc_class="NSFastEnumeration") +FastEnumeration :: struct {using _: Object} + +@(objc_class="NSEnumerator") +Enumerator :: struct($T: typeid) where intrinsics.type_is_pointer(T), intrinsics.type_is_subtype_of(T, ^Object) { + using _: FastEnumeration, +} + + +@(objc_type=FastEnumeration, objc_name="alloc", objc_is_class_method=true) +FastEnumeration_alloc :: proc() -> ^FastEnumeration { + return msgSend(^FastEnumeration, FastEnumeration, "alloc") +} + +@(objc_type=FastEnumeration, objc_name="init") +FastEnumeration_init :: proc(self: ^FastEnumeration) -> ^FastEnumeration { + return msgSend(^FastEnumeration, self, "init") +} + + +@(objc_type=FastEnumeration, objc_name="countByEnumerating") +FastEnumeration_countByEnumerating :: proc(self: ^FastEnumeration, state: ^FastEnumerationState, buffer: [^]^Object, len: UInteger) -> UInteger { + return msgSend(UInteger, self, "countByEnumeratingWithState:objects:count:", state, buffer, len) +} + +Enumerator_nextObject :: proc(self: ^$E/Enumerator($T)) -> T { + return msgSend(T, self, "nextObject") +} + +Enumerator_allObjects :: proc(self: ^$E/Enumerator($T)) -> (all: ^Array) { + return msgSend(type_of(all), self, "allObjects") +} + +Enumerator_iterator :: proc(self: ^$E/Enumerator($T)) -> (obj: T, ok: bool) { + obj = msgSend(T, self, "nextObject") + ok = obj != nil + return +} diff --git a/vendor/darwin/Foundation/NSError.odin b/vendor/darwin/Foundation/NSError.odin new file mode 100644 index 000000000..23e6eaba7 --- /dev/null +++ b/vendor/darwin/Foundation/NSError.odin @@ -0,0 +1,88 @@ +package objc_Foundation + +foreign import "system:Foundation.framework" + +ErrorDomain :: ^String + +foreign Foundation { + @(linkage="weak") CocoaErrorDomain: ErrorDomain + @(linkage="weak") POSIXErrorDomain: ErrorDomain + @(linkage="weak") OSStatusErrorDomain: ErrorDomain + @(linkage="weak") MachErrorDomain: ErrorDomain +} + +ErrorUserInfoKey :: ^String + +foreign Foundation { + @(linkage="weak") UnderlyingErrorKey: ErrorUserInfoKey + @(linkage="weak") LocalizedDescriptionKey: ErrorUserInfoKey + @(linkage="weak") LocalizedFailureReasonErrorKey: ErrorUserInfoKey + @(linkage="weak") LocalizedRecoverySuggestionErrorKey: ErrorUserInfoKey + @(linkage="weak") LocalizedRecoveryOptionsErrorKey: ErrorUserInfoKey + @(linkage="weak") RecoveryAttempterErrorKey: ErrorUserInfoKey + @(linkage="weak") HelpAnchorErrorKey: ErrorUserInfoKey + @(linkage="weak") DebugDescriptionErrorKey: ErrorUserInfoKey + @(linkage="weak") LocalizedFailureErrorKey: ErrorUserInfoKey + @(linkage="weak") StringEncodingErrorKey: ErrorUserInfoKey + @(linkage="weak") URLErrorKey: ErrorUserInfoKey + @(linkage="weak") FilePathErrorKey: ErrorUserInfoKey +} + +@(objc_class="NSError") +Error :: struct { using _: Copying(Error) } + + +@(objc_type=Error, objc_name="alloc", objc_is_class_method=true) +Error_alloc :: proc() -> ^Error { + return msgSend(^Error, Error, "alloc") +} + +@(objc_type=Error, objc_name="init") +Error_init :: proc(self: ^Error) -> ^Error { + return msgSend(^Error, self, "init") +} + +@(objc_type=Error, objc_name="errorWithDomain", objc_is_class_method=true) +Error_errorWithDomain :: proc(domain: ErrorDomain, code: Integer, userInfo: ^Dictionary) -> ^Error { + return msgSend(^Error, Error, "errorWithDomain:code:userInfo:", domain, code, userInfo) +} + +@(objc_type=Error, objc_name="initWithDomain") +Error_initWithDomain :: proc(self: ^Error, domain: ErrorDomain, code: Integer, userInfo: ^Dictionary) -> ^Error { + return msgSend(^Error, self, "initWithDomain:code:userInfo:", domain, code, userInfo) +} + +@(objc_type=Error, objc_name="code") +Error_code :: proc(self: ^Error) -> Integer { + return msgSend(Integer, self, "code") +} + +@(objc_type=Error, objc_name="domain") +Error_domain :: proc(self: ^Error) -> ErrorDomain { + return msgSend(ErrorDomain, self, "domain") +} + +@(objc_type=Error, objc_name="userInfo") +Error_userInfo :: proc(self: ^Error) -> ^Dictionary { + return msgSend(^Dictionary, self, "userInfo") +} + +@(objc_type=Error, objc_name="localizedDescription") +Error_localizedDescription :: proc(self: ^Error) -> ^String { + return msgSend(^String, self, "localizedDescription") +} + +@(objc_type=Error, objc_name="localizedRecoveryOptions") +Error_localizedRecoveryOptions :: proc(self: ^Error) -> (options: ^Array) { + return msgSend(type_of(options), self, "localizedRecoveryOptions") +} + +@(objc_type=Error, objc_name="localizedRecoverySuggestion") +Error_localizedRecoverySuggestion :: proc(self: ^Error) -> ^String { + return msgSend(^String, self, "localizedRecoverySuggestion") +} + +@(objc_type=Error, objc_name="localizedFailureReason") +Error_localizedFailureReason :: proc(self: ^Error) -> ^String { + return msgSend(^String, self, "localizedFailureReason") +} \ No newline at end of file diff --git a/vendor/darwin/Foundation/NSLock.odin b/vendor/darwin/Foundation/NSLock.odin new file mode 100644 index 000000000..c48b5dbad --- /dev/null +++ b/vendor/darwin/Foundation/NSLock.odin @@ -0,0 +1,53 @@ +package objc_Foundation + +Locking :: struct($T: typeid) {using _: Object} + +Locking_lock :: proc(self: ^Locking($T)) { + msgSend(nil, self, "lock") +} +Locking_unlock :: proc(self: ^Locking($T)) { + msgSend(nil, self, "unlock") +} + +@(objc_class="NSCondition") +Condition :: struct {using _: Locking(Condition) } + + +@(objc_type=Condition, objc_name="alloc", objc_is_class_method=true) +Condition_alloc :: proc() -> ^Condition { + return msgSend(^Condition, Condition, "alloc") +} + +@(objc_type=Condition, objc_name="init") +Condition_init :: proc(self: ^Condition) -> ^Condition { + return msgSend(^Condition, self, "init") +} + +@(objc_type=Condition, objc_name="wait") +Condition_wait :: proc(self: ^Condition) { + msgSend(nil, self, "wait") +} + +@(objc_type=Condition, objc_name="waitUntilDate") +Condition_waitUntilDate :: proc(self: ^Condition, limit: ^Date) -> BOOL { + return msgSend(BOOL, self, "waitUntilDate:", limit) +} + +@(objc_type=Condition, objc_name="signal") +Condition_signal :: proc(self: ^Condition) { + msgSend(nil, self, "signal") +} + +@(objc_type=Condition, objc_name="broadcast") +Condition_broadcast :: proc(self: ^Condition) { + msgSend(nil, self, "broadcast") +} + +@(objc_type=Condition, objc_name="lock") +Condition_lock :: proc(self: ^Condition) { + msgSend(nil, self, "lock") +} +@(objc_type=Condition, objc_name="unlock") +Condition_unlock :: proc(self: ^Condition) { + msgSend(nil, self, "unlock") +} \ No newline at end of file diff --git a/vendor/darwin/Foundation/NSMenu.odin b/vendor/darwin/Foundation/NSMenu.odin new file mode 100644 index 000000000..964e3061d --- /dev/null +++ b/vendor/darwin/Foundation/NSMenu.odin @@ -0,0 +1,103 @@ +package objc_Foundation + +import "core:builtin" +import "core:intrinsics" + +KeyEquivalentModifierFlag :: enum UInteger { + CapsLock = 16, // Set if Caps Lock key is pressed. + Shift = 17, // Set if Shift key is pressed. + Control = 18, // Set if Control key is pressed. + Option = 19, // Set if Option or Alternate key is pressed. + Command = 20, // Set if Command key is pressed. + NumericPad = 21, // Set if any key in the numeric keypad is pressed. + Help = 22, // Set if the Help key is pressed. + Function = 23, // Set if any function key is pressed. +} +KeyEquivalentModifierMask :: distinct bit_set[KeyEquivalentModifierFlag; UInteger] + +// Used to retrieve only the device-independent modifier flags, allowing applications to mask off the device-dependent modifier flags, including event coalescing information. +KeyEventModifierFlagDeviceIndependentFlagsMask := transmute(KeyEquivalentModifierMask)_KeyEventModifierFlagDeviceIndependentFlagsMask +@(private) _KeyEventModifierFlagDeviceIndependentFlagsMask := UInteger(0xffff0000) + + +MenuItemCallback :: proc "c" (unused: rawptr, name: SEL, sender: ^Object) + + +@(objc_class="NSMenuItem") +MenuItem :: struct {using _: Object} + +@(objc_type=MenuItem, objc_name="alloc", objc_is_class_method=true) +MenuItem_alloc :: proc() -> ^MenuItem { + return msgSend(^MenuItem, MenuItem, "alloc") +} +@(objc_type=MenuItem, objc_name="registerActionCallback", objc_is_class_method=true) +MenuItem_registerActionCallback :: proc(name: cstring, callback: MenuItemCallback) -> SEL { + s := string(name) + n := len(s) + sel: SEL + if n > 0 && s[n-1] != ':' { + col_name := intrinsics.alloca(n+2, 1) + builtin.copy(col_name[:n], s) + col_name[n] = ':' + col_name[n+1] = 0 + sel = sel_registerName(cstring(col_name)) + } else { + sel = sel_registerName(name) + } + if callback != nil { + class_addMethod(intrinsics.objc_find_class("NSObject"), sel, auto_cast callback, "v@:@") + } + return sel +} + +@(objc_type=MenuItem, objc_name="init") +MenuItem_init :: proc(self: ^MenuItem) -> ^MenuItem { + return msgSend(^MenuItem, self, "init") +} + +@(objc_type=MenuItem, objc_name="setKeyEquivalentModifierMask") +MenuItem_setKeyEquivalentModifierMask :: proc(self: ^MenuItem, modifierMask: KeyEquivalentModifierMask) { + msgSend(nil, self, "setKeyEquivalentModifierMask:", modifierMask) +} + +@(objc_type=MenuItem, objc_name="keyEquivalentModifierMask") +MenuItem_keyEquivalentModifierMask :: proc(self: ^MenuItem) -> KeyEquivalentModifierMask { + return msgSend(KeyEquivalentModifierMask, self, "keyEquivalentModifierMask") +} + +@(objc_type=MenuItem, objc_name="setSubmenu") +MenuItem_setSubmenu :: proc(self: ^MenuItem, submenu: ^Menu) { + msgSend(nil, self, "setSubmenu:", submenu) +} + + + + +@(objc_class="NSMenu") +Menu :: struct {using _: Object} + +@(objc_type=Menu, objc_name="alloc", objc_is_class_method=true) +Menu_alloc :: proc() -> ^Menu { + return msgSend(^Menu, Menu, "alloc") +} + +@(objc_type=Menu, objc_name="init") +Menu_init :: proc(self: ^Menu) -> ^Menu { + return msgSend(^Menu, self, "init") +} + +@(objc_type=Menu, objc_name="initWithTitle") +Menu_initWithTitle :: proc(self: ^Menu, title: ^String) -> ^Menu { + return msgSend(^Menu, self, "initWithTitle:", title) +} + + +@(objc_type=Menu, objc_name="addItem") +Menu_addItem :: proc(self: ^Menu, item: ^MenuItem) { + msgSend(nil, self, "addItem:", item) +} + +@(objc_type=Menu, objc_name="addItemWithTitle") +Menu_addItemWithTitle :: proc(self: ^Menu, title: ^String, selector: SEL, keyEquivalent: ^String) -> ^MenuItem { + return msgSend(^MenuItem, self, "addItemWithTitle:action:keyEquivalent:", title, selector, keyEquivalent) +} \ No newline at end of file diff --git a/vendor/darwin/Foundation/NSNotification.odin b/vendor/darwin/Foundation/NSNotification.odin new file mode 100644 index 000000000..ec8dddab7 --- /dev/null +++ b/vendor/darwin/Foundation/NSNotification.odin @@ -0,0 +1,30 @@ +package objc_Foundation + +@(objc_class="NSNotification") +Notification :: struct{using _: Object} + + +@(objc_type=Notification, objc_name="alloc", objc_is_class_method=true) +Notification_alloc :: proc() -> ^Notification { + return msgSend(^Notification, Notification, "alloc") +} + +@(objc_type=Notification, objc_name="init") +Notification_init :: proc(self: ^Notification) -> ^Notification { + return msgSend(^Notification, self, "init") +} + +@(objc_type=Notification, objc_name="name") +Notification_name :: proc(self: ^Notification) -> ^String { + return msgSend(^String, self, "name") +} + +@(objc_type=Notification, objc_name="object") +Notification_object :: proc(self: ^Notification) -> ^Object { + return msgSend(^Object, self, "object") +} + +@(objc_type=Notification, objc_name="userInfo") +Notification_userInfo :: proc(self: ^Notification) -> ^Dictionary { + return msgSend(^Dictionary, self, "userInfo") +} \ No newline at end of file diff --git a/vendor/darwin/Foundation/NSNumber.odin b/vendor/darwin/Foundation/NSNumber.odin new file mode 100644 index 000000000..d459e673f --- /dev/null +++ b/vendor/darwin/Foundation/NSNumber.odin @@ -0,0 +1,154 @@ +package objc_Foundation + +when ODIN_OS == .Darwin { + import "core:c" + _ :: c + + #assert(size_of(c.long) == size_of(int)) + #assert(size_of(c.ulong) == size_of(uint)) +} + +@(objc_class="NSValue") +Value :: struct{using _: Copying(Value)} + +@(objc_type=Value, objc_name="alloc", objc_is_class_method=true) +Value_alloc :: proc() -> ^Value { + return msgSend(^Value, Value, "alloc") +} + +@(objc_type=Value, objc_name="init") +Value_init :: proc(self: ^Value) -> ^Value { + return msgSend(^Value, self, "init") +} + +@(objc_type=Value, objc_name="valueWithBytes", objc_is_class_method=true) +Value_valueWithBytes :: proc(value: rawptr, type: cstring) -> ^Value { + return msgSend(^Value, Value, "valueWithBytes:objCType:", value, type) +} + +@(objc_type=Value, objc_name="valueWithPointer", objc_is_class_method=true) +Value_valueWithPointer :: proc(pointer: rawptr) -> ^Value { + return msgSend(^Value, Value, "valueWithPointer:", pointer) +} + +@(objc_type=Value, objc_name="initWithBytes") +Value_initWithBytes :: proc(self: ^Value, value: rawptr, type: cstring) -> ^Value { + return msgSend(^Value, self, "initWithBytes:objCType:", value, type) +} + +@(objc_type=Value, objc_name="initWithCoder") +Value_initWithCoder :: proc(self: ^Value, coder: ^Coder) -> ^Value { + return msgSend(^Value, self, "initWithCoder:", coder) +} + +@(objc_type=Value, objc_name="getValue") +Value_getValue :: proc(self: ^Value, value: rawptr, size: UInteger) { + msgSend(nil, self, "getValue:size:", value, size) +} + + +@(objc_type=Value, objc_name="objCType") +Value_objCType :: proc "c" (self: ^Value) -> cstring { + return msgSend(cstring, self, "objCType") +} + +@(objc_type=Value, objc_name="isEqualToValue") +Value_isEqualToValue :: proc "c" (self, other: ^Value) -> BOOL { + return msgSend(BOOL, self, "isEqualToValue:", other) +} + +@(objc_type=Value, objc_name="pointerValue") +Value_pointerValue :: proc "c" (self: ^Value) -> rawptr { + return msgSend(rawptr, self, "pointerValue") +} + + +@(objc_class="NSNumber") +Number :: struct{using _: Copying(Number), using _: Value} + +@(objc_type=Number, objc_name="alloc", objc_is_class_method=true) +Number_alloc :: proc() -> ^Number { + return msgSend(^Number, Number, "alloc") +} + +@(objc_type=Number, objc_name="init") +Number_init :: proc(self: ^Number) -> ^Number { + return msgSend(^Number, self, "init") +} + +@(objc_type=Number, objc_name="numberWithI8", objc_is_class_method=true) Number_numberWithI8 :: proc(value: i8) -> ^Number { return msgSend(^Number, Number, "numberWithChar:", value) } +@(objc_type=Number, objc_name="numberWithU8", objc_is_class_method=true) Number_numberWithU8 :: proc(value: u8) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedChar:", value) } +@(objc_type=Number, objc_name="numberWithI16", objc_is_class_method=true) Number_numberWithI16 :: proc(value: i16) -> ^Number { return msgSend(^Number, Number, "numberWithShort:", value) } +@(objc_type=Number, objc_name="numberWithU16", objc_is_class_method=true) Number_numberWithU16 :: proc(value: u16) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedShort:", value) } +@(objc_type=Number, objc_name="numberWithI32", objc_is_class_method=true) Number_numberWithI32 :: proc(value: i32) -> ^Number { return msgSend(^Number, Number, "numberWithInt:", value) } +@(objc_type=Number, objc_name="numberWithU32", objc_is_class_method=true) Number_numberWithU32 :: proc(value: u32) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedInt:", value) } +@(objc_type=Number, objc_name="numberWithInt", objc_is_class_method=true) Number_numberWithInt :: proc(value: int) -> ^Number { return msgSend(^Number, Number, "numberWithLong:", value) } +@(objc_type=Number, objc_name="numberWithUint", objc_is_class_method=true) Number_numberWithUint :: proc(value: uint) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedLong:", value) } +@(objc_type=Number, objc_name="numberWithU64", objc_is_class_method=true) Number_numberWithU64 :: proc(value: u64) -> ^Number { return msgSend(^Number, Number, "numberWithLongLong:", value) } +@(objc_type=Number, objc_name="numberWithI64", objc_is_class_method=true) Number_numberWithI64 :: proc(value: i64) -> ^Number { return msgSend(^Number, Number, "numberWithUnsignedLongLong:", value) } +@(objc_type=Number, objc_name="numberWithF32", objc_is_class_method=true) Number_numberWithF32 :: proc(value: f32) -> ^Number { return msgSend(^Number, Number, "numberWithFloat:", value) } +@(objc_type=Number, objc_name="numberWithF64", objc_is_class_method=true) Number_numberWithF64 :: proc(value: f64) -> ^Number { return msgSend(^Number, Number, "numberWithDouble:", value) } +@(objc_type=Number, objc_name="numberWithBool", objc_is_class_method=true) Number_numberWithBool :: proc(value: BOOL) -> ^Number { return msgSend(^Number, Number, "numberWithBool:", value) } + +Number_number :: proc{ + Number_numberWithI8, + Number_numberWithU8, + Number_numberWithI16, + Number_numberWithU16, + Number_numberWithI32, + Number_numberWithU32, + Number_numberWithInt, + Number_numberWithUint, + Number_numberWithU64, + Number_numberWithI64, + Number_numberWithF32, + Number_numberWithF64, + Number_numberWithBool, +} + +@(objc_type=Number, objc_name="initWithI8") Number_initWithI8 :: proc(self: ^Number, value: i8) -> ^Number { return msgSend(^Number, self, "initWithChar:", value) } +@(objc_type=Number, objc_name="initWithU8") Number_initWithU8 :: proc(self: ^Number, value: u8) -> ^Number { return msgSend(^Number, self, "initWithUnsignedChar:", value) } +@(objc_type=Number, objc_name="initWithI16") Number_initWithI16 :: proc(self: ^Number, value: i16) -> ^Number { return msgSend(^Number, self, "initWithShort:", value) } +@(objc_type=Number, objc_name="initWithU16") Number_initWithU16 :: proc(self: ^Number, value: u16) -> ^Number { return msgSend(^Number, self, "initWithUnsignedShort:", value) } +@(objc_type=Number, objc_name="initWithI32") Number_initWithI32 :: proc(self: ^Number, value: i32) -> ^Number { return msgSend(^Number, self, "initWithInt:", value) } +@(objc_type=Number, objc_name="initWithU32") Number_initWithU32 :: proc(self: ^Number, value: u32) -> ^Number { return msgSend(^Number, self, "initWithUnsignedInt:", value) } +@(objc_type=Number, objc_name="initWithInt") Number_initWithInt :: proc(self: ^Number, value: int) -> ^Number { return msgSend(^Number, self, "initWithLong:", value) } +@(objc_type=Number, objc_name="initWithUint") Number_initWithUint :: proc(self: ^Number, value: uint) -> ^Number { return msgSend(^Number, self, "initWithUnsignedLong:", value) } +@(objc_type=Number, objc_name="initWithU64") Number_initWithU64 :: proc(self: ^Number, value: u64) -> ^Number { return msgSend(^Number, self, "initWithLongLong:", value) } +@(objc_type=Number, objc_name="initWithI64") Number_initWithI64 :: proc(self: ^Number, value: i64) -> ^Number { return msgSend(^Number, self, "initWithUnsignedLongLong:", value) } +@(objc_type=Number, objc_name="initWithF32") Number_initWithF32 :: proc(self: ^Number, value: f32) -> ^Number { return msgSend(^Number, self, "initWithFloat:", value) } +@(objc_type=Number, objc_name="initWithF64") Number_initWithF64 :: proc(self: ^Number, value: f64) -> ^Number { return msgSend(^Number, self, "initWithDouble:", value) } +@(objc_type=Number, objc_name="initWithBool") Number_initWithBool :: proc(self: ^Number, value: BOOL) -> ^Number { return msgSend(^Number, self, "initWithBool:", value) } + + +@(objc_type=Number, objc_name="i8Value") Number_i8Value :: proc(self: ^Number) -> i8 { return msgSend(i8, self, "charValue") } +@(objc_type=Number, objc_name="u8Value") Number_u8Value :: proc(self: ^Number) -> u8 { return msgSend(u8, self, "unsignedCharValue") } +@(objc_type=Number, objc_name="i16Value") Number_i16Value :: proc(self: ^Number) -> i16 { return msgSend(i16, self, "shortValue") } +@(objc_type=Number, objc_name="u16Value") Number_u16Value :: proc(self: ^Number) -> u16 { return msgSend(u16, self, "unsignedShortValue") } +@(objc_type=Number, objc_name="i32Value") Number_i32Value :: proc(self: ^Number) -> i32 { return msgSend(i32, self, "intValue") } +@(objc_type=Number, objc_name="u32Value") Number_u32Value :: proc(self: ^Number) -> u32 { return msgSend(u32, self, "unsignedIntValue") } +@(objc_type=Number, objc_name="intValue") Number_intValue :: proc(self: ^Number) -> int { return msgSend(int, self, "longValue") } +@(objc_type=Number, objc_name="uintValue") Number_uintValue :: proc(self: ^Number) -> uint { return msgSend(uint, self, "unsignedLongValue") } +@(objc_type=Number, objc_name="u64Value") Number_u64Value :: proc(self: ^Number) -> u64 { return msgSend(u64, self, "longLongValue") } +@(objc_type=Number, objc_name="i64Value") Number_i64Value :: proc(self: ^Number) -> i64 { return msgSend(i64, self, "unsignedLongLongValue") } +@(objc_type=Number, objc_name="f32Value") Number_f32Value :: proc(self: ^Number) -> f32 { return msgSend(f32, self, "floatValue") } +@(objc_type=Number, objc_name="f64Value") Number_f64Value :: proc(self: ^Number) -> f64 { return msgSend(f64, self, "doubleValue") } +@(objc_type=Number, objc_name="boolValue") Number_boolValue :: proc(self: ^Number) -> BOOL { return msgSend(BOOL, self, "boolValue") } +@(objc_type=Number, objc_name="integerValue") Number_integerValue :: proc(self: ^Number) -> Integer { return msgSend(Integer, self, "integerValue") } +@(objc_type=Number, objc_name="uintegerValue") Number_uintegerValue :: proc(self: ^Number) -> UInteger { return msgSend(UInteger, self, "unsignedIntegerValue") } +@(objc_type=Number, objc_name="stringValue") Number_stringValue :: proc(self: ^Number) -> ^String { return msgSend(^String, self, "stringValue") } + +@(objc_type=Number, objc_name="compare") +Number_compare :: proc(self, other: ^Number) -> ComparisonResult { + return msgSend(ComparisonResult, self, "compare:", other) +} + +@(objc_type=Number, objc_name="isEqualToNumber") +Number_isEqualToNumber :: proc(self, other: ^Number) -> BOOL { + return msgSend(BOOL, self, "isEqualToNumber:", other) +} + +@(objc_type=Number, objc_name="descriptionWithLocale") +Number_descriptionWithLocale :: proc(self: ^Number, locale: ^Object) -> ^String { + return msgSend(^String, self, "descriptionWithLocale:", locale) +} \ No newline at end of file diff --git a/vendor/darwin/Foundation/NSObject.odin b/vendor/darwin/Foundation/NSObject.odin new file mode 100644 index 000000000..6ec5939ee --- /dev/null +++ b/vendor/darwin/Foundation/NSObject.odin @@ -0,0 +1,91 @@ +package objc_Foundation + +import "core:intrinsics" + +methodSignatureForSelector :: proc "c" (obj: ^Object, selector: SEL) -> rawptr { + return msgSend(rawptr, obj, "methodSignatureForSelector:", selector) +} + +respondsToSelector :: proc "c" (obj: ^Object, selector: SEL) -> BOOL { + return msgSend(BOOL, obj, "respondsToSelector:", selector) +} + +msgSendSafeCheck :: proc "c" (obj: ^Object, selector: SEL) -> BOOL { + return respondsToSelector(obj, selector) || methodSignatureForSelector(obj, selector) != nil +} + + +@(objc_class="NSObject") +Object :: struct {using _: intrinsics.objc_object} + +@(objc_class="NSObject") +Copying :: struct($T: typeid) {using _: Object} + +alloc :: proc($T: typeid) -> ^T where intrinsics.type_is_subtype_of(T, Object) { + return msgSend(^T, T, "alloc") +} +@(objc_type=Object, objc_name="init") +init :: proc(self: ^$T) -> ^T where intrinsics.type_is_subtype_of(T, Object) { + return msgSend(^T, self, "init") +} +@(objc_type=Object, objc_name="copy") +copy :: proc(self: ^Copying($T)) -> ^T where intrinsics.type_is_subtype_of(T, Object) { + return msgSend(^T, self, "copy") +} + +new :: proc($T: typeid) -> ^T where intrinsics.type_is_subtype_of(T, Object) { + return init(alloc(T)) +} + +@(objc_type=Object, objc_name="retain") +retain :: proc(self: ^Object) { + _ = msgSend(^Object, self, "retain") +} +@(objc_type=Object, objc_name="release") +release :: proc(self: ^Object) { + msgSend(nil, self, "release") +} +@(objc_type=Object, objc_name="autorelease") +autorelease :: proc(self: ^Object) { + msgSend(nil, self, "autorelease") +} +@(objc_type=Object, objc_name="retainCount") +retainCount :: proc(self: ^Object) -> UInteger { + return msgSend(UInteger, self, "retainCount") +} +@(objc_type=Object, objc_name="class") +class :: proc(self: ^Object) -> Class { + return msgSend(Class, self, "class") +} + +@(objc_type=Object, objc_name="hash") +hash :: proc(self: ^Object) -> UInteger { + return msgSend(UInteger, self, "hash") +} + +@(objc_type=Object, objc_name="isEqual") +isEqual :: proc(self, pObject: ^Object) -> BOOL { + return msgSend(BOOL, self, "isEqual:", pObject) +} + +@(objc_type=Object, objc_name="description") +description :: proc(self: ^Object) -> ^String { + return msgSend(^String, self, "description") +} + +@(objc_type=Object, objc_name="debugDescription") +debugDescription :: proc(self: ^Object) -> ^String { + if msgSendSafeCheck(self, intrinsics.objc_find_selector("debugDescription")) { + return msgSend(^String, self, "debugDescription") + } + return nil +} + +bridgingCast :: proc($T: typeid, obj: ^Object) where intrinsics.type_is_pointer(T), intrinsics.type_is_subtype_of(T, ^Object) { + return (T)(obj) +} + + +@(objc_class="NSCoder") +Coder :: struct {using _: Object} +// TODO(bill): Implement all the methods for this massive type \ No newline at end of file diff --git a/vendor/darwin/Foundation/NSRange.odin b/vendor/darwin/Foundation/NSRange.odin new file mode 100644 index 000000000..74ce595a3 --- /dev/null +++ b/vendor/darwin/Foundation/NSRange.odin @@ -0,0 +1,22 @@ +package objc_Foundation + +Range :: struct { + location: UInteger, + length: UInteger, +} + +Range_Make :: proc(loc, len: UInteger) -> Range { + return Range{loc, len} +} + +Range_Equal :: proc(a, b: Range) -> BOOL { + return a == b +} + +Range_LocationInRange :: proc(self: Range, loc: UInteger) -> BOOL { + return !((loc < self.location) && ((loc - self.location) < self.length)) +} + +Range_Max :: proc(self: Range) -> UInteger { + return self.location + self.length +} \ No newline at end of file diff --git a/vendor/darwin/Foundation/NSString.odin b/vendor/darwin/Foundation/NSString.odin new file mode 100644 index 000000000..18e392415 --- /dev/null +++ b/vendor/darwin/Foundation/NSString.odin @@ -0,0 +1,140 @@ +package objc_Foundation + +foreign import "system:Foundation.framework" + +@(objc_class="NSString") +String :: struct {using _: Copying(String)} + +StringEncoding :: enum UInteger { + ASCII = 1, + NEXTSTEP = 2, + JapaneseEUC = 3, + UTF8 = 4, + ISOLatin1 = 5, + Symbol = 6, + NonLossyASCII = 7, + ShiftJIS = 8, + ISOLatin2 = 9, + Unicode = 10, + WindowsCP1251 = 11, + WindowsCP1252 = 12, + WindowsCP1253 = 13, + WindowsCP1254 = 14, + WindowsCP1250 = 15, + ISO2022JP = 21, + MacOSRoman = 30, + + UTF16 = Unicode, + + UTF16BigEndian = 0x90000100, + UTF16LittleEndian = 0x94000100, + + UTF32 = 0x8c000100, + UTF32BigEndian = 0x98000100, + UTF32LittleEndian = 0x9c000100, +} + +StringCompareOptions :: distinct bit_set[StringCompareOption; UInteger] +StringCompareOption :: enum UInteger { + CaseInsensitive = 0, + LiteralSearch = 1, + BackwardsSearch = 2, + AnchoredSearch = 3, + NumericSearch = 6, + DiacriticInsensitive = 7, + WidthInsensitive = 8, + ForcedOrdering = 9, + RegularExpression = 10, +} + +unichar :: distinct u16 + +@(link_prefix="NS", default_calling_convention="c") +foreign Foundation { + StringFromClass :: proc(cls: Class) -> ^String --- +} + +AT :: MakeConstantString +MakeConstantString :: proc "c" (#const c: cstring) -> ^String { + foreign Foundation { + __CFStringMakeConstantString :: proc "c" (c: cstring) -> ^String --- + } + return __CFStringMakeConstantString(c) +} + + +@(objc_type=String, objc_name="alloc", objc_is_class_method=true) +String_alloc :: proc() -> ^String { + return msgSend(^String, String, "alloc") +} + +@(objc_type=String, objc_name="init") +String_init :: proc(self: ^String) -> ^String { + return msgSend(^String, self, "init") +} + + +@(objc_type=String, objc_name="initWithString") +String_initWithString :: proc(self: ^String, other: ^String) -> ^String { + return msgSend(^String, self, "initWithString:", other) +} + +@(objc_type=String, objc_name="initWithCString") +String_initWithCString :: proc(self: ^String, pString: cstring, encoding: StringEncoding) -> ^String { + return msgSend(^String, self, "initWithCstring:encoding:", pString, encoding) +} + +@(objc_type=String, objc_name="initWithBytesNoCopy") +String_initWithBytesNoCopy :: proc(self: ^String, pBytes: rawptr, length: UInteger, encoding: StringEncoding, freeWhenDone: bool) -> ^String { + return msgSend(^String, self, "initWithBytesNoCopy:length:encoding:freeWhenDone:", pBytes, length, encoding, freeWhenDone) +} + +@(objc_type=String, objc_name="initWithOdinString") +String_initWithOdinString :: proc(self: ^String, str: string) -> ^String { + return String_initWithBytesNoCopy(self, raw_data(str), UInteger(len(str)), .UTF8, false) +} + +@(objc_type=String, objc_name="characterAtIndex") +String_characterAtIndex :: proc(self: ^String, index: UInteger) -> unichar { + return msgSend(unichar, self, "characterAtIndex:", index) +} + +@(objc_type=String, objc_name="length") +String_length :: proc(self: ^String) -> UInteger { + return msgSend(UInteger, self, "length") +} + +@(objc_type=String, objc_name="cstringUsingEncoding") +String_cstringUsingEncoding :: proc(self: ^String, encoding: StringEncoding) -> cstring { + return msgSend(cstring, self, "cStringUsingEncoding:", encoding) +} + +@(objc_type=String, objc_name="UTF8String") +String_UTF8String :: proc(self: ^String) -> cstring { + return msgSend(cstring, self, "UTF8String") +} + +@(objc_type=String, objc_name="odinString") +String_odinString :: proc(self: ^String) -> string { + return string(String_UTF8String(self)) +} + +@(objc_type=String, objc_name="maximumLengthOfBytesUsingEncoding") +String_maximumLengthOfBytesUsingEncoding :: proc(self: ^String, encoding: StringEncoding) -> UInteger { + return msgSend(UInteger, self, "maximumLengthOfBytesUsingEncoding:", encoding) +} + +@(objc_type=String, objc_name="lengthOfBytesUsingEncoding") +String_lengthOfBytesUsingEncoding :: proc(self: ^String, encoding: StringEncoding) -> UInteger { + return msgSend(UInteger, self, "lengthOfBytesUsingEncoding:", encoding) +} + +@(objc_type=String, objc_name="isEqualToString") +String_isEqualToString :: proc(self, other: ^String) -> BOOL { + return msgSend(BOOL, self, "isEqualToString:", other) +} + +@(objc_type=String, objc_name="rangeOfString") +String_rangeOfString :: proc(self, other: ^String, options: StringCompareOptions) -> Range { + return msgSend(Range, self, "rangeOfString:options:", other, options) +} \ No newline at end of file diff --git a/vendor/darwin/Foundation/NSTypes.odin b/vendor/darwin/Foundation/NSTypes.odin new file mode 100644 index 000000000..ef895d449 --- /dev/null +++ b/vendor/darwin/Foundation/NSTypes.odin @@ -0,0 +1,42 @@ +package objc_Foundation + +import "core:intrinsics" + +@(private) msgSend :: intrinsics.objc_send + +id :: ^intrinsics.objc_object +SEL :: ^intrinsics.objc_selector +Class :: ^intrinsics.objc_class + +TimeInterval :: distinct f64 +Integer :: distinct int +UInteger :: distinct uint + +IntegerMax :: max(Integer) +Integermin :: min(Integer) +UIntegerMax :: max(UInteger) + +BOOL :: bool // TODO(bill): should this be `distinct`? +YES :: true +NO :: false + +OperatingSystemVersion :: struct #packed { + majorVersion: Integer, + minorVersion: Integer, + patchVersion: Integer, +} + +ComparisonResult :: enum Integer { + OrderedAscending = -1, + OrderedSame = 0, + OrderedDescending = 1, +} + +NotFound :: IntegerMax + +Float :: distinct (f32 when size_of(uint) == 4 else f64) + +Size :: struct { + width: Float, + height: Float, +} \ No newline at end of file diff --git a/vendor/darwin/Foundation/NSURL.odin b/vendor/darwin/Foundation/NSURL.odin new file mode 100644 index 000000000..72e5fc906 --- /dev/null +++ b/vendor/darwin/Foundation/NSURL.odin @@ -0,0 +1,30 @@ +package objc_Foundation + +@(objc_class="NSURL") +URL :: struct{using _: Copying(URL)} + + +@(objc_type=URL, objc_name="alloc", objc_is_class_method=true) +URL_alloc :: proc() -> ^URL { + return msgSend(^URL, URL, "alloc") +} + +@(objc_type=URL, objc_name="init") +URL_init :: proc(self: ^URL) -> ^URL { + return msgSend(^URL, self, "init") +} + +@(objc_type=URL, objc_name="initWithString") +URL_initWithString :: proc(self: ^URL, value: ^String) -> ^URL { + return msgSend(^URL, self, "initWithString:", value) +} + +@(objc_type=URL, objc_name="initFileURLWithPath") +URL_initFileURLWithPath :: proc(self: ^URL, path: ^String) -> ^URL { + return msgSend(^URL, self, "initFileURLWithPath:", path) +} + +@(objc_type=URL, objc_name="fileSystemRepresentation") +URL_fileSystemRepresentation :: proc(self: ^URL) -> ^String { + return msgSend(^String, self, "fileSystemRepresentation") +} \ No newline at end of file diff --git a/vendor/darwin/Foundation/NSWindow.odin b/vendor/darwin/Foundation/NSWindow.odin new file mode 100644 index 000000000..3c7c17023 --- /dev/null +++ b/vendor/darwin/Foundation/NSWindow.odin @@ -0,0 +1,151 @@ +package objc_Foundation + +import NS "vendor:darwin/Foundation" + +Rect :: struct { + x, y: f64, + width, height: f64, +} + +WindowStyleFlag :: enum NS.UInteger { + Titled = 0, + Closable = 1, + Miniaturizable = 2, + Resizable = 3, + TexturedBackground = 8, + UnifiedTitleAndToolbar = 12, + FullScreen = 14, + FullSizeContentView = 15, + UtilityWindow = 4, + DocModalWindow = 6, + NonactivatingPanel = 7, + HUDWindow = 13, +} +WindowStyleMask :: distinct bit_set[WindowStyleFlag; NS.UInteger] +WindowStyleMaskBorderless :: WindowStyleMask{} +WindowStyleMaskTitled :: WindowStyleMask{.Titled} +WindowStyleMaskClosable :: WindowStyleMask{.Closable} +WindowStyleMaskMiniaturizable :: WindowStyleMask{.Miniaturizable} +WindowStyleMaskResizable :: WindowStyleMask{.Resizable} +WindowStyleMaskTexturedBackground :: WindowStyleMask{.TexturedBackground} +WindowStyleMaskUnifiedTitleAndToolbar :: WindowStyleMask{.UnifiedTitleAndToolbar} +WindowStyleMaskFullScreen :: WindowStyleMask{.FullScreen} +WindowStyleMaskFullSizeContentView :: WindowStyleMask{.FullSizeContentView} +WindowStyleMaskUtilityWindow :: WindowStyleMask{.UtilityWindow} +WindowStyleMaskDocModalWindow :: WindowStyleMask{.DocModalWindow} +WindowStyleMaskNonactivatingPanel :: WindowStyleMask{.NonactivatingPanel} +WindowStyleMaskHUDWindow :: WindowStyleMask{.HUDWindow} + +BackingStoreType :: enum NS.UInteger { + Retained = 0, + Nonretained = 1, + Buffered = 2, +} + +@(objc_class="NSColor") +Color :: struct {using _: Object} + +@(objc_class="CALayer") +Layer :: struct { using _: NS.Object } + +@(objc_type=Layer, objc_name="contentsScale") +Layer_contentsScale :: proc(self: ^Layer) -> Float { + return msgSend(Float, self, "contentsScale") +} +@(objc_type=Layer, objc_name="setContentsScale") +Layer_setContentsScale :: proc(self: ^Layer, scale: Float) { + msgSend(nil, self, "setContentsScale:", scale) +} +@(objc_type=Layer, objc_name="frame") +Layer_frame :: proc(self: ^Layer) -> Rect { + return msgSend(Rect, self, "frame") +} +@(objc_type=Layer, objc_name="addSublayer") +Layer_addSublayer :: proc(self: ^Layer, layer: ^Layer) { + msgSend(nil, self, "addSublayer:", layer) +} + +@(objc_class="NSResponder") +Responder :: struct {using _: Object} + +@(objc_class="NSView") +View :: struct {using _: Responder} + + +@(objc_type=View, objc_name="initWithFrame") +View_initWithFrame :: proc(self: ^View, frame: Rect) -> ^View { + return msgSend(^View, self, "initWithFrame:", frame) +} +@(objc_type=View, objc_name="layer") +View_layer :: proc(self: ^View) -> ^Layer { + return msgSend(^Layer, self, "layer") +} +@(objc_type=View, objc_name="setLayer") +View_setLayer :: proc(self: ^View, layer: ^Layer) { + msgSend(nil, self, "setLayer:", layer) +} +@(objc_type=View, objc_name="wantsLayer") +View_wantsLayer :: proc(self: ^View) -> BOOL { + return msgSend(BOOL, self, "wantsLayer") +} +@(objc_type=View, objc_name="setWantsLayer") +View_setWantsLayer :: proc(self: ^View, wantsLayer: BOOL) { + msgSend(nil, self, "setWantsLayer:", wantsLayer) +} + +@(objc_class="NSWindow") +Window :: struct {using _: Responder} + +@(objc_type=Window, objc_name="alloc", objc_is_class_method=true) +Window_alloc :: proc() -> ^Window { + return msgSend(^Window, Window, "alloc") +} + +@(objc_type=Window, objc_name="initWithContentRect") +Window_initWithContentRect :: proc(self: ^Window, contentRect: Rect, styleMask: WindowStyleMask, backing: BackingStoreType, doDefer: bool) -> ^Window { + return msgSend(^Window, self, "initWithContentRect:styleMask:backing:defer:", contentRect, styleMask, backing, doDefer) +} +@(objc_type=Window, objc_name="contentView") +Window_contentView :: proc(self: ^Window) -> ^View { + return msgSend(^View, self, "contentView") +} +@(objc_type=Window, objc_name="setContentView") +Window_setContentView :: proc(self: ^Window, content_view: ^View) { + msgSend(nil, self, "setContentView:", content_view) +} +@(objc_type=Window, objc_name="frame") +Window_frame :: proc(self: ^Window) -> Rect { + return msgSend(Rect, self, "frame") +} +@(objc_type=Window, objc_name="setFrame") +Window_setFrame :: proc(self: ^Window, frame: Rect) { + msgSend(nil, self, "setFrame:", frame) +} +@(objc_type=Window, objc_name="opaque") +Window_opaque :: proc(self: ^Window) -> NS.BOOL { + return msgSend(NS.BOOL, self, "opaque") +} +@(objc_type=Window, objc_name="setOpaque") +Window_setOpaque :: proc(self: ^Window, ok: NS.BOOL) { + msgSend(nil, self, "setOpaque:", ok) +} +@(objc_type=Window, objc_name="backgroundColor") +Window_backgroundColor :: proc(self: ^Window) -> ^NS.Color { + return msgSend(^NS.Color, self, "backgroundColor") +} +@(objc_type=Window, objc_name="setBackgroundColor") +Window_setBackgroundColor :: proc(self: ^Window, color: ^NS.Color) { + msgSend(nil, self, "setBackgroundColor:", color) +} +@(objc_type=Window, objc_name="makeKeyAndOrderFront") +Window_makeKeyAndOrderFront :: proc(self: ^Window, key: ^NS.Object) { + msgSend(nil, self, "makeKeyAndOrderFront:", key) +} +@(objc_type=Window, objc_name="setTitle") +Window_setTitle :: proc(self: ^Window, title: ^NS.String) { + msgSend(nil, self, "setTitle:", title) +} +@(objc_type=Window, objc_name="close") +Window_close :: proc(self: ^Window) { + msgSend(nil, self, "close") +} \ No newline at end of file diff --git a/vendor/darwin/Foundation/objc.odin b/vendor/darwin/Foundation/objc.odin new file mode 100644 index 000000000..7db82df73 --- /dev/null +++ b/vendor/darwin/Foundation/objc.odin @@ -0,0 +1,73 @@ +package objc_Foundation + +foreign import "system:Foundation.framework" + +import "core:intrinsics" +import "core:c" + +IMP :: proc "c" (object: id, sel: SEL, #c_vararg args: ..any) -> id + +foreign Foundation { + objc_lookUpClass :: proc "c" (name: cstring) -> Class --- + sel_registerName :: proc "c" (name: cstring) -> SEL --- + objc_allocateClassPair :: proc "c" (superclass: Class, name: cstring, extraBytes: uint) --- + + class_addMethod :: proc "c" (cls: Class, name: SEL, imp: IMP, types: cstring) -> BOOL --- +} + + +@(objc_class="NSZone") +Zone :: struct {using _: Object} + +@(link_prefix="NS") +foreign Foundation { + AllocateObject :: proc "c" (aClass: Class, extraBytes: UInteger, zone: ^Zone) -> id --- + DeallocateObject :: proc "c" (object: id) --- +} + +Method :: ^objc_method +objc_method :: struct { + method_name: SEL, + method_types: cstring, + method_imp: IMP, +} +objc_method_list :: struct {} + +objc_ivar :: struct {} +objc_ivar_list :: struct {} + +objc_cache :: struct { + mask: u32, + occupied: u32, + buckets: [1]Method, +} + +objc_protocol_list :: struct { + next: ^objc_protocol_list, + count: c.int, + list: [1]^Protocol, +} + +@(objc_class="Protocol") +Protocol :: struct{using _: intrinsics.objc_object} + +objc_object_internals :: struct { + isa: ^objc_class_internals, +} + + +objc_class_internals :: struct { + isa: Class, + super_class: Class, + name: cstring, + version: c.long, + info: c.long, + instance_size: c.long, + ivars: ^objc_ivar_list, + + methodLists: ^^objc_method_list, + + cache: rawptr, + protocols: rawptr, + +} \ No newline at end of file diff --git a/vendor/darwin/Metal/MetalClasses.odin b/vendor/darwin/Metal/MetalClasses.odin new file mode 100644 index 000000000..075aae545 --- /dev/null +++ b/vendor/darwin/Metal/MetalClasses.odin @@ -0,0 +1,8561 @@ +package objc_Metal + +import NS "vendor:darwin/Foundation" +import "core:mem" +_ :: mem + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + AccelerationStructureBoundingBoxGeometryDescriptor +Class Methods: + alloc + descriptor +Methods: + init + boundingBoxBuffer + boundingBoxBufferOffset + boundingBoxCount + boundingBoxStride + setBoundingBoxBuffer + setBoundingBoxBufferOffset + setBoundingBoxCount + setBoundingBoxStride +*/ +@(objc_class="MTLAccelerationStructureBoundingBoxGeometryDescriptor") +AccelerationStructureBoundingBoxGeometryDescriptor :: struct { using _: NS.Copying(AccelerationStructureBoundingBoxGeometryDescriptor), using _: AccelerationStructureDescriptor } + +@(objc_type=AccelerationStructureBoundingBoxGeometryDescriptor, objc_name="alloc", objc_is_class_method=true) +AccelerationStructureBoundingBoxGeometryDescriptor_alloc :: #force_inline proc() -> ^AccelerationStructureBoundingBoxGeometryDescriptor { + return msgSend(^AccelerationStructureBoundingBoxGeometryDescriptor, AccelerationStructureBoundingBoxGeometryDescriptor, "alloc") +} +@(objc_type=AccelerationStructureBoundingBoxGeometryDescriptor, objc_name="init") +AccelerationStructureBoundingBoxGeometryDescriptor_init :: #force_inline proc(self: ^AccelerationStructureBoundingBoxGeometryDescriptor) -> ^AccelerationStructureBoundingBoxGeometryDescriptor { + return msgSend(^AccelerationStructureBoundingBoxGeometryDescriptor, self, "init") +} +@(objc_type=AccelerationStructureBoundingBoxGeometryDescriptor, objc_name="boundingBoxBuffer") +AccelerationStructureBoundingBoxGeometryDescriptor_boundingBoxBuffer :: #force_inline proc(self: ^AccelerationStructureBoundingBoxGeometryDescriptor) -> ^Buffer { + return msgSend(^Buffer, self, "boundingBoxBuffer") +} +@(objc_type=AccelerationStructureBoundingBoxGeometryDescriptor, objc_name="boundingBoxBufferOffset") +AccelerationStructureBoundingBoxGeometryDescriptor_boundingBoxBufferOffset :: #force_inline proc(self: ^AccelerationStructureBoundingBoxGeometryDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "boundingBoxBufferOffset") +} +@(objc_type=AccelerationStructureBoundingBoxGeometryDescriptor, objc_name="boundingBoxCount") +AccelerationStructureBoundingBoxGeometryDescriptor_boundingBoxCount :: #force_inline proc(self: ^AccelerationStructureBoundingBoxGeometryDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "boundingBoxCount") +} +@(objc_type=AccelerationStructureBoundingBoxGeometryDescriptor, objc_name="boundingBoxStride") +AccelerationStructureBoundingBoxGeometryDescriptor_boundingBoxStride :: #force_inline proc(self: ^AccelerationStructureBoundingBoxGeometryDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "boundingBoxStride") +} +@(objc_type=AccelerationStructureBoundingBoxGeometryDescriptor, objc_name="descriptor", objc_is_class_method=true) +AccelerationStructureBoundingBoxGeometryDescriptor_descriptor :: #force_inline proc() -> ^AccelerationStructureBoundingBoxGeometryDescriptor { + return msgSend(^AccelerationStructureBoundingBoxGeometryDescriptor, AccelerationStructureBoundingBoxGeometryDescriptor, "descriptor") +} +@(objc_type=AccelerationStructureBoundingBoxGeometryDescriptor, objc_name="setBoundingBoxBuffer") +AccelerationStructureBoundingBoxGeometryDescriptor_setBoundingBoxBuffer :: #force_inline proc(self: ^AccelerationStructureBoundingBoxGeometryDescriptor, boundingBoxBuffer: ^Buffer) { + msgSend(nil, self, "setBoundingBoxBuffer:", boundingBoxBuffer) +} +@(objc_type=AccelerationStructureBoundingBoxGeometryDescriptor, objc_name="setBoundingBoxBufferOffset") +AccelerationStructureBoundingBoxGeometryDescriptor_setBoundingBoxBufferOffset :: #force_inline proc(self: ^AccelerationStructureBoundingBoxGeometryDescriptor, boundingBoxBufferOffset: NS.UInteger) { + msgSend(nil, self, "setBoundingBoxBufferOffset:", boundingBoxBufferOffset) +} +@(objc_type=AccelerationStructureBoundingBoxGeometryDescriptor, objc_name="setBoundingBoxCount") +AccelerationStructureBoundingBoxGeometryDescriptor_setBoundingBoxCount :: #force_inline proc(self: ^AccelerationStructureBoundingBoxGeometryDescriptor, boundingBoxCount: NS.UInteger) { + msgSend(nil, self, "setBoundingBoxCount:", boundingBoxCount) +} +@(objc_type=AccelerationStructureBoundingBoxGeometryDescriptor, objc_name="setBoundingBoxStride") +AccelerationStructureBoundingBoxGeometryDescriptor_setBoundingBoxStride :: #force_inline proc(self: ^AccelerationStructureBoundingBoxGeometryDescriptor, boundingBoxStride: NS.UInteger) { + msgSend(nil, self, "setBoundingBoxStride:", boundingBoxStride) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + MotionKeyframeData +Class Methods: + alloc + data +Methods: + init + buffer + setBuffer + offset + setOffset +*/ + +@(objc_class="MTLMotionKeyframeData") +MotionKeyframeData :: struct { using _: NS.Object } + +@(objc_type=MotionKeyframeData, objc_name="alloc", objc_is_class_method=true) +MotionKeyframeData_alloc :: #force_inline proc() -> ^MotionKeyframeData { + return msgSend(^MotionKeyframeData, MotionKeyframeData, "alloc") +} +@(objc_type=MotionKeyframeData, objc_name="data", objc_is_class_method=true) +MotionKeyframeData_data :: #force_inline proc() -> ^MotionKeyframeData { + return msgSend(^MotionKeyframeData, MotionKeyframeData, "data") +} +@(objc_type=MotionKeyframeData, objc_name="init", objc_is_class_method=true) +MotionKeyframeData_init :: #force_inline proc(self: ^MotionKeyframeData) -> ^MotionKeyframeData { + return msgSend(^MotionKeyframeData, self, "init") +} +@(objc_type=MotionKeyframeData, objc_name="buffer", objc_is_class_method=true) +MotionKeyframeData_buffer :: #force_inline proc(self: ^MotionKeyframeData) -> ^Buffer { + return msgSend(^Buffer, self, "buffer") +} +@(objc_type=MotionKeyframeData, objc_name="setBuffer", objc_is_class_method=true) +MotionKeyframeData_setBuffer :: #force_inline proc(self: ^MotionKeyframeData, buffer: ^Buffer) { + msgSend(nil, self, "setBuffer:", buffer) +} +@(objc_type=MotionKeyframeData, objc_name="offset", objc_is_class_method=true) +MotionKeyframeData_offset :: #force_inline proc(self: ^MotionKeyframeData) -> NS.UInteger { + return msgSend(NS.UInteger, self, "offset") +} +@(objc_type=MotionKeyframeData, objc_name="setOffset", objc_is_class_method=true) +MotionKeyframeData_setOffset :: #force_inline proc(self: ^MotionKeyframeData, offset: NS.UInteger) { + msgSend(nil, self, "setOffset:", offset) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + AccelerationStructureMotionTriangleGeometryDescriptor +*/ + +@(objc_class="MTLAccelerationStructureMotionTriangleGeometryDescriptor") +AccelerationStructureMotionTriangleGeometryDescriptor :: struct { using _: NS.Copying(AccelerationStructureMotionTriangleGeometryDescriptor), using _: AccelerationStructureGeometryDescriptor } + +@(objc_type=AccelerationStructureMotionTriangleGeometryDescriptor, objc_name="alloc", objc_is_class_method=true) +AccelerationStructureMotionTriangleGeometryDescriptor_alloc :: #force_inline proc() -> ^AccelerationStructureMotionTriangleGeometryDescriptor { + return msgSend(^AccelerationStructureMotionTriangleGeometryDescriptor, AccelerationStructureMotionTriangleGeometryDescriptor, "alloc") +} +@(objc_type=AccelerationStructureMotionTriangleGeometryDescriptor, objc_name="init") +AccelerationStructureMotionTriangleGeometryDescriptor_init :: #force_inline proc(self: ^AccelerationStructureMotionTriangleGeometryDescriptor) -> ^AccelerationStructureMotionTriangleGeometryDescriptor { + return msgSend(^AccelerationStructureMotionTriangleGeometryDescriptor, self, "init") +} + +@(objc_type=AccelerationStructureMotionTriangleGeometryDescriptor, objc_name="vertexBuffers") +AccelerationStructureMotionTriangleGeometryDescriptor_vertexBuffers :: #force_inline proc(self: ^AccelerationStructureMotionTriangleGeometryDescriptor) -> ^NS.Array { + return msgSend(^NS.Array, self, "vertexBuffers") +} +@(objc_type=AccelerationStructureMotionTriangleGeometryDescriptor, objc_name="setVertexBuffers") +AccelerationStructureMotionTriangleGeometryDescriptor_setVertexBuffers :: #force_inline proc(self: ^AccelerationStructureMotionTriangleGeometryDescriptor, buffers: ^NS.Array) { + msgSend(nil, self, "setVertexBuffers:", buffers) +} + +@(objc_type=AccelerationStructureMotionTriangleGeometryDescriptor, objc_name="vertexStride") +AccelerationStructureMotionTriangleGeometryDescriptor_vertexStride :: #force_inline proc(self: ^AccelerationStructureMotionTriangleGeometryDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "vertexStride") +} +@(objc_type=AccelerationStructureMotionTriangleGeometryDescriptor, objc_name="setVertexStride") +AccelerationStructureMotionTriangleGeometryDescriptor_setVertexStride :: #force_inline proc(self: ^AccelerationStructureMotionTriangleGeometryDescriptor, stride: NS.UInteger) { + msgSend(nil, self, "setVertexStride:", stride) +} + + +@(objc_type=AccelerationStructureMotionTriangleGeometryDescriptor, objc_name="indexBuffer") +AccelerationStructureMotionTriangleGeometryDescriptor_indexBuffer :: #force_inline proc(self: ^AccelerationStructureMotionTriangleGeometryDescriptor) -> ^Buffer { + return msgSend(^Buffer, self, "indexBuffer") +} +@(objc_type=AccelerationStructureMotionTriangleGeometryDescriptor, objc_name="setIndexBuffer") +AccelerationStructureMotionTriangleGeometryDescriptor_setIndexBuffer :: #force_inline proc(self: ^AccelerationStructureMotionTriangleGeometryDescriptor, buffer: ^Buffer) { + msgSend(nil, self, "setIndexBuffer:", buffer) +} + + +@(objc_type=AccelerationStructureMotionTriangleGeometryDescriptor, objc_name="indexBufferOffset") +AccelerationStructureMotionTriangleGeometryDescriptor_indexBufferOffset :: #force_inline proc(self: ^AccelerationStructureMotionTriangleGeometryDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "indexBufferOffset") +} +@(objc_type=AccelerationStructureMotionTriangleGeometryDescriptor, objc_name="setIndexBufferOffset") +AccelerationStructureMotionTriangleGeometryDescriptor_setIndexBufferOffset :: #force_inline proc(self: ^AccelerationStructureMotionTriangleGeometryDescriptor, offset: NS.UInteger) { + msgSend(nil, self, "setIndexBufferOffset:", offset) +} + +@(objc_type=AccelerationStructureMotionTriangleGeometryDescriptor, objc_name="indexType") +AccelerationStructureMotionTriangleGeometryDescriptor_indexType :: #force_inline proc(self: ^AccelerationStructureMotionTriangleGeometryDescriptor) -> IndexType { + return msgSend(IndexType, self, "indexType") +} +@(objc_type=AccelerationStructureMotionTriangleGeometryDescriptor, objc_name="setIndexType") +AccelerationStructureMotionTriangleGeometryDescriptor_setIndexType :: #force_inline proc(self: ^AccelerationStructureMotionTriangleGeometryDescriptor, indexType: IndexType) { + msgSend(nil, self, "setIndexType:", indexType) +} + +@(objc_type=AccelerationStructureMotionTriangleGeometryDescriptor, objc_name="triangleCount") +AccelerationStructureMotionTriangleGeometryDescriptor_triangleCount :: #force_inline proc(self: ^AccelerationStructureMotionTriangleGeometryDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "triangleCount") +} +@(objc_type=AccelerationStructureMotionTriangleGeometryDescriptor, objc_name="setTriangleCount") +AccelerationStructureMotionTriangleGeometryDescriptor_setTriangleCount :: #force_inline proc(self: ^AccelerationStructureMotionTriangleGeometryDescriptor, count: NS.UInteger) { + msgSend(nil, self, "setTriangleCount:", count) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + AccelerationStructureMotionBoundingBoxGeometryDescriptor +*/ + +@(objc_class="MTLAccelerationStructureMotionBoundingBoxGeometryDescriptor") +AccelerationStructureMotionBoundingBoxGeometryDescriptor :: struct { using _: NS.Copying(AccelerationStructureMotionBoundingBoxGeometryDescriptor), using _: AccelerationStructureGeometryDescriptor } + +@(objc_type=AccelerationStructureMotionBoundingBoxGeometryDescriptor, objc_name="alloc", objc_is_class_method=true) +AccelerationStructureMotionBoundingBoxGeometryDescriptor_alloc :: #force_inline proc() -> ^AccelerationStructureMotionBoundingBoxGeometryDescriptor { + return msgSend(^AccelerationStructureMotionBoundingBoxGeometryDescriptor, AccelerationStructureMotionBoundingBoxGeometryDescriptor, "alloc") +} +@(objc_type=AccelerationStructureMotionBoundingBoxGeometryDescriptor, objc_name="init") +AccelerationStructureMotionBoundingBoxGeometryDescriptor_init :: #force_inline proc(self: ^AccelerationStructureMotionBoundingBoxGeometryDescriptor) -> ^AccelerationStructureMotionBoundingBoxGeometryDescriptor { + return msgSend(^AccelerationStructureMotionBoundingBoxGeometryDescriptor, self, "init") +} + +@(objc_type=AccelerationStructureMotionBoundingBoxGeometryDescriptor, objc_name="descriptor", objc_is_class_method=true) +AccelerationStructureMotionBoundingBoxGeometryDescriptor_descriptor :: #force_inline proc() -> ^AccelerationStructureMotionBoundingBoxGeometryDescriptor { + return msgSend(^AccelerationStructureMotionBoundingBoxGeometryDescriptor, AccelerationStructureMotionBoundingBoxGeometryDescriptor, "descriptor") +} + +@(objc_type=AccelerationStructureMotionBoundingBoxGeometryDescriptor, objc_name="boundingBoxBuffers") +AccelerationStructureMotionBoundingBoxGeometryDescriptor_boundingBoxBuffers :: #force_inline proc(self: ^AccelerationStructureMotionBoundingBoxGeometryDescriptor) -> ^NS.Array { + return msgSend(^NS.Array, self, "boundingBoxBuffers") +} +@(objc_type=AccelerationStructureMotionBoundingBoxGeometryDescriptor, objc_name="setBoundBoxBuffers") +AccelerationStructureMotionBoundingBoxGeometryDescriptor_setBoundBoxBuffers :: #force_inline proc(self: ^AccelerationStructureMotionBoundingBoxGeometryDescriptor, buffers: ^NS.Array) { + msgSend(nil, self, "setBoundBoxBuffers:", buffers) +} + +@(objc_type=AccelerationStructureMotionBoundingBoxGeometryDescriptor, objc_name="boundingBoxStride") +AccelerationStructureMotionBoundingBoxGeometryDescriptor_boundingBoxStride :: #force_inline proc(self: ^AccelerationStructureMotionBoundingBoxGeometryDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "boundingBoxStride") +} +@(objc_type=AccelerationStructureMotionBoundingBoxGeometryDescriptor, objc_name="setBoundingBoxStride") +AccelerationStructureMotionBoundingBoxGeometryDescriptor_setBoundingBoxStride :: #force_inline proc(self: ^AccelerationStructureMotionBoundingBoxGeometryDescriptor, stride: NS.UInteger) { + msgSend(nil, self, "setBoundingBoxStride:", stride) +} + +@(objc_type=AccelerationStructureMotionBoundingBoxGeometryDescriptor, objc_name="boundingBoxCount") +AccelerationStructureMotionBoundingBoxGeometryDescriptor_boundingBoxCount :: #force_inline proc(self: ^AccelerationStructureMotionBoundingBoxGeometryDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "boundingBoxCount") +} +@(objc_type=AccelerationStructureMotionBoundingBoxGeometryDescriptor, objc_name="setBoundingBoxCount") +AccelerationStructureMotionBoundingBoxGeometryDescriptor_setBoundingBoxCount :: #force_inline proc(self: ^AccelerationStructureMotionBoundingBoxGeometryDescriptor, offset: NS.UInteger) { + msgSend(nil, self, "setBoundingBoxCount:", offset) +} + + + + + + + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + AccelerationStructureDescriptor +Class Methods: + alloc +Methods: + init + setUsage + usage +*/ +@(objc_class="MTLAccelerationStructureDescriptor") +AccelerationStructureDescriptor :: struct { using _: NS.Copying(AccelerationStructureDescriptor) } + +@(objc_type=AccelerationStructureDescriptor, objc_name="alloc", objc_is_class_method=true) +AccelerationStructureDescriptor_alloc :: #force_inline proc() -> ^AccelerationStructureDescriptor { + return msgSend(^AccelerationStructureDescriptor, AccelerationStructureDescriptor, "alloc") +} +@(objc_type=AccelerationStructureDescriptor, objc_name="init") +AccelerationStructureDescriptor_init :: #force_inline proc(self: ^AccelerationStructureDescriptor) -> ^AccelerationStructureDescriptor { + return msgSend(^AccelerationStructureDescriptor, self, "init") +} +@(objc_type=AccelerationStructureDescriptor, objc_name="setUsage") +AccelerationStructureDescriptor_setUsage :: #force_inline proc(self: ^AccelerationStructureDescriptor, usage: AccelerationStructureUsage) { + msgSend(nil, self, "setUsage:", usage) +} +@(objc_type=AccelerationStructureDescriptor, objc_name="usage") +AccelerationStructureDescriptor_usage :: #force_inline proc(self: ^AccelerationStructureDescriptor) -> AccelerationStructureUsage { + return msgSend(AccelerationStructureUsage, self, "usage") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + AccelerationStructureGeometryDescriptor +Class Methods: + alloc +Methods: + init + allowDuplicateIntersectionFunctionInvocation + intersectionFunctionTableOffset + opaque + setAllowDuplicateIntersectionFunctionInvocation + setIntersectionFunctionTableOffset + setOpaque +*/ +@(objc_class="MTLAccelerationStructureGeometryDescriptor") +AccelerationStructureGeometryDescriptor :: struct { using _: NS.Copying(AccelerationStructureGeometryDescriptor) } + +@(objc_type=AccelerationStructureGeometryDescriptor, objc_name="alloc", objc_is_class_method=true) +AccelerationStructureGeometryDescriptor_alloc :: #force_inline proc() -> ^AccelerationStructureGeometryDescriptor { + return msgSend(^AccelerationStructureGeometryDescriptor, AccelerationStructureGeometryDescriptor, "alloc") +} +@(objc_type=AccelerationStructureGeometryDescriptor, objc_name="init") +AccelerationStructureGeometryDescriptor_init :: #force_inline proc(self: ^AccelerationStructureGeometryDescriptor) -> ^AccelerationStructureGeometryDescriptor { + return msgSend(^AccelerationStructureGeometryDescriptor, self, "init") +} +@(objc_type=AccelerationStructureGeometryDescriptor, objc_name="allowDuplicateIntersectionFunctionInvocation") +AccelerationStructureGeometryDescriptor_allowDuplicateIntersectionFunctionInvocation :: #force_inline proc(self: ^AccelerationStructureGeometryDescriptor) -> BOOL { + return msgSend(BOOL, self, "allowDuplicateIntersectionFunctionInvocation") +} +@(objc_type=AccelerationStructureGeometryDescriptor, objc_name="intersectionFunctionTableOffset") +AccelerationStructureGeometryDescriptor_intersectionFunctionTableOffset :: #force_inline proc(self: ^AccelerationStructureGeometryDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "intersectionFunctionTableOffset") +} +@(objc_type=AccelerationStructureGeometryDescriptor, objc_name="opaque") +AccelerationStructureGeometryDescriptor_opaque :: #force_inline proc(self: ^AccelerationStructureGeometryDescriptor) -> BOOL { + return msgSend(BOOL, self, "opaque") +} +@(objc_type=AccelerationStructureGeometryDescriptor, objc_name="setAllowDuplicateIntersectionFunctionInvocation") +AccelerationStructureGeometryDescriptor_setAllowDuplicateIntersectionFunctionInvocation :: #force_inline proc(self: ^AccelerationStructureGeometryDescriptor, allowDuplicateIntersectionFunctionInvocation: BOOL) { + msgSend(nil, self, "setAllowDuplicateIntersectionFunctionInvocation:", allowDuplicateIntersectionFunctionInvocation) +} +@(objc_type=AccelerationStructureGeometryDescriptor, objc_name="setIntersectionFunctionTableOffset") +AccelerationStructureGeometryDescriptor_setIntersectionFunctionTableOffset :: #force_inline proc(self: ^AccelerationStructureGeometryDescriptor, intersectionFunctionTableOffset: NS.UInteger) { + msgSend(nil, self, "setIntersectionFunctionTableOffset:", intersectionFunctionTableOffset) +} +@(objc_type=AccelerationStructureGeometryDescriptor, objc_name="setOpaque") +AccelerationStructureGeometryDescriptor_setOpaque :: #force_inline proc(self: ^AccelerationStructureGeometryDescriptor, opaque: BOOL) { + msgSend(nil, self, "setOpaque:", opaque) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + AccelerationStructureTriangleGeometryDescriptor +Class Methods: + alloc + descriptor +Methods: + init + indexBuffer + indexBufferOffset + indexType + setIndexBuffer + setIndexBufferOffset + setIndexType + setTriangleCount + setVertexBuffer + setVertexBufferOffset + setVertexStride + triangleCount + vertexBuffer + vertexBufferOffset + vertexStride +*/ +@(objc_class="MTLAccelerationStructureTriangleGeometryDescriptor") +AccelerationStructureTriangleGeometryDescriptor :: struct { using _: NS.Copying(AccelerationStructureTriangleGeometryDescriptor), using _: AccelerationStructureDescriptor } + +@(objc_type=AccelerationStructureTriangleGeometryDescriptor, objc_name="alloc", objc_is_class_method=true) +AccelerationStructureTriangleGeometryDescriptor_alloc :: #force_inline proc() -> ^AccelerationStructureTriangleGeometryDescriptor { + return msgSend(^AccelerationStructureTriangleGeometryDescriptor, AccelerationStructureTriangleGeometryDescriptor, "alloc") +} +@(objc_type=AccelerationStructureTriangleGeometryDescriptor, objc_name="init") +AccelerationStructureTriangleGeometryDescriptor_init :: #force_inline proc(self: ^AccelerationStructureTriangleGeometryDescriptor) -> ^AccelerationStructureTriangleGeometryDescriptor { + return msgSend(^AccelerationStructureTriangleGeometryDescriptor, self, "init") +} +@(objc_type=AccelerationStructureTriangleGeometryDescriptor, objc_name="descriptor", objc_is_class_method=true) +AccelerationStructureTriangleGeometryDescriptor_descriptor :: #force_inline proc() -> ^AccelerationStructureTriangleGeometryDescriptor { + return msgSend(^AccelerationStructureTriangleGeometryDescriptor, AccelerationStructureTriangleGeometryDescriptor, "descriptor") +} +@(objc_type=AccelerationStructureTriangleGeometryDescriptor, objc_name="indexBuffer") +AccelerationStructureTriangleGeometryDescriptor_indexBuffer :: #force_inline proc(self: ^AccelerationStructureTriangleGeometryDescriptor) -> ^Buffer { + return msgSend(^Buffer, self, "indexBuffer") +} +@(objc_type=AccelerationStructureTriangleGeometryDescriptor, objc_name="indexBufferOffset") +AccelerationStructureTriangleGeometryDescriptor_indexBufferOffset :: #force_inline proc(self: ^AccelerationStructureTriangleGeometryDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "indexBufferOffset") +} +@(objc_type=AccelerationStructureTriangleGeometryDescriptor, objc_name="indexType") +AccelerationStructureTriangleGeometryDescriptor_indexType :: #force_inline proc(self: ^AccelerationStructureTriangleGeometryDescriptor) -> IndexType { + return msgSend(IndexType, self, "indexType") +} +@(objc_type=AccelerationStructureTriangleGeometryDescriptor, objc_name="setIndexBuffer") +AccelerationStructureTriangleGeometryDescriptor_setIndexBuffer :: #force_inline proc(self: ^AccelerationStructureTriangleGeometryDescriptor, indexBuffer: ^Buffer) { + msgSend(nil, self, "setIndexBuffer:", indexBuffer) +} +@(objc_type=AccelerationStructureTriangleGeometryDescriptor, objc_name="setIndexBufferOffset") +AccelerationStructureTriangleGeometryDescriptor_setIndexBufferOffset :: #force_inline proc(self: ^AccelerationStructureTriangleGeometryDescriptor, indexBufferOffset: NS.UInteger) { + msgSend(nil, self, "setIndexBufferOffset:", indexBufferOffset) +} +@(objc_type=AccelerationStructureTriangleGeometryDescriptor, objc_name="setIndexType") +AccelerationStructureTriangleGeometryDescriptor_setIndexType :: #force_inline proc(self: ^AccelerationStructureTriangleGeometryDescriptor, indexType: IndexType) { + msgSend(nil, self, "setIndexType:", indexType) +} +@(objc_type=AccelerationStructureTriangleGeometryDescriptor, objc_name="setTriangleCount") +AccelerationStructureTriangleGeometryDescriptor_setTriangleCount :: #force_inline proc(self: ^AccelerationStructureTriangleGeometryDescriptor, triangleCount: NS.UInteger) { + msgSend(nil, self, "setTriangleCount:", triangleCount) +} +@(objc_type=AccelerationStructureTriangleGeometryDescriptor, objc_name="setVertexBuffer") +AccelerationStructureTriangleGeometryDescriptor_setVertexBuffer :: #force_inline proc(self: ^AccelerationStructureTriangleGeometryDescriptor, vertexBuffer: ^Buffer) { + msgSend(nil, self, "setVertexBuffer:", vertexBuffer) +} +@(objc_type=AccelerationStructureTriangleGeometryDescriptor, objc_name="setVertexBufferOffset") +AccelerationStructureTriangleGeometryDescriptor_setVertexBufferOffset :: #force_inline proc(self: ^AccelerationStructureTriangleGeometryDescriptor, vertexBufferOffset: NS.UInteger) { + msgSend(nil, self, "setVertexBufferOffset:", vertexBufferOffset) +} +@(objc_type=AccelerationStructureTriangleGeometryDescriptor, objc_name="setVertexStride") +AccelerationStructureTriangleGeometryDescriptor_setVertexStride :: #force_inline proc(self: ^AccelerationStructureTriangleGeometryDescriptor, vertexStride: NS.UInteger) { + msgSend(nil, self, "setVertexStride:", vertexStride) +} +@(objc_type=AccelerationStructureTriangleGeometryDescriptor, objc_name="triangleCount") +AccelerationStructureTriangleGeometryDescriptor_triangleCount :: #force_inline proc(self: ^AccelerationStructureTriangleGeometryDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "triangleCount") +} +@(objc_type=AccelerationStructureTriangleGeometryDescriptor, objc_name="vertexBuffer") +AccelerationStructureTriangleGeometryDescriptor_vertexBuffer :: #force_inline proc(self: ^AccelerationStructureTriangleGeometryDescriptor) -> ^Buffer { + return msgSend(^Buffer, self, "vertexBuffer") +} +@(objc_type=AccelerationStructureTriangleGeometryDescriptor, objc_name="vertexBufferOffset") +AccelerationStructureTriangleGeometryDescriptor_vertexBufferOffset :: #force_inline proc(self: ^AccelerationStructureTriangleGeometryDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "vertexBufferOffset") +} +@(objc_type=AccelerationStructureTriangleGeometryDescriptor, objc_name="vertexStride") +AccelerationStructureTriangleGeometryDescriptor_vertexStride :: #force_inline proc(self: ^AccelerationStructureTriangleGeometryDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "vertexStride") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + Argument +Class Methods: + alloc +Methods: + init + access + arrayLength + bufferAlignment + bufferDataSize + bufferDataType + bufferPointerType + bufferStructType + index + isActive + isDepthTexture + name + textureDataType + textureType + threadgroupMemoryAlignment + threadgroupMemoryDataSize + type +*/ +@(objc_class="MTLArgument") +Argument :: struct { using _: NS.Object } + +@(objc_type=Argument, objc_name="alloc", objc_is_class_method=true) +Argument_alloc :: #force_inline proc() -> ^Argument { + return msgSend(^Argument, Argument, "alloc") +} +@(objc_type=Argument, objc_name="init") +Argument_init :: #force_inline proc(self: ^Argument) -> ^Argument { + return msgSend(^Argument, self, "init") +} +@(objc_type=Argument, objc_name="access") +Argument_access :: #force_inline proc(self: ^Argument) -> ArgumentAccess { + return msgSend(ArgumentAccess, self, "access") +} +@(objc_type=Argument, objc_name="arrayLength") +Argument_arrayLength :: #force_inline proc(self: ^Argument) -> NS.UInteger { + return msgSend(NS.UInteger, self, "arrayLength") +} +@(objc_type=Argument, objc_name="bufferAlignment") +Argument_bufferAlignment :: #force_inline proc(self: ^Argument) -> NS.UInteger { + return msgSend(NS.UInteger, self, "bufferAlignment") +} +@(objc_type=Argument, objc_name="bufferDataSize") +Argument_bufferDataSize :: #force_inline proc(self: ^Argument) -> NS.UInteger { + return msgSend(NS.UInteger, self, "bufferDataSize") +} +@(objc_type=Argument, objc_name="bufferDataType") +Argument_bufferDataType :: #force_inline proc(self: ^Argument) -> DataType { + return msgSend(DataType, self, "bufferDataType") +} +@(objc_type=Argument, objc_name="bufferPointerType") +Argument_bufferPointerType :: #force_inline proc(self: ^Argument) -> ^PointerType { + return msgSend(^PointerType, self, "bufferPointerType") +} +@(objc_type=Argument, objc_name="bufferStructType") +Argument_bufferStructType :: #force_inline proc(self: ^Argument) -> ^StructType { + return msgSend(^StructType, self, "bufferStructType") +} +@(objc_type=Argument, objc_name="index") +Argument_index :: #force_inline proc(self: ^Argument) -> NS.UInteger { + return msgSend(NS.UInteger, self, "index") +} +@(objc_type=Argument, objc_name="isActive") +Argument_isActive :: #force_inline proc(self: ^Argument) -> BOOL { + return msgSend(BOOL, self, "isActive") +} +@(objc_type=Argument, objc_name="isDepthTexture") +Argument_isDepthTexture :: #force_inline proc(self: ^Argument) -> BOOL { + return msgSend(BOOL, self, "isDepthTexture") +} +@(objc_type=Argument, objc_name="name") +Argument_name :: #force_inline proc(self: ^Argument) -> ^NS.String { + return msgSend(^NS.String, self, "name") +} +@(objc_type=Argument, objc_name="textureDataType") +Argument_textureDataType :: #force_inline proc(self: ^Argument) -> DataType { + return msgSend(DataType, self, "textureDataType") +} +@(objc_type=Argument, objc_name="textureType") +Argument_textureType :: #force_inline proc(self: ^Argument) -> TextureType { + return msgSend(TextureType, self, "textureType") +} +@(objc_type=Argument, objc_name="threadgroupMemoryAlignment") +Argument_threadgroupMemoryAlignment :: #force_inline proc(self: ^Argument) -> NS.UInteger { + return msgSend(NS.UInteger, self, "threadgroupMemoryAlignment") +} +@(objc_type=Argument, objc_name="threadgroupMemoryDataSize") +Argument_threadgroupMemoryDataSize :: #force_inline proc(self: ^Argument) -> NS.UInteger { + return msgSend(NS.UInteger, self, "threadgroupMemoryDataSize") +} +@(objc_type=Argument, objc_name="type") +Argument_type :: #force_inline proc(self: ^Argument) -> ArgumentType { + return msgSend(ArgumentType, self, "type") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + ArgumentDescriptor +Class Methods: + alloc + argumentDescriptor +Methods: + init + access + arrayLength + constantBlockAlignment + dataType + index + setAccess + setArrayLength + setConstantBlockAlignment + setDataType + setIndex + setTextureType + textureType +*/ +@(objc_class="MTLArgumentDescriptor") +ArgumentDescriptor :: struct { using _: NS.Copying(ArgumentDescriptor) } + +@(objc_type=ArgumentDescriptor, objc_name="alloc", objc_is_class_method=true) +ArgumentDescriptor_alloc :: #force_inline proc() -> ^ArgumentDescriptor { + return msgSend(^ArgumentDescriptor, ArgumentDescriptor, "alloc") +} +@(objc_type=ArgumentDescriptor, objc_name="init") +ArgumentDescriptor_init :: #force_inline proc(self: ^ArgumentDescriptor) -> ^ArgumentDescriptor { + return msgSend(^ArgumentDescriptor, self, "init") +} +@(objc_type=ArgumentDescriptor, objc_name="access") +ArgumentDescriptor_access :: #force_inline proc(self: ^ArgumentDescriptor) -> ArgumentAccess { + return msgSend(ArgumentAccess, self, "access") +} +@(objc_type=ArgumentDescriptor, objc_name="argumentDescriptor", objc_is_class_method=true) +ArgumentDescriptor_argumentDescriptor :: #force_inline proc() -> ^ArgumentDescriptor { + return msgSend(^ArgumentDescriptor, ArgumentDescriptor, "argumentDescriptor") +} +@(objc_type=ArgumentDescriptor, objc_name="arrayLength") +ArgumentDescriptor_arrayLength :: #force_inline proc(self: ^ArgumentDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "arrayLength") +} +@(objc_type=ArgumentDescriptor, objc_name="constantBlockAlignment") +ArgumentDescriptor_constantBlockAlignment :: #force_inline proc(self: ^ArgumentDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "constantBlockAlignment") +} +@(objc_type=ArgumentDescriptor, objc_name="dataType") +ArgumentDescriptor_dataType :: #force_inline proc(self: ^ArgumentDescriptor) -> DataType { + return msgSend(DataType, self, "dataType") +} +@(objc_type=ArgumentDescriptor, objc_name="index") +ArgumentDescriptor_index :: #force_inline proc(self: ^ArgumentDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "index") +} +@(objc_type=ArgumentDescriptor, objc_name="setAccess") +ArgumentDescriptor_setAccess :: #force_inline proc(self: ^ArgumentDescriptor, access: ArgumentAccess) { + msgSend(nil, self, "setAccess:", access) +} +@(objc_type=ArgumentDescriptor, objc_name="setArrayLength") +ArgumentDescriptor_setArrayLength :: #force_inline proc(self: ^ArgumentDescriptor, arrayLength: NS.UInteger) { + msgSend(nil, self, "setArrayLength:", arrayLength) +} +@(objc_type=ArgumentDescriptor, objc_name="setConstantBlockAlignment") +ArgumentDescriptor_setConstantBlockAlignment :: #force_inline proc(self: ^ArgumentDescriptor, constantBlockAlignment: NS.UInteger) { + msgSend(nil, self, "setConstantBlockAlignment:", constantBlockAlignment) +} +@(objc_type=ArgumentDescriptor, objc_name="setDataType") +ArgumentDescriptor_setDataType :: #force_inline proc(self: ^ArgumentDescriptor, dataType: DataType) { + msgSend(nil, self, "setDataType:", dataType) +} +@(objc_type=ArgumentDescriptor, objc_name="setIndex") +ArgumentDescriptor_setIndex :: #force_inline proc(self: ^ArgumentDescriptor, index: NS.UInteger) { + msgSend(nil, self, "setIndex:", index) +} +@(objc_type=ArgumentDescriptor, objc_name="setTextureType") +ArgumentDescriptor_setTextureType :: #force_inline proc(self: ^ArgumentDescriptor, textureType: TextureType) { + msgSend(nil, self, "setTextureType:", textureType) +} +@(objc_type=ArgumentDescriptor, objc_name="textureType") +ArgumentDescriptor_textureType :: #force_inline proc(self: ^ArgumentDescriptor) -> TextureType { + return msgSend(TextureType, self, "textureType") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + ArrayType +Class Methods: + alloc +Methods: + init + argumentIndexStride + arrayLength + elementArrayType + elementPointerType + elementStructType + elementTextureReferenceType + elementType + stride +*/ +@(objc_class="MTLArrayType") +ArrayType :: struct { using _: Type } + +@(objc_type=ArrayType, objc_name="alloc", objc_is_class_method=true) +ArrayType_alloc :: #force_inline proc() -> ^ArrayType { + return msgSend(^ArrayType, ArrayType, "alloc") +} +@(objc_type=ArrayType, objc_name="init") +ArrayType_init :: #force_inline proc(self: ^ArrayType) -> ^ArrayType { + return msgSend(^ArrayType, self, "init") +} +@(objc_type=ArrayType, objc_name="argumentIndexStride") +ArrayType_argumentIndexStride :: #force_inline proc(self: ^ArrayType) -> NS.UInteger { + return msgSend(NS.UInteger, self, "argumentIndexStride") +} +@(objc_type=ArrayType, objc_name="arrayLength") +ArrayType_arrayLength :: #force_inline proc(self: ^ArrayType) -> NS.UInteger { + return msgSend(NS.UInteger, self, "arrayLength") +} +@(objc_type=ArrayType, objc_name="elementArrayType") +ArrayType_elementArrayType :: #force_inline proc(self: ^ArrayType) -> ^ArrayType { + return msgSend(^ArrayType, self, "elementArrayType") +} +@(objc_type=ArrayType, objc_name="elementPointerType") +ArrayType_elementPointerType :: #force_inline proc(self: ^ArrayType) -> ^PointerType { + return msgSend(^PointerType, self, "elementPointerType") +} +@(objc_type=ArrayType, objc_name="elementStructType") +ArrayType_elementStructType :: #force_inline proc(self: ^ArrayType) -> ^StructType { + return msgSend(^StructType, self, "elementStructType") +} +@(objc_type=ArrayType, objc_name="elementTextureReferenceType") +ArrayType_elementTextureReferenceType :: #force_inline proc(self: ^ArrayType) -> ^TextureReferenceType { + return msgSend(^TextureReferenceType, self, "elementTextureReferenceType") +} +@(objc_type=ArrayType, objc_name="elementType") +ArrayType_elementType :: #force_inline proc(self: ^ArrayType) -> DataType { + return msgSend(DataType, self, "elementType") +} +@(objc_type=ArrayType, objc_name="stride") +ArrayType_stride :: #force_inline proc(self: ^ArrayType) -> NS.UInteger { + return msgSend(NS.UInteger, self, "stride") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + Attribute +Class Methods: + alloc +Methods: + init + attributeIndex + attributeType + isActive + isPatchControlPointData + isPatchData + name +*/ +@(objc_class="MTLAttribute") +Attribute :: struct { using _: NS.Object } + +@(objc_type=Attribute, objc_name="alloc", objc_is_class_method=true) +Attribute_alloc :: #force_inline proc() -> ^Attribute { + return msgSend(^Attribute, Attribute, "alloc") +} +@(objc_type=Attribute, objc_name="init") +Attribute_init :: #force_inline proc(self: ^Attribute) -> ^Attribute { + return msgSend(^Attribute, self, "init") +} +@(objc_type=Attribute, objc_name="attributeIndex") +Attribute_attributeIndex :: #force_inline proc(self: ^Attribute) -> NS.UInteger { + return msgSend(NS.UInteger, self, "attributeIndex") +} +@(objc_type=Attribute, objc_name="attributeType") +Attribute_attributeType :: #force_inline proc(self: ^Attribute) -> DataType { + return msgSend(DataType, self, "attributeType") +} +@(objc_type=Attribute, objc_name="isActive") +Attribute_isActive :: #force_inline proc(self: ^Attribute) -> BOOL { + return msgSend(BOOL, self, "isActive") +} +@(objc_type=Attribute, objc_name="isPatchControlPointData") +Attribute_isPatchControlPointData :: #force_inline proc(self: ^Attribute) -> BOOL { + return msgSend(BOOL, self, "isPatchControlPointData") +} +@(objc_type=Attribute, objc_name="isPatchData") +Attribute_isPatchData :: #force_inline proc(self: ^Attribute) -> BOOL { + return msgSend(BOOL, self, "isPatchData") +} +@(objc_type=Attribute, objc_name="name") +Attribute_name :: #force_inline proc(self: ^Attribute) -> ^NS.String { + return msgSend(^NS.String, self, "name") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + AttributeDescriptor +Class Methods: + alloc +Methods: + init + bufferIndex + format + offset + setBufferIndex + setFormat + setOffset +*/ +@(objc_class="MTLAttributeDescriptor") +AttributeDescriptor :: struct { using _: NS.Copying(AttributeDescriptor) } + +@(objc_type=AttributeDescriptor, objc_name="alloc", objc_is_class_method=true) +AttributeDescriptor_alloc :: #force_inline proc() -> ^AttributeDescriptor { + return msgSend(^AttributeDescriptor, AttributeDescriptor, "alloc") +} +@(objc_type=AttributeDescriptor, objc_name="init") +AttributeDescriptor_init :: #force_inline proc(self: ^AttributeDescriptor) -> ^AttributeDescriptor { + return msgSend(^AttributeDescriptor, self, "init") +} +@(objc_type=AttributeDescriptor, objc_name="bufferIndex") +AttributeDescriptor_bufferIndex :: #force_inline proc(self: ^AttributeDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "bufferIndex") +} +@(objc_type=AttributeDescriptor, objc_name="format") +AttributeDescriptor_format :: #force_inline proc(self: ^AttributeDescriptor) -> AttributeFormat { + return msgSend(AttributeFormat, self, "format") +} +@(objc_type=AttributeDescriptor, objc_name="offset") +AttributeDescriptor_offset :: #force_inline proc(self: ^AttributeDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "offset") +} +@(objc_type=AttributeDescriptor, objc_name="setBufferIndex") +AttributeDescriptor_setBufferIndex :: #force_inline proc(self: ^AttributeDescriptor, bufferIndex: NS.UInteger) { + msgSend(nil, self, "setBufferIndex:", bufferIndex) +} +@(objc_type=AttributeDescriptor, objc_name="setFormat") +AttributeDescriptor_setFormat :: #force_inline proc(self: ^AttributeDescriptor, format: AttributeFormat) { + msgSend(nil, self, "setFormat:", format) +} +@(objc_type=AttributeDescriptor, objc_name="setOffset") +AttributeDescriptor_setOffset :: #force_inline proc(self: ^AttributeDescriptor, offset: NS.UInteger) { + msgSend(nil, self, "setOffset:", offset) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + AttributeDescriptorArray +Class Methods: + alloc +Methods: + init + objectAtIndexedSubscript + setObject +*/ +@(objc_class="MTLAttributeDescriptorArray") +AttributeDescriptorArray :: struct { using _: NS.Object } + +@(objc_type=AttributeDescriptorArray, objc_name="alloc", objc_is_class_method=true) +AttributeDescriptorArray_alloc :: #force_inline proc() -> ^AttributeDescriptorArray { + return msgSend(^AttributeDescriptorArray, AttributeDescriptorArray, "alloc") +} +@(objc_type=AttributeDescriptorArray, objc_name="init") +AttributeDescriptorArray_init :: #force_inline proc(self: ^AttributeDescriptorArray) -> ^AttributeDescriptorArray { + return msgSend(^AttributeDescriptorArray, self, "init") +} +@(objc_type=AttributeDescriptorArray, objc_name="object") +AttributeDescriptorArray_object :: #force_inline proc(self: ^AttributeDescriptorArray, index: NS.UInteger) -> ^AttributeDescriptor { + return msgSend(^AttributeDescriptor, self, "objectAtIndexedSubscript:", index) +} +@(objc_type=AttributeDescriptorArray, objc_name="setObject") +AttributeDescriptorArray_setObject :: #force_inline proc(self: ^AttributeDescriptorArray, attributeDesc: ^AttributeDescriptor, index: NS.UInteger) { + msgSend(nil, self, "setObject:atIndexedSubscript:", attributeDesc, index) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + BinaryArchiveDescriptor +Class Methods: + alloc +Methods: + init + setUrl + url +*/ +@(objc_class="MTLBinaryArchiveDescriptor") +BinaryArchiveDescriptor :: struct { using _: NS.Copying(BinaryArchiveDescriptor) } + +@(objc_type=BinaryArchiveDescriptor, objc_name="alloc", objc_is_class_method=true) +BinaryArchiveDescriptor_alloc :: #force_inline proc() -> ^BinaryArchiveDescriptor { + return msgSend(^BinaryArchiveDescriptor, BinaryArchiveDescriptor, "alloc") +} +@(objc_type=BinaryArchiveDescriptor, objc_name="init") +BinaryArchiveDescriptor_init :: #force_inline proc(self: ^BinaryArchiveDescriptor) -> ^BinaryArchiveDescriptor { + return msgSend(^BinaryArchiveDescriptor, self, "init") +} +@(objc_type=BinaryArchiveDescriptor, objc_name="setUrl") +BinaryArchiveDescriptor_setUrl :: #force_inline proc(self: ^BinaryArchiveDescriptor, url: ^NS.URL) { + msgSend(nil, self, "setUrl:", url) +} +@(objc_type=BinaryArchiveDescriptor, objc_name="url") +BinaryArchiveDescriptor_url :: #force_inline proc(self: ^BinaryArchiveDescriptor) -> ^NS.URL { + return msgSend(^NS.URL, self, "url") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + BlitPassDescriptor +Class Methods: + alloc + blitPassDescriptor +Methods: + init + sampleBufferAttachments +*/ +@(objc_class="MTLBlitPassDescriptor") +BlitPassDescriptor :: struct { using _: NS.Copying(BlitPassDescriptor) } + +@(objc_type=BlitPassDescriptor, objc_name="alloc", objc_is_class_method=true) +BlitPassDescriptor_alloc :: #force_inline proc() -> ^BlitPassDescriptor { + return msgSend(^BlitPassDescriptor, BlitPassDescriptor, "alloc") +} +@(objc_type=BlitPassDescriptor, objc_name="init") +BlitPassDescriptor_init :: #force_inline proc(self: ^BlitPassDescriptor) -> ^BlitPassDescriptor { + return msgSend(^BlitPassDescriptor, self, "init") +} +@(objc_type=BlitPassDescriptor, objc_name="blitPassDescriptor", objc_is_class_method=true) +BlitPassDescriptor_blitPassDescriptor :: #force_inline proc() -> ^BlitPassDescriptor { + return msgSend(^BlitPassDescriptor, BlitPassDescriptor, "blitPassDescriptor") +} +@(objc_type=BlitPassDescriptor, objc_name="sampleBufferAttachments") +BlitPassDescriptor_sampleBufferAttachments :: #force_inline proc(self: ^BlitPassDescriptor) -> ^BlitPassSampleBufferAttachmentDescriptorArray { + return msgSend(^BlitPassSampleBufferAttachmentDescriptorArray, self, "sampleBufferAttachments") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + BlitPassSampleBufferAttachmentDescriptor +Class Methods: + alloc +Methods: + init + endOfEncoderSampleIndex + sampleBuffer + setEndOfEncoderSampleIndex + setSampleBuffer + setStartOfEncoderSampleIndex + startOfEncoderSampleIndex +*/ +@(objc_class="MTLBlitPassSampleBufferAttachmentDescriptor") +BlitPassSampleBufferAttachmentDescriptor :: struct { using _: NS.Copying(BlitPassSampleBufferAttachmentDescriptor) } + +@(objc_type=BlitPassSampleBufferAttachmentDescriptor, objc_name="alloc", objc_is_class_method=true) +BlitPassSampleBufferAttachmentDescriptor_alloc :: #force_inline proc() -> ^BlitPassSampleBufferAttachmentDescriptor { + return msgSend(^BlitPassSampleBufferAttachmentDescriptor, BlitPassSampleBufferAttachmentDescriptor, "alloc") +} +@(objc_type=BlitPassSampleBufferAttachmentDescriptor, objc_name="init") +BlitPassSampleBufferAttachmentDescriptor_init :: #force_inline proc(self: ^BlitPassSampleBufferAttachmentDescriptor) -> ^BlitPassSampleBufferAttachmentDescriptor { + return msgSend(^BlitPassSampleBufferAttachmentDescriptor, self, "init") +} +@(objc_type=BlitPassSampleBufferAttachmentDescriptor, objc_name="endOfEncoderSampleIndex") +BlitPassSampleBufferAttachmentDescriptor_endOfEncoderSampleIndex :: #force_inline proc(self: ^BlitPassSampleBufferAttachmentDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "endOfEncoderSampleIndex") +} +@(objc_type=BlitPassSampleBufferAttachmentDescriptor, objc_name="sampleBuffer") +BlitPassSampleBufferAttachmentDescriptor_sampleBuffer :: #force_inline proc(self: ^BlitPassSampleBufferAttachmentDescriptor) -> ^CounterSampleBuffer { + return msgSend(^CounterSampleBuffer, self, "sampleBuffer") +} +@(objc_type=BlitPassSampleBufferAttachmentDescriptor, objc_name="setEndOfEncoderSampleIndex") +BlitPassSampleBufferAttachmentDescriptor_setEndOfEncoderSampleIndex :: #force_inline proc(self: ^BlitPassSampleBufferAttachmentDescriptor, endOfEncoderSampleIndex: NS.UInteger) { + msgSend(nil, self, "setEndOfEncoderSampleIndex:", endOfEncoderSampleIndex) +} +@(objc_type=BlitPassSampleBufferAttachmentDescriptor, objc_name="setSampleBuffer") +BlitPassSampleBufferAttachmentDescriptor_setSampleBuffer :: #force_inline proc(self: ^BlitPassSampleBufferAttachmentDescriptor, sampleBuffer: ^CounterSampleBuffer) { + msgSend(nil, self, "setSampleBuffer:", sampleBuffer) +} +@(objc_type=BlitPassSampleBufferAttachmentDescriptor, objc_name="setStartOfEncoderSampleIndex") +BlitPassSampleBufferAttachmentDescriptor_setStartOfEncoderSampleIndex :: #force_inline proc(self: ^BlitPassSampleBufferAttachmentDescriptor, startOfEncoderSampleIndex: NS.UInteger) { + msgSend(nil, self, "setStartOfEncoderSampleIndex:", startOfEncoderSampleIndex) +} +@(objc_type=BlitPassSampleBufferAttachmentDescriptor, objc_name="startOfEncoderSampleIndex") +BlitPassSampleBufferAttachmentDescriptor_startOfEncoderSampleIndex :: #force_inline proc(self: ^BlitPassSampleBufferAttachmentDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "startOfEncoderSampleIndex") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + BlitPassSampleBufferAttachmentDescriptorArray +Class Methods: + alloc +Methods: + init + objectAtIndexedSubscript + setObject +*/ +@(objc_class="MTLBlitPassSampleBufferAttachmentDescriptorArray") +BlitPassSampleBufferAttachmentDescriptorArray :: struct { using _: NS.Object } + +@(objc_type=BlitPassSampleBufferAttachmentDescriptorArray, objc_name="alloc", objc_is_class_method=true) +BlitPassSampleBufferAttachmentDescriptorArray_alloc :: #force_inline proc() -> ^BlitPassSampleBufferAttachmentDescriptorArray { + return msgSend(^BlitPassSampleBufferAttachmentDescriptorArray, BlitPassSampleBufferAttachmentDescriptorArray, "alloc") +} +@(objc_type=BlitPassSampleBufferAttachmentDescriptorArray, objc_name="init") +BlitPassSampleBufferAttachmentDescriptorArray_init :: #force_inline proc(self: ^BlitPassSampleBufferAttachmentDescriptorArray) -> ^BlitPassSampleBufferAttachmentDescriptorArray { + return msgSend(^BlitPassSampleBufferAttachmentDescriptorArray, self, "init") +} +@(objc_type=BlitPassSampleBufferAttachmentDescriptorArray, objc_name="object") +BlitPassSampleBufferAttachmentDescriptorArray_object :: #force_inline proc(self: ^BlitPassSampleBufferAttachmentDescriptorArray, attachmentIndex: NS.UInteger) -> ^BlitPassSampleBufferAttachmentDescriptor { + return msgSend(^BlitPassSampleBufferAttachmentDescriptor, self, "objectAtIndexedSubscript:", attachmentIndex) +} +@(objc_type=BlitPassSampleBufferAttachmentDescriptorArray, objc_name="setObject") +BlitPassSampleBufferAttachmentDescriptorArray_setObject :: #force_inline proc(self: ^BlitPassSampleBufferAttachmentDescriptorArray, attachment: ^BlitPassSampleBufferAttachmentDescriptor, attachmentIndex: NS.UInteger) { + msgSend(nil, self, "setObject:atIndexedSubscript:", attachment, attachmentIndex) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + BufferLayoutDescriptor +Class Methods: + alloc +Methods: + init + setStepFunction + setStepRate + setStride + stepFunction + stepRate + stride +*/ +@(objc_class="MTLBufferLayoutDescriptor") +BufferLayoutDescriptor :: struct { using _: NS.Copying(BufferLayoutDescriptor) } + +@(objc_type=BufferLayoutDescriptor, objc_name="alloc", objc_is_class_method=true) +BufferLayoutDescriptor_alloc :: #force_inline proc() -> ^BufferLayoutDescriptor { + return msgSend(^BufferLayoutDescriptor, BufferLayoutDescriptor, "alloc") +} +@(objc_type=BufferLayoutDescriptor, objc_name="init") +BufferLayoutDescriptor_init :: #force_inline proc(self: ^BufferLayoutDescriptor) -> ^BufferLayoutDescriptor { + return msgSend(^BufferLayoutDescriptor, self, "init") +} +@(objc_type=BufferLayoutDescriptor, objc_name="setStepFunction") +BufferLayoutDescriptor_setStepFunction :: #force_inline proc(self: ^BufferLayoutDescriptor, stepFunction: StepFunction) { + msgSend(nil, self, "setStepFunction:", stepFunction) +} +@(objc_type=BufferLayoutDescriptor, objc_name="setStepRate") +BufferLayoutDescriptor_setStepRate :: #force_inline proc(self: ^BufferLayoutDescriptor, stepRate: NS.UInteger) { + msgSend(nil, self, "setStepRate:", stepRate) +} +@(objc_type=BufferLayoutDescriptor, objc_name="setStride") +BufferLayoutDescriptor_setStride :: #force_inline proc(self: ^BufferLayoutDescriptor, stride: NS.UInteger) { + msgSend(nil, self, "setStride:", stride) +} +@(objc_type=BufferLayoutDescriptor, objc_name="stepFunction") +BufferLayoutDescriptor_stepFunction :: #force_inline proc(self: ^BufferLayoutDescriptor) -> StepFunction { + return msgSend(StepFunction, self, "stepFunction") +} +@(objc_type=BufferLayoutDescriptor, objc_name="stepRate") +BufferLayoutDescriptor_stepRate :: #force_inline proc(self: ^BufferLayoutDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "stepRate") +} +@(objc_type=BufferLayoutDescriptor, objc_name="stride") +BufferLayoutDescriptor_stride :: #force_inline proc(self: ^BufferLayoutDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "stride") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + BufferLayoutDescriptorArray +Class Methods: + alloc +Methods: + init + objectAtIndexedSubscript + setObject +*/ +@(objc_class="MTLBufferLayoutDescriptorArray") +BufferLayoutDescriptorArray :: struct { using _: NS.Object } + +@(objc_type=BufferLayoutDescriptorArray, objc_name="alloc", objc_is_class_method=true) +BufferLayoutDescriptorArray_alloc :: #force_inline proc() -> ^BufferLayoutDescriptorArray { + return msgSend(^BufferLayoutDescriptorArray, BufferLayoutDescriptorArray, "alloc") +} +@(objc_type=BufferLayoutDescriptorArray, objc_name="init") +BufferLayoutDescriptorArray_init :: #force_inline proc(self: ^BufferLayoutDescriptorArray) -> ^BufferLayoutDescriptorArray { + return msgSend(^BufferLayoutDescriptorArray, self, "init") +} +@(objc_type=BufferLayoutDescriptorArray, objc_name="object") +BufferLayoutDescriptorArray_object :: #force_inline proc(self: ^BufferLayoutDescriptorArray, index: NS.UInteger) -> ^BufferLayoutDescriptor { + return msgSend(^BufferLayoutDescriptor, self, "objectAtIndexedSubscript:", index) +} +@(objc_type=BufferLayoutDescriptorArray, objc_name="setObject") +BufferLayoutDescriptorArray_setObject :: #force_inline proc(self: ^BufferLayoutDescriptorArray, bufferDesc: ^BufferLayoutDescriptor, index: NS.UInteger) { + msgSend(nil, self, "setObject:atIndexedSubscript:", bufferDesc, index) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + CaptureDescriptor +Class Methods: + alloc +Methods: + init + captureObject + destination + outputURL + setCaptureObject + setDestination + setOutputURL +*/ +@(objc_class="MTLCaptureDescriptor") +CaptureDescriptor :: struct { using _: NS.Copying(CaptureDescriptor) } + +@(objc_type=CaptureDescriptor, objc_name="alloc", objc_is_class_method=true) +CaptureDescriptor_alloc :: #force_inline proc() -> ^CaptureDescriptor { + return msgSend(^CaptureDescriptor, CaptureDescriptor, "alloc") +} +@(objc_type=CaptureDescriptor, objc_name="init") +CaptureDescriptor_init :: #force_inline proc(self: ^CaptureDescriptor) -> ^CaptureDescriptor { + return msgSend(^CaptureDescriptor, self, "init") +} +@(objc_type=CaptureDescriptor, objc_name="captureObject") +CaptureDescriptor_captureObject :: #force_inline proc(self: ^CaptureDescriptor) -> id { + return msgSend(id, self, "captureObject") +} +@(objc_type=CaptureDescriptor, objc_name="destination") +CaptureDescriptor_destination :: #force_inline proc(self: ^CaptureDescriptor) -> CaptureDestination { + return msgSend(CaptureDestination, self, "destination") +} +@(objc_type=CaptureDescriptor, objc_name="outputURL") +CaptureDescriptor_outputURL :: #force_inline proc(self: ^CaptureDescriptor) -> ^NS.URL { + return msgSend(^NS.URL, self, "outputURL") +} +@(objc_type=CaptureDescriptor, objc_name="setCaptureObject") +CaptureDescriptor_setCaptureObject :: #force_inline proc(self: ^CaptureDescriptor, captureObject: id) { + msgSend(nil, self, "setCaptureObject:", captureObject) +} +@(objc_type=CaptureDescriptor, objc_name="setDestination") +CaptureDescriptor_setDestination :: #force_inline proc(self: ^CaptureDescriptor, destination: CaptureDestination) { + msgSend(nil, self, "setDestination:", destination) +} +@(objc_type=CaptureDescriptor, objc_name="setOutputURL") +CaptureDescriptor_setOutputURL :: #force_inline proc(self: ^CaptureDescriptor, outputURL: ^NS.URL) { + msgSend(nil, self, "setOutputURL:", outputURL) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + CaptureManager +Class Methods: + alloc + sharedCaptureManager +Methods: + defaultCaptureScope + init + isCapturing + newCaptureScopeWithCommandQueue + newCaptureScopeWithDevice + setDefaultCaptureScope + startCaptureWithCommandQueue + startCaptureWithDescriptor + startCaptureWithDevice + startCaptureWithScope + stopCapture + supportsDestination +*/ +@(objc_class="MTLCaptureManager") +CaptureManager :: struct { using _: NS.Object } + +@(objc_type=CaptureManager, objc_name="alloc", objc_is_class_method=true) +CaptureManager_alloc :: #force_inline proc() -> ^CaptureManager { + return msgSend(^CaptureManager, CaptureManager, "alloc") +} +@(objc_type=CaptureManager, objc_name="defaultCaptureScope") +CaptureManager_defaultCaptureScope :: #force_inline proc(self: ^CaptureManager) -> ^CaptureManager { + return msgSend(^CaptureManager, self, "defaultCaptureScope") +} +@(objc_type=CaptureManager, objc_name="init") +CaptureManager_init :: #force_inline proc(self: ^CaptureManager) -> ^CaptureManager { + return msgSend(^CaptureManager, self, "init") +} +@(objc_type=CaptureManager, objc_name="isCapturing") +CaptureManager_isCapturing :: #force_inline proc(self: ^CaptureManager) -> BOOL { + return msgSend(BOOL, self, "isCapturing") +} +@(objc_type=CaptureManager, objc_name="newCaptureScopeWithCommandQueue") +CaptureManager_newCaptureScopeWithCommandQueue :: #force_inline proc(self: ^CaptureManager, commandQueue: ^CommandQueue) -> ^CaptureScope { + return msgSend(^CaptureScope, self, "newCaptureScopeWithCommandQueue:", commandQueue) +} +@(objc_type=CaptureManager, objc_name="newCaptureScopeWithDevice") +CaptureManager_newCaptureScopeWithDevice :: #force_inline proc(self: ^CaptureManager, device: ^Device) -> ^CaptureScope { + return msgSend(^CaptureScope, self, "newCaptureScopeWithDevice:", device) +} +@(objc_type=CaptureManager, objc_name="newCaptureScope") +CaptureManager_newCaptureScope :: proc{ + CaptureManager_newCaptureScopeWithCommandQueue, + CaptureManager_newCaptureScopeWithDevice, +} + +@(objc_type=CaptureManager, objc_name="setDefaultCaptureScope") +CaptureManager_setDefaultCaptureScope :: #force_inline proc(self: ^CaptureManager, defaultCaptureScope: ^CaptureScope) { + msgSend(nil, self, "setDefaultCaptureScope:", defaultCaptureScope) +} +@(objc_type=CaptureManager, objc_name="sharedCaptureManager", objc_is_class_method=true) +CaptureManager_sharedCaptureManager :: #force_inline proc() -> ^CaptureManager { + return msgSend(^CaptureManager, CaptureManager, "sharedCaptureManager") +} +@(objc_type=CaptureManager, objc_name="startCaptureWithCommandQueue") +CaptureManager_startCaptureWithCommandQueue :: #force_inline proc(self: ^CaptureManager, commandQueue: ^CommandQueue) { + msgSend(nil, self, "startCaptureWithCommandQueue:", commandQueue) +} +@(objc_type=CaptureManager, objc_name="startCaptureWithDescriptor") +CaptureManager_startCaptureWithDescriptor :: #force_inline proc(self: ^CaptureManager, descriptor: ^CaptureDescriptor) -> (ok: BOOL, error: ^NS.Error) { + ok = msgSend(BOOL, self, "startCaptureWithDescriptor:error:", descriptor, &error) + return +} +@(objc_type=CaptureManager, objc_name="startCaptureWithDevice") +CaptureManager_startCaptureWithDevice :: #force_inline proc(self: ^CaptureManager, device: ^Device) { + msgSend(nil, self, "startCaptureWithDevice:", device) +} +@(objc_type=CaptureManager, objc_name="startCaptureWithScope") +CaptureManager_startCaptureWithScope :: #force_inline proc(self: ^CaptureManager, captureScope: ^CaptureScope) { + msgSend(nil, self, "startCaptureWithScope:", captureScope) +} +@(objc_type=CaptureManager, objc_name="stopCapture") +CaptureManager_stopCapture :: #force_inline proc(self: ^CaptureManager) { + msgSend(nil, self, "stopCapture") +} +@(objc_type=CaptureManager, objc_name="supportsDestination") +CaptureManager_supportsDestination :: #force_inline proc(self: ^CaptureManager, destination: CaptureDestination) -> BOOL { + return msgSend(BOOL, self, "supportsDestination:", destination) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + CommandBufferDescriptor +Class Methods: + alloc +Methods: + init + errorOptions + retainedReferences + setErrorOptions + setRetainedReferences +*/ +@(objc_class="MTLCommandBufferDescriptor") +CommandBufferDescriptor :: struct { using _: NS.Copying(CommandBufferDescriptor) } + +@(objc_type=CommandBufferDescriptor, objc_name="alloc", objc_is_class_method=true) +CommandBufferDescriptor_alloc :: #force_inline proc() -> ^CommandBufferDescriptor { + return msgSend(^CommandBufferDescriptor, CommandBufferDescriptor, "alloc") +} +@(objc_type=CommandBufferDescriptor, objc_name="init") +CommandBufferDescriptor_init :: #force_inline proc(self: ^CommandBufferDescriptor) -> ^CommandBufferDescriptor { + return msgSend(^CommandBufferDescriptor, self, "init") +} +@(objc_type=CommandBufferDescriptor, objc_name="errorOptions") +CommandBufferDescriptor_errorOptions :: #force_inline proc(self: ^CommandBufferDescriptor) -> CommandBufferErrorOption { + return msgSend(CommandBufferErrorOption, self, "errorOptions") +} +@(objc_type=CommandBufferDescriptor, objc_name="retainedReferences") +CommandBufferDescriptor_retainedReferences :: #force_inline proc(self: ^CommandBufferDescriptor) -> BOOL { + return msgSend(BOOL, self, "retainedReferences") +} +@(objc_type=CommandBufferDescriptor, objc_name="setErrorOptions") +CommandBufferDescriptor_setErrorOptions :: #force_inline proc(self: ^CommandBufferDescriptor, errorOptions: CommandBufferErrorOption) { + msgSend(nil, self, "setErrorOptions:", errorOptions) +} +@(objc_type=CommandBufferDescriptor, objc_name="setRetainedReferences") +CommandBufferDescriptor_setRetainedReferences :: #force_inline proc(self: ^CommandBufferDescriptor, retainedReferences: BOOL) { + msgSend(nil, self, "setRetainedReferences:", retainedReferences) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + CompileOptions +Class Methods: + alloc +Methods: + init + fastMathEnabled + installName + languageVersion + libraries + libraryType + preprocessorMacros + preserveInvariance + setFastMathEnabled + setInstallName + setLanguageVersion + setLibraries + setLibraryType + setPreprocessorMacros + setPreserveInvariance +*/ +@(objc_class="MTLCompileOptions") +CompileOptions :: struct { using _: NS.Copying(CompileOptions) } + +@(objc_type=CompileOptions, objc_name="alloc", objc_is_class_method=true) +CompileOptions_alloc :: #force_inline proc() -> ^CompileOptions { + return msgSend(^CompileOptions, CompileOptions, "alloc") +} +@(objc_type=CompileOptions, objc_name="init") +CompileOptions_init :: #force_inline proc(self: ^CompileOptions) -> ^CompileOptions { + return msgSend(^CompileOptions, self, "init") +} +@(objc_type=CompileOptions, objc_name="fastMathEnabled") +CompileOptions_fastMathEnabled :: #force_inline proc(self: ^CompileOptions) -> BOOL { + return msgSend(BOOL, self, "fastMathEnabled") +} +@(objc_type=CompileOptions, objc_name="installName") +CompileOptions_installName :: #force_inline proc(self: ^CompileOptions) -> ^NS.String { + return msgSend(^NS.String, self, "installName") +} +@(objc_type=CompileOptions, objc_name="languageVersion") +CompileOptions_languageVersion :: #force_inline proc(self: ^CompileOptions) -> LanguageVersion { + return msgSend(LanguageVersion, self, "languageVersion") +} +@(objc_type=CompileOptions, objc_name="libraries") +CompileOptions_libraries :: #force_inline proc(self: ^CompileOptions) -> ^NS.Array { + return msgSend(^NS.Array, self, "libraries") +} +@(objc_type=CompileOptions, objc_name="libraryType") +CompileOptions_libraryType :: #force_inline proc(self: ^CompileOptions) -> LibraryType { + return msgSend(LibraryType, self, "libraryType") +} +@(objc_type=CompileOptions, objc_name="preprocessorMacros") +CompileOptions_preprocessorMacros :: #force_inline proc(self: ^CompileOptions) -> ^NS.Dictionary { + return msgSend(^NS.Dictionary, self, "preprocessorMacros") +} +@(objc_type=CompileOptions, objc_name="preserveInvariance") +CompileOptions_preserveInvariance :: #force_inline proc(self: ^CompileOptions) -> BOOL { + return msgSend(BOOL, self, "preserveInvariance") +} +@(objc_type=CompileOptions, objc_name="setFastMathEnabled") +CompileOptions_setFastMathEnabled :: #force_inline proc(self: ^CompileOptions, fastMathEnabled: BOOL) { + msgSend(nil, self, "setFastMathEnabled:", fastMathEnabled) +} +@(objc_type=CompileOptions, objc_name="setInstallName") +CompileOptions_setInstallName :: #force_inline proc(self: ^CompileOptions, installName: ^NS.String) { + msgSend(nil, self, "setInstallName:", installName) +} +@(objc_type=CompileOptions, objc_name="setLanguageVersion") +CompileOptions_setLanguageVersion :: #force_inline proc(self: ^CompileOptions, languageVersion: LanguageVersion) { + msgSend(nil, self, "setLanguageVersion:", languageVersion) +} +@(objc_type=CompileOptions, objc_name="setLibraries") +CompileOptions_setLibraries :: #force_inline proc(self: ^CompileOptions, libraries: ^NS.Array) { + msgSend(nil, self, "setLibraries:", libraries) +} +@(objc_type=CompileOptions, objc_name="setLibraryType") +CompileOptions_setLibraryType :: #force_inline proc(self: ^CompileOptions, libraryType: LibraryType) { + msgSend(nil, self, "setLibraryType:", libraryType) +} +@(objc_type=CompileOptions, objc_name="setPreprocessorMacros") +CompileOptions_setPreprocessorMacros :: #force_inline proc(self: ^CompileOptions, preprocessorMacros: ^NS.Dictionary) { + msgSend(nil, self, "setPreprocessorMacros:", preprocessorMacros) +} +@(objc_type=CompileOptions, objc_name="setPreserveInvariance") +CompileOptions_setPreserveInvariance :: #force_inline proc(self: ^CompileOptions, preserveInvariance: BOOL) { + msgSend(nil, self, "setPreserveInvariance:", preserveInvariance) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + ComputePassDescriptor +Class Methods: + alloc + computePassDescriptor +Methods: + init + dispatchType + sampleBufferAttachments + setDispatchType +*/ +@(objc_class="MTLComputePassDescriptor") +ComputePassDescriptor :: struct { using _: NS.Copying(ComputePassDescriptor) } + +@(objc_type=ComputePassDescriptor, objc_name="alloc", objc_is_class_method=true) +ComputePassDescriptor_alloc :: #force_inline proc() -> ^ComputePassDescriptor { + return msgSend(^ComputePassDescriptor, ComputePassDescriptor, "alloc") +} +@(objc_type=ComputePassDescriptor, objc_name="init") +ComputePassDescriptor_init :: #force_inline proc(self: ^ComputePassDescriptor) -> ^ComputePassDescriptor { + return msgSend(^ComputePassDescriptor, self, "init") +} +@(objc_type=ComputePassDescriptor, objc_name="computePassDescriptor", objc_is_class_method=true) +ComputePassDescriptor_computePassDescriptor :: #force_inline proc() -> ^ComputePassDescriptor { + return msgSend(^ComputePassDescriptor, ComputePassDescriptor, "computePassDescriptor") +} +@(objc_type=ComputePassDescriptor, objc_name="dispatchType") +ComputePassDescriptor_dispatchType :: #force_inline proc(self: ^ComputePassDescriptor) -> DispatchType { + return msgSend(DispatchType, self, "dispatchType") +} +@(objc_type=ComputePassDescriptor, objc_name="sampleBufferAttachments") +ComputePassDescriptor_sampleBufferAttachments :: #force_inline proc(self: ^ComputePassDescriptor) -> ^ComputePassSampleBufferAttachmentDescriptorArray { + return msgSend(^ComputePassSampleBufferAttachmentDescriptorArray, self, "sampleBufferAttachments") +} +@(objc_type=ComputePassDescriptor, objc_name="setDispatchType") +ComputePassDescriptor_setDispatchType :: #force_inline proc(self: ^ComputePassDescriptor, dispatchType: DispatchType) { + msgSend(nil, self, "setDispatchType:", dispatchType) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + ComputePassSampleBufferAttachmentDescriptor +Class Methods: + alloc +Methods: + init + endOfEncoderSampleIndex + sampleBuffer + setEndOfEncoderSampleIndex + setSampleBuffer + setStartOfEncoderSampleIndex + startOfEncoderSampleIndex +*/ +@(objc_class="MTLComputePassSampleBufferAttachmentDescriptor") +ComputePassSampleBufferAttachmentDescriptor :: struct { using _: NS.Copying(ComputePassSampleBufferAttachmentDescriptor) } + +@(objc_type=ComputePassSampleBufferAttachmentDescriptor, objc_name="alloc", objc_is_class_method=true) +ComputePassSampleBufferAttachmentDescriptor_alloc :: #force_inline proc() -> ^ComputePassSampleBufferAttachmentDescriptor { + return msgSend(^ComputePassSampleBufferAttachmentDescriptor, ComputePassSampleBufferAttachmentDescriptor, "alloc") +} +@(objc_type=ComputePassSampleBufferAttachmentDescriptor, objc_name="init") +ComputePassSampleBufferAttachmentDescriptor_init :: #force_inline proc(self: ^ComputePassSampleBufferAttachmentDescriptor) -> ^ComputePassSampleBufferAttachmentDescriptor { + return msgSend(^ComputePassSampleBufferAttachmentDescriptor, self, "init") +} +@(objc_type=ComputePassSampleBufferAttachmentDescriptor, objc_name="endOfEncoderSampleIndex") +ComputePassSampleBufferAttachmentDescriptor_endOfEncoderSampleIndex :: #force_inline proc(self: ^ComputePassSampleBufferAttachmentDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "endOfEncoderSampleIndex") +} +@(objc_type=ComputePassSampleBufferAttachmentDescriptor, objc_name="sampleBuffer") +ComputePassSampleBufferAttachmentDescriptor_sampleBuffer :: #force_inline proc(self: ^ComputePassSampleBufferAttachmentDescriptor) -> ^CounterSampleBuffer { + return msgSend(^CounterSampleBuffer, self, "sampleBuffer") +} +@(objc_type=ComputePassSampleBufferAttachmentDescriptor, objc_name="setEndOfEncoderSampleIndex") +ComputePassSampleBufferAttachmentDescriptor_setEndOfEncoderSampleIndex :: #force_inline proc(self: ^ComputePassSampleBufferAttachmentDescriptor, endOfEncoderSampleIndex: NS.UInteger) { + msgSend(nil, self, "setEndOfEncoderSampleIndex:", endOfEncoderSampleIndex) +} +@(objc_type=ComputePassSampleBufferAttachmentDescriptor, objc_name="setSampleBuffer") +ComputePassSampleBufferAttachmentDescriptor_setSampleBuffer :: #force_inline proc(self: ^ComputePassSampleBufferAttachmentDescriptor, sampleBuffer: ^Buffer) { + msgSend(nil, self, "setSampleBuffer:", sampleBuffer) +} +@(objc_type=ComputePassSampleBufferAttachmentDescriptor, objc_name="setStartOfEncoderSampleIndex") +ComputePassSampleBufferAttachmentDescriptor_setStartOfEncoderSampleIndex :: #force_inline proc(self: ^ComputePassSampleBufferAttachmentDescriptor, startOfEncoderSampleIndex: NS.UInteger) { + msgSend(nil, self, "setStartOfEncoderSampleIndex:", startOfEncoderSampleIndex) +} +@(objc_type=ComputePassSampleBufferAttachmentDescriptor, objc_name="startOfEncoderSampleIndex") +ComputePassSampleBufferAttachmentDescriptor_startOfEncoderSampleIndex :: #force_inline proc(self: ^ComputePassSampleBufferAttachmentDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "startOfEncoderSampleIndex") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + ComputePassSampleBufferAttachmentDescriptorArray +Class Methods: + alloc +Methods: + init + objectAtIndexedSubscript + setObject +*/ +@(objc_class="MTLComputePassSampleBufferAttachmentDescriptorArray") +ComputePassSampleBufferAttachmentDescriptorArray :: struct { using _: NS.Object } + +@(objc_type=ComputePassSampleBufferAttachmentDescriptorArray, objc_name="alloc", objc_is_class_method=true) +ComputePassSampleBufferAttachmentDescriptorArray_alloc :: #force_inline proc() -> ^ComputePassSampleBufferAttachmentDescriptorArray { + return msgSend(^ComputePassSampleBufferAttachmentDescriptorArray, ComputePassSampleBufferAttachmentDescriptorArray, "alloc") +} +@(objc_type=ComputePassSampleBufferAttachmentDescriptorArray, objc_name="init") +ComputePassSampleBufferAttachmentDescriptorArray_init :: #force_inline proc(self: ^ComputePassSampleBufferAttachmentDescriptorArray) -> ^ComputePassSampleBufferAttachmentDescriptorArray { + return msgSend(^ComputePassSampleBufferAttachmentDescriptorArray, self, "init") +} +@(objc_type=ComputePassSampleBufferAttachmentDescriptorArray, objc_name="object") +ComputePassSampleBufferAttachmentDescriptorArray_object :: #force_inline proc(self: ^ComputePassSampleBufferAttachmentDescriptorArray, attachmentIndex: NS.UInteger) -> ^ComputePassSampleBufferAttachmentDescriptor { + return msgSend(^ComputePassSampleBufferAttachmentDescriptor, self, "objectAtIndexedSubscript:", attachmentIndex) +} +@(objc_type=ComputePassSampleBufferAttachmentDescriptorArray, objc_name="setObject") +ComputePassSampleBufferAttachmentDescriptorArray_setObject :: #force_inline proc(self: ^ComputePassSampleBufferAttachmentDescriptorArray, attachment: ^ComputePassSampleBufferAttachmentDescriptor, attachmentIndex: NS.UInteger) { + msgSend(nil, self, "setObject:atIndexedSubscript:", attachment, attachmentIndex) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + ComputePipelineDescriptor +Class Methods: + alloc +Methods: + init + binaryArchives + buffers + computeFunction + insertLibraries + label + linkedFunctions + maxCallStackDepth + maxTotalThreadsPerThreadgroup + reset + setBinaryArchives + setComputeFunction + setInsertLibraries + setLabel + setLinkedFunctions + setMaxCallStackDepth + setMaxTotalThreadsPerThreadgroup + setStageInputDescriptor + setSupportAddingBinaryFunctions + setSupportIndirectCommandBuffers + setThreadGroupSizeIsMultipleOfThreadExecutionWidth + stageInputDescriptor + supportAddingBinaryFunctions + supportIndirectCommandBuffers + threadGroupSizeIsMultipleOfThreadExecutionWidth +*/ +@(objc_class="MTLComputePipelineDescriptor") +ComputePipelineDescriptor :: struct { using _: NS.Copying(ComputePipelineDescriptor) } + +@(objc_type=ComputePipelineDescriptor, objc_name="alloc", objc_is_class_method=true) +ComputePipelineDescriptor_alloc :: #force_inline proc() -> ^ComputePipelineDescriptor { + return msgSend(^ComputePipelineDescriptor, ComputePipelineDescriptor, "alloc") +} +@(objc_type=ComputePipelineDescriptor, objc_name="init") +ComputePipelineDescriptor_init :: #force_inline proc(self: ^ComputePipelineDescriptor) -> ^ComputePipelineDescriptor { + return msgSend(^ComputePipelineDescriptor, self, "init") +} +@(objc_type=ComputePipelineDescriptor, objc_name="binaryArchives") +ComputePipelineDescriptor_binaryArchives :: #force_inline proc(self: ^ComputePipelineDescriptor) -> ^NS.Array { + return msgSend(^NS.Array, self, "binaryArchives") +} +@(objc_type=ComputePipelineDescriptor, objc_name="buffers") +ComputePipelineDescriptor_buffers :: #force_inline proc(self: ^ComputePipelineDescriptor) -> ^PipelineBufferDescriptorArray { + return msgSend(^PipelineBufferDescriptorArray, self, "buffers") +} +@(objc_type=ComputePipelineDescriptor, objc_name="computeFunction") +ComputePipelineDescriptor_computeFunction :: #force_inline proc(self: ^ComputePipelineDescriptor) -> ^Function { + return msgSend(^Function, self, "computeFunction") +} +@(objc_type=ComputePipelineDescriptor, objc_name="insertLibraries") +ComputePipelineDescriptor_insertLibraries :: #force_inline proc(self: ^ComputePipelineDescriptor) -> ^NS.Array { + return msgSend(^NS.Array, self, "insertLibraries") +} +@(objc_type=ComputePipelineDescriptor, objc_name="label") +ComputePipelineDescriptor_label :: #force_inline proc(self: ^ComputePipelineDescriptor) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=ComputePipelineDescriptor, objc_name="linkedFunctions") +ComputePipelineDescriptor_linkedFunctions :: #force_inline proc(self: ^ComputePipelineDescriptor) -> ^LinkedFunctions { + return msgSend(^LinkedFunctions, self, "linkedFunctions") +} +@(objc_type=ComputePipelineDescriptor, objc_name="maxCallStackDepth") +ComputePipelineDescriptor_maxCallStackDepth :: #force_inline proc(self: ^ComputePipelineDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "maxCallStackDepth") +} +@(objc_type=ComputePipelineDescriptor, objc_name="maxTotalThreadsPerThreadgroup") +ComputePipelineDescriptor_maxTotalThreadsPerThreadgroup :: #force_inline proc(self: ^ComputePipelineDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "maxTotalThreadsPerThreadgroup") +} +@(objc_type=ComputePipelineDescriptor, objc_name="reset") +ComputePipelineDescriptor_reset :: #force_inline proc(self: ^ComputePipelineDescriptor) { + msgSend(nil, self, "reset") +} +@(objc_type=ComputePipelineDescriptor, objc_name="setBinaryArchives") +ComputePipelineDescriptor_setBinaryArchives :: #force_inline proc(self: ^ComputePipelineDescriptor, binaryArchives: ^NS.Array) { + msgSend(nil, self, "setBinaryArchives:", binaryArchives) +} +@(objc_type=ComputePipelineDescriptor, objc_name="setComputeFunction") +ComputePipelineDescriptor_setComputeFunction :: #force_inline proc(self: ^ComputePipelineDescriptor, computeFunction: ^Function) { + msgSend(nil, self, "setComputeFunction:", computeFunction) +} +@(objc_type=ComputePipelineDescriptor, objc_name="setInsertLibraries") +ComputePipelineDescriptor_setInsertLibraries :: #force_inline proc(self: ^ComputePipelineDescriptor, insertLibraries: ^NS.Array) { + msgSend(nil, self, "setInsertLibraries:", insertLibraries) +} +@(objc_type=ComputePipelineDescriptor, objc_name="setLabel") +ComputePipelineDescriptor_setLabel :: #force_inline proc(self: ^ComputePipelineDescriptor, label: ^NS.String) { + msgSend(nil, self, "setLabel:", label) +} +@(objc_type=ComputePipelineDescriptor, objc_name="setLinkedFunctions") +ComputePipelineDescriptor_setLinkedFunctions :: #force_inline proc(self: ^ComputePipelineDescriptor, linkedFunctions: ^LinkedFunctions) { + msgSend(nil, self, "setLinkedFunctions:", linkedFunctions) +} +@(objc_type=ComputePipelineDescriptor, objc_name="setMaxCallStackDepth") +ComputePipelineDescriptor_setMaxCallStackDepth :: #force_inline proc(self: ^ComputePipelineDescriptor, maxCallStackDepth: NS.UInteger) { + msgSend(nil, self, "setMaxCallStackDepth:", maxCallStackDepth) +} +@(objc_type=ComputePipelineDescriptor, objc_name="setMaxTotalThreadsPerThreadgroup") +ComputePipelineDescriptor_setMaxTotalThreadsPerThreadgroup :: #force_inline proc(self: ^ComputePipelineDescriptor, maxTotalThreadsPerThreadgroup: NS.UInteger) { + msgSend(nil, self, "setMaxTotalThreadsPerThreadgroup:", maxTotalThreadsPerThreadgroup) +} +@(objc_type=ComputePipelineDescriptor, objc_name="setStageInputDescriptor") +ComputePipelineDescriptor_setStageInputDescriptor :: #force_inline proc(self: ^ComputePipelineDescriptor, stageInputDescriptor: ^StageInputOutputDescriptor) { + msgSend(nil, self, "setStageInputDescriptor:", stageInputDescriptor) +} +@(objc_type=ComputePipelineDescriptor, objc_name="setSupportAddingBinaryFunctions") +ComputePipelineDescriptor_setSupportAddingBinaryFunctions :: #force_inline proc(self: ^ComputePipelineDescriptor, supportAddingBinaryFunctions: BOOL) { + msgSend(nil, self, "setSupportAddingBinaryFunctions:", supportAddingBinaryFunctions) +} +@(objc_type=ComputePipelineDescriptor, objc_name="setSupportIndirectCommandBuffers") +ComputePipelineDescriptor_setSupportIndirectCommandBuffers :: #force_inline proc(self: ^ComputePipelineDescriptor, supportIndirectCommandBuffers: BOOL) { + msgSend(nil, self, "setSupportIndirectCommandBuffers:", supportIndirectCommandBuffers) +} +@(objc_type=ComputePipelineDescriptor, objc_name="setThreadGroupSizeIsMultipleOfThreadExecutionWidth") +ComputePipelineDescriptor_setThreadGroupSizeIsMultipleOfThreadExecutionWidth :: #force_inline proc(self: ^ComputePipelineDescriptor, threadGroupSizeIsMultipleOfThreadExecutionWidth: BOOL) { + msgSend(nil, self, "setThreadGroupSizeIsMultipleOfThreadExecutionWidth:", threadGroupSizeIsMultipleOfThreadExecutionWidth) +} +@(objc_type=ComputePipelineDescriptor, objc_name="stageInputDescriptor") +ComputePipelineDescriptor_stageInputDescriptor :: #force_inline proc(self: ^ComputePipelineDescriptor) -> ^StageInputOutputDescriptor { + return msgSend(^StageInputOutputDescriptor, self, "stageInputDescriptor") +} +@(objc_type=ComputePipelineDescriptor, objc_name="supportAddingBinaryFunctions") +ComputePipelineDescriptor_supportAddingBinaryFunctions :: #force_inline proc(self: ^ComputePipelineDescriptor) -> BOOL { + return msgSend(BOOL, self, "supportAddingBinaryFunctions") +} +@(objc_type=ComputePipelineDescriptor, objc_name="supportIndirectCommandBuffers") +ComputePipelineDescriptor_supportIndirectCommandBuffers :: #force_inline proc(self: ^ComputePipelineDescriptor) -> BOOL { + return msgSend(BOOL, self, "supportIndirectCommandBuffers") +} +@(objc_type=ComputePipelineDescriptor, objc_name="threadGroupSizeIsMultipleOfThreadExecutionWidth") +ComputePipelineDescriptor_threadGroupSizeIsMultipleOfThreadExecutionWidth :: #force_inline proc(self: ^ComputePipelineDescriptor) -> BOOL { + return msgSend(BOOL, self, "threadGroupSizeIsMultipleOfThreadExecutionWidth") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + ComputePipelineReflection +Class Methods: + alloc +Methods: + init + arguments +*/ +@(objc_class="MTLComputePipelineReflection") +ComputePipelineReflection :: struct { using _: NS.Object } + +@(objc_type=ComputePipelineReflection, objc_name="alloc", objc_is_class_method=true) +ComputePipelineReflection_alloc :: #force_inline proc() -> ^ComputePipelineReflection { + return msgSend(^ComputePipelineReflection, ComputePipelineReflection, "alloc") +} +@(objc_type=ComputePipelineReflection, objc_name="init") +ComputePipelineReflection_init :: #force_inline proc(self: ^ComputePipelineReflection) -> ^ComputePipelineReflection { + return msgSend(^ComputePipelineReflection, self, "init") +} +@(objc_type=ComputePipelineReflection, objc_name="arguments") +ComputePipelineReflection_arguments :: #force_inline proc(self: ^ComputePipelineReflection) -> ^NS.Array { + return msgSend(^NS.Array, self, "arguments") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + CounterSampleBufferDescriptor +Class Methods: + alloc +Methods: + init + counterSet + label + sampleCount + setCounterSet + setLabel + setSampleCount + setStorageMode + storageMode +*/ +@(objc_class="MTLCounterSampleBufferDescriptor") +CounterSampleBufferDescriptor :: struct { using _: NS.Copying(CounterSampleBufferDescriptor) } + +@(objc_type=CounterSampleBufferDescriptor, objc_name="alloc", objc_is_class_method=true) +CounterSampleBufferDescriptor_alloc :: #force_inline proc() -> ^CounterSampleBufferDescriptor { + return msgSend(^CounterSampleBufferDescriptor, CounterSampleBufferDescriptor, "alloc") +} +@(objc_type=CounterSampleBufferDescriptor, objc_name="init") +CounterSampleBufferDescriptor_init :: #force_inline proc(self: ^CounterSampleBufferDescriptor) -> ^CounterSampleBufferDescriptor { + return msgSend(^CounterSampleBufferDescriptor, self, "init") +} +@(objc_type=CounterSampleBufferDescriptor, objc_name="counterSet") +CounterSampleBufferDescriptor_counterSet :: #force_inline proc(self: ^CounterSampleBufferDescriptor) -> ^CounterSet { + return msgSend(^CounterSet, self, "counterSet") +} +@(objc_type=CounterSampleBufferDescriptor, objc_name="label") +CounterSampleBufferDescriptor_label :: #force_inline proc(self: ^CounterSampleBufferDescriptor) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=CounterSampleBufferDescriptor, objc_name="sampleCount") +CounterSampleBufferDescriptor_sampleCount :: #force_inline proc(self: ^CounterSampleBufferDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "sampleCount") +} +@(objc_type=CounterSampleBufferDescriptor, objc_name="setCounterSet") +CounterSampleBufferDescriptor_setCounterSet :: #force_inline proc(self: ^CounterSampleBufferDescriptor, counterSet: ^CounterSet) { + msgSend(nil, self, "setCounterSet:", counterSet) +} +@(objc_type=CounterSampleBufferDescriptor, objc_name="setLabel") +CounterSampleBufferDescriptor_setLabel :: #force_inline proc(self: ^CounterSampleBufferDescriptor, label: ^NS.String) { + msgSend(nil, self, "setLabel:", label) +} +@(objc_type=CounterSampleBufferDescriptor, objc_name="setSampleCount") +CounterSampleBufferDescriptor_setSampleCount :: #force_inline proc(self: ^CounterSampleBufferDescriptor, sampleCount: NS.UInteger) { + msgSend(nil, self, "setSampleCount:", sampleCount) +} +@(objc_type=CounterSampleBufferDescriptor, objc_name="setStorageMode") +CounterSampleBufferDescriptor_setStorageMode :: #force_inline proc(self: ^CounterSampleBufferDescriptor, storageMode: StorageMode) { + msgSend(nil, self, "setStorageMode:", storageMode) +} +@(objc_type=CounterSampleBufferDescriptor, objc_name="storageMode") +CounterSampleBufferDescriptor_storageMode :: #force_inline proc(self: ^CounterSampleBufferDescriptor) -> StorageMode { + return msgSend(StorageMode, self, "storageMode") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + DepthStencilDescriptor +Class Methods: + alloc +Methods: + init + backFaceStencil + depthCompareFunction + frontFaceStencil + isDepthWriteEnabled + label + setBackFaceStencil + setDepthCompareFunction + setDepthWriteEnabled + setFrontFaceStencil + setLabel +*/ +@(objc_class="MTLDepthStencilDescriptor") +DepthStencilDescriptor :: struct { using _: NS.Copying(DepthStencilDescriptor) } + +@(objc_type=DepthStencilDescriptor, objc_name="alloc", objc_is_class_method=true) +DepthStencilDescriptor_alloc :: #force_inline proc() -> ^DepthStencilDescriptor { + return msgSend(^DepthStencilDescriptor, DepthStencilDescriptor, "alloc") +} +@(objc_type=DepthStencilDescriptor, objc_name="init") +DepthStencilDescriptor_init :: #force_inline proc(self: ^DepthStencilDescriptor) -> ^DepthStencilDescriptor { + return msgSend(^DepthStencilDescriptor, self, "init") +} +@(objc_type=DepthStencilDescriptor, objc_name="backFaceStencil") +DepthStencilDescriptor_backFaceStencil :: #force_inline proc(self: ^DepthStencilDescriptor) -> ^StencilDescriptor { + return msgSend(^StencilDescriptor, self, "backFaceStencil") +} +@(objc_type=DepthStencilDescriptor, objc_name="depthCompareFunction") +DepthStencilDescriptor_depthCompareFunction :: #force_inline proc(self: ^DepthStencilDescriptor) -> CompareFunction { + return msgSend(CompareFunction, self, "depthCompareFunction") +} +@(objc_type=DepthStencilDescriptor, objc_name="frontFaceStencil") +DepthStencilDescriptor_frontFaceStencil :: #force_inline proc(self: ^DepthStencilDescriptor) -> ^StencilDescriptor { + return msgSend(^StencilDescriptor, self, "frontFaceStencil") +} +@(objc_type=DepthStencilDescriptor, objc_name="isDepthWriteEnabled") +DepthStencilDescriptor_isDepthWriteEnabled :: #force_inline proc(self: ^DepthStencilDescriptor) -> BOOL { + return msgSend(BOOL, self, "isDepthWriteEnabled") +} +@(objc_type=DepthStencilDescriptor, objc_name="label") +DepthStencilDescriptor_label :: #force_inline proc(self: ^DepthStencilDescriptor) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=DepthStencilDescriptor, objc_name="setBackFaceStencil") +DepthStencilDescriptor_setBackFaceStencil :: #force_inline proc(self: ^DepthStencilDescriptor, backFaceStencil: ^StencilDescriptor) { + msgSend(nil, self, "setBackFaceStencil:", backFaceStencil) +} +@(objc_type=DepthStencilDescriptor, objc_name="setDepthCompareFunction") +DepthStencilDescriptor_setDepthCompareFunction :: #force_inline proc(self: ^DepthStencilDescriptor, depthCompareFunction: CompareFunction) { + msgSend(nil, self, "setDepthCompareFunction:", depthCompareFunction) +} +@(objc_type=DepthStencilDescriptor, objc_name="setDepthWriteEnabled") +DepthStencilDescriptor_setDepthWriteEnabled :: #force_inline proc(self: ^DepthStencilDescriptor, depthWriteEnabled: BOOL) { + msgSend(nil, self, "setDepthWriteEnabled:", depthWriteEnabled) +} +@(objc_type=DepthStencilDescriptor, objc_name="setFrontFaceStencil") +DepthStencilDescriptor_setFrontFaceStencil :: #force_inline proc(self: ^DepthStencilDescriptor, frontFaceStencil: ^StencilDescriptor) { + msgSend(nil, self, "setFrontFaceStencil:", frontFaceStencil) +} +@(objc_type=DepthStencilDescriptor, objc_name="setLabel") +DepthStencilDescriptor_setLabel :: #force_inline proc(self: ^DepthStencilDescriptor, label: ^NS.String) { + msgSend(nil, self, "setLabel:", label) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + FunctionConstant +Class Methods: + alloc +Methods: + init + index + name + required + type +*/ +@(objc_class="MTLFunctionConstant") +FunctionConstant :: struct { using _: NS.Copying(FunctionConstant) } + +@(objc_type=FunctionConstant, objc_name="alloc", objc_is_class_method=true) +FunctionConstant_alloc :: #force_inline proc() -> ^FunctionConstant { + return msgSend(^FunctionConstant, FunctionConstant, "alloc") +} +@(objc_type=FunctionConstant, objc_name="init") +FunctionConstant_init :: #force_inline proc(self: ^FunctionConstant) -> ^FunctionConstant { + return msgSend(^FunctionConstant, self, "init") +} +@(objc_type=FunctionConstant, objc_name="index") +FunctionConstant_index :: #force_inline proc(self: ^FunctionConstant) -> NS.UInteger { + return msgSend(NS.UInteger, self, "index") +} +@(objc_type=FunctionConstant, objc_name="name") +FunctionConstant_name :: #force_inline proc(self: ^FunctionConstant) -> ^NS.String { + return msgSend(^NS.String, self, "name") +} +@(objc_type=FunctionConstant, objc_name="required") +FunctionConstant_required :: #force_inline proc(self: ^FunctionConstant) -> BOOL { + return msgSend(BOOL, self, "required") +} +@(objc_type=FunctionConstant, objc_name="type") +FunctionConstant_type :: #force_inline proc(self: ^FunctionConstant) -> DataType { + return msgSend(DataType, self, "type") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + FunctionConstantValues +Class Methods: + alloc +Methods: + init + reset + setConstantValue + setConstantValue + setConstantValues +*/ +@(objc_class="MTLFunctionConstantValues") +FunctionConstantValues :: struct { using _: NS.Copying(FunctionConstantValues) } + +@(objc_type=FunctionConstantValues, objc_name="alloc", objc_is_class_method=true) +FunctionConstantValues_alloc :: #force_inline proc() -> ^FunctionConstantValues { + return msgSend(^FunctionConstantValues, FunctionConstantValues, "alloc") +} +@(objc_type=FunctionConstantValues, objc_name="init") +FunctionConstantValues_init :: #force_inline proc(self: ^FunctionConstantValues) -> ^FunctionConstantValues { + return msgSend(^FunctionConstantValues, self, "init") +} +@(objc_type=FunctionConstantValues, objc_name="reset") +FunctionConstantValues_reset :: #force_inline proc(self: ^FunctionConstantValues) { + msgSend(nil, self, "reset") +} +@(objc_type=FunctionConstantValues, objc_name="setConstantValue") +FunctionConstantValues_setConstantValue :: #force_inline proc(self: ^FunctionConstantValues, value: rawptr, type: DataType, index: NS.UInteger) { + msgSend(nil, self, "setConstantValue:type:atIndex:", value, type, index) +} +@(objc_type=FunctionConstantValues, objc_name="setConstantValueWithName") +FunctionConstantValues_setConstantValueWithName :: #force_inline proc(self: ^FunctionConstantValues, value: rawptr, type: DataType, name: ^NS.String) { + msgSend(nil, self, "setConstantValue:type:withName:", value, type, name) +} +@(objc_type=FunctionConstantValues, objc_name="setConstantValues") +FunctionConstantValues_setConstantValues :: #force_inline proc(self: ^FunctionConstantValues, values: rawptr, type: DataType, range: NS.Range) { + msgSend(nil, self, "setConstantValues:type:withRange:", values, type, range) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + FunctionDescriptor +Class Methods: + alloc + functionDescriptor +Methods: + init + constantValues + name + options + setConstantValues + setName + setOptions + setSpecializedName + specializedName +*/ +@(objc_class="MTLFunctionDescriptor") +FunctionDescriptor :: struct { using _: NS.Copying(FunctionDescriptor) } + +@(objc_type=FunctionDescriptor, objc_name="alloc", objc_is_class_method=true) +FunctionDescriptor_alloc :: #force_inline proc() -> ^FunctionDescriptor { + return msgSend(^FunctionDescriptor, FunctionDescriptor, "alloc") +} +@(objc_type=FunctionDescriptor, objc_name="init") +FunctionDescriptor_init :: #force_inline proc(self: ^FunctionDescriptor) -> ^FunctionDescriptor { + return msgSend(^FunctionDescriptor, self, "init") +} +@(objc_type=FunctionDescriptor, objc_name="constantValues") +FunctionDescriptor_constantValues :: #force_inline proc(self: ^FunctionDescriptor) -> ^FunctionConstantValues { + return msgSend(^FunctionConstantValues, self, "constantValues") +} +@(objc_type=FunctionDescriptor, objc_name="functionDescriptor", objc_is_class_method=true) +FunctionDescriptor_functionDescriptor :: #force_inline proc() -> ^FunctionDescriptor { + return msgSend(^FunctionDescriptor, FunctionDescriptor, "functionDescriptor") +} +@(objc_type=FunctionDescriptor, objc_name="name") +FunctionDescriptor_name :: #force_inline proc(self: ^FunctionDescriptor) -> ^NS.String { + return msgSend(^NS.String, self, "name") +} +@(objc_type=FunctionDescriptor, objc_name="options") +FunctionDescriptor_options :: #force_inline proc(self: ^FunctionDescriptor) -> FunctionOptions { + return msgSend(FunctionOptions, self, "options") +} +@(objc_type=FunctionDescriptor, objc_name="setConstantValues") +FunctionDescriptor_setConstantValues :: #force_inline proc(self: ^FunctionDescriptor, constantValues: ^FunctionConstantValues) { + msgSend(nil, self, "setConstantValues:", constantValues) +} +@(objc_type=FunctionDescriptor, objc_name="setName") +FunctionDescriptor_setName :: #force_inline proc(self: ^FunctionDescriptor, name: ^NS.String) { + msgSend(nil, self, "setName:", name) +} +@(objc_type=FunctionDescriptor, objc_name="setOptions") +FunctionDescriptor_setOptions :: #force_inline proc(self: ^FunctionDescriptor, options: FunctionOptions) { + msgSend(nil, self, "setOptions:", options) +} +@(objc_type=FunctionDescriptor, objc_name="setSpecializedName") +FunctionDescriptor_setSpecializedName :: #force_inline proc(self: ^FunctionDescriptor, specializedName: ^NS.String) { + msgSend(nil, self, "setSpecializedName:", specializedName) +} +@(objc_type=FunctionDescriptor, objc_name="specializedName") +FunctionDescriptor_specializedName :: #force_inline proc(self: ^FunctionDescriptor) -> ^NS.String { + return msgSend(^NS.String, self, "specializedName") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + IntersectionFunctionDescriptor +Class Methods: + alloc +Methods: + init +*/ +@(objc_class="MTLIntersectionFunctionDescriptor") +IntersectionFunctionDescriptor :: struct { using _: NS.Copying(IntersectionFunctionDescriptor) } + +@(objc_type=IntersectionFunctionDescriptor, objc_name="alloc", objc_is_class_method=true) +IntersectionFunctionDescriptor_alloc :: #force_inline proc() -> ^IntersectionFunctionDescriptor { + return msgSend(^IntersectionFunctionDescriptor, IntersectionFunctionDescriptor, "alloc") +} +@(objc_type=IntersectionFunctionDescriptor, objc_name="init") +IntersectionFunctionDescriptor_init :: #force_inline proc(self: ^IntersectionFunctionDescriptor) -> ^IntersectionFunctionDescriptor { + return msgSend(^IntersectionFunctionDescriptor, self, "init") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + HeapDescriptor +Class Methods: + alloc +Methods: + init + cpuCacheMode + hazardTrackingMode + resourceOptions + setCpuCacheMode + setHazardTrackingMode + setResourceOptions + setSize + setStorageMode + setType + size + storageMode + type +*/ +@(objc_class="MTLHeapDescriptor") +HeapDescriptor :: struct { using _: NS.Copying(HeapDescriptor) } + +@(objc_type=HeapDescriptor, objc_name="alloc", objc_is_class_method=true) +HeapDescriptor_alloc :: #force_inline proc() -> ^HeapDescriptor { + return msgSend(^HeapDescriptor, HeapDescriptor, "alloc") +} +@(objc_type=HeapDescriptor, objc_name="init") +HeapDescriptor_init :: #force_inline proc(self: ^HeapDescriptor) -> ^HeapDescriptor { + return msgSend(^HeapDescriptor, self, "init") +} +@(objc_type=HeapDescriptor, objc_name="cpuCacheMode") +HeapDescriptor_cpuCacheMode :: #force_inline proc(self: ^HeapDescriptor) -> CPUCacheMode { + return msgSend(CPUCacheMode, self, "cpuCacheMode") +} +@(objc_type=HeapDescriptor, objc_name="hazardTrackingMode") +HeapDescriptor_hazardTrackingMode :: #force_inline proc(self: ^HeapDescriptor) -> HazardTrackingMode { + return msgSend(HazardTrackingMode, self, "hazardTrackingMode") +} +@(objc_type=HeapDescriptor, objc_name="resourceOptions") +HeapDescriptor_resourceOptions :: #force_inline proc(self: ^HeapDescriptor) -> ResourceOptions { + return msgSend(ResourceOptions, self, "resourceOptions") +} +@(objc_type=HeapDescriptor, objc_name="setCpuCacheMode") +HeapDescriptor_setCpuCacheMode :: #force_inline proc(self: ^HeapDescriptor, cpuCacheMode: CPUCacheMode) { + msgSend(nil, self, "setCpuCacheMode:", cpuCacheMode) +} +@(objc_type=HeapDescriptor, objc_name="setHazardTrackingMode") +HeapDescriptor_setHazardTrackingMode :: #force_inline proc(self: ^HeapDescriptor, hazardTrackingMode: HazardTrackingMode) { + msgSend(nil, self, "setHazardTrackingMode:", hazardTrackingMode) +} +@(objc_type=HeapDescriptor, objc_name="setResourceOptions") +HeapDescriptor_setResourceOptions :: #force_inline proc(self: ^HeapDescriptor, resourceOptions: ResourceOptions) { + msgSend(nil, self, "setResourceOptions:", resourceOptions) +} +@(objc_type=HeapDescriptor, objc_name="setSize") +HeapDescriptor_setSize :: #force_inline proc(self: ^HeapDescriptor, size: NS.UInteger) { + msgSend(nil, self, "setSize:", size) +} +@(objc_type=HeapDescriptor, objc_name="setStorageMode") +HeapDescriptor_setStorageMode :: #force_inline proc(self: ^HeapDescriptor, storageMode: StorageMode) { + msgSend(nil, self, "setStorageMode:", storageMode) +} +@(objc_type=HeapDescriptor, objc_name="setType") +HeapDescriptor_setType :: #force_inline proc(self: ^HeapDescriptor, type: HeapType) { + msgSend(nil, self, "setType:", type) +} +@(objc_type=HeapDescriptor, objc_name="size") +HeapDescriptor_size :: #force_inline proc(self: ^HeapDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "size") +} +@(objc_type=HeapDescriptor, objc_name="storageMode") +HeapDescriptor_storageMode :: #force_inline proc(self: ^HeapDescriptor) -> StorageMode { + return msgSend(StorageMode, self, "storageMode") +} +@(objc_type=HeapDescriptor, objc_name="type") +HeapDescriptor_type :: #force_inline proc(self: ^HeapDescriptor) -> HeapType { + return msgSend(HeapType, self, "type") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + IndirectCommandBufferDescriptor +Class Methods: + alloc +Methods: + init + commandTypes + inheritBuffers + inheritPipelineState + maxFragmentBufferBindCount + maxKernelBufferBindCount + maxVertexBufferBindCount + setCommandTypes + setInheritBuffers + setInheritPipelineState + setMaxFragmentBufferBindCount + setMaxKernelBufferBindCount + setMaxVertexBufferBindCount +*/ +@(objc_class="MTLIndirectCommandBufferDescriptor") +IndirectCommandBufferDescriptor :: struct { using _: NS.Copying(IndirectCommandBufferDescriptor) } + +@(objc_type=IndirectCommandBufferDescriptor, objc_name="alloc", objc_is_class_method=true) +IndirectCommandBufferDescriptor_alloc :: #force_inline proc() -> ^IndirectCommandBufferDescriptor { + return msgSend(^IndirectCommandBufferDescriptor, IndirectCommandBufferDescriptor, "alloc") +} +@(objc_type=IndirectCommandBufferDescriptor, objc_name="init") +IndirectCommandBufferDescriptor_init :: #force_inline proc(self: ^IndirectCommandBufferDescriptor) -> ^IndirectCommandBufferDescriptor { + return msgSend(^IndirectCommandBufferDescriptor, self, "init") +} +@(objc_type=IndirectCommandBufferDescriptor, objc_name="commandTypes") +IndirectCommandBufferDescriptor_commandTypes :: #force_inline proc(self: ^IndirectCommandBufferDescriptor) -> IndirectCommandType { + return msgSend(IndirectCommandType, self, "commandTypes") +} +@(objc_type=IndirectCommandBufferDescriptor, objc_name="inheritBuffers") +IndirectCommandBufferDescriptor_inheritBuffers :: #force_inline proc(self: ^IndirectCommandBufferDescriptor) -> BOOL { + return msgSend(BOOL, self, "inheritBuffers") +} +@(objc_type=IndirectCommandBufferDescriptor, objc_name="inheritPipelineState") +IndirectCommandBufferDescriptor_inheritPipelineState :: #force_inline proc(self: ^IndirectCommandBufferDescriptor) -> BOOL { + return msgSend(BOOL, self, "inheritPipelineState") +} +@(objc_type=IndirectCommandBufferDescriptor, objc_name="maxFragmentBufferBindCount") +IndirectCommandBufferDescriptor_maxFragmentBufferBindCount :: #force_inline proc(self: ^IndirectCommandBufferDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "maxFragmentBufferBindCount") +} +@(objc_type=IndirectCommandBufferDescriptor, objc_name="maxKernelBufferBindCount") +IndirectCommandBufferDescriptor_maxKernelBufferBindCount :: #force_inline proc(self: ^IndirectCommandBufferDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "maxKernelBufferBindCount") +} +@(objc_type=IndirectCommandBufferDescriptor, objc_name="maxVertexBufferBindCount") +IndirectCommandBufferDescriptor_maxVertexBufferBindCount :: #force_inline proc(self: ^IndirectCommandBufferDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "maxVertexBufferBindCount") +} +@(objc_type=IndirectCommandBufferDescriptor, objc_name="setCommandTypes") +IndirectCommandBufferDescriptor_setCommandTypes :: #force_inline proc(self: ^IndirectCommandBufferDescriptor, commandTypes: IndirectCommandType) { + msgSend(nil, self, "setCommandTypes:", commandTypes) +} +@(objc_type=IndirectCommandBufferDescriptor, objc_name="setInheritBuffers") +IndirectCommandBufferDescriptor_setInheritBuffers :: #force_inline proc(self: ^IndirectCommandBufferDescriptor, inheritBuffers: BOOL) { + msgSend(nil, self, "setInheritBuffers:", inheritBuffers) +} +@(objc_type=IndirectCommandBufferDescriptor, objc_name="setInheritPipelineState") +IndirectCommandBufferDescriptor_setInheritPipelineState :: #force_inline proc(self: ^IndirectCommandBufferDescriptor, inheritPipelineState: BOOL) { + msgSend(nil, self, "setInheritPipelineState:", inheritPipelineState) +} +@(objc_type=IndirectCommandBufferDescriptor, objc_name="setMaxFragmentBufferBindCount") +IndirectCommandBufferDescriptor_setMaxFragmentBufferBindCount :: #force_inline proc(self: ^IndirectCommandBufferDescriptor, maxFragmentBufferBindCount: NS.UInteger) { + msgSend(nil, self, "setMaxFragmentBufferBindCount:", maxFragmentBufferBindCount) +} +@(objc_type=IndirectCommandBufferDescriptor, objc_name="setMaxKernelBufferBindCount") +IndirectCommandBufferDescriptor_setMaxKernelBufferBindCount :: #force_inline proc(self: ^IndirectCommandBufferDescriptor, maxKernelBufferBindCount: NS.UInteger) { + msgSend(nil, self, "setMaxKernelBufferBindCount:", maxKernelBufferBindCount) +} +@(objc_type=IndirectCommandBufferDescriptor, objc_name="setMaxVertexBufferBindCount") +IndirectCommandBufferDescriptor_setMaxVertexBufferBindCount :: #force_inline proc(self: ^IndirectCommandBufferDescriptor, maxVertexBufferBindCount: NS.UInteger) { + msgSend(nil, self, "setMaxVertexBufferBindCount:", maxVertexBufferBindCount) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + InstanceAccelerationStructureDescriptor +Class Methods: + alloc + descriptor +Methods: + init + instanceCount + instanceDescriptorBuffer + instanceDescriptorBufferOffset + instanceDescriptorStride + instancedAccelerationStructures + setInstanceCount + setInstanceDescriptorBuffer + setInstanceDescriptorBufferOffset + setInstanceDescriptorStride + setInstancedAccelerationStructures +*/ +@(objc_class="MTLInstanceAccelerationStructureDescriptor") +InstanceAccelerationStructureDescriptor :: struct { using _: NS.Copying(InstanceAccelerationStructureDescriptor), using _: AccelerationStructureDescriptor } + +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="alloc", objc_is_class_method=true) +InstanceAccelerationStructureDescriptor_alloc :: #force_inline proc() -> ^InstanceAccelerationStructureDescriptor { + return msgSend(^InstanceAccelerationStructureDescriptor, InstanceAccelerationStructureDescriptor, "alloc") +} +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="init") +InstanceAccelerationStructureDescriptor_init :: #force_inline proc(self: ^InstanceAccelerationStructureDescriptor) -> ^InstanceAccelerationStructureDescriptor { + return msgSend(^InstanceAccelerationStructureDescriptor, self, "init") +} +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="descriptor", objc_is_class_method=true) +InstanceAccelerationStructureDescriptor_descriptor :: #force_inline proc() -> ^InstanceAccelerationStructureDescriptor { + return msgSend(^InstanceAccelerationStructureDescriptor, InstanceAccelerationStructureDescriptor, "descriptor") +} +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="instanceCount") +InstanceAccelerationStructureDescriptor_instanceCount :: #force_inline proc(self: ^InstanceAccelerationStructureDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "instanceCount") +} +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="instanceDescriptorBuffer") +InstanceAccelerationStructureDescriptor_instanceDescriptorBuffer :: #force_inline proc(self: ^InstanceAccelerationStructureDescriptor) -> ^Buffer { + return msgSend(^Buffer, self, "instanceDescriptorBuffer") +} +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="instanceDescriptorBufferOffset") +InstanceAccelerationStructureDescriptor_instanceDescriptorBufferOffset :: #force_inline proc(self: ^InstanceAccelerationStructureDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "instanceDescriptorBufferOffset") +} +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="instanceDescriptorStride") +InstanceAccelerationStructureDescriptor_instanceDescriptorStride :: #force_inline proc(self: ^InstanceAccelerationStructureDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "instanceDescriptorStride") +} +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="instancedAccelerationStructures") +InstanceAccelerationStructureDescriptor_instancedAccelerationStructures :: #force_inline proc(self: ^InstanceAccelerationStructureDescriptor) -> ^NS.Array { + return msgSend(^NS.Array, self, "instancedAccelerationStructures") +} +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="setInstanceCount") +InstanceAccelerationStructureDescriptor_setInstanceCount :: #force_inline proc(self: ^InstanceAccelerationStructureDescriptor, instanceCount: NS.UInteger) { + msgSend(nil, self, "setInstanceCount:", instanceCount) +} +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="setInstanceDescriptorBuffer") +InstanceAccelerationStructureDescriptor_setInstanceDescriptorBuffer :: #force_inline proc(self: ^InstanceAccelerationStructureDescriptor, instanceDescriptorBuffer: ^Buffer) { + msgSend(nil, self, "setInstanceDescriptorBuffer:", instanceDescriptorBuffer) +} +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="setInstanceDescriptorBufferOffset") +InstanceAccelerationStructureDescriptor_setInstanceDescriptorBufferOffset :: #force_inline proc(self: ^InstanceAccelerationStructureDescriptor, instanceDescriptorBufferOffset: NS.UInteger) { + msgSend(nil, self, "setInstanceDescriptorBufferOffset:", instanceDescriptorBufferOffset) +} +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="setInstanceDescriptorStride") +InstanceAccelerationStructureDescriptor_setInstanceDescriptorStride :: #force_inline proc(self: ^InstanceAccelerationStructureDescriptor, instanceDescriptorStride: NS.UInteger) { + msgSend(nil, self, "setInstanceDescriptorStride:", instanceDescriptorStride) +} +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="setInstancedAccelerationStructures") +InstanceAccelerationStructureDescriptor_setInstancedAccelerationStructures :: #force_inline proc(self: ^InstanceAccelerationStructureDescriptor, instancedAccelerationStructures: ^NS.Array) { + msgSend(nil, self, "setInstancedAccelerationStructures:", instancedAccelerationStructures) +} + +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="instanceDescriptorType") +InstanceAccelerationStructureDescriptor_instanceDescriptorType :: #force_inline proc(self: ^InstanceAccelerationStructureDescriptor) -> AccelerationStructureInstanceDescriptorType { + return msgSend(AccelerationStructureInstanceDescriptorType, self, "instanceDescriptorType") +} +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="setInstanceDescriptorType") +InstanceAccelerationStructureDescriptor_setInstanceDescriptorType :: #force_inline proc(self: ^InstanceAccelerationStructureDescriptor, buffer: AccelerationStructureInstanceDescriptorType) { + msgSend(nil, self, "setInstanceDescriptorType:", buffer) +} + + +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="motionTransformBuffer") +InstanceAccelerationStructureDescriptor_motionTransformBuffer :: #force_inline proc(self: ^InstanceAccelerationStructureDescriptor) -> ^Buffer { + return msgSend(^Buffer, self, "motionTransformBuffer") +} +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="setMotionTransformBuffer") +InstanceAccelerationStructureDescriptor_setMotionTransformBuffer :: #force_inline proc(self: ^InstanceAccelerationStructureDescriptor, buffer: ^Buffer) { + msgSend(nil, self, "setMotionTransformBuffer:", buffer) +} + + +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="motionTransformBufferOffset") +InstanceAccelerationStructureDescriptor_motionTransformBufferOffset :: #force_inline proc(self: ^InstanceAccelerationStructureDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "motionTransformBufferOffset") +} +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="setMotionTransformBufferOffset") +InstanceAccelerationStructureDescriptor_setMotionTransformBufferOffset :: #force_inline proc(self: ^InstanceAccelerationStructureDescriptor, offset: NS.UInteger) { + msgSend(nil, self, "setMotionTransformBufferOffset:", offset) +} + +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="motionTransformCount") +InstanceAccelerationStructureDescriptor_motionTransformCount :: #force_inline proc(self: ^InstanceAccelerationStructureDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "motionTransformCount") +} +@(objc_type=InstanceAccelerationStructureDescriptor, objc_name="setMotionTransformCount") +InstanceAccelerationStructureDescriptor_setMotionTransformCount :: #force_inline proc(self: ^InstanceAccelerationStructureDescriptor, offset: NS.UInteger) { + msgSend(nil, self, "setMotionTransformCount:", offset) +} + + + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + IntersectionFunctionTableDescriptor +Class Methods: + alloc + intersectionFunctionTableDescriptor +Methods: + init + functionCount + setFunctionCount +*/ +@(objc_class="MTLIntersectionFunctionTableDescriptor") +IntersectionFunctionTableDescriptor :: struct { using _: NS.Copying(IntersectionFunctionTableDescriptor) } + +@(objc_type=IntersectionFunctionTableDescriptor, objc_name="alloc", objc_is_class_method=true) +IntersectionFunctionTableDescriptor_alloc :: #force_inline proc() -> ^IntersectionFunctionTableDescriptor { + return msgSend(^IntersectionFunctionTableDescriptor, IntersectionFunctionTableDescriptor, "alloc") +} +@(objc_type=IntersectionFunctionTableDescriptor, objc_name="init") +IntersectionFunctionTableDescriptor_init :: #force_inline proc(self: ^IntersectionFunctionTableDescriptor) -> ^IntersectionFunctionTableDescriptor { + return msgSend(^IntersectionFunctionTableDescriptor, self, "init") +} +@(objc_type=IntersectionFunctionTableDescriptor, objc_name="functionCount") +IntersectionFunctionTableDescriptor_functionCount :: #force_inline proc(self: ^IntersectionFunctionTableDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "functionCount") +} +@(objc_type=IntersectionFunctionTableDescriptor, objc_name="intersectionFunctionTableDescriptor", objc_is_class_method=true) +IntersectionFunctionTableDescriptor_intersectionFunctionTableDescriptor :: #force_inline proc() -> ^IntersectionFunctionTableDescriptor { + return msgSend(^IntersectionFunctionTableDescriptor, IntersectionFunctionTableDescriptor, "intersectionFunctionTableDescriptor") +} +@(objc_type=IntersectionFunctionTableDescriptor, objc_name="setFunctionCount") +IntersectionFunctionTableDescriptor_setFunctionCount :: #force_inline proc(self: ^IntersectionFunctionTableDescriptor, functionCount: NS.UInteger) { + msgSend(nil, self, "setFunctionCount:", functionCount) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + LinkedFunctions +Class Methods: + alloc + linkedFunctions +Methods: + init + binaryFunctions + functions + groups + setBinaryFunctions + setFunctions + setGroups +*/ +@(objc_class="MTLLinkedFunctions") +LinkedFunctions :: struct { using _: NS.Copying(LinkedFunctions) } + +@(objc_type=LinkedFunctions, objc_name="alloc", objc_is_class_method=true) +LinkedFunctions_alloc :: #force_inline proc() -> ^LinkedFunctions { + return msgSend(^LinkedFunctions, LinkedFunctions, "alloc") +} +@(objc_type=LinkedFunctions, objc_name="init") +LinkedFunctions_init :: #force_inline proc(self: ^LinkedFunctions) -> ^LinkedFunctions { + return msgSend(^LinkedFunctions, self, "init") +} +@(objc_type=LinkedFunctions, objc_name="binaryFunctions") +LinkedFunctions_binaryFunctions :: #force_inline proc(self: ^LinkedFunctions) -> ^NS.Array { + return msgSend(^NS.Array, self, "binaryFunctions") +} +@(objc_type=LinkedFunctions, objc_name="functions") +LinkedFunctions_functions :: #force_inline proc(self: ^LinkedFunctions) -> ^NS.Array { + return msgSend(^NS.Array, self, "functions") +} +@(objc_type=LinkedFunctions, objc_name="groups") +LinkedFunctions_groups :: #force_inline proc(self: ^LinkedFunctions) -> ^NS.Dictionary { + return msgSend(^NS.Dictionary, self, "groups") +} +@(objc_type=LinkedFunctions, objc_name="linkedFunctions", objc_is_class_method=true) +LinkedFunctions_linkedFunctions :: #force_inline proc() -> ^LinkedFunctions { + return msgSend(^LinkedFunctions, LinkedFunctions, "linkedFunctions") +} +@(objc_type=LinkedFunctions, objc_name="setBinaryFunctions") +LinkedFunctions_setBinaryFunctions :: #force_inline proc(self: ^LinkedFunctions, binaryFunctions: ^NS.Array) { + msgSend(nil, self, "setBinaryFunctions:", binaryFunctions) +} +@(objc_type=LinkedFunctions, objc_name="setFunctions") +LinkedFunctions_setFunctions :: #force_inline proc(self: ^LinkedFunctions, functions: ^NS.Array) { + msgSend(nil, self, "setFunctions:", functions) +} +@(objc_type=LinkedFunctions, objc_name="setGroups") +LinkedFunctions_setGroups :: #force_inline proc(self: ^LinkedFunctions, groups: ^NS.Dictionary) { + msgSend(nil, self, "setGroups:", groups) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + PipelineBufferDescriptor +Class Methods: + alloc +Methods: + init + mutability + setMutability +*/ +@(objc_class="MTLPipelineBufferDescriptor") +PipelineBufferDescriptor :: struct { using _: NS.Copying(PipelineBufferDescriptor) } + +@(objc_type=PipelineBufferDescriptor, objc_name="alloc", objc_is_class_method=true) +PipelineBufferDescriptor_alloc :: #force_inline proc() -> ^PipelineBufferDescriptor { + return msgSend(^PipelineBufferDescriptor, PipelineBufferDescriptor, "alloc") +} +@(objc_type=PipelineBufferDescriptor, objc_name="init") +PipelineBufferDescriptor_init :: #force_inline proc(self: ^PipelineBufferDescriptor) -> ^PipelineBufferDescriptor { + return msgSend(^PipelineBufferDescriptor, self, "init") +} +@(objc_type=PipelineBufferDescriptor, objc_name="mutability") +PipelineBufferDescriptor_mutability :: #force_inline proc(self: ^PipelineBufferDescriptor) -> Mutability { + return msgSend(Mutability, self, "mutability") +} +@(objc_type=PipelineBufferDescriptor, objc_name="setMutability") +PipelineBufferDescriptor_setMutability :: #force_inline proc(self: ^PipelineBufferDescriptor, mutability: Mutability) { + msgSend(nil, self, "setMutability:", mutability) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + PipelineBufferDescriptorArray +Class Methods: + alloc +Methods: + init + objectAtIndexedSubscript + setObject +*/ +@(objc_class="MTLPipelineBufferDescriptorArray") +PipelineBufferDescriptorArray :: struct { using _: NS.Object } + +@(objc_type=PipelineBufferDescriptorArray, objc_name="alloc", objc_is_class_method=true) +PipelineBufferDescriptorArray_alloc :: #force_inline proc() -> ^PipelineBufferDescriptorArray { + return msgSend(^PipelineBufferDescriptorArray, PipelineBufferDescriptorArray, "alloc") +} +@(objc_type=PipelineBufferDescriptorArray, objc_name="init") +PipelineBufferDescriptorArray_init :: #force_inline proc(self: ^PipelineBufferDescriptorArray) -> ^PipelineBufferDescriptorArray { + return msgSend(^PipelineBufferDescriptorArray, self, "init") +} +@(objc_type=PipelineBufferDescriptorArray, objc_name="object") +PipelineBufferDescriptorArray_object :: #force_inline proc(self: ^PipelineBufferDescriptorArray, bufferIndex: NS.UInteger) -> ^PipelineBufferDescriptor { + return msgSend(^PipelineBufferDescriptor, self, "objectAtIndexedSubscript:", bufferIndex) +} +@(objc_type=PipelineBufferDescriptorArray, objc_name="setObject") +PipelineBufferDescriptorArray_setObject :: #force_inline proc(self: ^PipelineBufferDescriptorArray, buffer: ^PipelineBufferDescriptor, bufferIndex: NS.UInteger) { + msgSend(nil, self, "setObject:atIndexedSubscript:", buffer, bufferIndex) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + PointerType +Class Methods: + alloc +Methods: + init + access + alignment + dataSize + elementArrayType + elementIsArgumentBuffer + elementStructType + elementType +*/ +@(objc_class="MTLPointerType") +PointerType :: struct { using _: Type } + +@(objc_type=PointerType, objc_name="alloc", objc_is_class_method=true) +PointerType_alloc :: #force_inline proc() -> ^PointerType { + return msgSend(^PointerType, PointerType, "alloc") +} +@(objc_type=PointerType, objc_name="init") +PointerType_init :: #force_inline proc(self: ^PointerType) -> ^PointerType { + return msgSend(^PointerType, self, "init") +} +@(objc_type=PointerType, objc_name="access") +PointerType_access :: #force_inline proc(self: ^PointerType) -> ArgumentAccess { + return msgSend(ArgumentAccess, self, "access") +} +@(objc_type=PointerType, objc_name="alignment") +PointerType_alignment :: #force_inline proc(self: ^PointerType) -> NS.UInteger { + return msgSend(NS.UInteger, self, "alignment") +} +@(objc_type=PointerType, objc_name="dataSize") +PointerType_dataSize :: #force_inline proc(self: ^PointerType) -> NS.UInteger { + return msgSend(NS.UInteger, self, "dataSize") +} +@(objc_type=PointerType, objc_name="elementArrayType") +PointerType_elementArrayType :: #force_inline proc(self: ^PointerType) -> ^ArrayType { + return msgSend(^ArrayType, self, "elementArrayType") +} +@(objc_type=PointerType, objc_name="elementIsArgumentBuffer") +PointerType_elementIsArgumentBuffer :: #force_inline proc(self: ^PointerType) -> BOOL { + return msgSend(BOOL, self, "elementIsArgumentBuffer") +} +@(objc_type=PointerType, objc_name="elementStructType") +PointerType_elementStructType :: #force_inline proc(self: ^PointerType) -> ^StructType { + return msgSend(^StructType, self, "elementStructType") +} +@(objc_type=PointerType, objc_name="elementType") +PointerType_elementType :: #force_inline proc(self: ^PointerType) -> DataType { + return msgSend(DataType, self, "elementType") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + PrimitiveAccelerationStructureDescriptor +Class Methods: + alloc + descriptor +Methods: + init + geometryDescriptors + setGeometryDescriptors +*/ +@(objc_class="MTLPrimitiveAccelerationStructureDescriptor") +PrimitiveAccelerationStructureDescriptor :: struct { using _: NS.Copying(PrimitiveAccelerationStructureDescriptor), using _: AccelerationStructureDescriptor } + +@(objc_type=PrimitiveAccelerationStructureDescriptor, objc_name="alloc", objc_is_class_method=true) +PrimitiveAccelerationStructureDescriptor_alloc :: #force_inline proc() -> ^PrimitiveAccelerationStructureDescriptor { + return msgSend(^PrimitiveAccelerationStructureDescriptor, PrimitiveAccelerationStructureDescriptor, "alloc") +} +@(objc_type=PrimitiveAccelerationStructureDescriptor, objc_name="init") +PrimitiveAccelerationStructureDescriptor_init :: #force_inline proc(self: ^PrimitiveAccelerationStructureDescriptor) -> ^PrimitiveAccelerationStructureDescriptor { + return msgSend(^PrimitiveAccelerationStructureDescriptor, self, "init") +} +@(objc_type=PrimitiveAccelerationStructureDescriptor, objc_name="descriptor", objc_is_class_method=true) +PrimitiveAccelerationStructureDescriptor_descriptor :: #force_inline proc() -> ^PrimitiveAccelerationStructureDescriptor { + return msgSend(^PrimitiveAccelerationStructureDescriptor, PrimitiveAccelerationStructureDescriptor, "descriptor") +} +@(objc_type=PrimitiveAccelerationStructureDescriptor, objc_name="geometryDescriptors") +PrimitiveAccelerationStructureDescriptor_geometryDescriptors :: #force_inline proc(self: ^PrimitiveAccelerationStructureDescriptor) -> ^NS.Array { + return msgSend(^NS.Array, self, "geometryDescriptors") +} +@(objc_type=PrimitiveAccelerationStructureDescriptor, objc_name="setGeometryDescriptors") +PrimitiveAccelerationStructureDescriptor_setGeometryDescriptors :: #force_inline proc(self: ^PrimitiveAccelerationStructureDescriptor, geometryDescriptors: ^NS.Array) { + msgSend(nil, self, "setGeometryDescriptors:", geometryDescriptors) +} + +@(objc_type=PrimitiveAccelerationStructureDescriptor, objc_name="motionStartBorderMode") +PrimitiveAccelerationStructureDescriptor_motionStartBorderMode :: #force_inline proc(self: ^PrimitiveAccelerationStructureDescriptor) -> MotionBorderMode { + return msgSend(MotionBorderMode, self, "motionStartBorderMode") +} +@(objc_type=PrimitiveAccelerationStructureDescriptor, objc_name="setMotionStartBorderMode") +PrimitiveAccelerationStructureDescriptor_setMotionStartBorderMode :: #force_inline proc(self: ^PrimitiveAccelerationStructureDescriptor, motionStartBorderMode: MotionBorderMode) { + msgSend(nil, self, "setMotionStartBorderMode:", motionStartBorderMode) +} + +@(objc_type=PrimitiveAccelerationStructureDescriptor, objc_name="motionEndBorderMode") +PrimitiveAccelerationStructureDescriptor_motionEndBorderMode :: #force_inline proc(self: ^PrimitiveAccelerationStructureDescriptor) -> MotionBorderMode { + return msgSend(MotionBorderMode, self, "motionEndBorderMode") +} +@(objc_type=PrimitiveAccelerationStructureDescriptor, objc_name="setMotionEndBorderMode") +PrimitiveAccelerationStructureDescriptor_setMotionEndBorderMode :: #force_inline proc(self: ^PrimitiveAccelerationStructureDescriptor, motionEndBorderMode: MotionBorderMode) { + msgSend(nil, self, "setMotionEndBorderMode:", motionEndBorderMode) +} + +@(objc_type=PrimitiveAccelerationStructureDescriptor, objc_name="motionStartTime") +PrimitiveAccelerationStructureDescriptor_motionStartTime :: #force_inline proc(self: ^PrimitiveAccelerationStructureDescriptor) -> f32 { + return msgSend(f32, self, "motionStartTime") +} +@(objc_type=PrimitiveAccelerationStructureDescriptor, objc_name="setMotionStartTime") +PrimitiveAccelerationStructureDescriptor_setMotionStartTime :: #force_inline proc(self: ^PrimitiveAccelerationStructureDescriptor, motionStartTime: f32) { + msgSend(nil, self, "setMotionStartTime:", motionStartTime) +} + + +@(objc_type=PrimitiveAccelerationStructureDescriptor, objc_name="motionEndTime") +PrimitiveAccelerationStructureDescriptor_motionEndTime :: #force_inline proc(self: ^PrimitiveAccelerationStructureDescriptor) -> f32 { + return msgSend(f32, self, "motionEndTime") +} +@(objc_type=PrimitiveAccelerationStructureDescriptor, objc_name="setMotionEndTime") +PrimitiveAccelerationStructureDescriptor_setMotionEndTime :: #force_inline proc(self: ^PrimitiveAccelerationStructureDescriptor, motionEndTime: f32) { + msgSend(nil, self, "setMotionEndTime:", motionEndTime) +} + +@(objc_type=PrimitiveAccelerationStructureDescriptor, objc_name="motionKeyframeCount") +PrimitiveAccelerationStructureDescriptor_motionKeyframeCount :: #force_inline proc(self: ^PrimitiveAccelerationStructureDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "motionKeyframeCount") +} +@(objc_type=PrimitiveAccelerationStructureDescriptor, objc_name="setMotionKeyframeCount") +PrimitiveAccelerationStructureDescriptor_setMotionKeyframeCount :: #force_inline proc(self: ^PrimitiveAccelerationStructureDescriptor, motionKeyframeCount: NS.UInteger) { + msgSend(nil, self, "setMotionKeyframeCount:", motionKeyframeCount) +} + + + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + RasterizationRateLayerArray +Class Methods: + alloc +Methods: + init + objectAtIndexedSubscript + setObject +*/ +@(objc_class="MTLRasterizationRateLayerArray") +RasterizationRateLayerArray :: struct { using _: NS.Object } + +@(objc_type=RasterizationRateLayerArray, objc_name="alloc", objc_is_class_method=true) +RasterizationRateLayerArray_alloc :: #force_inline proc() -> ^RasterizationRateLayerArray { + return msgSend(^RasterizationRateLayerArray, RasterizationRateLayerArray, "alloc") +} +@(objc_type=RasterizationRateLayerArray, objc_name="init") +RasterizationRateLayerArray_init :: #force_inline proc(self: ^RasterizationRateLayerArray) -> ^RasterizationRateLayerArray { + return msgSend(^RasterizationRateLayerArray, self, "init") +} +@(objc_type=RasterizationRateLayerArray, objc_name="object") +RasterizationRateLayerArray_object :: #force_inline proc(self: ^RasterizationRateLayerArray, layerIndex: NS.UInteger) -> ^RasterizationRateLayerDescriptor { + return msgSend(^RasterizationRateLayerDescriptor, self, "objectAtIndexedSubscript:", layerIndex) +} +@(objc_type=RasterizationRateLayerArray, objc_name="setObject") +RasterizationRateLayerArray_setObject :: #force_inline proc(self: ^RasterizationRateLayerArray, layer: ^RasterizationRateLayerDescriptor, layerIndex: NS.UInteger) { + msgSend(nil, self, "setObject:atIndexedSubscript:", layer, layerIndex) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + RasterizationRateLayerDescriptor +Class Methods: + alloc +Methods: + horizontal + horizontalSampleStorage + init + initWithSampleCount + initWithSampleCount + sampleCount + vertical + verticalSampleStorage +*/ +@(objc_class="MTLRasterizationRateLayerDescriptor") +RasterizationRateLayerDescriptor :: struct { using _: NS.Copying(RasterizationRateLayerDescriptor) } + +@(objc_type=RasterizationRateLayerDescriptor, objc_name="alloc", objc_is_class_method=true) +RasterizationRateLayerDescriptor_alloc :: #force_inline proc() -> ^RasterizationRateLayerDescriptor { + return msgSend(^RasterizationRateLayerDescriptor, RasterizationRateLayerDescriptor, "alloc") +} +@(objc_type=RasterizationRateLayerDescriptor, objc_name="horizontal") +RasterizationRateLayerDescriptor_horizontal :: #force_inline proc(self: ^RasterizationRateLayerDescriptor) -> ^RasterizationRateSampleArray { + return msgSend(^RasterizationRateSampleArray, self, "horizontal") +} +@(objc_type=RasterizationRateLayerDescriptor, objc_name="horizontalSampleStorage") +RasterizationRateLayerDescriptor_horizontalSampleStorage :: #force_inline proc(self: ^RasterizationRateLayerDescriptor) -> [^]f32 { // TODO: how could this be made into a slice? + return msgSend([^]f32, self, "horizontalSampleStorage") +} +@(objc_type=RasterizationRateLayerDescriptor, objc_name="init") +RasterizationRateLayerDescriptor_init :: #force_inline proc(self: ^RasterizationRateLayerDescriptor) -> ^RasterizationRateLayerDescriptor { + return msgSend(^RasterizationRateLayerDescriptor, self, "init") +} +@(objc_type=RasterizationRateLayerDescriptor, objc_name="initWithSampleCount") +RasterizationRateLayerDescriptor_initWithSampleCount :: #force_inline proc(self: ^RasterizationRateLayerDescriptor, sampleCount: Size) -> ^RasterizationRateLayerDescriptor { + return msgSend(^RasterizationRateLayerDescriptor, self, "initWithSampleCount:", sampleCount) +} +@(objc_type=RasterizationRateLayerDescriptor, objc_name="initWithSampleCountWithDimensions") +RasterizationRateLayerDescriptor_initWithSampleCountWithDimensions :: #force_inline proc(self: ^RasterizationRateLayerDescriptor, sampleCount: Size, horizontal: []f32, vertical: []f32) -> ^RasterizationRateLayerDescriptor { + return msgSend(^RasterizationRateLayerDescriptor, self, "initWithSampleCount:horizontal:vertical:", sampleCount, raw_data(horizontal), raw_data(vertical)) +} +@(objc_type=RasterizationRateLayerDescriptor, objc_name="sampleCount") +RasterizationRateLayerDescriptor_sampleCount :: #force_inline proc(self: ^RasterizationRateLayerDescriptor) -> Size { + return msgSend(Size, self, "sampleCount") +} +@(objc_type=RasterizationRateLayerDescriptor, objc_name="vertical") +RasterizationRateLayerDescriptor_vertical :: #force_inline proc(self: ^RasterizationRateLayerDescriptor) -> ^RasterizationRateSampleArray { + return msgSend(^RasterizationRateSampleArray, self, "vertical") +} +@(objc_type=RasterizationRateLayerDescriptor, objc_name="verticalSampleStorage") +RasterizationRateLayerDescriptor_verticalSampleStorage :: #force_inline proc(self: ^RasterizationRateLayerDescriptor) -> [^]f32 { // TODO: how could this be made into a slice? + return msgSend([^]f32, self, "verticalSampleStorage") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + RasterizationRateMapDescriptor +Class Methods: + alloc + rasterizationRateMapDescriptorWithScreenSize + rasterizationRateMapDescriptorWithScreenSize + rasterizationRateMapDescriptorWithScreenSize +Methods: + init + label + layerAtIndex + layerCount + layers + screenSize + setLabel + setLayer + setScreenSize +*/ +@(objc_class="MTLRasterizationRateMapDescriptor") +RasterizationRateMapDescriptor :: struct { using _: NS.Copying(RasterizationRateMapDescriptor) } + +@(objc_type=RasterizationRateMapDescriptor, objc_name="alloc", objc_is_class_method=true) +RasterizationRateMapDescriptor_alloc :: #force_inline proc() -> ^RasterizationRateMapDescriptor { + return msgSend(^RasterizationRateMapDescriptor, RasterizationRateMapDescriptor, "alloc") +} +@(objc_type=RasterizationRateMapDescriptor, objc_name="init") +RasterizationRateMapDescriptor_init :: #force_inline proc(self: ^RasterizationRateMapDescriptor) -> ^RasterizationRateMapDescriptor { + return msgSend(^RasterizationRateMapDescriptor, self, "init") +} +@(objc_type=RasterizationRateMapDescriptor, objc_name="label") +RasterizationRateMapDescriptor_label :: #force_inline proc(self: ^RasterizationRateMapDescriptor) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=RasterizationRateMapDescriptor, objc_name="layer") +RasterizationRateMapDescriptor_layer :: #force_inline proc(self: ^RasterizationRateMapDescriptor, layerIndex: NS.UInteger) -> ^RasterizationRateLayerDescriptor { + return msgSend(^RasterizationRateLayerDescriptor, self, "layerAtIndex:", layerIndex) +} +@(objc_type=RasterizationRateMapDescriptor, objc_name="layerCount") +RasterizationRateMapDescriptor_layerCount :: #force_inline proc(self: ^RasterizationRateMapDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "layerCount") +} +@(objc_type=RasterizationRateMapDescriptor, objc_name="layers") +RasterizationRateMapDescriptor_layers :: #force_inline proc(self: ^RasterizationRateMapDescriptor) -> ^RasterizationRateLayerArray { + return msgSend(^RasterizationRateLayerArray, self, "layers") +} +@(objc_type=RasterizationRateMapDescriptor, objc_name="rasterizationRateMapDescriptorWithScreenSize", objc_is_class_method=true) +RasterizationRateMapDescriptor_rasterizationRateMapDescriptorWithScreenSize :: #force_inline proc(screenSize: Size) -> ^RasterizationRateMapDescriptor { + return msgSend(^RasterizationRateMapDescriptor, RasterizationRateMapDescriptor, "rasterizationRateMapDescriptorWithScreenSize:", screenSize) +} +@(objc_type=RasterizationRateMapDescriptor, objc_name="rasterizationRateMapDescriptorWithScreenSizeWithLayer", objc_is_class_method=true) +RasterizationRateMapDescriptor_rasterizationRateMapDescriptorWithScreenSizeWithLayer :: #force_inline proc(screenSize: Size, layer: ^RasterizationRateLayerDescriptor) -> ^RasterizationRateMapDescriptor { + return msgSend(^RasterizationRateMapDescriptor, RasterizationRateMapDescriptor, "rasterizationRateMapDescriptorWithScreenSize:layer:", screenSize, layer) +} +@(objc_type=RasterizationRateMapDescriptor, objc_name="rasterizationRateMapDescriptorWithScreenSizeWithLayers", objc_is_class_method=true) +RasterizationRateMapDescriptor_rasterizationRateMapDescriptorWithScreenSizeWithLayers :: #force_inline proc(screenSize: Size, layers: []^RasterizationRateLayerDescriptor) -> ^RasterizationRateMapDescriptor { + return msgSend(^RasterizationRateMapDescriptor, RasterizationRateMapDescriptor, "rasterizationRateMapDescriptorWithScreenSize:layerCount:layers:", screenSize, NS.UInteger(len(layers)), layers) +} +@(objc_type=RasterizationRateMapDescriptor, objc_name="screenSize") +RasterizationRateMapDescriptor_screenSize :: #force_inline proc(self: ^RasterizationRateMapDescriptor) -> Size { + return msgSend(Size, self, "screenSize") +} +@(objc_type=RasterizationRateMapDescriptor, objc_name="setLabel") +RasterizationRateMapDescriptor_setLabel :: #force_inline proc(self: ^RasterizationRateMapDescriptor, label: ^NS.String) { + msgSend(nil, self, "setLabel:", label) +} +@(objc_type=RasterizationRateMapDescriptor, objc_name="setLayer") +RasterizationRateMapDescriptor_setLayer :: #force_inline proc(self: ^RasterizationRateMapDescriptor, layer: ^RasterizationRateLayerDescriptor, layerIndex: NS.UInteger) { + msgSend(nil, self, "setLayer:atIndex:", layer, layerIndex) +} +@(objc_type=RasterizationRateMapDescriptor, objc_name="setScreenSize") +RasterizationRateMapDescriptor_setScreenSize :: #force_inline proc(self: ^RasterizationRateMapDescriptor, screenSize: Size) { + msgSend(nil, self, "setScreenSize:", screenSize) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + RasterizationRateSampleArray +Class Methods: + alloc +Methods: + init + objectAtIndexedSubscript + setObject +*/ +@(objc_class="MTLRasterizationRateSampleArray") +RasterizationRateSampleArray :: struct { using _: NS.Object } + +@(objc_type=RasterizationRateSampleArray, objc_name="alloc", objc_is_class_method=true) +RasterizationRateSampleArray_alloc :: #force_inline proc() -> ^RasterizationRateSampleArray { + return msgSend(^RasterizationRateSampleArray, RasterizationRateSampleArray, "alloc") +} +@(objc_type=RasterizationRateSampleArray, objc_name="init") +RasterizationRateSampleArray_init :: #force_inline proc(self: ^RasterizationRateSampleArray) -> ^RasterizationRateSampleArray { + return msgSend(^RasterizationRateSampleArray, self, "init") +} +@(objc_type=RasterizationRateSampleArray, objc_name="object") +RasterizationRateSampleArray_object :: #force_inline proc(self: ^RasterizationRateSampleArray, index: NS.UInteger) -> ^NS.Number { + return msgSend(^NS.Number, self, "objectAtIndexedSubscript:", index) +} +@(objc_type=RasterizationRateSampleArray, objc_name="setObject") +RasterizationRateSampleArray_setObject :: #force_inline proc(self: ^RasterizationRateSampleArray, value: ^NS.Number, index: NS.UInteger) { + msgSend(nil, self, "setObject:atIndexedSubscript:", value, index) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + RenderPassAttachmentDescriptor +Class Methods: + alloc +Methods: + init + depthPlane + level + loadAction + resolveDepthPlane + resolveLevel + resolveSlice + resolveTexture + setDepthPlane + setLevel + setLoadAction + setResolveDepthPlane + setResolveLevel + setResolveSlice + setResolveTexture + setSlice + setStoreAction + setStoreActionOptions + setTexture + slice + storeAction + storeActionOptions + texture +*/ +@(objc_class="MTLRenderPassAttachmentDescriptor") +RenderPassAttachmentDescriptor :: struct { using _: NS.Copying(RenderPassAttachmentDescriptor) } + +@(objc_type=RenderPassAttachmentDescriptor, objc_name="alloc", objc_is_class_method=true) +RenderPassAttachmentDescriptor_alloc :: #force_inline proc() -> ^RenderPassAttachmentDescriptor { + return msgSend(^RenderPassAttachmentDescriptor, RenderPassAttachmentDescriptor, "alloc") +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="init") +RenderPassAttachmentDescriptor_init :: #force_inline proc(self: ^RenderPassAttachmentDescriptor) -> ^RenderPassAttachmentDescriptor { + return msgSend(^RenderPassAttachmentDescriptor, self, "init") +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="depthPlane") +RenderPassAttachmentDescriptor_depthPlane :: #force_inline proc(self: ^RenderPassAttachmentDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "depthPlane") +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="level") +RenderPassAttachmentDescriptor_level :: #force_inline proc(self: ^RenderPassAttachmentDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "level") +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="loadAction") +RenderPassAttachmentDescriptor_loadAction :: #force_inline proc(self: ^RenderPassAttachmentDescriptor) -> LoadAction { + return msgSend(LoadAction, self, "loadAction") +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="resolveDepthPlane") +RenderPassAttachmentDescriptor_resolveDepthPlane :: #force_inline proc(self: ^RenderPassAttachmentDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "resolveDepthPlane") +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="resolveLevel") +RenderPassAttachmentDescriptor_resolveLevel :: #force_inline proc(self: ^RenderPassAttachmentDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "resolveLevel") +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="resolveSlice") +RenderPassAttachmentDescriptor_resolveSlice :: #force_inline proc(self: ^RenderPassAttachmentDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "resolveSlice") +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="resolveTexture") +RenderPassAttachmentDescriptor_resolveTexture :: #force_inline proc(self: ^RenderPassAttachmentDescriptor) -> ^Texture { + return msgSend(^Texture, self, "resolveTexture") +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="setDepthPlane") +RenderPassAttachmentDescriptor_setDepthPlane :: #force_inline proc(self: ^RenderPassAttachmentDescriptor, depthPlane: NS.UInteger) { + msgSend(nil, self, "setDepthPlane:", depthPlane) +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="setLevel") +RenderPassAttachmentDescriptor_setLevel :: #force_inline proc(self: ^RenderPassAttachmentDescriptor, level: NS.UInteger) { + msgSend(nil, self, "setLevel:", level) +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="setLoadAction") +RenderPassAttachmentDescriptor_setLoadAction :: #force_inline proc(self: ^RenderPassAttachmentDescriptor, loadAction: LoadAction) { + msgSend(nil, self, "setLoadAction:", loadAction) +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="setResolveDepthPlane") +RenderPassAttachmentDescriptor_setResolveDepthPlane :: #force_inline proc(self: ^RenderPassAttachmentDescriptor, resolveDepthPlane: NS.UInteger) { + msgSend(nil, self, "setResolveDepthPlane:", resolveDepthPlane) +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="setResolveLevel") +RenderPassAttachmentDescriptor_setResolveLevel :: #force_inline proc(self: ^RenderPassAttachmentDescriptor, resolveLevel: NS.UInteger) { + msgSend(nil, self, "setResolveLevel:", resolveLevel) +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="setResolveSlice") +RenderPassAttachmentDescriptor_setResolveSlice :: #force_inline proc(self: ^RenderPassAttachmentDescriptor, resolveSlice: NS.UInteger) { + msgSend(nil, self, "setResolveSlice:", resolveSlice) +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="setResolveTexture") +RenderPassAttachmentDescriptor_setResolveTexture :: #force_inline proc(self: ^RenderPassAttachmentDescriptor, resolveTexture: ^Texture) { + msgSend(nil, self, "setResolveTexture:", resolveTexture) +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="setSlice") +RenderPassAttachmentDescriptor_setSlice :: #force_inline proc(self: ^RenderPassAttachmentDescriptor, slice: NS.UInteger) { + msgSend(nil, self, "setSlice:", slice) +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="setStoreAction") +RenderPassAttachmentDescriptor_setStoreAction :: #force_inline proc(self: ^RenderPassAttachmentDescriptor, storeAction: StoreAction) { + msgSend(nil, self, "setStoreAction:", storeAction) +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="setStoreActionOptions") +RenderPassAttachmentDescriptor_setStoreActionOptions :: #force_inline proc(self: ^RenderPassAttachmentDescriptor, storeActionOptions: StoreActionOptions) { + msgSend(nil, self, "setStoreActionOptions:", storeActionOptions) +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="setTexture") +RenderPassAttachmentDescriptor_setTexture :: #force_inline proc(self: ^RenderPassAttachmentDescriptor, texture: ^Texture) { + msgSend(nil, self, "setTexture:", texture) +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="slice") +RenderPassAttachmentDescriptor_slice :: #force_inline proc(self: ^RenderPassAttachmentDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "slice") +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="storeAction") +RenderPassAttachmentDescriptor_storeAction :: #force_inline proc(self: ^RenderPassAttachmentDescriptor) -> StoreAction { + return msgSend(StoreAction, self, "storeAction") +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="storeActionOptions") +RenderPassAttachmentDescriptor_storeActionOptions :: #force_inline proc(self: ^RenderPassAttachmentDescriptor) -> StoreActionOptions { + return msgSend(StoreActionOptions, self, "storeActionOptions") +} +@(objc_type=RenderPassAttachmentDescriptor, objc_name="texture") +RenderPassAttachmentDescriptor_texture :: #force_inline proc(self: ^RenderPassAttachmentDescriptor) -> ^Texture { + return msgSend(^Texture, self, "texture") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + RenderPassColorAttachmentDescriptor +Class Methods: + alloc +Methods: + init + clearColor + setClearColor +*/ +@(objc_class="MTLRenderPassColorAttachmentDescriptor") +RenderPassColorAttachmentDescriptor :: struct { using _: NS.Copying(RenderPassColorAttachmentDescriptor), using _: RenderPassAttachmentDescriptor } + +@(objc_type=RenderPassColorAttachmentDescriptor, objc_name="alloc", objc_is_class_method=true) +RenderPassColorAttachmentDescriptor_alloc :: #force_inline proc() -> ^RenderPassColorAttachmentDescriptor { + return msgSend(^RenderPassColorAttachmentDescriptor, RenderPassColorAttachmentDescriptor, "alloc") +} +@(objc_type=RenderPassColorAttachmentDescriptor, objc_name="init") +RenderPassColorAttachmentDescriptor_init :: #force_inline proc(self: ^RenderPassColorAttachmentDescriptor) -> ^RenderPassColorAttachmentDescriptor { + return msgSend(^RenderPassColorAttachmentDescriptor, self, "init") +} +@(objc_type=RenderPassColorAttachmentDescriptor, objc_name="clearColor") +RenderPassColorAttachmentDescriptor_clearColor :: #force_inline proc(self: ^RenderPassColorAttachmentDescriptor) -> ClearColor { + return msgSend(ClearColor, self, "clearColor") +} +@(objc_type=RenderPassColorAttachmentDescriptor, objc_name="setClearColor") +RenderPassColorAttachmentDescriptor_setClearColor :: #force_inline proc(self: ^RenderPassColorAttachmentDescriptor, clearColor: ClearColor) { + msgSend(nil, self, "setClearColor:", clearColor) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + RenderPassColorAttachmentDescriptorArray +Class Methods: + alloc +Methods: + init + objectAtIndexedSubscript + setObject +*/ +@(objc_class="MTLRenderPassColorAttachmentDescriptorArray") +RenderPassColorAttachmentDescriptorArray :: struct { using _: NS.Object } + +@(objc_type=RenderPassColorAttachmentDescriptorArray, objc_name="alloc", objc_is_class_method=true) +RenderPassColorAttachmentDescriptorArray_alloc :: #force_inline proc() -> ^RenderPassColorAttachmentDescriptorArray { + return msgSend(^RenderPassColorAttachmentDescriptorArray, RenderPassColorAttachmentDescriptorArray, "alloc") +} +@(objc_type=RenderPassColorAttachmentDescriptorArray, objc_name="init") +RenderPassColorAttachmentDescriptorArray_init :: #force_inline proc(self: ^RenderPassColorAttachmentDescriptorArray) -> ^RenderPassColorAttachmentDescriptorArray { + return msgSend(^RenderPassColorAttachmentDescriptorArray, self, "init") +} +@(objc_type=RenderPassColorAttachmentDescriptorArray, objc_name="object") +RenderPassColorAttachmentDescriptorArray_object :: #force_inline proc(self: ^RenderPassColorAttachmentDescriptorArray, attachmentIndex: NS.UInteger) -> ^RenderPassColorAttachmentDescriptor { + return msgSend(^RenderPassColorAttachmentDescriptor, self, "objectAtIndexedSubscript:", attachmentIndex) +} +@(objc_type=RenderPassColorAttachmentDescriptorArray, objc_name="setObject") +RenderPassColorAttachmentDescriptorArray_setObject :: #force_inline proc(self: ^RenderPassColorAttachmentDescriptorArray, attachment: ^RenderPassColorAttachmentDescriptor, attachmentIndex: NS.UInteger) { + msgSend(nil, self, "setObject:atIndexedSubscript:", attachment, attachmentIndex) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + RenderPassDepthAttachmentDescriptor +Class Methods: + alloc +Methods: + init + clearDepth + depthResolveFilter + setClearDepth + setDepthResolveFilter +*/ +@(objc_class="MTLRenderPassDepthAttachmentDescriptor") +RenderPassDepthAttachmentDescriptor :: struct { using _: NS.Copying(RenderPassDepthAttachmentDescriptor), using _: RenderPassAttachmentDescriptor } + +@(objc_type=RenderPassDepthAttachmentDescriptor, objc_name="alloc", objc_is_class_method=true) +RenderPassDepthAttachmentDescriptor_alloc :: #force_inline proc() -> ^RenderPassDepthAttachmentDescriptor { + return msgSend(^RenderPassDepthAttachmentDescriptor, RenderPassDepthAttachmentDescriptor, "alloc") +} +@(objc_type=RenderPassDepthAttachmentDescriptor, objc_name="init") +RenderPassDepthAttachmentDescriptor_init :: #force_inline proc(self: ^RenderPassDepthAttachmentDescriptor) -> ^RenderPassDepthAttachmentDescriptor { + return msgSend(^RenderPassDepthAttachmentDescriptor, self, "init") +} +@(objc_type=RenderPassDepthAttachmentDescriptor, objc_name="clearDepth") +RenderPassDepthAttachmentDescriptor_clearDepth :: #force_inline proc(self: ^RenderPassDepthAttachmentDescriptor) -> f64 { + return msgSend(f64, self, "clearDepth") +} +@(objc_type=RenderPassDepthAttachmentDescriptor, objc_name="depthResolveFilter") +RenderPassDepthAttachmentDescriptor_depthResolveFilter :: #force_inline proc(self: ^RenderPassDepthAttachmentDescriptor) -> MultisampleDepthResolveFilter { + return msgSend(MultisampleDepthResolveFilter, self, "depthResolveFilter") +} +@(objc_type=RenderPassDepthAttachmentDescriptor, objc_name="setClearDepth") +RenderPassDepthAttachmentDescriptor_setClearDepth :: #force_inline proc(self: ^RenderPassDepthAttachmentDescriptor, clearDepth: f64) { + msgSend(nil, self, "setClearDepth:", clearDepth) +} +@(objc_type=RenderPassDepthAttachmentDescriptor, objc_name="setDepthResolveFilter") +RenderPassDepthAttachmentDescriptor_setDepthResolveFilter :: #force_inline proc(self: ^RenderPassDepthAttachmentDescriptor, depthResolveFilter: MultisampleDepthResolveFilter) { + msgSend(nil, self, "setDepthResolveFilter:", depthResolveFilter) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + RenderPassDescriptor +Class Methods: + alloc + renderPassDescriptor +Methods: + init + colorAttachments + defaultRasterSampleCount + depthAttachment + getSamplePositions + imageblockSampleLength + rasterizationRateMap + renderTargetArrayLength + renderTargetHeight + renderTargetWidth + sampleBufferAttachments + setDefaultRasterSampleCount + setDepthAttachment + setImageblockSampleLength + setRasterizationRateMap + setRenderTargetArrayLength + setRenderTargetHeight + setRenderTargetWidth + setSamplePositions + setStencilAttachment + setThreadgroupMemoryLength + setTileHeight + setTileWidth + setVisibilityResultBuffer + stencilAttachment + threadgroupMemoryLength + tileHeight + tileWidth + visibilityResultBuffer +*/ +@(objc_class="MTLRenderPassDescriptor") +RenderPassDescriptor :: struct { using _: NS.Copying(RenderPassDescriptor), using _: AccelerationStructureDescriptor } + +@(objc_type=RenderPassDescriptor, objc_name="alloc", objc_is_class_method=true) +RenderPassDescriptor_alloc :: #force_inline proc() -> ^RenderPassDescriptor { + return msgSend(^RenderPassDescriptor, RenderPassDescriptor, "alloc") +} +@(objc_type=RenderPassDescriptor, objc_name="init") +RenderPassDescriptor_init :: #force_inline proc(self: ^RenderPassDescriptor) -> ^RenderPassDescriptor { + return msgSend(^RenderPassDescriptor, self, "init") +} +@(objc_type=RenderPassDescriptor, objc_name="colorAttachments") +RenderPassDescriptor_colorAttachments :: #force_inline proc(self: ^RenderPassDescriptor) -> ^RenderPassColorAttachmentDescriptorArray { + return msgSend(^RenderPassColorAttachmentDescriptorArray, self, "colorAttachments") +} +@(objc_type=RenderPassDescriptor, objc_name="defaultRasterSampleCount") +RenderPassDescriptor_defaultRasterSampleCount :: #force_inline proc(self: ^RenderPassDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "defaultRasterSampleCount") +} +@(objc_type=RenderPassDescriptor, objc_name="depthAttachment") +RenderPassDescriptor_depthAttachment :: #force_inline proc(self: ^RenderPassDescriptor) -> ^RenderPassDepthAttachmentDescriptor { + return msgSend(^RenderPassDepthAttachmentDescriptor, self, "depthAttachment") +} +@(objc_type=RenderPassDescriptor, objc_name="getSamplePositions") +RenderPassDescriptor_getSamplePositions :: #force_inline proc(self: ^RenderPassDescriptor, positions: []SamplePosition) -> NS.UInteger { + return msgSend(NS.UInteger, self, "getSamplePositions:count:", raw_data(positions), NS.UInteger(len(positions))) +} +@(objc_type=RenderPassDescriptor, objc_name="imageblockSampleLength") +RenderPassDescriptor_imageblockSampleLength :: #force_inline proc(self: ^RenderPassDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "imageblockSampleLength") +} +@(objc_type=RenderPassDescriptor, objc_name="rasterizationRateMap") +RenderPassDescriptor_rasterizationRateMap :: #force_inline proc(self: ^RenderPassDescriptor) -> ^RasterizationRateMap { + return msgSend(^RasterizationRateMap, self, "rasterizationRateMap") +} +@(objc_type=RenderPassDescriptor, objc_name="renderPassDescriptor", objc_is_class_method=true) +RenderPassDescriptor_renderPassDescriptor :: #force_inline proc() -> ^RenderPassDescriptor { + return msgSend(^RenderPassDescriptor, RenderPassDescriptor, "renderPassDescriptor") +} +@(objc_type=RenderPassDescriptor, objc_name="renderTargetArrayLength") +RenderPassDescriptor_renderTargetArrayLength :: #force_inline proc(self: ^RenderPassDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "renderTargetArrayLength") +} +@(objc_type=RenderPassDescriptor, objc_name="renderTargetHeight") +RenderPassDescriptor_renderTargetHeight :: #force_inline proc(self: ^RenderPassDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "renderTargetHeight") +} +@(objc_type=RenderPassDescriptor, objc_name="renderTargetWidth") +RenderPassDescriptor_renderTargetWidth :: #force_inline proc(self: ^RenderPassDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "renderTargetWidth") +} +@(objc_type=RenderPassDescriptor, objc_name="sampleBufferAttachments") +RenderPassDescriptor_sampleBufferAttachments :: #force_inline proc(self: ^RenderPassDescriptor) -> ^RenderPassSampleBufferAttachmentDescriptorArray { + return msgSend(^RenderPassSampleBufferAttachmentDescriptorArray, self, "sampleBufferAttachments") +} +@(objc_type=RenderPassDescriptor, objc_name="setDefaultRasterSampleCount") +RenderPassDescriptor_setDefaultRasterSampleCount :: #force_inline proc(self: ^RenderPassDescriptor, defaultRasterSampleCount: NS.UInteger) { + msgSend(nil, self, "setDefaultRasterSampleCount:", defaultRasterSampleCount) +} +@(objc_type=RenderPassDescriptor, objc_name="setDepthAttachment") +RenderPassDescriptor_setDepthAttachment :: #force_inline proc(self: ^RenderPassDescriptor, depthAttachment: ^RenderPassDepthAttachmentDescriptor) { + msgSend(nil, self, "setDepthAttachment:", depthAttachment) +} +@(objc_type=RenderPassDescriptor, objc_name="setImageblockSampleLength") +RenderPassDescriptor_setImageblockSampleLength :: #force_inline proc(self: ^RenderPassDescriptor, imageblockSampleLength: NS.UInteger) { + msgSend(nil, self, "setImageblockSampleLength:", imageblockSampleLength) +} +@(objc_type=RenderPassDescriptor, objc_name="setRasterizationRateMap") +RenderPassDescriptor_setRasterizationRateMap :: #force_inline proc(self: ^RenderPassDescriptor, rasterizationRateMap: ^RasterizationRateMap) { + msgSend(nil, self, "setRasterizationRateMap:", rasterizationRateMap) +} +@(objc_type=RenderPassDescriptor, objc_name="setRenderTargetArrayLength") +RenderPassDescriptor_setRenderTargetArrayLength :: #force_inline proc(self: ^RenderPassDescriptor, renderTargetArrayLength: NS.UInteger) { + msgSend(nil, self, "setRenderTargetArrayLength:", renderTargetArrayLength) +} +@(objc_type=RenderPassDescriptor, objc_name="setRenderTargetHeight") +RenderPassDescriptor_setRenderTargetHeight :: #force_inline proc(self: ^RenderPassDescriptor, renderTargetHeight: NS.UInteger) { + msgSend(nil, self, "setRenderTargetHeight:", renderTargetHeight) +} +@(objc_type=RenderPassDescriptor, objc_name="setRenderTargetWidth") +RenderPassDescriptor_setRenderTargetWidth :: #force_inline proc(self: ^RenderPassDescriptor, renderTargetWidth: NS.UInteger) { + msgSend(nil, self, "setRenderTargetWidth:", renderTargetWidth) +} +@(objc_type=RenderPassDescriptor, objc_name="setSamplePositions") +RenderPassDescriptor_setSamplePositions :: #force_inline proc(self: ^RenderPassDescriptor, positions: []SamplePosition) { + msgSend(nil, self, "setSamplePositions:count:", raw_data(positions), NS.UInteger(len(positions))) +} +@(objc_type=RenderPassDescriptor, objc_name="setStencilAttachment") +RenderPassDescriptor_setStencilAttachment :: #force_inline proc(self: ^RenderPassDescriptor, stencilAttachment: ^RenderPassStencilAttachmentDescriptor) { + msgSend(nil, self, "setStencilAttachment:", stencilAttachment) +} +@(objc_type=RenderPassDescriptor, objc_name="setThreadgroupMemoryLength") +RenderPassDescriptor_setThreadgroupMemoryLength :: #force_inline proc(self: ^RenderPassDescriptor, threadgroupMemoryLength: NS.UInteger) { + msgSend(nil, self, "setThreadgroupMemoryLength:", threadgroupMemoryLength) +} +@(objc_type=RenderPassDescriptor, objc_name="setTileHeight") +RenderPassDescriptor_setTileHeight :: #force_inline proc(self: ^RenderPassDescriptor, tileHeight: NS.UInteger) { + msgSend(nil, self, "setTileHeight:", tileHeight) +} +@(objc_type=RenderPassDescriptor, objc_name="setTileWidth") +RenderPassDescriptor_setTileWidth :: #force_inline proc(self: ^RenderPassDescriptor, tileWidth: NS.UInteger) { + msgSend(nil, self, "setTileWidth:", tileWidth) +} +@(objc_type=RenderPassDescriptor, objc_name="setVisibilityResultBuffer") +RenderPassDescriptor_setVisibilityResultBuffer :: #force_inline proc(self: ^RenderPassDescriptor, visibilityResultBuffer: ^Buffer) { + msgSend(nil, self, "setVisibilityResultBuffer:", visibilityResultBuffer) +} +@(objc_type=RenderPassDescriptor, objc_name="stencilAttachment") +RenderPassDescriptor_stencilAttachment :: #force_inline proc(self: ^RenderPassDescriptor) -> ^RenderPassStencilAttachmentDescriptor { + return msgSend(^RenderPassStencilAttachmentDescriptor, self, "stencilAttachment") +} +@(objc_type=RenderPassDescriptor, objc_name="threadgroupMemoryLength") +RenderPassDescriptor_threadgroupMemoryLength :: #force_inline proc(self: ^RenderPassDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "threadgroupMemoryLength") +} +@(objc_type=RenderPassDescriptor, objc_name="tileHeight") +RenderPassDescriptor_tileHeight :: #force_inline proc(self: ^RenderPassDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "tileHeight") +} +@(objc_type=RenderPassDescriptor, objc_name="tileWidth") +RenderPassDescriptor_tileWidth :: #force_inline proc(self: ^RenderPassDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "tileWidth") +} +@(objc_type=RenderPassDescriptor, objc_name="visibilityResultBuffer") +RenderPassDescriptor_visibilityResultBuffer :: #force_inline proc(self: ^RenderPassDescriptor) -> ^Buffer { + return msgSend(^Buffer, self, "visibilityResultBuffer") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + RenderPassSampleBufferAttachmentDescriptor +Class Methods: + alloc +Methods: + init + endOfFragmentSampleIndex + endOfVertexSampleIndex + sampleBuffer + setEndOfFragmentSampleIndex + setEndOfVertexSampleIndex + setSampleBuffer + setStartOfFragmentSampleIndex + setStartOfVertexSampleIndex + startOfFragmentSampleIndex + startOfVertexSampleIndex +*/ +@(objc_class="MTLRenderPassSampleBufferAttachmentDescriptor") +RenderPassSampleBufferAttachmentDescriptor :: struct { using _: NS.Copying(RenderPassSampleBufferAttachmentDescriptor) } + +@(objc_type=RenderPassSampleBufferAttachmentDescriptor, objc_name="alloc", objc_is_class_method=true) +RenderPassSampleBufferAttachmentDescriptor_alloc :: #force_inline proc() -> ^RenderPassSampleBufferAttachmentDescriptor { + return msgSend(^RenderPassSampleBufferAttachmentDescriptor, RenderPassSampleBufferAttachmentDescriptor, "alloc") +} +@(objc_type=RenderPassSampleBufferAttachmentDescriptor, objc_name="init") +RenderPassSampleBufferAttachmentDescriptor_init :: #force_inline proc(self: ^RenderPassSampleBufferAttachmentDescriptor) -> ^RenderPassSampleBufferAttachmentDescriptor { + return msgSend(^RenderPassSampleBufferAttachmentDescriptor, self, "init") +} +@(objc_type=RenderPassSampleBufferAttachmentDescriptor, objc_name="endOfFragmentSampleIndex") +RenderPassSampleBufferAttachmentDescriptor_endOfFragmentSampleIndex :: #force_inline proc(self: ^RenderPassSampleBufferAttachmentDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "endOfFragmentSampleIndex") +} +@(objc_type=RenderPassSampleBufferAttachmentDescriptor, objc_name="endOfVertexSampleIndex") +RenderPassSampleBufferAttachmentDescriptor_endOfVertexSampleIndex :: #force_inline proc(self: ^RenderPassSampleBufferAttachmentDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "endOfVertexSampleIndex") +} +@(objc_type=RenderPassSampleBufferAttachmentDescriptor, objc_name="sampleBuffer") +RenderPassSampleBufferAttachmentDescriptor_sampleBuffer :: #force_inline proc(self: ^RenderPassSampleBufferAttachmentDescriptor) -> ^CounterSampleBuffer { + return msgSend(^CounterSampleBuffer, self, "sampleBuffer") +} +@(objc_type=RenderPassSampleBufferAttachmentDescriptor, objc_name="setEndOfFragmentSampleIndex") +RenderPassSampleBufferAttachmentDescriptor_setEndOfFragmentSampleIndex :: #force_inline proc(self: ^RenderPassSampleBufferAttachmentDescriptor, endOfFragmentSampleIndex: NS.UInteger) { + msgSend(nil, self, "setEndOfFragmentSampleIndex:", endOfFragmentSampleIndex) +} +@(objc_type=RenderPassSampleBufferAttachmentDescriptor, objc_name="setEndOfVertexSampleIndex") +RenderPassSampleBufferAttachmentDescriptor_setEndOfVertexSampleIndex :: #force_inline proc(self: ^RenderPassSampleBufferAttachmentDescriptor, endOfVertexSampleIndex: NS.UInteger) { + msgSend(nil, self, "setEndOfVertexSampleIndex:", endOfVertexSampleIndex) +} +@(objc_type=RenderPassSampleBufferAttachmentDescriptor, objc_name="setSampleBuffer") +RenderPassSampleBufferAttachmentDescriptor_setSampleBuffer :: #force_inline proc(self: ^RenderPassSampleBufferAttachmentDescriptor, sampleBuffer: ^CounterSampleBuffer) { + msgSend(nil, self, "setSampleBuffer:", sampleBuffer) +} +@(objc_type=RenderPassSampleBufferAttachmentDescriptor, objc_name="setStartOfFragmentSampleIndex") +RenderPassSampleBufferAttachmentDescriptor_setStartOfFragmentSampleIndex :: #force_inline proc(self: ^RenderPassSampleBufferAttachmentDescriptor, startOfFragmentSampleIndex: NS.UInteger) { + msgSend(nil, self, "setStartOfFragmentSampleIndex:", startOfFragmentSampleIndex) +} +@(objc_type=RenderPassSampleBufferAttachmentDescriptor, objc_name="setStartOfVertexSampleIndex") +RenderPassSampleBufferAttachmentDescriptor_setStartOfVertexSampleIndex :: #force_inline proc(self: ^RenderPassSampleBufferAttachmentDescriptor, startOfVertexSampleIndex: NS.UInteger) { + msgSend(nil, self, "setStartOfVertexSampleIndex:", startOfVertexSampleIndex) +} +@(objc_type=RenderPassSampleBufferAttachmentDescriptor, objc_name="startOfFragmentSampleIndex") +RenderPassSampleBufferAttachmentDescriptor_startOfFragmentSampleIndex :: #force_inline proc(self: ^RenderPassSampleBufferAttachmentDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "startOfFragmentSampleIndex") +} +@(objc_type=RenderPassSampleBufferAttachmentDescriptor, objc_name="startOfVertexSampleIndex") +RenderPassSampleBufferAttachmentDescriptor_startOfVertexSampleIndex :: #force_inline proc(self: ^RenderPassSampleBufferAttachmentDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "startOfVertexSampleIndex") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + RenderPassSampleBufferAttachmentDescriptorArray +Class Methods: + alloc +Methods: + init + objectAtIndexedSubscript + setObject +*/ +@(objc_class="MTLRenderPassSampleBufferAttachmentDescriptorArray") +RenderPassSampleBufferAttachmentDescriptorArray :: struct { using _: NS.Object } + +@(objc_type=RenderPassSampleBufferAttachmentDescriptorArray, objc_name="alloc", objc_is_class_method=true) +RenderPassSampleBufferAttachmentDescriptorArray_alloc :: #force_inline proc() -> ^RenderPassSampleBufferAttachmentDescriptorArray { + return msgSend(^RenderPassSampleBufferAttachmentDescriptorArray, RenderPassSampleBufferAttachmentDescriptorArray, "alloc") +} +@(objc_type=RenderPassSampleBufferAttachmentDescriptorArray, objc_name="init") +RenderPassSampleBufferAttachmentDescriptorArray_init :: #force_inline proc(self: ^RenderPassSampleBufferAttachmentDescriptorArray) -> ^RenderPassSampleBufferAttachmentDescriptorArray { + return msgSend(^RenderPassSampleBufferAttachmentDescriptorArray, self, "init") +} +@(objc_type=RenderPassSampleBufferAttachmentDescriptorArray, objc_name="object") +RenderPassSampleBufferAttachmentDescriptorArray_object :: #force_inline proc(self: ^RenderPassSampleBufferAttachmentDescriptorArray, attachmentIndex: NS.UInteger) -> ^RenderPassSampleBufferAttachmentDescriptor { + return msgSend(^RenderPassSampleBufferAttachmentDescriptor, self, "objectAtIndexedSubscript:", attachmentIndex) +} +@(objc_type=RenderPassSampleBufferAttachmentDescriptorArray, objc_name="setObject") +RenderPassSampleBufferAttachmentDescriptorArray_setObject :: #force_inline proc(self: ^RenderPassSampleBufferAttachmentDescriptorArray, attachment: ^RenderPassSampleBufferAttachmentDescriptor, attachmentIndex: NS.UInteger) { + msgSend(nil, self, "setObject:atIndexedSubscript:", attachment, attachmentIndex) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + RenderPassStencilAttachmentDescriptor +Class Methods: + alloc +Methods: + init + clearStencil + setClearStencil + setStencilResolveFilter + stencilResolveFilter +*/ +@(objc_class="MTLRenderPassStencilAttachmentDescriptor") +RenderPassStencilAttachmentDescriptor :: struct { using _: NS.Copying(RenderPassStencilAttachmentDescriptor) } + +@(objc_type=RenderPassStencilAttachmentDescriptor, objc_name="alloc", objc_is_class_method=true) +RenderPassStencilAttachmentDescriptor_alloc :: #force_inline proc() -> ^RenderPassStencilAttachmentDescriptor { + return msgSend(^RenderPassStencilAttachmentDescriptor, RenderPassStencilAttachmentDescriptor, "alloc") +} +@(objc_type=RenderPassStencilAttachmentDescriptor, objc_name="init") +RenderPassStencilAttachmentDescriptor_init :: #force_inline proc(self: ^RenderPassStencilAttachmentDescriptor) -> ^RenderPassStencilAttachmentDescriptor { + return msgSend(^RenderPassStencilAttachmentDescriptor, self, "init") +} +@(objc_type=RenderPassStencilAttachmentDescriptor, objc_name="clearStencil") +RenderPassStencilAttachmentDescriptor_clearStencil :: #force_inline proc(self: ^RenderPassStencilAttachmentDescriptor) -> u32 { + return msgSend(u32, self, "clearStencil") +} +@(objc_type=RenderPassStencilAttachmentDescriptor, objc_name="setClearStencil") +RenderPassStencilAttachmentDescriptor_setClearStencil :: #force_inline proc(self: ^RenderPassStencilAttachmentDescriptor, clearStencil: u32) { + msgSend(nil, self, "setClearStencil:", clearStencil) +} +@(objc_type=RenderPassStencilAttachmentDescriptor, objc_name="setStencilResolveFilter") +RenderPassStencilAttachmentDescriptor_setStencilResolveFilter :: #force_inline proc(self: ^RenderPassStencilAttachmentDescriptor, stencilResolveFilter: MultisampleStencilResolveFilter) { + msgSend(nil, self, "setStencilResolveFilter:", stencilResolveFilter) +} +@(objc_type=RenderPassStencilAttachmentDescriptor, objc_name="stencilResolveFilter") +RenderPassStencilAttachmentDescriptor_stencilResolveFilter :: #force_inline proc(self: ^RenderPassStencilAttachmentDescriptor) -> MultisampleStencilResolveFilter { + return msgSend(MultisampleStencilResolveFilter, self, "stencilResolveFilter") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + RenderPipelineColorAttachmentDescriptor +Class Methods: + alloc +Methods: + init + alphaBlendOperation + destinationAlphaBlendFactor + destinationRGBBlendFactor + isBlendingEnabled + pixelFormat + rgbBlendOperation + setAlphaBlendOperation + setBlendingEnabled + setDestinationAlphaBlendFactor + setDestinationRGBBlendFactor + setPixelFormat + setRgbBlendOperation + setSourceAlphaBlendFactor + setSourceRGBBlendFactor + setWriteMask + sourceAlphaBlendFactor + sourceRGBBlendFactor + writeMask +*/ +@(objc_class="MTLRenderPipelineColorAttachmentDescriptor") +RenderPipelineColorAttachmentDescriptor :: struct { using _: NS.Copying(RenderPipelineColorAttachmentDescriptor), using _: RenderPassAttachmentDescriptor } + +@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_name="alloc", objc_is_class_method=true) +RenderPipelineColorAttachmentDescriptor_alloc :: #force_inline proc() -> ^RenderPipelineColorAttachmentDescriptor { + return msgSend(^RenderPipelineColorAttachmentDescriptor, RenderPipelineColorAttachmentDescriptor, "alloc") +} +@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_name="init") +RenderPipelineColorAttachmentDescriptor_init :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptor) -> ^RenderPipelineColorAttachmentDescriptor { + return msgSend(^RenderPipelineColorAttachmentDescriptor, self, "init") +} +@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_name="alphaBlendOperation") +RenderPipelineColorAttachmentDescriptor_alphaBlendOperation :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptor) -> BlendOperation { + return msgSend(BlendOperation, self, "alphaBlendOperation") +} +@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_name="destinationAlphaBlendFactor") +RenderPipelineColorAttachmentDescriptor_destinationAlphaBlendFactor :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptor) -> BlendFactor { + return msgSend(BlendFactor, self, "destinationAlphaBlendFactor") +} +@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_name="destinationRGBBlendFactor") +RenderPipelineColorAttachmentDescriptor_destinationRGBBlendFactor :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptor) -> BlendFactor { + return msgSend(BlendFactor, self, "destinationRGBBlendFactor") +} +@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_name="isBlendingEnabled") +RenderPipelineColorAttachmentDescriptor_isBlendingEnabled :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptor) -> BOOL { + return msgSend(BOOL, self, "isBlendingEnabled") +} +@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_name="pixelFormat") +RenderPipelineColorAttachmentDescriptor_pixelFormat :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptor) -> PixelFormat { + return msgSend(PixelFormat, self, "pixelFormat") +} +@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_name="rgbBlendOperation") +RenderPipelineColorAttachmentDescriptor_rgbBlendOperation :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptor) -> BlendOperation { + return msgSend(BlendOperation, self, "rgbBlendOperation") +} +@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_name="setAlphaBlendOperation") +RenderPipelineColorAttachmentDescriptor_setAlphaBlendOperation :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptor, alphaBlendOperation: BlendOperation) { + msgSend(nil, self, "setAlphaBlendOperation:", alphaBlendOperation) +} +@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_name="setBlendingEnabled") +RenderPipelineColorAttachmentDescriptor_setBlendingEnabled :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptor, blendingEnabled: BOOL) { + msgSend(nil, self, "setBlendingEnabled:", blendingEnabled) +} +@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_name="setDestinationAlphaBlendFactor") +RenderPipelineColorAttachmentDescriptor_setDestinationAlphaBlendFactor :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptor, destinationAlphaBlendFactor: BlendFactor) { + msgSend(nil, self, "setDestinationAlphaBlendFactor:", destinationAlphaBlendFactor) +} +@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_name="setDestinationRGBBlendFactor") +RenderPipelineColorAttachmentDescriptor_setDestinationRGBBlendFactor :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptor, destinationRGBBlendFactor: BlendFactor) { + msgSend(nil, self, "setDestinationRGBBlendFactor:", destinationRGBBlendFactor) +} +@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_name="setPixelFormat") +RenderPipelineColorAttachmentDescriptor_setPixelFormat :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptor, pixelFormat: PixelFormat) { + msgSend(nil, self, "setPixelFormat:", pixelFormat) +} +@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_name="setRgbBlendOperation") +RenderPipelineColorAttachmentDescriptor_setRgbBlendOperation :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptor, rgbBlendOperation: BlendOperation) { + msgSend(nil, self, "setRgbBlendOperation:", rgbBlendOperation) +} +@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_name="setSourceAlphaBlendFactor") +RenderPipelineColorAttachmentDescriptor_setSourceAlphaBlendFactor :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptor, sourceAlphaBlendFactor: BlendFactor) { + msgSend(nil, self, "setSourceAlphaBlendFactor:", sourceAlphaBlendFactor) +} +@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_name="setSourceRGBBlendFactor") +RenderPipelineColorAttachmentDescriptor_setSourceRGBBlendFactor :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptor, sourceRGBBlendFactor: BlendFactor) { + msgSend(nil, self, "setSourceRGBBlendFactor:", sourceRGBBlendFactor) +} +@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_name="setWriteMask") +RenderPipelineColorAttachmentDescriptor_setWriteMask :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptor, writeMask: ColorWriteMask) { + msgSend(nil, self, "setWriteMask:", writeMask) +} +@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_name="sourceAlphaBlendFactor") +RenderPipelineColorAttachmentDescriptor_sourceAlphaBlendFactor :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptor) -> BlendFactor { + return msgSend(BlendFactor, self, "sourceAlphaBlendFactor") +} +@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_name="sourceRGBBlendFactor") +RenderPipelineColorAttachmentDescriptor_sourceRGBBlendFactor :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptor) -> BlendFactor { + return msgSend(BlendFactor, self, "sourceRGBBlendFactor") +} +@(objc_type=RenderPipelineColorAttachmentDescriptor, objc_name="writeMask") +RenderPipelineColorAttachmentDescriptor_writeMask :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptor) -> ColorWriteMask { + return msgSend(ColorWriteMask, self, "writeMask") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + RenderPipelineColorAttachmentDescriptorArray +Class Methods: + alloc +Methods: + init + objectAtIndexedSubscript + setObject +*/ +@(objc_class="MTLRenderPipelineColorAttachmentDescriptorArray") +RenderPipelineColorAttachmentDescriptorArray :: struct { using _: NS.Object } + +@(objc_type=RenderPipelineColorAttachmentDescriptorArray, objc_name="alloc", objc_is_class_method=true) +RenderPipelineColorAttachmentDescriptorArray_alloc :: #force_inline proc() -> ^RenderPipelineColorAttachmentDescriptorArray { + return msgSend(^RenderPipelineColorAttachmentDescriptorArray, RenderPipelineColorAttachmentDescriptorArray, "alloc") +} +@(objc_type=RenderPipelineColorAttachmentDescriptorArray, objc_name="init") +RenderPipelineColorAttachmentDescriptorArray_init :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptorArray) -> ^RenderPipelineColorAttachmentDescriptorArray { + return msgSend(^RenderPipelineColorAttachmentDescriptorArray, self, "init") +} +@(objc_type=RenderPipelineColorAttachmentDescriptorArray, objc_name="object") +RenderPipelineColorAttachmentDescriptorArray_object :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptorArray, attachmentIndex: NS.UInteger) -> ^RenderPipelineColorAttachmentDescriptor { + return msgSend(^RenderPipelineColorAttachmentDescriptor, self, "objectAtIndexedSubscript:", attachmentIndex) +} +@(objc_type=RenderPipelineColorAttachmentDescriptorArray, objc_name="setObject") +RenderPipelineColorAttachmentDescriptorArray_setObject :: #force_inline proc(self: ^RenderPipelineColorAttachmentDescriptorArray, attachment: ^RenderPipelineColorAttachmentDescriptor, attachmentIndex: NS.UInteger) { + msgSend(nil, self, "setObject:atIndexedSubscript:", attachment, attachmentIndex) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + RenderPipelineDescriptor +Class Methods: + alloc +Methods: + init + binaryArchives + colorAttachments + depthAttachmentPixelFormat + fragmentBuffers + fragmentFunction + inputPrimitiveTopology + isAlphaToCoverageEnabled + isAlphaToOneEnabled + isRasterizationEnabled + isTessellationFactorScaleEnabled + label + maxTessellationFactor + maxVertexAmplificationCount + rasterSampleCount + reset + sampleCount + setAlphaToCoverageEnabled + setAlphaToOneEnabled + setBinaryArchives + setDepthAttachmentPixelFormat + setFragmentFunction + setInputPrimitiveTopology + setLabel + setMaxTessellationFactor + setMaxVertexAmplificationCount + setRasterSampleCount + setRasterizationEnabled + setSampleCount + setStencilAttachmentPixelFormat + setSupportIndirectCommandBuffers + setTessellationControlPointIndexType + setTessellationFactorFormat + setTessellationFactorScaleEnabled + setTessellationFactorStepFunction + setTessellationOutputWindingOrder + setTessellationPartitionMode + setVertexDescriptor + setVertexFunction + stencilAttachmentPixelFormat + supportIndirectCommandBuffers + tessellationControlPointIndexType + tessellationFactorFormat + tessellationFactorStepFunction + tessellationOutputWindingOrder + tessellationPartitionMode + vertexBuffers + vertexDescriptor + vertexFunction +*/ +@(objc_class="MTLRenderPipelineDescriptor") +RenderPipelineDescriptor :: struct { using _: NS.Copying(RenderPipelineDescriptor) } + +@(objc_type=RenderPipelineDescriptor, objc_name="alloc", objc_is_class_method=true) +RenderPipelineDescriptor_alloc :: #force_inline proc() -> ^RenderPipelineDescriptor { + return msgSend(^RenderPipelineDescriptor, RenderPipelineDescriptor, "alloc") +} +@(objc_type=RenderPipelineDescriptor, objc_name="init") +RenderPipelineDescriptor_init :: #force_inline proc(self: ^RenderPipelineDescriptor) -> ^RenderPipelineDescriptor { + return msgSend(^RenderPipelineDescriptor, self, "init") +} +@(objc_type=RenderPipelineDescriptor, objc_name="binaryArchives") +RenderPipelineDescriptor_binaryArchives :: #force_inline proc(self: ^RenderPipelineDescriptor) -> ^NS.Array { + return msgSend(^NS.Array, self, "binaryArchives") +} +@(objc_type=RenderPipelineDescriptor, objc_name="colorAttachments") +RenderPipelineDescriptor_colorAttachments :: #force_inline proc(self: ^RenderPipelineDescriptor) -> ^RenderPipelineColorAttachmentDescriptorArray { + return msgSend(^RenderPipelineColorAttachmentDescriptorArray, self, "colorAttachments") +} +@(objc_type=RenderPipelineDescriptor, objc_name="depthAttachmentPixelFormat") +RenderPipelineDescriptor_depthAttachmentPixelFormat :: #force_inline proc(self: ^RenderPipelineDescriptor) -> PixelFormat { + return msgSend(PixelFormat, self, "depthAttachmentPixelFormat") +} +@(objc_type=RenderPipelineDescriptor, objc_name="fragmentBuffers") +RenderPipelineDescriptor_fragmentBuffers :: #force_inline proc(self: ^RenderPipelineDescriptor) -> ^PipelineBufferDescriptorArray { + return msgSend(^PipelineBufferDescriptorArray, self, "fragmentBuffers") +} +@(objc_type=RenderPipelineDescriptor, objc_name="fragmentFunction") +RenderPipelineDescriptor_fragmentFunction :: #force_inline proc(self: ^RenderPipelineDescriptor) -> ^Function { + return msgSend(^Function, self, "fragmentFunction") +} +@(objc_type=RenderPipelineDescriptor, objc_name="inputPrimitiveTopology") +RenderPipelineDescriptor_inputPrimitiveTopology :: #force_inline proc(self: ^RenderPipelineDescriptor) -> PrimitiveTopologyClass { + return msgSend(PrimitiveTopologyClass, self, "inputPrimitiveTopology") +} +@(objc_type=RenderPipelineDescriptor, objc_name="isAlphaToCoverageEnabled") +RenderPipelineDescriptor_isAlphaToCoverageEnabled :: #force_inline proc(self: ^RenderPipelineDescriptor) -> BOOL { + return msgSend(BOOL, self, "isAlphaToCoverageEnabled") +} +@(objc_type=RenderPipelineDescriptor, objc_name="isAlphaToOneEnabled") +RenderPipelineDescriptor_isAlphaToOneEnabled :: #force_inline proc(self: ^RenderPipelineDescriptor) -> BOOL { + return msgSend(BOOL, self, "isAlphaToOneEnabled") +} +@(objc_type=RenderPipelineDescriptor, objc_name="isRasterizationEnabled") +RenderPipelineDescriptor_isRasterizationEnabled :: #force_inline proc(self: ^RenderPipelineDescriptor) -> BOOL { + return msgSend(BOOL, self, "isRasterizationEnabled") +} +@(objc_type=RenderPipelineDescriptor, objc_name="isTessellationFactorScaleEnabled") +RenderPipelineDescriptor_isTessellationFactorScaleEnabled :: #force_inline proc(self: ^RenderPipelineDescriptor) -> BOOL { + return msgSend(BOOL, self, "isTessellationFactorScaleEnabled") +} +@(objc_type=RenderPipelineDescriptor, objc_name="label") +RenderPipelineDescriptor_label :: #force_inline proc(self: ^RenderPipelineDescriptor) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=RenderPipelineDescriptor, objc_name="maxTessellationFactor") +RenderPipelineDescriptor_maxTessellationFactor :: #force_inline proc(self: ^RenderPipelineDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "maxTessellationFactor") +} +@(objc_type=RenderPipelineDescriptor, objc_name="maxVertexAmplificationCount") +RenderPipelineDescriptor_maxVertexAmplificationCount :: #force_inline proc(self: ^RenderPipelineDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "maxVertexAmplificationCount") +} +@(objc_type=RenderPipelineDescriptor, objc_name="rasterSampleCount") +RenderPipelineDescriptor_rasterSampleCount :: #force_inline proc(self: ^RenderPipelineDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "rasterSampleCount") +} +@(objc_type=RenderPipelineDescriptor, objc_name="reset") +RenderPipelineDescriptor_reset :: #force_inline proc(self: ^RenderPipelineDescriptor) { + msgSend(nil, self, "reset") +} +@(objc_type=RenderPipelineDescriptor, objc_name="sampleCount") +RenderPipelineDescriptor_sampleCount :: #force_inline proc(self: ^RenderPipelineDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "sampleCount") +} +@(objc_type=RenderPipelineDescriptor, objc_name="setAlphaToCoverageEnabled") +RenderPipelineDescriptor_setAlphaToCoverageEnabled :: #force_inline proc(self: ^RenderPipelineDescriptor, alphaToCoverageEnabled: BOOL) { + msgSend(nil, self, "setAlphaToCoverageEnabled:", alphaToCoverageEnabled) +} +@(objc_type=RenderPipelineDescriptor, objc_name="setAlphaToOneEnabled") +RenderPipelineDescriptor_setAlphaToOneEnabled :: #force_inline proc(self: ^RenderPipelineDescriptor, alphaToOneEnabled: BOOL) { + msgSend(nil, self, "setAlphaToOneEnabled:", alphaToOneEnabled) +} +@(objc_type=RenderPipelineDescriptor, objc_name="setBinaryArchives") +RenderPipelineDescriptor_setBinaryArchives :: #force_inline proc(self: ^RenderPipelineDescriptor, binaryArchives: ^NS.Array) { + msgSend(nil, self, "setBinaryArchives:", binaryArchives) +} +@(objc_type=RenderPipelineDescriptor, objc_name="setDepthAttachmentPixelFormat") +RenderPipelineDescriptor_setDepthAttachmentPixelFormat :: #force_inline proc(self: ^RenderPipelineDescriptor, depthAttachmentPixelFormat: PixelFormat) { + msgSend(nil, self, "setDepthAttachmentPixelFormat:", depthAttachmentPixelFormat) +} +@(objc_type=RenderPipelineDescriptor, objc_name="setFragmentFunction") +RenderPipelineDescriptor_setFragmentFunction :: #force_inline proc(self: ^RenderPipelineDescriptor, fragmentFunction: ^Function) { + msgSend(nil, self, "setFragmentFunction:", fragmentFunction) +} +@(objc_type=RenderPipelineDescriptor, objc_name="setInputPrimitiveTopology") +RenderPipelineDescriptor_setInputPrimitiveTopology :: #force_inline proc(self: ^RenderPipelineDescriptor, inputPrimitiveTopology: PrimitiveTopologyClass) { + msgSend(nil, self, "setInputPrimitiveTopology:", inputPrimitiveTopology) +} +@(objc_type=RenderPipelineDescriptor, objc_name="setLabel") +RenderPipelineDescriptor_setLabel :: #force_inline proc(self: ^RenderPipelineDescriptor, label: ^NS.String) { + msgSend(nil, self, "setLabel:", label) +} +@(objc_type=RenderPipelineDescriptor, objc_name="setMaxTessellationFactor") +RenderPipelineDescriptor_setMaxTessellationFactor :: #force_inline proc(self: ^RenderPipelineDescriptor, maxTessellationFactor: NS.UInteger) { + msgSend(nil, self, "setMaxTessellationFactor:", maxTessellationFactor) +} +@(objc_type=RenderPipelineDescriptor, objc_name="setMaxVertexAmplificationCount") +RenderPipelineDescriptor_setMaxVertexAmplificationCount :: #force_inline proc(self: ^RenderPipelineDescriptor, maxVertexAmplificationCount: NS.UInteger) { + msgSend(nil, self, "setMaxVertexAmplificationCount:", maxVertexAmplificationCount) +} +@(objc_type=RenderPipelineDescriptor, objc_name="setRasterSampleCount") +RenderPipelineDescriptor_setRasterSampleCount :: #force_inline proc(self: ^RenderPipelineDescriptor, rasterSampleCount: NS.UInteger) { + msgSend(nil, self, "setRasterSampleCount:", rasterSampleCount) +} +@(objc_type=RenderPipelineDescriptor, objc_name="setRasterizationEnabled") +RenderPipelineDescriptor_setRasterizationEnabled :: #force_inline proc(self: ^RenderPipelineDescriptor, rasterizationEnabled: BOOL) { + msgSend(nil, self, "setRasterizationEnabled:", rasterizationEnabled) +} +@(objc_type=RenderPipelineDescriptor, objc_name="setSampleCount") +RenderPipelineDescriptor_setSampleCount :: #force_inline proc(self: ^RenderPipelineDescriptor, sampleCount: NS.UInteger) { + msgSend(nil, self, "setSampleCount:", sampleCount) +} +@(objc_type=RenderPipelineDescriptor, objc_name="setStencilAttachmentPixelFormat") +RenderPipelineDescriptor_setStencilAttachmentPixelFormat :: #force_inline proc(self: ^RenderPipelineDescriptor, stencilAttachmentPixelFormat: PixelFormat) { + msgSend(nil, self, "setStencilAttachmentPixelFormat:", stencilAttachmentPixelFormat) +} +@(objc_type=RenderPipelineDescriptor, objc_name="setSupportIndirectCommandBuffers") +RenderPipelineDescriptor_setSupportIndirectCommandBuffers :: #force_inline proc(self: ^RenderPipelineDescriptor, supportIndirectCommandBuffers: BOOL) { + msgSend(nil, self, "setSupportIndirectCommandBuffers:", supportIndirectCommandBuffers) +} +@(objc_type=RenderPipelineDescriptor, objc_name="setTessellationControlPointIndexType") +RenderPipelineDescriptor_setTessellationControlPointIndexType :: #force_inline proc(self: ^RenderPipelineDescriptor, tessellationControlPointIndexType: TessellationControlPointIndexType) { + msgSend(nil, self, "setTessellationControlPointIndexType:", tessellationControlPointIndexType) +} +@(objc_type=RenderPipelineDescriptor, objc_name="setTessellationFactorFormat") +RenderPipelineDescriptor_setTessellationFactorFormat :: #force_inline proc(self: ^RenderPipelineDescriptor, tessellationFactorFormat: TessellationFactorFormat) { + msgSend(nil, self, "setTessellationFactorFormat:", tessellationFactorFormat) +} +@(objc_type=RenderPipelineDescriptor, objc_name="setTessellationFactorScaleEnabled") +RenderPipelineDescriptor_setTessellationFactorScaleEnabled :: #force_inline proc(self: ^RenderPipelineDescriptor, tessellationFactorScaleEnabled: BOOL) { + msgSend(nil, self, "setTessellationFactorScaleEnabled:", tessellationFactorScaleEnabled) +} +@(objc_type=RenderPipelineDescriptor, objc_name="setTessellationFactorStepFunction") +RenderPipelineDescriptor_setTessellationFactorStepFunction :: #force_inline proc(self: ^RenderPipelineDescriptor, tessellationFactorStepFunction: TessellationFactorStepFunction) { + msgSend(nil, self, "setTessellationFactorStepFunction:", tessellationFactorStepFunction) +} +@(objc_type=RenderPipelineDescriptor, objc_name="setTessellationOutputWindingOrder") +RenderPipelineDescriptor_setTessellationOutputWindingOrder :: #force_inline proc(self: ^RenderPipelineDescriptor, tessellationOutputWindingOrder: Winding) { + msgSend(nil, self, "setTessellationOutputWindingOrder:", tessellationOutputWindingOrder) +} +@(objc_type=RenderPipelineDescriptor, objc_name="setTessellationPartitionMode") +RenderPipelineDescriptor_setTessellationPartitionMode :: #force_inline proc(self: ^RenderPipelineDescriptor, tessellationPartitionMode: TessellationPartitionMode) { + msgSend(nil, self, "setTessellationPartitionMode:", tessellationPartitionMode) +} +@(objc_type=RenderPipelineDescriptor, objc_name="setVertexDescriptor") +RenderPipelineDescriptor_setVertexDescriptor :: #force_inline proc(self: ^RenderPipelineDescriptor, vertexDescriptor: ^VertexDescriptor) { + msgSend(nil, self, "setVertexDescriptor:", vertexDescriptor) +} +@(objc_type=RenderPipelineDescriptor, objc_name="setVertexFunction") +RenderPipelineDescriptor_setVertexFunction :: #force_inline proc(self: ^RenderPipelineDescriptor, vertexFunction: ^Function) { + msgSend(nil, self, "setVertexFunction:", vertexFunction) +} +@(objc_type=RenderPipelineDescriptor, objc_name="stencilAttachmentPixelFormat") +RenderPipelineDescriptor_stencilAttachmentPixelFormat :: #force_inline proc(self: ^RenderPipelineDescriptor) -> PixelFormat { + return msgSend(PixelFormat, self, "stencilAttachmentPixelFormat") +} +@(objc_type=RenderPipelineDescriptor, objc_name="supportIndirectCommandBuffers") +RenderPipelineDescriptor_supportIndirectCommandBuffers :: #force_inline proc(self: ^RenderPipelineDescriptor) -> BOOL { + return msgSend(BOOL, self, "supportIndirectCommandBuffers") +} +@(objc_type=RenderPipelineDescriptor, objc_name="tessellationControlPointIndexType") +RenderPipelineDescriptor_tessellationControlPointIndexType :: #force_inline proc(self: ^RenderPipelineDescriptor) -> TessellationControlPointIndexType { + return msgSend(TessellationControlPointIndexType, self, "tessellationControlPointIndexType") +} +@(objc_type=RenderPipelineDescriptor, objc_name="tessellationFactorFormat") +RenderPipelineDescriptor_tessellationFactorFormat :: #force_inline proc(self: ^RenderPipelineDescriptor) -> TessellationFactorFormat { + return msgSend(TessellationFactorFormat, self, "tessellationFactorFormat") +} +@(objc_type=RenderPipelineDescriptor, objc_name="tessellationFactorStepFunction") +RenderPipelineDescriptor_tessellationFactorStepFunction :: #force_inline proc(self: ^RenderPipelineDescriptor) -> TessellationFactorStepFunction { + return msgSend(TessellationFactorStepFunction, self, "tessellationFactorStepFunction") +} +@(objc_type=RenderPipelineDescriptor, objc_name="tessellationOutputWindingOrder") +RenderPipelineDescriptor_tessellationOutputWindingOrder :: #force_inline proc(self: ^RenderPipelineDescriptor) -> Winding { + return msgSend(Winding, self, "tessellationOutputWindingOrder") +} +@(objc_type=RenderPipelineDescriptor, objc_name="tessellationPartitionMode") +RenderPipelineDescriptor_tessellationPartitionMode :: #force_inline proc(self: ^RenderPipelineDescriptor) -> TessellationPartitionMode { + return msgSend(TessellationPartitionMode, self, "tessellationPartitionMode") +} +@(objc_type=RenderPipelineDescriptor, objc_name="vertexBuffers") +RenderPipelineDescriptor_vertexBuffers :: #force_inline proc(self: ^RenderPipelineDescriptor) -> ^PipelineBufferDescriptorArray { + return msgSend(^PipelineBufferDescriptorArray, self, "vertexBuffers") +} +@(objc_type=RenderPipelineDescriptor, objc_name="vertexDescriptor") +RenderPipelineDescriptor_vertexDescriptor :: #force_inline proc(self: ^RenderPipelineDescriptor) -> ^VertexDescriptor { + return msgSend(^VertexDescriptor, self, "vertexDescriptor") +} +@(objc_type=RenderPipelineDescriptor, objc_name="vertexFunction") +RenderPipelineDescriptor_vertexFunction :: #force_inline proc(self: ^RenderPipelineDescriptor) -> ^Function { + return msgSend(^Function, self, "vertexFunction") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + RenderPipelineReflection +Class Methods: + alloc +Methods: + init + fragmentArguments + tileArguments + vertexArguments +*/ +@(objc_class="MTLRenderPipelineReflection") +RenderPipelineReflection :: struct { using _: NS.Object } + +@(objc_type=RenderPipelineReflection, objc_name="alloc", objc_is_class_method=true) +RenderPipelineReflection_alloc :: #force_inline proc() -> ^RenderPipelineReflection { + return msgSend(^RenderPipelineReflection, RenderPipelineReflection, "alloc") +} +@(objc_type=RenderPipelineReflection, objc_name="init") +RenderPipelineReflection_init :: #force_inline proc(self: ^RenderPipelineReflection) -> ^RenderPipelineReflection { + return msgSend(^RenderPipelineReflection, self, "init") +} +@(objc_type=RenderPipelineReflection, objc_name="fragmentArguments") +RenderPipelineReflection_fragmentArguments :: #force_inline proc(self: ^RenderPipelineReflection) -> ^NS.Array { + return msgSend(^NS.Array, self, "fragmentArguments") +} +@(objc_type=RenderPipelineReflection, objc_name="tileArguments") +RenderPipelineReflection_tileArguments :: #force_inline proc(self: ^RenderPipelineReflection) -> ^NS.Array { + return msgSend(^NS.Array, self, "tileArguments") +} +@(objc_type=RenderPipelineReflection, objc_name="vertexArguments") +RenderPipelineReflection_vertexArguments :: #force_inline proc(self: ^RenderPipelineReflection) -> ^NS.Array { + return msgSend(^NS.Array, self, "vertexArguments") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + ResourceStatePassDescriptor +Class Methods: + alloc + resourceStatePassDescriptor +Methods: + init + sampleBufferAttachments +*/ +@(objc_class="MTLResourceStatePassDescriptor") +ResourceStatePassDescriptor :: struct { using _: NS.Copying(ResourceStatePassDescriptor) } + +@(objc_type=ResourceStatePassDescriptor, objc_name="alloc", objc_is_class_method=true) +ResourceStatePassDescriptor_alloc :: #force_inline proc() -> ^ResourceStatePassDescriptor { + return msgSend(^ResourceStatePassDescriptor, ResourceStatePassDescriptor, "alloc") +} +@(objc_type=ResourceStatePassDescriptor, objc_name="init") +ResourceStatePassDescriptor_init :: #force_inline proc(self: ^ResourceStatePassDescriptor) -> ^ResourceStatePassDescriptor { + return msgSend(^ResourceStatePassDescriptor, self, "init") +} +@(objc_type=ResourceStatePassDescriptor, objc_name="resourceStatePassDescriptor", objc_is_class_method=true) +ResourceStatePassDescriptor_resourceStatePassDescriptor :: #force_inline proc() -> ^ResourceStatePassDescriptor { + return msgSend(^ResourceStatePassDescriptor, ResourceStatePassDescriptor, "resourceStatePassDescriptor") +} +@(objc_type=ResourceStatePassDescriptor, objc_name="sampleBufferAttachments") +ResourceStatePassDescriptor_sampleBufferAttachments :: #force_inline proc(self: ^ResourceStatePassDescriptor) -> ^ResourceStatePassSampleBufferAttachmentDescriptorArray { + return msgSend(^ResourceStatePassSampleBufferAttachmentDescriptorArray, self, "sampleBufferAttachments") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + ResourceStatePassSampleBufferAttachmentDescriptor +Class Methods: + alloc +Methods: + init + endOfEncoderSampleIndex + sampleBuffer + setEndOfEncoderSampleIndex + setSampleBuffer + setStartOfEncoderSampleIndex + startOfEncoderSampleIndex +*/ +@(objc_class="MTLResourceStatePassSampleBufferAttachmentDescriptor") +ResourceStatePassSampleBufferAttachmentDescriptor :: struct { using _: NS.Copying(ResourceStatePassSampleBufferAttachmentDescriptor) } + +@(objc_type=ResourceStatePassSampleBufferAttachmentDescriptor, objc_name="alloc", objc_is_class_method=true) +ResourceStatePassSampleBufferAttachmentDescriptor_alloc :: #force_inline proc() -> ^ResourceStatePassSampleBufferAttachmentDescriptor { + return msgSend(^ResourceStatePassSampleBufferAttachmentDescriptor, ResourceStatePassSampleBufferAttachmentDescriptor, "alloc") +} +@(objc_type=ResourceStatePassSampleBufferAttachmentDescriptor, objc_name="init") +ResourceStatePassSampleBufferAttachmentDescriptor_init :: #force_inline proc(self: ^ResourceStatePassSampleBufferAttachmentDescriptor) -> ^ResourceStatePassSampleBufferAttachmentDescriptor { + return msgSend(^ResourceStatePassSampleBufferAttachmentDescriptor, self, "init") +} +@(objc_type=ResourceStatePassSampleBufferAttachmentDescriptor, objc_name="endOfEncoderSampleIndex") +ResourceStatePassSampleBufferAttachmentDescriptor_endOfEncoderSampleIndex :: #force_inline proc(self: ^ResourceStatePassSampleBufferAttachmentDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "endOfEncoderSampleIndex") +} +@(objc_type=ResourceStatePassSampleBufferAttachmentDescriptor, objc_name="sampleBuffer") +ResourceStatePassSampleBufferAttachmentDescriptor_sampleBuffer :: #force_inline proc(self: ^ResourceStatePassSampleBufferAttachmentDescriptor) -> ^CounterSampleBuffer { + return msgSend(^CounterSampleBuffer, self, "sampleBuffer") +} +@(objc_type=ResourceStatePassSampleBufferAttachmentDescriptor, objc_name="setEndOfEncoderSampleIndex") +ResourceStatePassSampleBufferAttachmentDescriptor_setEndOfEncoderSampleIndex :: #force_inline proc(self: ^ResourceStatePassSampleBufferAttachmentDescriptor, endOfEncoderSampleIndex: NS.UInteger) { + msgSend(nil, self, "setEndOfEncoderSampleIndex:", endOfEncoderSampleIndex) +} +@(objc_type=ResourceStatePassSampleBufferAttachmentDescriptor, objc_name="setSampleBuffer") +ResourceStatePassSampleBufferAttachmentDescriptor_setSampleBuffer :: #force_inline proc(self: ^ResourceStatePassSampleBufferAttachmentDescriptor, sampleBuffer: ^CounterSampleBuffer) { + msgSend(nil, self, "setSampleBuffer:", sampleBuffer) +} +@(objc_type=ResourceStatePassSampleBufferAttachmentDescriptor, objc_name="setStartOfEncoderSampleIndex") +ResourceStatePassSampleBufferAttachmentDescriptor_setStartOfEncoderSampleIndex :: #force_inline proc(self: ^ResourceStatePassSampleBufferAttachmentDescriptor, startOfEncoderSampleIndex: NS.UInteger) { + msgSend(nil, self, "setStartOfEncoderSampleIndex:", startOfEncoderSampleIndex) +} +@(objc_type=ResourceStatePassSampleBufferAttachmentDescriptor, objc_name="startOfEncoderSampleIndex") +ResourceStatePassSampleBufferAttachmentDescriptor_startOfEncoderSampleIndex :: #force_inline proc(self: ^ResourceStatePassSampleBufferAttachmentDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "startOfEncoderSampleIndex") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + ResourceStatePassSampleBufferAttachmentDescriptorArray +Class Methods: + alloc +Methods: + init + objectAtIndexedSubscript + setObject +*/ +@(objc_class="MTLResourceStatePassSampleBufferAttachmentDescriptorArray") +ResourceStatePassSampleBufferAttachmentDescriptorArray :: struct { using _: NS.Object } + +@(objc_type=ResourceStatePassSampleBufferAttachmentDescriptorArray, objc_name="alloc", objc_is_class_method=true) +ResourceStatePassSampleBufferAttachmentDescriptorArray_alloc :: #force_inline proc() -> ^ResourceStatePassSampleBufferAttachmentDescriptorArray { + return msgSend(^ResourceStatePassSampleBufferAttachmentDescriptorArray, ResourceStatePassSampleBufferAttachmentDescriptorArray, "alloc") +} +@(objc_type=ResourceStatePassSampleBufferAttachmentDescriptorArray, objc_name="init") +ResourceStatePassSampleBufferAttachmentDescriptorArray_init :: #force_inline proc(self: ^ResourceStatePassSampleBufferAttachmentDescriptorArray) -> ^ResourceStatePassSampleBufferAttachmentDescriptorArray { + return msgSend(^ResourceStatePassSampleBufferAttachmentDescriptorArray, self, "init") +} +@(objc_type=ResourceStatePassSampleBufferAttachmentDescriptorArray, objc_name="object") +ResourceStatePassSampleBufferAttachmentDescriptorArray_object :: #force_inline proc(self: ^ResourceStatePassSampleBufferAttachmentDescriptorArray, attachmentIndex: NS.UInteger) -> ^ResourceStatePassSampleBufferAttachmentDescriptor { + return msgSend(^ResourceStatePassSampleBufferAttachmentDescriptor, self, "objectAtIndexedSubscript:", attachmentIndex) +} +@(objc_type=ResourceStatePassSampleBufferAttachmentDescriptorArray, objc_name="setObject") +ResourceStatePassSampleBufferAttachmentDescriptorArray_setObject :: #force_inline proc(self: ^ResourceStatePassSampleBufferAttachmentDescriptorArray, attachment: ^ResourceStatePassSampleBufferAttachmentDescriptor, attachmentIndex: NS.UInteger) { + msgSend(nil, self, "setObject:atIndexedSubscript:", attachment, attachmentIndex) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + SamplerDescriptor +Class Methods: + alloc +Methods: + init + borderColor + compareFunction + label + lodAverage + lodMaxClamp + lodMinClamp + magFilter + maxAnisotropy + minFilter + mipFilter + normalizedCoordinates + rAddressMode + sAddressMode + setBorderColor + setCompareFunction + setLabel + setLodAverage + setLodMaxClamp + setLodMinClamp + setMagFilter + setMaxAnisotropy + setMinFilter + setMipFilter + setNormalizedCoordinates + setRAddressMode + setSAddressMode + setSupportArgumentBuffers + setTAddressMode + supportArgumentBuffers + tAddressMode +*/ +@(objc_class="MTLSamplerDescriptor") +SamplerDescriptor :: struct { using _: NS.Copying(SamplerDescriptor) } + +@(objc_type=SamplerDescriptor, objc_name="alloc", objc_is_class_method=true) +SamplerDescriptor_alloc :: #force_inline proc() -> ^SamplerDescriptor { + return msgSend(^SamplerDescriptor, SamplerDescriptor, "alloc") +} +@(objc_type=SamplerDescriptor, objc_name="init") +SamplerDescriptor_init :: #force_inline proc(self: ^SamplerDescriptor) -> ^SamplerDescriptor { + return msgSend(^SamplerDescriptor, self, "init") +} +@(objc_type=SamplerDescriptor, objc_name="borderColor") +SamplerDescriptor_borderColor :: #force_inline proc(self: ^SamplerDescriptor) -> SamplerBorderColor { + return msgSend(SamplerBorderColor, self, "borderColor") +} +@(objc_type=SamplerDescriptor, objc_name="compareFunction") +SamplerDescriptor_compareFunction :: #force_inline proc(self: ^SamplerDescriptor) -> CompareFunction { + return msgSend(CompareFunction, self, "compareFunction") +} +@(objc_type=SamplerDescriptor, objc_name="label") +SamplerDescriptor_label :: #force_inline proc(self: ^SamplerDescriptor) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=SamplerDescriptor, objc_name="lodAverage") +SamplerDescriptor_lodAverage :: #force_inline proc(self: ^SamplerDescriptor) -> BOOL { + return msgSend(BOOL, self, "lodAverage") +} +@(objc_type=SamplerDescriptor, objc_name="lodMaxClamp") +SamplerDescriptor_lodMaxClamp :: #force_inline proc(self: ^SamplerDescriptor) -> f32 { + return msgSend(f32, self, "lodMaxClamp") +} +@(objc_type=SamplerDescriptor, objc_name="lodMinClamp") +SamplerDescriptor_lodMinClamp :: #force_inline proc(self: ^SamplerDescriptor) -> f32 { + return msgSend(f32, self, "lodMinClamp") +} +@(objc_type=SamplerDescriptor, objc_name="magFilter") +SamplerDescriptor_magFilter :: #force_inline proc(self: ^SamplerDescriptor) -> SamplerMinMagFilter { + return msgSend(SamplerMinMagFilter, self, "magFilter") +} +@(objc_type=SamplerDescriptor, objc_name="maxAnisotropy") +SamplerDescriptor_maxAnisotropy :: #force_inline proc(self: ^SamplerDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "maxAnisotropy") +} +@(objc_type=SamplerDescriptor, objc_name="minFilter") +SamplerDescriptor_minFilter :: #force_inline proc(self: ^SamplerDescriptor) -> SamplerMinMagFilter { + return msgSend(SamplerMinMagFilter, self, "minFilter") +} +@(objc_type=SamplerDescriptor, objc_name="mipFilter") +SamplerDescriptor_mipFilter :: #force_inline proc(self: ^SamplerDescriptor) -> SamplerMipFilter { + return msgSend(SamplerMipFilter, self, "mipFilter") +} +@(objc_type=SamplerDescriptor, objc_name="normalizedCoordinates") +SamplerDescriptor_normalizedCoordinates :: #force_inline proc(self: ^SamplerDescriptor) -> BOOL { + return msgSend(BOOL, self, "normalizedCoordinates") +} +@(objc_type=SamplerDescriptor, objc_name="rAddressMode") +SamplerDescriptor_rAddressMode :: #force_inline proc(self: ^SamplerDescriptor) -> SamplerAddressMode { + return msgSend(SamplerAddressMode, self, "rAddressMode") +} +@(objc_type=SamplerDescriptor, objc_name="sAddressMode") +SamplerDescriptor_sAddressMode :: #force_inline proc(self: ^SamplerDescriptor) -> SamplerAddressMode { + return msgSend(SamplerAddressMode, self, "sAddressMode") +} +@(objc_type=SamplerDescriptor, objc_name="setBorderColor") +SamplerDescriptor_setBorderColor :: #force_inline proc(self: ^SamplerDescriptor, borderColor: SamplerBorderColor) { + msgSend(nil, self, "setBorderColor:", borderColor) +} +@(objc_type=SamplerDescriptor, objc_name="setCompareFunction") +SamplerDescriptor_setCompareFunction :: #force_inline proc(self: ^SamplerDescriptor, compareFunction: CompareFunction) { + msgSend(nil, self, "setCompareFunction:", compareFunction) +} +@(objc_type=SamplerDescriptor, objc_name="setLabel") +SamplerDescriptor_setLabel :: #force_inline proc(self: ^SamplerDescriptor, label: ^NS.String) { + msgSend(nil, self, "setLabel:", label) +} +@(objc_type=SamplerDescriptor, objc_name="setLodAverage") +SamplerDescriptor_setLodAverage :: #force_inline proc(self: ^SamplerDescriptor, lodAverage: BOOL) { + msgSend(nil, self, "setLodAverage:", lodAverage) +} +@(objc_type=SamplerDescriptor, objc_name="setLodMaxClamp") +SamplerDescriptor_setLodMaxClamp :: #force_inline proc(self: ^SamplerDescriptor, lodMaxClamp: f32) { + msgSend(nil, self, "setLodMaxClamp:", lodMaxClamp) +} +@(objc_type=SamplerDescriptor, objc_name="setLodMinClamp") +SamplerDescriptor_setLodMinClamp :: #force_inline proc(self: ^SamplerDescriptor, lodMinClamp: f32) { + msgSend(nil, self, "setLodMinClamp:", lodMinClamp) +} +@(objc_type=SamplerDescriptor, objc_name="setMagFilter") +SamplerDescriptor_setMagFilter :: #force_inline proc(self: ^SamplerDescriptor, magFilter: SamplerMinMagFilter) { + msgSend(nil, self, "setMagFilter:", magFilter) +} +@(objc_type=SamplerDescriptor, objc_name="setMaxAnisotropy") +SamplerDescriptor_setMaxAnisotropy :: #force_inline proc(self: ^SamplerDescriptor, maxAnisotropy: NS.UInteger) { + msgSend(nil, self, "setMaxAnisotropy:", maxAnisotropy) +} +@(objc_type=SamplerDescriptor, objc_name="setMinFilter") +SamplerDescriptor_setMinFilter :: #force_inline proc(self: ^SamplerDescriptor, minFilter: SamplerMinMagFilter) { + msgSend(nil, self, "setMinFilter:", minFilter) +} +@(objc_type=SamplerDescriptor, objc_name="setMipFilter") +SamplerDescriptor_setMipFilter :: #force_inline proc(self: ^SamplerDescriptor, mipFilter: SamplerMipFilter) { + msgSend(nil, self, "setMipFilter:", mipFilter) +} +@(objc_type=SamplerDescriptor, objc_name="setNormalizedCoordinates") +SamplerDescriptor_setNormalizedCoordinates :: #force_inline proc(self: ^SamplerDescriptor, normalizedCoordinates: BOOL) { + msgSend(nil, self, "setNormalizedCoordinates:", normalizedCoordinates) +} +@(objc_type=SamplerDescriptor, objc_name="setRAddressMode") +SamplerDescriptor_setRAddressMode :: #force_inline proc(self: ^SamplerDescriptor, rAddressMode: SamplerAddressMode) { + msgSend(nil, self, "setRAddressMode:", rAddressMode) +} +@(objc_type=SamplerDescriptor, objc_name="setSAddressMode") +SamplerDescriptor_setSAddressMode :: #force_inline proc(self: ^SamplerDescriptor, sAddressMode: SamplerAddressMode) { + msgSend(nil, self, "setSAddressMode:", sAddressMode) +} +@(objc_type=SamplerDescriptor, objc_name="setSupportArgumentBuffers") +SamplerDescriptor_setSupportArgumentBuffers :: #force_inline proc(self: ^SamplerDescriptor, supportArgumentBuffers: BOOL) { + msgSend(nil, self, "setSupportArgumentBuffers:", supportArgumentBuffers) +} +@(objc_type=SamplerDescriptor, objc_name="setTAddressMode") +SamplerDescriptor_setTAddressMode :: #force_inline proc(self: ^SamplerDescriptor, tAddressMode: SamplerAddressMode) { + msgSend(nil, self, "setTAddressMode:", tAddressMode) +} +@(objc_type=SamplerDescriptor, objc_name="supportArgumentBuffers") +SamplerDescriptor_supportArgumentBuffers :: #force_inline proc(self: ^SamplerDescriptor) -> BOOL { + return msgSend(BOOL, self, "supportArgumentBuffers") +} +@(objc_type=SamplerDescriptor, objc_name="tAddressMode") +SamplerDescriptor_tAddressMode :: #force_inline proc(self: ^SamplerDescriptor) -> SamplerAddressMode { + return msgSend(SamplerAddressMode, self, "tAddressMode") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + SharedEventHandle +Class Methods: + alloc +Methods: + init + label +*/ +@(objc_class="MTLSharedEventHandle") +SharedEventHandle :: struct { using _: NS.Object } + +@(objc_type=SharedEventHandle, objc_name="alloc", objc_is_class_method=true) +SharedEventHandle_alloc :: #force_inline proc() -> ^SharedEventHandle { + return msgSend(^SharedEventHandle, SharedEventHandle, "alloc") +} +@(objc_type=SharedEventHandle, objc_name="init") +SharedEventHandle_init :: #force_inline proc(self: ^SharedEventHandle) -> ^SharedEventHandle { + return msgSend(^SharedEventHandle, self, "init") +} +@(objc_type=SharedEventHandle, objc_name="label") +SharedEventHandle_label :: #force_inline proc(self: ^SharedEventHandle) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + SharedEventListener +Class Methods: + alloc +Methods: + dispatchQueue + init + initWithDispatchQueue +*/ +@(objc_class="MTLSharedEventListener") +SharedEventListener :: struct { using _: NS.Object } + +@(objc_type=SharedEventListener, objc_name="alloc", objc_is_class_method=true) +SharedEventListener_alloc :: #force_inline proc() -> ^SharedEventListener { + return msgSend(^SharedEventListener, SharedEventListener, "alloc") +} +@(objc_type=SharedEventListener, objc_name="dispatchQueue") +SharedEventListener_dispatchQueue :: #force_inline proc(self: ^SharedEventListener) -> dispatch_queue_t { + return msgSend(dispatch_queue_t, self, "dispatchQueue") +} +@(objc_type=SharedEventListener, objc_name="init") +SharedEventListener_init :: #force_inline proc(self: ^SharedEventListener) -> ^SharedEventListener { + return msgSend(^SharedEventListener, self, "init") +} +@(objc_type=SharedEventListener, objc_name="initWithDispatchQueue") +SharedEventListener_initWithDispatchQueue :: #force_inline proc(self: ^SharedEventListener, dispatchQueue: dispatch_queue_t) -> ^SharedEventListener { + return msgSend(^SharedEventListener, self, "initWithDispatchQueue:", dispatchQueue) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + SharedTextureHandle +Class Methods: + alloc +Methods: + init + device + label +*/ +@(objc_class="MTLSharedTextureHandle") +SharedTextureHandle :: struct { using _: NS.Object } + +@(objc_type=SharedTextureHandle, objc_name="alloc", objc_is_class_method=true) +SharedTextureHandle_alloc :: #force_inline proc() -> ^SharedTextureHandle { + return msgSend(^SharedTextureHandle, SharedTextureHandle, "alloc") +} +@(objc_type=SharedTextureHandle, objc_name="init") +SharedTextureHandle_init :: #force_inline proc(self: ^SharedTextureHandle) -> ^SharedTextureHandle { + return msgSend(^SharedTextureHandle, self, "init") +} +@(objc_type=SharedTextureHandle, objc_name="device") +SharedTextureHandle_device :: #force_inline proc(self: ^SharedTextureHandle) -> ^Device { + return msgSend(^Device, self, "device") +} +@(objc_type=SharedTextureHandle, objc_name="label") +SharedTextureHandle_label :: #force_inline proc(self: ^SharedTextureHandle) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + StageInputOutputDescriptor +Class Methods: + alloc + stageInputOutputDescriptor +Methods: + init + attributes + indexBufferIndex + indexType + layouts + reset + setIndexBufferIndex + setIndexType +*/ +@(objc_class="MTLStageInputOutputDescriptor") +StageInputOutputDescriptor :: struct { using _: NS.Copying(StageInputOutputDescriptor) } + +@(objc_type=StageInputOutputDescriptor, objc_name="alloc", objc_is_class_method=true) +StageInputOutputDescriptor_alloc :: #force_inline proc() -> ^StageInputOutputDescriptor { + return msgSend(^StageInputOutputDescriptor, StageInputOutputDescriptor, "alloc") +} +@(objc_type=StageInputOutputDescriptor, objc_name="init") +StageInputOutputDescriptor_init :: #force_inline proc(self: ^StageInputOutputDescriptor) -> ^StageInputOutputDescriptor { + return msgSend(^StageInputOutputDescriptor, self, "init") +} +@(objc_type=StageInputOutputDescriptor, objc_name="attributes") +StageInputOutputDescriptor_attributes :: #force_inline proc(self: ^StageInputOutputDescriptor) -> ^AttributeDescriptorArray { + return msgSend(^AttributeDescriptorArray, self, "attributes") +} +@(objc_type=StageInputOutputDescriptor, objc_name="indexBufferIndex") +StageInputOutputDescriptor_indexBufferIndex :: #force_inline proc(self: ^StageInputOutputDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "indexBufferIndex") +} +@(objc_type=StageInputOutputDescriptor, objc_name="indexType") +StageInputOutputDescriptor_indexType :: #force_inline proc(self: ^StageInputOutputDescriptor) -> IndexType { + return msgSend(IndexType, self, "indexType") +} +@(objc_type=StageInputOutputDescriptor, objc_name="layouts") +StageInputOutputDescriptor_layouts :: #force_inline proc(self: ^StageInputOutputDescriptor) -> ^BufferLayoutDescriptorArray { + return msgSend(^BufferLayoutDescriptorArray, self, "layouts") +} +@(objc_type=StageInputOutputDescriptor, objc_name="reset") +StageInputOutputDescriptor_reset :: #force_inline proc(self: ^StageInputOutputDescriptor) { + msgSend(nil, self, "reset") +} +@(objc_type=StageInputOutputDescriptor, objc_name="setIndexBufferIndex") +StageInputOutputDescriptor_setIndexBufferIndex :: #force_inline proc(self: ^StageInputOutputDescriptor, indexBufferIndex: NS.UInteger) { + msgSend(nil, self, "setIndexBufferIndex:", indexBufferIndex) +} +@(objc_type=StageInputOutputDescriptor, objc_name="setIndexType") +StageInputOutputDescriptor_setIndexType :: #force_inline proc(self: ^StageInputOutputDescriptor, indexType: IndexType) { + msgSend(nil, self, "setIndexType:", indexType) +} +@(objc_type=StageInputOutputDescriptor, objc_name="stageInputOutputDescriptor", objc_is_class_method=true) +StageInputOutputDescriptor_stageInputOutputDescriptor :: #force_inline proc() -> ^StageInputOutputDescriptor { + return msgSend(^StageInputOutputDescriptor, StageInputOutputDescriptor, "stageInputOutputDescriptor") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + StencilDescriptor +Class Methods: + alloc +Methods: + init + depthFailureOperation + depthStencilPassOperation + readMask + setDepthFailureOperation + setDepthStencilPassOperation + setReadMask + setStencilCompareFunction + setStencilFailureOperation + setWriteMask + stencilCompareFunction + stencilFailureOperation + writeMask +*/ +@(objc_class="MTLStencilDescriptor") +StencilDescriptor :: struct { using _: NS.Copying(StencilDescriptor) } + +@(objc_type=StencilDescriptor, objc_name="alloc", objc_is_class_method=true) +StencilDescriptor_alloc :: #force_inline proc() -> ^StencilDescriptor { + return msgSend(^StencilDescriptor, StencilDescriptor, "alloc") +} +@(objc_type=StencilDescriptor, objc_name="init") +StencilDescriptor_init :: #force_inline proc(self: ^StencilDescriptor) -> ^StencilDescriptor { + return msgSend(^StencilDescriptor, self, "init") +} +@(objc_type=StencilDescriptor, objc_name="depthFailureOperation") +StencilDescriptor_depthFailureOperation :: #force_inline proc(self: ^StencilDescriptor) -> StencilOperation { + return msgSend(StencilOperation, self, "depthFailureOperation") +} +@(objc_type=StencilDescriptor, objc_name="depthStencilPassOperation") +StencilDescriptor_depthStencilPassOperation :: #force_inline proc(self: ^StencilDescriptor) -> StencilOperation { + return msgSend(StencilOperation, self, "depthStencilPassOperation") +} +@(objc_type=StencilDescriptor, objc_name="readMask") +StencilDescriptor_readMask :: #force_inline proc(self: ^StencilDescriptor) -> u32 { + return msgSend(u32, self, "readMask") +} +@(objc_type=StencilDescriptor, objc_name="setDepthFailureOperation") +StencilDescriptor_setDepthFailureOperation :: #force_inline proc(self: ^StencilDescriptor, depthFailureOperation: StencilOperation) { + msgSend(nil, self, "setDepthFailureOperation:", depthFailureOperation) +} +@(objc_type=StencilDescriptor, objc_name="setDepthStencilPassOperation") +StencilDescriptor_setDepthStencilPassOperation :: #force_inline proc(self: ^StencilDescriptor, depthStencilPassOperation: StencilOperation) { + msgSend(nil, self, "setDepthStencilPassOperation:", depthStencilPassOperation) +} +@(objc_type=StencilDescriptor, objc_name="setReadMask") +StencilDescriptor_setReadMask :: #force_inline proc(self: ^StencilDescriptor, readMask: u32) { + msgSend(nil, self, "setReadMask:", readMask) +} +@(objc_type=StencilDescriptor, objc_name="setStencilCompareFunction") +StencilDescriptor_setStencilCompareFunction :: #force_inline proc(self: ^StencilDescriptor, stencilCompareFunction: CompareFunction) { + msgSend(nil, self, "setStencilCompareFunction:", stencilCompareFunction) +} +@(objc_type=StencilDescriptor, objc_name="setStencilFailureOperation") +StencilDescriptor_setStencilFailureOperation :: #force_inline proc(self: ^StencilDescriptor, stencilFailureOperation: StencilOperation) { + msgSend(nil, self, "setStencilFailureOperation:", stencilFailureOperation) +} +@(objc_type=StencilDescriptor, objc_name="setWriteMask") +StencilDescriptor_setWriteMask :: #force_inline proc(self: ^StencilDescriptor, writeMask: u32) { + msgSend(nil, self, "setWriteMask:", writeMask) +} +@(objc_type=StencilDescriptor, objc_name="stencilCompareFunction") +StencilDescriptor_stencilCompareFunction :: #force_inline proc(self: ^StencilDescriptor) -> CompareFunction { + return msgSend(CompareFunction, self, "stencilCompareFunction") +} +@(objc_type=StencilDescriptor, objc_name="stencilFailureOperation") +StencilDescriptor_stencilFailureOperation :: #force_inline proc(self: ^StencilDescriptor) -> StencilOperation { + return msgSend(StencilOperation, self, "stencilFailureOperation") +} +@(objc_type=StencilDescriptor, objc_name="writeMask") +StencilDescriptor_writeMask :: #force_inline proc(self: ^StencilDescriptor) -> u32 { + return msgSend(u32, self, "writeMask") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + StructMember +Class Methods: + alloc +Methods: + init + argumentIndex + arrayType + dataType + name + offset + pointerType + structType + textureReferenceType +*/ +@(objc_class="MTLStructMember") +StructMember :: struct { using _: NS.Object } + +@(objc_type=StructMember, objc_name="alloc", objc_is_class_method=true) +StructMember_alloc :: #force_inline proc() -> ^StructMember { + return msgSend(^StructMember, StructMember, "alloc") +} +@(objc_type=StructMember, objc_name="init") +StructMember_init :: #force_inline proc(self: ^StructMember) -> ^StructMember { + return msgSend(^StructMember, self, "init") +} +@(objc_type=StructMember, objc_name="argumentIndex") +StructMember_argumentIndex :: #force_inline proc(self: ^StructMember) -> NS.UInteger { + return msgSend(NS.UInteger, self, "argumentIndex") +} +@(objc_type=StructMember, objc_name="arrayType") +StructMember_arrayType :: #force_inline proc(self: ^StructMember) -> ^ArrayType { + return msgSend(^ArrayType, self, "arrayType") +} +@(objc_type=StructMember, objc_name="dataType") +StructMember_dataType :: #force_inline proc(self: ^StructMember) -> DataType { + return msgSend(DataType, self, "dataType") +} +@(objc_type=StructMember, objc_name="name") +StructMember_name :: #force_inline proc(self: ^StructMember) -> ^NS.String { + return msgSend(^NS.String, self, "name") +} +@(objc_type=StructMember, objc_name="offset") +StructMember_offset :: #force_inline proc(self: ^StructMember) -> NS.UInteger { + return msgSend(NS.UInteger, self, "offset") +} +@(objc_type=StructMember, objc_name="pointerType") +StructMember_pointerType :: #force_inline proc(self: ^StructMember) -> ^PointerType { + return msgSend(^PointerType, self, "pointerType") +} +@(objc_type=StructMember, objc_name="structType") +StructMember_structType :: #force_inline proc(self: ^StructMember) -> ^StructType { + return msgSend(^StructType, self, "structType") +} +@(objc_type=StructMember, objc_name="textureReferenceType") +StructMember_textureReferenceType :: #force_inline proc(self: ^StructMember) -> ^TextureReferenceType { + return msgSend(^TextureReferenceType, self, "textureReferenceType") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + StructType +Class Methods: + alloc +Methods: + init + memberByName + members +*/ +@(objc_class="MTLStructType") +StructType :: struct { using _: Type } + +@(objc_type=StructType, objc_name="alloc", objc_is_class_method=true) +StructType_alloc :: #force_inline proc() -> ^StructType { + return msgSend(^StructType, StructType, "alloc") +} +@(objc_type=StructType, objc_name="init") +StructType_init :: #force_inline proc(self: ^StructType) -> ^StructType { + return msgSend(^StructType, self, "init") +} +@(objc_type=StructType, objc_name="memberByName") +StructType_memberByName :: #force_inline proc(self: ^StructType, name: ^NS.String) -> ^StructMember { + return msgSend(^StructMember, self, "memberByName:", name) +} +@(objc_type=StructType, objc_name="members") +StructType_members :: #force_inline proc(self: ^StructType) -> ^NS.Array { + return msgSend(^NS.Array, self, "members") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + TextureDescriptor +Class Methods: + alloc + texture2DDescriptorWithPixelFormat + textureBufferDescriptorWithPixelFormat + textureCubeDescriptorWithPixelFormat +Methods: + init + allowGPUOptimizedContents + arrayLength + cpuCacheMode + depth + hazardTrackingMode + height + mipmapLevelCount + pixelFormat + resourceOptions + sampleCount + setAllowGPUOptimizedContents + setArrayLength + setCpuCacheMode + setDepth + setHazardTrackingMode + setHeight + setMipmapLevelCount + setPixelFormat + setResourceOptions + setSampleCount + setStorageMode + setSwizzle + setTextureType + setUsage + setWidth + storageMode + swizzle + textureType + usage + width +*/ +@(objc_class="MTLTextureDescriptor") +TextureDescriptor :: struct { using _: NS.Copying(TextureDescriptor) } + +@(objc_type=TextureDescriptor, objc_name="alloc", objc_is_class_method=true) +TextureDescriptor_alloc :: #force_inline proc() -> ^TextureDescriptor { + return msgSend(^TextureDescriptor, TextureDescriptor, "alloc") +} +@(objc_type=TextureDescriptor, objc_name="init") +TextureDescriptor_init :: #force_inline proc(self: ^TextureDescriptor) -> ^TextureDescriptor { + return msgSend(^TextureDescriptor, self, "init") +} +@(objc_type=TextureDescriptor, objc_name="allowGPUOptimizedContents") +TextureDescriptor_allowGPUOptimizedContents :: #force_inline proc(self: ^TextureDescriptor) -> BOOL { + return msgSend(BOOL, self, "allowGPUOptimizedContents") +} +@(objc_type=TextureDescriptor, objc_name="arrayLength") +TextureDescriptor_arrayLength :: #force_inline proc(self: ^TextureDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "arrayLength") +} +@(objc_type=TextureDescriptor, objc_name="cpuCacheMode") +TextureDescriptor_cpuCacheMode :: #force_inline proc(self: ^TextureDescriptor) -> CPUCacheMode { + return msgSend(CPUCacheMode, self, "cpuCacheMode") +} +@(objc_type=TextureDescriptor, objc_name="depth") +TextureDescriptor_depth :: #force_inline proc(self: ^TextureDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "depth") +} +@(objc_type=TextureDescriptor, objc_name="hazardTrackingMode") +TextureDescriptor_hazardTrackingMode :: #force_inline proc(self: ^TextureDescriptor) -> HazardTrackingMode { + return msgSend(HazardTrackingMode, self, "hazardTrackingMode") +} +@(objc_type=TextureDescriptor, objc_name="height") +TextureDescriptor_height :: #force_inline proc(self: ^TextureDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "height") +} +@(objc_type=TextureDescriptor, objc_name="mipmapLevelCount") +TextureDescriptor_mipmapLevelCount :: #force_inline proc(self: ^TextureDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "mipmapLevelCount") +} +@(objc_type=TextureDescriptor, objc_name="pixelFormat") +TextureDescriptor_pixelFormat :: #force_inline proc(self: ^TextureDescriptor) -> PixelFormat { + return msgSend(PixelFormat, self, "pixelFormat") +} +@(objc_type=TextureDescriptor, objc_name="resourceOptions") +TextureDescriptor_resourceOptions :: #force_inline proc(self: ^TextureDescriptor) -> ResourceOptions { + return msgSend(ResourceOptions, self, "resourceOptions") +} +@(objc_type=TextureDescriptor, objc_name="sampleCount") +TextureDescriptor_sampleCount :: #force_inline proc(self: ^TextureDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "sampleCount") +} +@(objc_type=TextureDescriptor, objc_name="setAllowGPUOptimizedContents") +TextureDescriptor_setAllowGPUOptimizedContents :: #force_inline proc(self: ^TextureDescriptor, allowGPUOptimizedContents: BOOL) { + msgSend(nil, self, "setAllowGPUOptimizedContents:", allowGPUOptimizedContents) +} +@(objc_type=TextureDescriptor, objc_name="setArrayLength") +TextureDescriptor_setArrayLength :: #force_inline proc(self: ^TextureDescriptor, arrayLength: NS.UInteger) { + msgSend(nil, self, "setArrayLength:", arrayLength) +} +@(objc_type=TextureDescriptor, objc_name="setCpuCacheMode") +TextureDescriptor_setCpuCacheMode :: #force_inline proc(self: ^TextureDescriptor, cpuCacheMode: CPUCacheMode) { + msgSend(nil, self, "setCpuCacheMode:", cpuCacheMode) +} +@(objc_type=TextureDescriptor, objc_name="setDepth") +TextureDescriptor_setDepth :: #force_inline proc(self: ^TextureDescriptor, depth: NS.UInteger) { + msgSend(nil, self, "setDepth:", depth) +} +@(objc_type=TextureDescriptor, objc_name="setHazardTrackingMode") +TextureDescriptor_setHazardTrackingMode :: #force_inline proc(self: ^TextureDescriptor, hazardTrackingMode: HazardTrackingMode) { + msgSend(nil, self, "setHazardTrackingMode:", hazardTrackingMode) +} +@(objc_type=TextureDescriptor, objc_name="setHeight") +TextureDescriptor_setHeight :: #force_inline proc(self: ^TextureDescriptor, height: NS.UInteger) { + msgSend(nil, self, "setHeight:", height) +} +@(objc_type=TextureDescriptor, objc_name="setMipmapLevelCount") +TextureDescriptor_setMipmapLevelCount :: #force_inline proc(self: ^TextureDescriptor, mipmapLevelCount: NS.UInteger) { + msgSend(nil, self, "setMipmapLevelCount:", mipmapLevelCount) +} +@(objc_type=TextureDescriptor, objc_name="setPixelFormat") +TextureDescriptor_setPixelFormat :: #force_inline proc(self: ^TextureDescriptor, pixelFormat: PixelFormat) { + msgSend(nil, self, "setPixelFormat:", pixelFormat) +} +@(objc_type=TextureDescriptor, objc_name="setResourceOptions") +TextureDescriptor_setResourceOptions :: #force_inline proc(self: ^TextureDescriptor, resourceOptions: ResourceOptions) { + msgSend(nil, self, "setResourceOptions:", resourceOptions) +} +@(objc_type=TextureDescriptor, objc_name="setSampleCount") +TextureDescriptor_setSampleCount :: #force_inline proc(self: ^TextureDescriptor, sampleCount: NS.UInteger) { + msgSend(nil, self, "setSampleCount:", sampleCount) +} +@(objc_type=TextureDescriptor, objc_name="setStorageMode") +TextureDescriptor_setStorageMode :: #force_inline proc(self: ^TextureDescriptor, storageMode: StorageMode) { + msgSend(nil, self, "setStorageMode:", storageMode) +} +@(objc_type=TextureDescriptor, objc_name="setSwizzle") +TextureDescriptor_setSwizzle :: #force_inline proc(self: ^TextureDescriptor, swizzle: TextureSwizzleChannels) { + msgSend(nil, self, "setSwizzle:", swizzle) +} +@(objc_type=TextureDescriptor, objc_name="setTextureType") +TextureDescriptor_setTextureType :: #force_inline proc(self: ^TextureDescriptor, textureType: TextureType) { + msgSend(nil, self, "setTextureType:", textureType) +} +@(objc_type=TextureDescriptor, objc_name="setUsage") +TextureDescriptor_setUsage :: #force_inline proc(self: ^TextureDescriptor, usage: TextureUsage) { + msgSend(nil, self, "setUsage:", usage) +} +@(objc_type=TextureDescriptor, objc_name="setWidth") +TextureDescriptor_setWidth :: #force_inline proc(self: ^TextureDescriptor, width: NS.UInteger) { + msgSend(nil, self, "setWidth:", width) +} +@(objc_type=TextureDescriptor, objc_name="storageMode") +TextureDescriptor_storageMode :: #force_inline proc(self: ^TextureDescriptor) -> StorageMode { + return msgSend(StorageMode, self, "storageMode") +} +@(objc_type=TextureDescriptor, objc_name="swizzle") +TextureDescriptor_swizzle :: #force_inline proc(self: ^TextureDescriptor) -> TextureSwizzleChannels { + return msgSend(TextureSwizzleChannels, self, "swizzle") +} +@(objc_type=TextureDescriptor, objc_name="texture2DDescriptorWithPixelFormat", objc_is_class_method=true) +TextureDescriptor_texture2DDescriptorWithPixelFormat :: #force_inline proc(pixelFormat: PixelFormat, width: NS.UInteger, height: NS.UInteger, mipmapped: BOOL) -> ^TextureDescriptor { + return msgSend(^TextureDescriptor, TextureDescriptor, "texture2DDescriptorWithPixelFormat:width:height:mipmapped:", pixelFormat, width, height, mipmapped) +} +@(objc_type=TextureDescriptor, objc_name="textureBufferDescriptorWithPixelFormat", objc_is_class_method=true) +TextureDescriptor_textureBufferDescriptorWithPixelFormat :: #force_inline proc(pixelFormat: PixelFormat, width: NS.UInteger, resourceOptions: ResourceOptions, usage: TextureUsage) -> ^TextureDescriptor { + return msgSend(^TextureDescriptor, TextureDescriptor, "textureBufferDescriptorWithPixelFormat:width:resourceOptions:usage:", pixelFormat, width, resourceOptions, usage) +} +@(objc_type=TextureDescriptor, objc_name="textureCubeDescriptorWithPixelFormat", objc_is_class_method=true) +TextureDescriptor_textureCubeDescriptorWithPixelFormat :: #force_inline proc(pixelFormat: PixelFormat, size: NS.UInteger, mipmapped: BOOL) -> ^TextureDescriptor { + return msgSend(^TextureDescriptor, TextureDescriptor, "textureCubeDescriptorWithPixelFormat:size:mipmapped:", pixelFormat, size, mipmapped) +} +@(objc_type=TextureDescriptor, objc_name="textureType") +TextureDescriptor_textureType :: #force_inline proc(self: ^TextureDescriptor) -> TextureType { + return msgSend(TextureType, self, "textureType") +} +@(objc_type=TextureDescriptor, objc_name="usage") +TextureDescriptor_usage :: #force_inline proc(self: ^TextureDescriptor) -> TextureUsage { + return msgSend(TextureUsage, self, "usage") +} +@(objc_type=TextureDescriptor, objc_name="width") +TextureDescriptor_width :: #force_inline proc(self: ^TextureDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "width") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + TextureReferenceType +Class Methods: + alloc +Methods: + init + access + isDepthTexture + textureDataType + textureType +*/ +@(objc_class="MTLTextureReferenceType") +TextureReferenceType :: struct { using _: Type } + +@(objc_type=TextureReferenceType, objc_name="alloc", objc_is_class_method=true) +TextureReferenceType_alloc :: #force_inline proc() -> ^TextureReferenceType { + return msgSend(^TextureReferenceType, TextureReferenceType, "alloc") +} +@(objc_type=TextureReferenceType, objc_name="init") +TextureReferenceType_init :: #force_inline proc(self: ^TextureReferenceType) -> ^TextureReferenceType { + return msgSend(^TextureReferenceType, self, "init") +} +@(objc_type=TextureReferenceType, objc_name="access") +TextureReferenceType_access :: #force_inline proc(self: ^TextureReferenceType) -> ArgumentAccess { + return msgSend(ArgumentAccess, self, "access") +} +@(objc_type=TextureReferenceType, objc_name="isDepthTexture") +TextureReferenceType_isDepthTexture :: #force_inline proc(self: ^TextureReferenceType) -> BOOL { + return msgSend(BOOL, self, "isDepthTexture") +} +@(objc_type=TextureReferenceType, objc_name="textureDataType") +TextureReferenceType_textureDataType :: #force_inline proc(self: ^TextureReferenceType) -> DataType { + return msgSend(DataType, self, "textureDataType") +} +@(objc_type=TextureReferenceType, objc_name="textureType") +TextureReferenceType_textureType :: #force_inline proc(self: ^TextureReferenceType) -> TextureType { + return msgSend(TextureType, self, "textureType") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + TileRenderPipelineColorAttachmentDescriptor +Class Methods: + alloc +Methods: + init + pixelFormat + setPixelFormat +*/ +@(objc_class="MTLTileRenderPipelineColorAttachmentDescriptor") +TileRenderPipelineColorAttachmentDescriptor :: struct { using _: NS.Copying(TileRenderPipelineColorAttachmentDescriptor) } + +@(objc_type=TileRenderPipelineColorAttachmentDescriptor, objc_name="alloc", objc_is_class_method=true) +TileRenderPipelineColorAttachmentDescriptor_alloc :: #force_inline proc() -> ^TileRenderPipelineColorAttachmentDescriptor { + return msgSend(^TileRenderPipelineColorAttachmentDescriptor, TileRenderPipelineColorAttachmentDescriptor, "alloc") +} +@(objc_type=TileRenderPipelineColorAttachmentDescriptor, objc_name="init") +TileRenderPipelineColorAttachmentDescriptor_init :: #force_inline proc(self: ^TileRenderPipelineColorAttachmentDescriptor) -> ^TileRenderPipelineColorAttachmentDescriptor { + return msgSend(^TileRenderPipelineColorAttachmentDescriptor, self, "init") +} +@(objc_type=TileRenderPipelineColorAttachmentDescriptor, objc_name="pixelFormat") +TileRenderPipelineColorAttachmentDescriptor_pixelFormat :: #force_inline proc(self: ^TileRenderPipelineColorAttachmentDescriptor) -> PixelFormat { + return msgSend(PixelFormat, self, "pixelFormat") +} +@(objc_type=TileRenderPipelineColorAttachmentDescriptor, objc_name="setPixelFormat") +TileRenderPipelineColorAttachmentDescriptor_setPixelFormat :: #force_inline proc(self: ^TileRenderPipelineColorAttachmentDescriptor, pixelFormat: PixelFormat) { + msgSend(nil, self, "setPixelFormat:", pixelFormat) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + TileRenderPipelineColorAttachmentDescriptorArray +Class Methods: + alloc +Methods: + init + objectAtIndexedSubscript + setObject +*/ +@(objc_class="MTLTileRenderPipelineColorAttachmentDescriptorArray") +TileRenderPipelineColorAttachmentDescriptorArray :: struct { using _: NS.Object } + +@(objc_type=TileRenderPipelineColorAttachmentDescriptorArray, objc_name="alloc", objc_is_class_method=true) +TileRenderPipelineColorAttachmentDescriptorArray_alloc :: #force_inline proc() -> ^TileRenderPipelineColorAttachmentDescriptorArray { + return msgSend(^TileRenderPipelineColorAttachmentDescriptorArray, TileRenderPipelineColorAttachmentDescriptorArray, "alloc") +} +@(objc_type=TileRenderPipelineColorAttachmentDescriptorArray, objc_name="init") +TileRenderPipelineColorAttachmentDescriptorArray_init :: #force_inline proc(self: ^TileRenderPipelineColorAttachmentDescriptorArray) -> ^TileRenderPipelineColorAttachmentDescriptorArray { + return msgSend(^TileRenderPipelineColorAttachmentDescriptorArray, self, "init") +} +@(objc_type=TileRenderPipelineColorAttachmentDescriptorArray, objc_name="object") +TileRenderPipelineColorAttachmentDescriptorArray_object :: #force_inline proc(self: ^TileRenderPipelineColorAttachmentDescriptorArray, attachmentIndex: NS.UInteger) -> ^TileRenderPipelineColorAttachmentDescriptor { + return msgSend(^TileRenderPipelineColorAttachmentDescriptor, self, "objectAtIndexedSubscript:", attachmentIndex) +} +@(objc_type=TileRenderPipelineColorAttachmentDescriptorArray, objc_name="setObject") +TileRenderPipelineColorAttachmentDescriptorArray_setObject :: #force_inline proc(self: ^TileRenderPipelineColorAttachmentDescriptorArray, attachment: ^TileRenderPipelineColorAttachmentDescriptor, attachmentIndex: NS.UInteger) { + msgSend(nil, self, "setObject:atIndexedSubscript:", attachment, attachmentIndex) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + TileRenderPipelineDescriptor +Class Methods: + alloc +Methods: + init + binaryArchives + colorAttachments + label + maxTotalThreadsPerThreadgroup + rasterSampleCount + reset + setBinaryArchives + setLabel + setMaxTotalThreadsPerThreadgroup + setRasterSampleCount + setThreadgroupSizeMatchesTileSize + setTileFunction + threadgroupSizeMatchesTileSize + tileBuffers + tileFunction +*/ +@(objc_class="MTLTileRenderPipelineDescriptor") +TileRenderPipelineDescriptor :: struct { using _: NS.Copying(TileRenderPipelineDescriptor) } + +@(objc_type=TileRenderPipelineDescriptor, objc_name="alloc", objc_is_class_method=true) +TileRenderPipelineDescriptor_alloc :: #force_inline proc() -> ^TileRenderPipelineDescriptor { + return msgSend(^TileRenderPipelineDescriptor, TileRenderPipelineDescriptor, "alloc") +} +@(objc_type=TileRenderPipelineDescriptor, objc_name="init") +TileRenderPipelineDescriptor_init :: #force_inline proc(self: ^TileRenderPipelineDescriptor) -> ^TileRenderPipelineDescriptor { + return msgSend(^TileRenderPipelineDescriptor, self, "init") +} +@(objc_type=TileRenderPipelineDescriptor, objc_name="binaryArchives") +TileRenderPipelineDescriptor_binaryArchives :: #force_inline proc(self: ^TileRenderPipelineDescriptor) -> ^NS.Array { + return msgSend(^NS.Array, self, "binaryArchives") +} +@(objc_type=TileRenderPipelineDescriptor, objc_name="colorAttachments") +TileRenderPipelineDescriptor_colorAttachments :: #force_inline proc(self: ^TileRenderPipelineDescriptor) -> ^TileRenderPipelineColorAttachmentDescriptorArray { + return msgSend(^TileRenderPipelineColorAttachmentDescriptorArray, self, "colorAttachments") +} +@(objc_type=TileRenderPipelineDescriptor, objc_name="label") +TileRenderPipelineDescriptor_label :: #force_inline proc(self: ^TileRenderPipelineDescriptor) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=TileRenderPipelineDescriptor, objc_name="maxTotalThreadsPerThreadgroup") +TileRenderPipelineDescriptor_maxTotalThreadsPerThreadgroup :: #force_inline proc(self: ^TileRenderPipelineDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "maxTotalThreadsPerThreadgroup") +} +@(objc_type=TileRenderPipelineDescriptor, objc_name="rasterSampleCount") +TileRenderPipelineDescriptor_rasterSampleCount :: #force_inline proc(self: ^TileRenderPipelineDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "rasterSampleCount") +} +@(objc_type=TileRenderPipelineDescriptor, objc_name="reset") +TileRenderPipelineDescriptor_reset :: #force_inline proc(self: ^TileRenderPipelineDescriptor) { + msgSend(nil, self, "reset") +} +@(objc_type=TileRenderPipelineDescriptor, objc_name="setBinaryArchives") +TileRenderPipelineDescriptor_setBinaryArchives :: #force_inline proc(self: ^TileRenderPipelineDescriptor, binaryArchives: ^NS.Array) { + msgSend(nil, self, "setBinaryArchives:", binaryArchives) +} +@(objc_type=TileRenderPipelineDescriptor, objc_name="setLabel") +TileRenderPipelineDescriptor_setLabel :: #force_inline proc(self: ^TileRenderPipelineDescriptor, label: ^NS.String) { + msgSend(nil, self, "setLabel:", label) +} +@(objc_type=TileRenderPipelineDescriptor, objc_name="setMaxTotalThreadsPerThreadgroup") +TileRenderPipelineDescriptor_setMaxTotalThreadsPerThreadgroup :: #force_inline proc(self: ^TileRenderPipelineDescriptor, maxTotalThreadsPerThreadgroup: NS.UInteger) { + msgSend(nil, self, "setMaxTotalThreadsPerThreadgroup:", maxTotalThreadsPerThreadgroup) +} +@(objc_type=TileRenderPipelineDescriptor, objc_name="setRasterSampleCount") +TileRenderPipelineDescriptor_setRasterSampleCount :: #force_inline proc(self: ^TileRenderPipelineDescriptor, rasterSampleCount: NS.UInteger) { + msgSend(nil, self, "setRasterSampleCount:", rasterSampleCount) +} +@(objc_type=TileRenderPipelineDescriptor, objc_name="setThreadgroupSizeMatchesTileSize") +TileRenderPipelineDescriptor_setThreadgroupSizeMatchesTileSize :: #force_inline proc(self: ^TileRenderPipelineDescriptor, threadgroupSizeMatchesTileSize: BOOL) { + msgSend(nil, self, "setThreadgroupSizeMatchesTileSize:", threadgroupSizeMatchesTileSize) +} +@(objc_type=TileRenderPipelineDescriptor, objc_name="setTileFunction") +TileRenderPipelineDescriptor_setTileFunction :: #force_inline proc(self: ^TileRenderPipelineDescriptor, tileFunction: ^Function) { + msgSend(nil, self, "setTileFunction:", tileFunction) +} +@(objc_type=TileRenderPipelineDescriptor, objc_name="threadgroupSizeMatchesTileSize") +TileRenderPipelineDescriptor_threadgroupSizeMatchesTileSize :: #force_inline proc(self: ^TileRenderPipelineDescriptor) -> BOOL { + return msgSend(BOOL, self, "threadgroupSizeMatchesTileSize") +} +@(objc_type=TileRenderPipelineDescriptor, objc_name="tileBuffers") +TileRenderPipelineDescriptor_tileBuffers :: #force_inline proc(self: ^TileRenderPipelineDescriptor) -> ^PipelineBufferDescriptorArray { + return msgSend(^PipelineBufferDescriptorArray, self, "tileBuffers") +} +@(objc_type=TileRenderPipelineDescriptor, objc_name="tileFunction") +TileRenderPipelineDescriptor_tileFunction :: #force_inline proc(self: ^TileRenderPipelineDescriptor) -> ^Function { + return msgSend(^Function, self, "tileFunction") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + Type +Class Methods: + alloc +Methods: + init + dataType +*/ +@(objc_class="MTLType") +Type :: struct { using _: NS.Object } + +@(objc_type=Type, objc_name="alloc", objc_is_class_method=true) +Type_alloc :: #force_inline proc() -> ^Type { + return msgSend(^Type, Type, "alloc") +} +@(objc_type=Type, objc_name="init") +Type_init :: #force_inline proc(self: ^Type) -> ^Type { + return msgSend(^Type, self, "init") +} +@(objc_type=Type, objc_name="dataType") +Type_dataType :: #force_inline proc(self: ^Type) -> DataType { + return msgSend(DataType, self, "dataType") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + VertexAttribute +Class Methods: + alloc +Methods: + init + attributeIndex + attributeType + isActive + isPatchControlPointData + isPatchData + name +*/ +@(objc_class="MTLVertexAttribute") +VertexAttribute :: struct { using _: NS.Object } + +@(objc_type=VertexAttribute, objc_name="alloc", objc_is_class_method=true) +VertexAttribute_alloc :: #force_inline proc() -> ^VertexAttribute { + return msgSend(^VertexAttribute, VertexAttribute, "alloc") +} +@(objc_type=VertexAttribute, objc_name="init") +VertexAttribute_init :: #force_inline proc(self: ^VertexAttribute) -> ^VertexAttribute { + return msgSend(^VertexAttribute, self, "init") +} +@(objc_type=VertexAttribute, objc_name="attributeIndex") +VertexAttribute_attributeIndex :: #force_inline proc(self: ^VertexAttribute) -> NS.UInteger { + return msgSend(NS.UInteger, self, "attributeIndex") +} +@(objc_type=VertexAttribute, objc_name="attributeType") +VertexAttribute_attributeType :: #force_inline proc(self: ^VertexAttribute) -> DataType { + return msgSend(DataType, self, "attributeType") +} +@(objc_type=VertexAttribute, objc_name="isActive") +VertexAttribute_isActive :: #force_inline proc(self: ^VertexAttribute) -> BOOL { + return msgSend(BOOL, self, "isActive") +} +@(objc_type=VertexAttribute, objc_name="isPatchControlPointData") +VertexAttribute_isPatchControlPointData :: #force_inline proc(self: ^VertexAttribute) -> BOOL { + return msgSend(BOOL, self, "isPatchControlPointData") +} +@(objc_type=VertexAttribute, objc_name="isPatchData") +VertexAttribute_isPatchData :: #force_inline proc(self: ^VertexAttribute) -> BOOL { + return msgSend(BOOL, self, "isPatchData") +} +@(objc_type=VertexAttribute, objc_name="name") +VertexAttribute_name :: #force_inline proc(self: ^VertexAttribute) -> ^NS.String { + return msgSend(^NS.String, self, "name") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + VertexAttributeDescriptor +Class Methods: + alloc +Methods: + init + bufferIndex + format + offset + setBufferIndex + setFormat + setOffset +*/ +@(objc_class="MTLVertexAttributeDescriptor") +VertexAttributeDescriptor :: struct { using _: NS.Copying(VertexAttributeDescriptor) } + +@(objc_type=VertexAttributeDescriptor, objc_name="alloc", objc_is_class_method=true) +VertexAttributeDescriptor_alloc :: #force_inline proc() -> ^VertexAttributeDescriptor { + return msgSend(^VertexAttributeDescriptor, VertexAttributeDescriptor, "alloc") +} +@(objc_type=VertexAttributeDescriptor, objc_name="init") +VertexAttributeDescriptor_init :: #force_inline proc(self: ^VertexAttributeDescriptor) -> ^VertexAttributeDescriptor { + return msgSend(^VertexAttributeDescriptor, self, "init") +} +@(objc_type=VertexAttributeDescriptor, objc_name="bufferIndex") +VertexAttributeDescriptor_bufferIndex :: #force_inline proc(self: ^VertexAttributeDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "bufferIndex") +} +@(objc_type=VertexAttributeDescriptor, objc_name="format") +VertexAttributeDescriptor_format :: #force_inline proc(self: ^VertexAttributeDescriptor) -> VertexFormat { + return msgSend(VertexFormat, self, "format") +} +@(objc_type=VertexAttributeDescriptor, objc_name="offset") +VertexAttributeDescriptor_offset :: #force_inline proc(self: ^VertexAttributeDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "offset") +} +@(objc_type=VertexAttributeDescriptor, objc_name="setBufferIndex") +VertexAttributeDescriptor_setBufferIndex :: #force_inline proc(self: ^VertexAttributeDescriptor, bufferIndex: NS.UInteger) { + msgSend(nil, self, "setBufferIndex:", bufferIndex) +} +@(objc_type=VertexAttributeDescriptor, objc_name="setFormat") +VertexAttributeDescriptor_setFormat :: #force_inline proc(self: ^VertexAttributeDescriptor, format: VertexFormat) { + msgSend(nil, self, "setFormat:", format) +} +@(objc_type=VertexAttributeDescriptor, objc_name="setOffset") +VertexAttributeDescriptor_setOffset :: #force_inline proc(self: ^VertexAttributeDescriptor, offset: NS.UInteger) { + msgSend(nil, self, "setOffset:", offset) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + VertexAttributeDescriptorArray +Class Methods: + alloc +Methods: + init + objectAtIndexedSubscript + setObject +*/ +@(objc_class="MTLVertexAttributeDescriptorArray") +VertexAttributeDescriptorArray :: struct { using _: NS.Object } + +@(objc_type=VertexAttributeDescriptorArray, objc_name="alloc", objc_is_class_method=true) +VertexAttributeDescriptorArray_alloc :: #force_inline proc() -> ^VertexAttributeDescriptorArray { + return msgSend(^VertexAttributeDescriptorArray, VertexAttributeDescriptorArray, "alloc") +} +@(objc_type=VertexAttributeDescriptorArray, objc_name="init") +VertexAttributeDescriptorArray_init :: #force_inline proc(self: ^VertexAttributeDescriptorArray) -> ^VertexAttributeDescriptorArray { + return msgSend(^VertexAttributeDescriptorArray, self, "init") +} +@(objc_type=VertexAttributeDescriptorArray, objc_name="object") +VertexAttributeDescriptorArray_object :: #force_inline proc(self: ^VertexAttributeDescriptorArray, index: NS.UInteger) -> ^VertexAttributeDescriptor { + return msgSend(^VertexAttributeDescriptor, self, "objectAtIndexedSubscript:", index) +} +@(objc_type=VertexAttributeDescriptorArray, objc_name="setObject") +VertexAttributeDescriptorArray_setObject :: #force_inline proc(self: ^VertexAttributeDescriptorArray, attributeDesc: ^VertexAttributeDescriptor, index: NS.UInteger) { + msgSend(nil, self, "setObject:atIndexedSubscript:", attributeDesc, index) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + VertexBufferLayoutDescriptor +Class Methods: + alloc +Methods: + init + setStepFunction + setStepRate + setStride + stepFunction + stepRate + stride +*/ +@(objc_class="MTLVertexBufferLayoutDescriptor") +VertexBufferLayoutDescriptor :: struct { using _: NS.Copying(VertexBufferLayoutDescriptor) } + +@(objc_type=VertexBufferLayoutDescriptor, objc_name="alloc", objc_is_class_method=true) +VertexBufferLayoutDescriptor_alloc :: #force_inline proc() -> ^VertexBufferLayoutDescriptor { + return msgSend(^VertexBufferLayoutDescriptor, VertexBufferLayoutDescriptor, "alloc") +} +@(objc_type=VertexBufferLayoutDescriptor, objc_name="init") +VertexBufferLayoutDescriptor_init :: #force_inline proc(self: ^VertexBufferLayoutDescriptor) -> ^VertexBufferLayoutDescriptor { + return msgSend(^VertexBufferLayoutDescriptor, self, "init") +} +@(objc_type=VertexBufferLayoutDescriptor, objc_name="setStepFunction") +VertexBufferLayoutDescriptor_setStepFunction :: #force_inline proc(self: ^VertexBufferLayoutDescriptor, stepFunction: VertexStepFunction) { + msgSend(nil, self, "setStepFunction:", stepFunction) +} +@(objc_type=VertexBufferLayoutDescriptor, objc_name="setStepRate") +VertexBufferLayoutDescriptor_setStepRate :: #force_inline proc(self: ^VertexBufferLayoutDescriptor, stepRate: NS.UInteger) { + msgSend(nil, self, "setStepRate:", stepRate) +} +@(objc_type=VertexBufferLayoutDescriptor, objc_name="setStride") +VertexBufferLayoutDescriptor_setStride :: #force_inline proc(self: ^VertexBufferLayoutDescriptor, stride: NS.UInteger) { + msgSend(nil, self, "setStride:", stride) +} +@(objc_type=VertexBufferLayoutDescriptor, objc_name="stepFunction") +VertexBufferLayoutDescriptor_stepFunction :: #force_inline proc(self: ^VertexBufferLayoutDescriptor) -> VertexStepFunction { + return msgSend(VertexStepFunction, self, "stepFunction") +} +@(objc_type=VertexBufferLayoutDescriptor, objc_name="stepRate") +VertexBufferLayoutDescriptor_stepRate :: #force_inline proc(self: ^VertexBufferLayoutDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "stepRate") +} +@(objc_type=VertexBufferLayoutDescriptor, objc_name="stride") +VertexBufferLayoutDescriptor_stride :: #force_inline proc(self: ^VertexBufferLayoutDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "stride") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + VertexBufferLayoutDescriptorArray +Class Methods: + alloc +Methods: + init + objectAtIndexedSubscript + setObject +*/ +@(objc_class="MTLVertexBufferLayoutDescriptorArray") +VertexBufferLayoutDescriptorArray :: struct { using _: NS.Object } + +@(objc_type=VertexBufferLayoutDescriptorArray, objc_name="alloc", objc_is_class_method=true) +VertexBufferLayoutDescriptorArray_alloc :: #force_inline proc() -> ^VertexBufferLayoutDescriptorArray { + return msgSend(^VertexBufferLayoutDescriptorArray, VertexBufferLayoutDescriptorArray, "alloc") +} +@(objc_type=VertexBufferLayoutDescriptorArray, objc_name="init") +VertexBufferLayoutDescriptorArray_init :: #force_inline proc(self: ^VertexBufferLayoutDescriptorArray) -> ^VertexBufferLayoutDescriptorArray { + return msgSend(^VertexBufferLayoutDescriptorArray, self, "init") +} +@(objc_type=VertexBufferLayoutDescriptorArray, objc_name="object") +VertexBufferLayoutDescriptorArray_object :: #force_inline proc(self: ^VertexBufferLayoutDescriptorArray, index: NS.UInteger) -> ^VertexBufferLayoutDescriptor { + return msgSend(^VertexBufferLayoutDescriptor, self, "objectAtIndexedSubscript:", index) +} +@(objc_type=VertexBufferLayoutDescriptorArray, objc_name="setObject") +VertexBufferLayoutDescriptorArray_setObject :: #force_inline proc(self: ^VertexBufferLayoutDescriptorArray, bufferDesc: ^VertexBufferLayoutDescriptor, index: NS.UInteger) { + msgSend(nil, self, "setObject:atIndexedSubscript:", bufferDesc, index) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + VertexDescriptor +Class Methods: + alloc + vertexDescriptor +Methods: + init + attributes + layouts + reset +*/ +@(objc_class="MTLVertexDescriptor") +VertexDescriptor :: struct { using _: NS.Copying(VertexDescriptor) } + +@(objc_type=VertexDescriptor, objc_name="alloc", objc_is_class_method=true) +VertexDescriptor_alloc :: #force_inline proc() -> ^VertexDescriptor { + return msgSend(^VertexDescriptor, VertexDescriptor, "alloc") +} +@(objc_type=VertexDescriptor, objc_name="init") +VertexDescriptor_init :: #force_inline proc(self: ^VertexDescriptor) -> ^VertexDescriptor { + return msgSend(^VertexDescriptor, self, "init") +} +@(objc_type=VertexDescriptor, objc_name="attributes") +VertexDescriptor_attributes :: #force_inline proc(self: ^VertexDescriptor) -> ^VertexAttributeDescriptorArray { + return msgSend(^VertexAttributeDescriptorArray, self, "attributes") +} +@(objc_type=VertexDescriptor, objc_name="layouts") +VertexDescriptor_layouts :: #force_inline proc(self: ^VertexDescriptor) -> ^VertexBufferLayoutDescriptorArray { + return msgSend(^VertexBufferLayoutDescriptorArray, self, "layouts") +} +@(objc_type=VertexDescriptor, objc_name="reset") +VertexDescriptor_reset :: #force_inline proc(self: ^VertexDescriptor) { + msgSend(nil, self, "reset") +} +@(objc_type=VertexDescriptor, objc_name="vertexDescriptor", objc_is_class_method=true) +VertexDescriptor_vertexDescriptor :: #force_inline proc() -> ^VertexDescriptor { + return msgSend(^VertexDescriptor, VertexDescriptor, "vertexDescriptor") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + VisibleFunctionTableDescriptor +Class Methods: + alloc + visibleFunctionTableDescriptor +Methods: + init + functionCount + setFunctionCount +*/ +@(objc_class="MTLVisibleFunctionTableDescriptor") +VisibleFunctionTableDescriptor :: struct { using _: NS.Copying(VisibleFunctionTableDescriptor) } + +@(objc_type=VisibleFunctionTableDescriptor, objc_name="alloc", objc_is_class_method=true) +VisibleFunctionTableDescriptor_alloc :: #force_inline proc() -> ^VisibleFunctionTableDescriptor { + return msgSend(^VisibleFunctionTableDescriptor, VisibleFunctionTableDescriptor, "alloc") +} +@(objc_type=VisibleFunctionTableDescriptor, objc_name="init") +VisibleFunctionTableDescriptor_init :: #force_inline proc(self: ^VisibleFunctionTableDescriptor) -> ^VisibleFunctionTableDescriptor { + return msgSend(^VisibleFunctionTableDescriptor, self, "init") +} +@(objc_type=VisibleFunctionTableDescriptor, objc_name="functionCount") +VisibleFunctionTableDescriptor_functionCount :: #force_inline proc(self: ^VisibleFunctionTableDescriptor) -> NS.UInteger { + return msgSend(NS.UInteger, self, "functionCount") +} +@(objc_type=VisibleFunctionTableDescriptor, objc_name="setFunctionCount") +VisibleFunctionTableDescriptor_setFunctionCount :: #force_inline proc(self: ^VisibleFunctionTableDescriptor, functionCount: NS.UInteger) { + msgSend(nil, self, "setFunctionCount:", functionCount) +} +@(objc_type=VisibleFunctionTableDescriptor, objc_name="visibleFunctionTableDescriptor", objc_is_class_method=true) +VisibleFunctionTableDescriptor_visibleFunctionTableDescriptor :: #force_inline proc() -> ^VisibleFunctionTableDescriptor { + return msgSend(^VisibleFunctionTableDescriptor, VisibleFunctionTableDescriptor, "visibleFunctionTableDescriptor") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + AccelerationStructure +Class Methods: +Methods: + size +*/ +@(objc_class="MTLAccelerationStructure") +AccelerationStructure :: struct { using _: Resource } + +@(objc_type=AccelerationStructure, objc_name="size") +AccelerationStructure_size :: #force_inline proc(self: ^AccelerationStructure) -> NS.UInteger { + return msgSend(NS.UInteger, self, "size") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + AccelerationStructureCommandEncoder +Class Methods: +Methods: + buildAccelerationStructure + copyAccelerationStructure + copyAndCompactAccelerationStructure + refitAccelerationStructure + sampleCountersInBuffer + updateFence + useHeap + useHeaps + useResource + useResources + waitForFence + writeCompactedAccelerationStructureSize +*/ +@(objc_class="MTLAccelerationStructureCommandEncoder") +AccelerationStructureCommandEncoder :: struct { using _: CommandEncoder } + +@(objc_type=AccelerationStructureCommandEncoder, objc_name="buildAccelerationStructure") +AccelerationStructureCommandEncoder_buildAccelerationStructure :: #force_inline proc(self: ^AccelerationStructureCommandEncoder, accelerationStructure: ^AccelerationStructure, descriptor: ^AccelerationStructureDescriptor, scratchBuffer: ^Buffer, scratchBufferOffset: NS.UInteger) { + msgSend(nil, self, "buildAccelerationStructure:descriptor:scratchBuffer:scratchBufferOffset:", accelerationStructure, descriptor, scratchBuffer, scratchBufferOffset) +} +@(objc_type=AccelerationStructureCommandEncoder, objc_name="copyAccelerationStructure") +AccelerationStructureCommandEncoder_copyAccelerationStructure :: #force_inline proc(self: ^AccelerationStructureCommandEncoder, sourceAccelerationStructure, destinationAccelerationStructure: ^AccelerationStructure) { + msgSend(nil, self, "copyAccelerationStructure:toAccelerationStructure:", sourceAccelerationStructure, destinationAccelerationStructure) +} +@(objc_type=AccelerationStructureCommandEncoder, objc_name="copyAndCompactAccelerationStructure") +AccelerationStructureCommandEncoder_copyAndCompactAccelerationStructure :: #force_inline proc(self: ^AccelerationStructureCommandEncoder, sourceAccelerationStructure, destinationAccelerationStructure: ^AccelerationStructure) { + msgSend(nil, self, "copyAndCompactAccelerationStructure:toAccelerationStructure:", sourceAccelerationStructure, destinationAccelerationStructure) +} +@(objc_type=AccelerationStructureCommandEncoder, objc_name="refitAccelerationStructure") +AccelerationStructureCommandEncoder_refitAccelerationStructure :: #force_inline proc(self: ^AccelerationStructureCommandEncoder, sourceAccelerationStructure: ^AccelerationStructure, descriptor: ^AccelerationStructureDescriptor, destinationAccelerationStructure: ^AccelerationStructure, scratchBuffer: ^Buffer, scratchBufferOffset: NS.UInteger) { + msgSend(nil, self, "refitAccelerationStructure:descriptor:destination:scratchBuffer:scratchBufferOffset:", sourceAccelerationStructure, descriptor, destinationAccelerationStructure, scratchBuffer, scratchBufferOffset) +} +@(objc_type=AccelerationStructureCommandEncoder, objc_name="sampleCountersInBuffer") +AccelerationStructureCommandEncoder_sampleCountersInBuffer :: #force_inline proc(self: ^AccelerationStructureCommandEncoder, sampleBuffer: ^Buffer, sampleIndex: NS.UInteger, barrier: BOOL) { + msgSend(nil, self, "sampleCountersInBuffer:atSampleIndex:withBarrier:", sampleBuffer, sampleIndex, barrier) +} +@(objc_type=AccelerationStructureCommandEncoder, objc_name="updateFence") +AccelerationStructureCommandEncoder_updateFence :: #force_inline proc(self: ^AccelerationStructureCommandEncoder, fence: ^Fence) { + msgSend(nil, self, "updateFence:", fence) +} +@(objc_type=AccelerationStructureCommandEncoder, objc_name="useHeap") +AccelerationStructureCommandEncoder_useHeap :: #force_inline proc(self: ^AccelerationStructureCommandEncoder, heap: ^Heap) { + msgSend(nil, self, "useHeap:", heap) +} +@(objc_type=AccelerationStructureCommandEncoder, objc_name="useHeaps") +AccelerationStructureCommandEncoder_useHeaps :: #force_inline proc(self: ^AccelerationStructureCommandEncoder, heaps: []^Heap) { + msgSend(nil, self, "useHeaps:count:", raw_data(heaps), NS.UInteger(len(heaps))) +} +@(objc_type=AccelerationStructureCommandEncoder, objc_name="useResource") +AccelerationStructureCommandEncoder_useResource :: #force_inline proc(self: ^AccelerationStructureCommandEncoder, resource: ^Resource, usage: ResourceUsage) { + msgSend(nil, self, "useResource:usage:", resource, usage) +} +@(objc_type=AccelerationStructureCommandEncoder, objc_name="useResources") +AccelerationStructureCommandEncoder_useResources :: #force_inline proc(self: ^AccelerationStructureCommandEncoder, resources: []^Resource, usage: ResourceUsage) { + msgSend(nil, self, "useResources:count:usage:", resources, NS.UInteger(len(resources)), usage) +} +@(objc_type=AccelerationStructureCommandEncoder, objc_name="waitForFence") +AccelerationStructureCommandEncoder_waitForFence :: #force_inline proc(self: ^AccelerationStructureCommandEncoder, fence: ^Fence) { + msgSend(nil, self, "waitForFence:", fence) +} +@(objc_type=AccelerationStructureCommandEncoder, objc_name="writeCompactedAccelerationStructureSize") +AccelerationStructureCommandEncoder_writeCompactedAccelerationStructureSize :: #force_inline proc(self: ^AccelerationStructureCommandEncoder, accelerationStructure: ^AccelerationStructure, buffer: ^Buffer, offset: NS.UInteger) { + msgSend(nil, self, "writeCompactedAccelerationStructureSize:toBuffer:offset:", accelerationStructure, buffer, offset) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + ArgumentEncoder +Class Methods: +Methods: + alignment + constantDataAtIndex + device + encodedLength + label + newArgumentEncoderForBufferAtIndex + setAccelerationStructure + setArgumentBuffer + setArgumentBuffer + setBuffer + setBuffers + setComputePipelineState + setComputePipelineStates + setIndirectCommandBuffer + setIndirectCommandBuffers + setIntersectionFunctionTable + setIntersectionFunctionTables + setLabel + setRenderPipelineState + setRenderPipelineStates + setSamplerState + setSamplerStates + setTexture + setTextures + setVisibleFunctionTable + setVisibleFunctionTables +*/ +@(objc_class="MTLArgumentEncoder") +ArgumentEncoder :: struct { using _: NS.Object } + +@(objc_type=ArgumentEncoder, objc_name="alignment") +ArgumentEncoder_alignment :: #force_inline proc(self: ^ArgumentEncoder) -> NS.UInteger { + return msgSend(NS.UInteger, self, "alignment") +} +@(objc_type=ArgumentEncoder, objc_name="constantData") +ArgumentEncoder_constantData :: #force_inline proc(self: ^ArgumentEncoder, index: NS.UInteger) -> rawptr { + return msgSend(rawptr, self, "constantDataAtIndex:", index) +} +@(objc_type=ArgumentEncoder, objc_name="device") +ArgumentEncoder_device :: #force_inline proc(self: ^ArgumentEncoder) -> ^Device { + return msgSend(^Device, self, "device") +} +@(objc_type=ArgumentEncoder, objc_name="encodedLength") +ArgumentEncoder_encodedLength :: #force_inline proc(self: ^ArgumentEncoder) -> NS.UInteger { + return msgSend(NS.UInteger, self, "encodedLength") +} +@(objc_type=ArgumentEncoder, objc_name="label") +ArgumentEncoder_label :: #force_inline proc(self: ^ArgumentEncoder) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=ArgumentEncoder, objc_name="newArgumentEncoderForBuffer") +ArgumentEncoder_newArgumentEncoderForBuffer :: #force_inline proc(self: ^ArgumentEncoder, index: NS.UInteger) -> ^ArgumentEncoder { + return msgSend(^ArgumentEncoder, self, "newArgumentEncoderForBufferAtIndex:", index) +} +@(objc_type=ArgumentEncoder, objc_name="setAccelerationStructure") +ArgumentEncoder_setAccelerationStructure :: #force_inline proc(self: ^ArgumentEncoder, accelerationStructure: ^AccelerationStructure, index: NS.UInteger) { + msgSend(nil, self, "setAccelerationStructure:atIndex:", accelerationStructure, index) +} +@(objc_type=ArgumentEncoder, objc_name="setArgumentBufferWithOffset") +ArgumentEncoder_setArgumentBufferWithOffset :: #force_inline proc(self: ^ArgumentEncoder, argumentBuffer: ^Buffer, offset: NS.UInteger) { + msgSend(nil, self, "setArgumentBuffer:offset:", argumentBuffer, offset) +} +@(objc_type=ArgumentEncoder, objc_name="setArgumentBufferWithStartOffset") +ArgumentEncoder_setArgumentBuffer_startOffsetWithStartOffset :: #force_inline proc(self: ^ArgumentEncoder, argumentBuffer: ^Buffer, startOffset: NS.UInteger, arrayElement: NS.UInteger) { + msgSend(nil, self, "setArgumentBuffer:startOffset:arrayElement:", argumentBuffer, startOffset, arrayElement) +} +@(objc_type=ArgumentEncoder, objc_name="setBuffer") +ArgumentEncoder_setBuffer :: #force_inline proc(self: ^ArgumentEncoder, buffer: ^Buffer, offset: NS.UInteger, index: NS.UInteger) { + msgSend(nil, self, "setBuffer:offset:atIndex:", buffer, offset, index) +} +@(objc_type=ArgumentEncoder, objc_name="setBuffers") +ArgumentEncoder_setBuffers :: #force_inline proc(self: ^ArgumentEncoder, buffers: []^Buffer, offsets: []NS.UInteger, range: NS.Range) { + assert(len(buffers) == len(offsets)) + msgSend(nil, self, "setBuffers:offsets:withRange:", raw_data(buffers), raw_data(offsets), range) +} +@(objc_type=ArgumentEncoder, objc_name="setComputePipelineState") +ArgumentEncoder_setComputePipelineState :: #force_inline proc(self: ^ArgumentEncoder, pipeline: ^ComputePipelineState, index: NS.UInteger) { + msgSend(nil, self, "setComputePipelineState:atIndex:", pipeline, index) +} +@(objc_type=ArgumentEncoder, objc_name="setComputePipelineStates") +ArgumentEncoder_setComputePipelineStates :: #force_inline proc(self: ^ArgumentEncoder, pipelines: []^ComputePipelineState, range: NS.Range) { + assert(range.length <= NS.UInteger(len(pipelines))) + msgSend(nil, self, "setComputePipelineStates:withRange:", raw_data(pipelines), range) +} +@(objc_type=ArgumentEncoder, objc_name="setIndirectCommandBuffer") +ArgumentEncoder_setIndirectCommandBuffer :: #force_inline proc(self: ^ArgumentEncoder, indirectCommandBuffer: ^IndirectCommandBuffer, index: NS.UInteger) { + msgSend(nil, self, "setIndirectCommandBuffer:atIndex:", indirectCommandBuffer, index) +} +@(objc_type=ArgumentEncoder, objc_name="setIndirectCommandBuffers") +ArgumentEncoder_setIndirectCommandBuffers :: #force_inline proc(self: ^ArgumentEncoder, buffers: []^IndirectCommandBuffer, range: NS.Range) { + assert(range.length <= NS.UInteger(len(buffers))) + msgSend(nil, self, "setIndirectCommandBuffers:withRange:", raw_data(buffers), range) +} +@(objc_type=ArgumentEncoder, objc_name="setIntersectionFunctionTable") +ArgumentEncoder_setIntersectionFunctionTable :: #force_inline proc(self: ^ArgumentEncoder, intersectionFunctionTable: ^IntersectionFunctionTable, index: NS.UInteger) { + msgSend(nil, self, "setIntersectionFunctionTable:atIndex:", intersectionFunctionTable, index) +} +@(objc_type=ArgumentEncoder, objc_name="setIntersectionFunctionTables") +ArgumentEncoder_setIntersectionFunctionTables :: #force_inline proc(self: ^ArgumentEncoder, intersectionFunctionTables: []^IntersectionFunctionTable, range: NS.Range) { + assert(range.length <= NS.UInteger(len(intersectionFunctionTables))) + msgSend(nil, self, "setIntersectionFunctionTables:withRange:", raw_data(intersectionFunctionTables), range) +} +@(objc_type=ArgumentEncoder, objc_name="setLabel") +ArgumentEncoder_setLabel :: #force_inline proc(self: ^ArgumentEncoder, label: ^NS.String) { + msgSend(nil, self, "setLabel:", label) +} +@(objc_type=ArgumentEncoder, objc_name="setRenderPipelineState") +ArgumentEncoder_setRenderPipelineState :: #force_inline proc(self: ^ArgumentEncoder, pipeline: ^RenderPipelineState, index: NS.UInteger) { + msgSend(nil, self, "setRenderPipelineState:atIndex:", pipeline, index) +} +@(objc_type=ArgumentEncoder, objc_name="setRenderPipelineStates") +ArgumentEncoder_setRenderPipelineStates :: #force_inline proc(self: ^ArgumentEncoder, pipelines: []^RenderPipelineState, range: NS.Range) { + assert(range.length <= NS.UInteger(len(pipelines))) + msgSend(nil, self, "setRenderPipelineStates:withRange:", raw_data(pipelines), range) +} +@(objc_type=ArgumentEncoder, objc_name="setSamplerState") +ArgumentEncoder_setSamplerState :: #force_inline proc(self: ^ArgumentEncoder, sampler: ^SamplerState, index: NS.UInteger) { + msgSend(nil, self, "setSamplerState:atIndex:", sampler, index) +} +@(objc_type=ArgumentEncoder, objc_name="setSamplerStates") +ArgumentEncoder_setSamplerStates :: #force_inline proc(self: ^ArgumentEncoder, samplers: []^SamplerState, range: NS.Range) { + assert(range.length <= NS.UInteger(len(samplers))) + msgSend(nil, self, "setSamplerStates:withRange:", raw_data(samplers), range) +} +@(objc_type=ArgumentEncoder, objc_name="setTexture") +ArgumentEncoder_setTexture :: #force_inline proc(self: ^ArgumentEncoder, texture: ^Texture, index: NS.UInteger) { + msgSend(nil, self, "setTexture:atIndex:", texture, index) +} +@(objc_type=ArgumentEncoder, objc_name="setTextures") +ArgumentEncoder_setTextures :: #force_inline proc(self: ^ArgumentEncoder, textures: []^Texture, range: NS.Range) { + assert(range.length <= NS.UInteger(len(textures))) + msgSend(nil, self, "setTextures:withRange:", raw_data(textures), range) +} +@(objc_type=ArgumentEncoder, objc_name="setVisibleFunctionTable") +ArgumentEncoder_setVisibleFunctionTable :: #force_inline proc(self: ^ArgumentEncoder, visibleFunctionTable: ^VisibleFunctionTable, index: NS.UInteger) { + msgSend(nil, self, "setVisibleFunctionTable:atIndex:", visibleFunctionTable, index) +} +@(objc_type=ArgumentEncoder, objc_name="setVisibleFunctionTables") +ArgumentEncoder_setVisibleFunctionTables :: #force_inline proc(self: ^ArgumentEncoder, visibleFunctionTables: []^VisibleFunctionTable, range: NS.Range) { + assert(range.length <= NS.UInteger(len(visibleFunctionTables))) + msgSend(nil, self, "setVisibleFunctionTables:withRange:", raw_data(visibleFunctionTables), range) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + BinaryArchive +Class Methods: +Methods: + addComputePipelineFunctionsWithDescriptor + addRenderPipelineFunctionsWithDescriptor + addTileRenderPipelineFunctionsWithDescriptor + device + label + serializeToURL + setLabel +*/ +@(objc_class="MTLBinaryArchive") +BinaryArchive :: struct { using _: NS.Copying(BinaryArchive) } + +@(objc_type=BinaryArchive, objc_name="addComputePipelineFunctions") +BinaryArchive_addComputePipelineFunctions :: #force_inline proc(self: ^BinaryArchive, descriptor: ^ComputePipelineDescriptor) -> (ok: BOOL, error: ^NS.Error) { + ok = msgSend(BOOL, self, "addComputePipelineFunctionsWithDescriptor:error:", descriptor, &error) + return +} +@(objc_type=BinaryArchive, objc_name="addRenderPipelineFunctions") +BinaryArchive_addRenderPipelineFunctions :: #force_inline proc(self: ^BinaryArchive, descriptor: ^RenderPipelineDescriptor) -> (ok: BOOL, error: ^NS.Error) { + ok = msgSend(BOOL, self, "addRenderPipelineFunctionsWithDescriptor:error:", descriptor, &error) + return +} +@(objc_type=BinaryArchive, objc_name="addTileRenderPipelineFunctions") +BinaryArchive_addTileRenderPipelineFunctions :: #force_inline proc(self: ^BinaryArchive, descriptor: ^TileRenderPipelineDescriptor) -> (ok: BOOL, error: ^NS.Error) { + ok = msgSend(BOOL, self, "addTileRenderPipelineFunctionsWithDescriptor:error:", descriptor, &error) + return +} +@(objc_type=BinaryArchive, objc_name="device") +BinaryArchive_device :: #force_inline proc(self: ^BinaryArchive) -> ^Device { + return msgSend(^Device, self, "device") +} +@(objc_type=BinaryArchive, objc_name="label") +BinaryArchive_label :: #force_inline proc(self: ^BinaryArchive) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=BinaryArchive, objc_name="serializeToURL") +BinaryArchive_serializeToURL :: #force_inline proc(self: ^BinaryArchive, url: ^NS.URL) -> (ok: BOOL, error: ^NS.Error) { + ok = msgSend(BOOL, self, "serializeToURL:error:", url, &error) + return +} +@(objc_type=BinaryArchive, objc_name="setLabel") +BinaryArchive_setLabel :: #force_inline proc(self: ^BinaryArchive, label: ^NS.String) { + msgSend(nil, self, "setLabel:", label) +} + + +@(objc_type=BinaryArchive, objc_name="addFunction") +BinaryArchive_addFunction :: #force_inline proc(self: ^BinaryArchive, descriptor: ^FunctionDescriptor, library: ^Library) -> (ok: BOOL, error: ^NS.Error) { + ok = msgSend(BOOL, self, "addFunction:", descriptor, library, &error) + return +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + BlitCommandEncoder +Class Methods: +Methods: + copyFromBuffer + copyFromBuffer + copyFromBuffer + copyFromTexture + copyFromTexture + copyFromTexture + copyFromTexture + copyFromTexture + copyIndirectCommandBuffer + fillBuffer + generateMipmapsForTexture + getTextureAccessCounters + optimizeContentsForCPUAccess + optimizeContentsForCPUAccess + optimizeContentsForGPUAccess + optimizeContentsForGPUAccess + optimizeIndirectCommandBuffer + resetCommandsInBuffer + resetTextureAccessCounters + resolveCounters + sampleCountersInBuffer + synchronizeResource + synchronizeTexture + updateFence + waitForFence +*/ +@(objc_class="MTLBlitCommandEncoder") +BlitCommandEncoder :: struct { using _: CommandEncoder } + +@(objc_type=BlitCommandEncoder, objc_name="copyFromBufferEx") +BlitCommandEncoder_copyFromBufferEx :: #force_inline proc(self: ^BlitCommandEncoder, sourceBuffer: ^Buffer, sourceOffset: NS.UInteger, sourceBytesPerRow: NS.UInteger, sourceBytesPerImage: NS.UInteger, sourceSize: Size, destinationTexture: ^Texture, destinationSlice: NS.UInteger, destinationLevel: NS.UInteger, destinationOrigin: Origin) { + msgSend(nil, self, "copyFromBuffer:sourceOffset:sourceBytesPerRow:sourceBytesPerImage:sourceSize:toTexture:destinationSlice:destinationLevel:destinationOrigin:", sourceBuffer, sourceOffset, sourceBytesPerRow, sourceBytesPerImage, sourceSize, destinationTexture, destinationSlice, destinationLevel, destinationOrigin) +} +@(objc_type=BlitCommandEncoder, objc_name="copyFromBufferExWithOptions") +BlitCommandEncoder_copyFromBufferExWithOptions :: #force_inline proc(self: ^BlitCommandEncoder, sourceBuffer: ^Buffer, sourceOffset: NS.UInteger, sourceBytesPerRow: NS.UInteger, sourceBytesPerImage: NS.UInteger, sourceSize: Size, destinationTexture: ^Texture, destinationSlice: NS.UInteger, destinationLevel: NS.UInteger, destinationOrigin: Origin, options: BlitOption) { + msgSend(nil, self, "copyFromBuffer:sourceOffset:sourceBytesPerRow:sourceBytesPerImage:sourceSize:toTexture:destinationSlice:destinationLevel:destinationOrigin:options:", sourceBuffer, sourceOffset, sourceBytesPerRow, sourceBytesPerImage, sourceSize, destinationTexture, destinationSlice, destinationLevel, destinationOrigin, options) +} +@(objc_type=BlitCommandEncoder, objc_name="copyFromBuffer") +BlitCommandEncoder_copyFromBuffer :: #force_inline proc(self: ^BlitCommandEncoder, sourceBuffer: ^Buffer, sourceOffset: NS.UInteger, destinationBuffer: ^Buffer, destinationOffset: NS.UInteger, size: NS.UInteger) { + msgSend(nil, self, "copyFromBuffer:sourceOffset:toBuffer:destinationOffset:size:", sourceBuffer, sourceOffset, destinationBuffer, destinationOffset, size) +} +@(objc_type=BlitCommandEncoder, objc_name="copyFromTextureEx") +BlitCommandEncoder_copyFromTextureEx :: #force_inline proc(self: ^BlitCommandEncoder, sourceTexture: ^Texture, sourceSlice: NS.UInteger, sourceLevel: NS.UInteger, sourceOrigin: Origin, sourceSize: Size, destinationBuffer: ^Buffer, destinationOffset: NS.UInteger, destinationBytesPerRow: NS.UInteger, destinationBytesPerImage: NS.UInteger) { + msgSend(nil, self, "copyFromTexture:sourceSlice:sourceLevel:sourceOrigin:sourceSize:toBuffer:destinationOffset:destinationBytesPerRow:destinationBytesPerImage:", sourceTexture, sourceSlice, sourceLevel, sourceOrigin, sourceSize, destinationBuffer, destinationOffset, destinationBytesPerRow, destinationBytesPerImage) +} +@(objc_type=BlitCommandEncoder, objc_name="copyFromTextureExWithOptions") +BlitCommandEncoder_copyFromTextureExWithOptions :: #force_inline proc(self: ^BlitCommandEncoder, sourceTexture: ^Texture, sourceSlice: NS.UInteger, sourceLevel: NS.UInteger, sourceOrigin: Origin, sourceSize: Size, destinationBuffer: ^Buffer, destinationOffset: NS.UInteger, destinationBytesPerRow: NS.UInteger, destinationBytesPerImage: NS.UInteger, options: BlitOption) { + msgSend(nil, self, "copyFromTexture:sourceSlice:sourceLevel:sourceOrigin:sourceSize:toBuffer:destinationOffset:destinationBytesPerRow:destinationBytesPerImage:options:", sourceTexture, sourceSlice, sourceLevel, sourceOrigin, sourceSize, destinationBuffer, destinationOffset, destinationBytesPerRow, destinationBytesPerImage, options) +} +@(objc_type=BlitCommandEncoder, objc_name="copyFromTextureWithDestinationOrigin") +BlitCommandEncoder_copyFromTextureWithDestinationOrigin :: #force_inline proc(self: ^BlitCommandEncoder, sourceTexture: ^Texture, sourceSlice: NS.UInteger, sourceLevel: NS.UInteger, sourceOrigin: Origin, sourceSize: Size, destinationTexture: ^Texture, destinationSlice: NS.UInteger, destinationLevel: NS.UInteger, destinationOrigin: Origin) { + msgSend(nil, self, "copyFromTexture:sourceSlice:sourceLevel:sourceOrigin:sourceSize:toTexture:destinationSlice:destinationLevel:destinationOrigin:", sourceTexture, sourceSlice, sourceLevel, sourceOrigin, sourceSize, destinationTexture, destinationSlice, destinationLevel, destinationOrigin) +} +@(objc_type=BlitCommandEncoder, objc_name="copyFromTextureWithCounts") +BlitCommandEncoder_copyFromTextureWithCounts :: #force_inline proc(self: ^BlitCommandEncoder, sourceTexture: ^Texture, sourceSlice: NS.UInteger, sourceLevel: NS.UInteger, destinationTexture: ^Texture, destinationSlice: NS.UInteger, destinationLevel: NS.UInteger, sliceCount: NS.UInteger, levelCount: NS.UInteger) { + msgSend(nil, self, "copyFromTexture:sourceSlice:sourceLevel:toTexture:destinationSlice:destinationLevel:sliceCount:levelCount:", sourceTexture, sourceSlice, sourceLevel, destinationTexture, destinationSlice, destinationLevel, sliceCount, levelCount) +} +@(objc_type=BlitCommandEncoder, objc_name="copyFromTexture") +BlitCommandEncoder_copyFromTexture :: #force_inline proc(self: ^BlitCommandEncoder, sourceTexture: ^Texture, destinationTexture: ^Texture) { + msgSend(nil, self, "copyFromTexture:toTexture:", sourceTexture, destinationTexture) +} +@(objc_type=BlitCommandEncoder, objc_name="copyIndirectCommandBuffer") +BlitCommandEncoder_copyIndirectCommandBuffer :: #force_inline proc(self: ^BlitCommandEncoder, source: ^IndirectCommandBuffer, sourceRange: NS.Range, destination: ^IndirectCommandBuffer, destinationIndex: NS.UInteger) { + msgSend(nil, self, "copyIndirectCommandBuffer:sourceRange:destination:destinationIndex:", source, sourceRange, destination, destinationIndex) +} +@(objc_type=BlitCommandEncoder, objc_name="fillBuffer") +BlitCommandEncoder_fillBuffer :: #force_inline proc(self: ^BlitCommandEncoder, buffer: ^Buffer, range: NS.Range, value: u8) { + msgSend(nil, self, "fillBuffer:range:value:", buffer, range, value) +} +@(objc_type=BlitCommandEncoder, objc_name="generateMipmapsForTexture") +BlitCommandEncoder_generateMipmapsForTexture :: #force_inline proc(self: ^BlitCommandEncoder, texture: ^Texture) { + msgSend(nil, self, "generateMipmapsForTexture:", texture) +} +@(objc_type=BlitCommandEncoder, objc_name="getTextureAccessCounters") +BlitCommandEncoder_getTextureAccessCounters :: #force_inline proc(self: ^BlitCommandEncoder, texture: ^Texture, region: Region, mipLevel: NS.UInteger, slice: NS.UInteger, resetCounters: BOOL, countersBuffer: ^Buffer, countersBufferOffset: NS.UInteger) { + msgSend(nil, self, "getTextureAccessCounters:region:mipLevel:slice:resetCounters:countersBuffer:countersBufferOffset:", texture, region, mipLevel, slice, resetCounters, countersBuffer, countersBufferOffset) +} +@(objc_type=BlitCommandEncoder, objc_name="optimizeContentsForCPUAccess") +BlitCommandEncoder_optimizeContentsForCPUAccess :: #force_inline proc(self: ^BlitCommandEncoder, texture: ^Texture) { + msgSend(nil, self, "optimizeContentsForCPUAccess:", texture) +} +@(objc_type=BlitCommandEncoder, objc_name="optimizeContentsForCPUAccessWithSliceAndLevel") +BlitCommandEncoder_optimizeContentsForCPUAccessWithSliceAndLevel :: #force_inline proc(self: ^BlitCommandEncoder, texture: ^Texture, slice: NS.UInteger, level: NS.UInteger) { + msgSend(nil, self, "optimizeContentsForCPUAccess:slice:level:", texture, slice, level) +} +@(objc_type=BlitCommandEncoder, objc_name="optimizeContentsForGPUAccess") +BlitCommandEncoder_optimizeContentsForGPUAccess :: #force_inline proc(self: ^BlitCommandEncoder, texture: ^Texture) { + msgSend(nil, self, "optimizeContentsForGPUAccess:", texture) +} +@(objc_type=BlitCommandEncoder, objc_name="optimizeContentsForGPUAccessWithSliceAndLevel") +BlitCommandEncoder_optimizeContentsForGPUAccessWithSliceAndLevel :: #force_inline proc(self: ^BlitCommandEncoder, texture: ^Texture, slice: NS.UInteger, level: NS.UInteger) { + msgSend(nil, self, "optimizeContentsForGPUAccess:slice:level:", texture, slice, level) +} +@(objc_type=BlitCommandEncoder, objc_name="optimizeIndirectCommandBuffer") +BlitCommandEncoder_optimizeIndirectCommandBuffer :: #force_inline proc(self: ^BlitCommandEncoder, indirectCommandBuffer: ^Buffer, range: NS.Range) { + msgSend(nil, self, "optimizeIndirectCommandBuffer:withRange:", indirectCommandBuffer, range) +} +@(objc_type=BlitCommandEncoder, objc_name="resetCommandsInBuffer") +BlitCommandEncoder_resetCommandsInBuffer :: #force_inline proc(self: ^BlitCommandEncoder, buffer: ^Buffer, range: NS.Range) { + msgSend(nil, self, "resetCommandsInBuffer:withRange:", buffer, range) +} +@(objc_type=BlitCommandEncoder, objc_name="resetTextureAccessCounters") +BlitCommandEncoder_resetTextureAccessCounters :: #force_inline proc(self: ^BlitCommandEncoder, texture: ^Texture, region: Region, mipLevel: NS.UInteger, slice: NS.UInteger) { + msgSend(nil, self, "resetTextureAccessCounters:region:mipLevel:slice:", texture, region, mipLevel, slice) +} +@(objc_type=BlitCommandEncoder, objc_name="resolveCounters") +BlitCommandEncoder_resolveCounters :: #force_inline proc(self: ^BlitCommandEncoder, sampleBuffer: ^Buffer, range: NS.Range, destinationBuffer: ^Buffer, destinationOffset: NS.UInteger) { + msgSend(nil, self, "resolveCounters:inRange:destinationBuffer:destinationOffset:", sampleBuffer, range, destinationBuffer, destinationOffset) +} +@(objc_type=BlitCommandEncoder, objc_name="sampleCountersInBuffer") +BlitCommandEncoder_sampleCountersInBuffer :: #force_inline proc(self: ^BlitCommandEncoder, sampleBuffer: ^Buffer, sampleIndex: NS.UInteger, barrier: BOOL) { + msgSend(nil, self, "sampleCountersInBuffer:atSampleIndex:withBarrier:", sampleBuffer, sampleIndex, barrier) +} +@(objc_type=BlitCommandEncoder, objc_name="synchronizeResource") +BlitCommandEncoder_synchronizeResource :: #force_inline proc(self: ^BlitCommandEncoder, resource: ^Resource) { + msgSend(nil, self, "synchronizeResource:", resource) +} +@(objc_type=BlitCommandEncoder, objc_name="synchronizeTexture") +BlitCommandEncoder_synchronizeTexture :: #force_inline proc(self: ^BlitCommandEncoder, texture: ^Texture, slice: NS.UInteger, level: NS.UInteger) { + msgSend(nil, self, "synchronizeTexture:slice:level:", texture, slice, level) +} +@(objc_type=BlitCommandEncoder, objc_name="updateFence") +BlitCommandEncoder_updateFence :: #force_inline proc(self: ^BlitCommandEncoder, fence: ^Fence) { + msgSend(nil, self, "updateFence:", fence) +} +@(objc_type=BlitCommandEncoder, objc_name="waitForFence") +BlitCommandEncoder_waitForFence :: #force_inline proc(self: ^BlitCommandEncoder, fence: ^Fence) { + msgSend(nil, self, "waitForFence:", fence) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + Buffer +Class Methods: +Methods: + addDebugMarker + contents + didModifyRange + length + newRemoteBufferViewForDevice + newTextureWithDescriptor + remoteStorageBuffer + removeAllDebugMarkers +*/ +@(objc_class="MTLBuffer") +Buffer :: struct { using _: Resource } + +@(objc_type=Buffer, objc_name="addDebugMarker") +Buffer_addDebugMarker :: #force_inline proc(self: ^Buffer, marker: ^NS.String, range: NS.Range) { + msgSend(nil, self, "addDebugMarker:range:", marker, range) +} +@(objc_type=Buffer, objc_name="contents") +Buffer_contents :: #force_inline proc(self: ^Buffer) -> []byte { + contents := msgSend([^]byte, self, "contents") + length := Buffer_length(self) + return contents[:length] +} +@(objc_type=Buffer, objc_name="contentsPointer") +Buffer_contentsPointer :: #force_inline proc(self: ^Buffer) -> rawptr { + return msgSend(rawptr, self, "contents") +} +@(objc_type=Buffer, objc_name="contentsAsSlice") +Buffer_contentsAsSlice :: #force_inline proc(self: ^Buffer, $T: typeid/[]$E) -> T { + contents := msgSend([^]byte, self, "contents") + length := Buffer_length(self) + return mem.slice_data_cast(T, contents[:length]) +} +@(objc_type=Buffer, objc_name="contentsAsType") +Buffer_contentsAsType :: #force_inline proc(self: ^Buffer, $T: typeid, offset: uintptr = 0) -> ^T { + ptr := msgSend(rawptr, self, "contents") + return (^T)(uintptr(ptr) + offset) +} +@(objc_type=Buffer, objc_name="didModifyRange") +Buffer_didModifyRange :: #force_inline proc(self: ^Buffer, range: NS.Range) { + msgSend(nil, self, "didModifyRange:", range) +} +@(objc_type=Buffer, objc_name="length") +Buffer_length :: #force_inline proc(self: ^Buffer) -> NS.UInteger { + return msgSend(NS.UInteger, self, "length") +} +@(objc_type=Buffer, objc_name="newRemoteBufferViewForDevice") +Buffer_newRemoteBufferViewForDevice :: #force_inline proc(self: ^Buffer, device: ^Device) -> ^Buffer { + return msgSend(^Buffer, self, "newRemoteBufferViewForDevice:", device) +} +@(objc_type=Buffer, objc_name="newTexture") +Buffer_newTexture :: #force_inline proc(self: ^Buffer, descriptor: ^TextureDescriptor, offset: NS.UInteger, bytesPerRow: NS.UInteger) -> ^Texture { + return msgSend(^Texture, self, "newTextureWithDescriptor:offset:bytesPerRow:", descriptor, offset, bytesPerRow) +} +@(objc_type=Buffer, objc_name="remoteStorageBuffer") +Buffer_remoteStorageBuffer :: #force_inline proc(self: ^Buffer) -> ^Buffer { + return msgSend(^Buffer, self, "remoteStorageBuffer") +} +@(objc_type=Buffer, objc_name="removeAllDebugMarkers") +Buffer_removeAllDebugMarkers :: #force_inline proc(self: ^Buffer) { + msgSend(nil, self, "removeAllDebugMarkers") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + CaptureScope +Class Methods: +Methods: + beginScope + commandQueue + device + endScope + label + setLabel +*/ +@(objc_class="MTLCaptureScope") +CaptureScope :: struct { using _: NS.Object } + +@(objc_type=CaptureScope, objc_name="beginScope") +CaptureScope_beginScope :: #force_inline proc(self: ^CaptureScope) { + msgSend(nil, self, "beginScope") +} +@(objc_type=CaptureScope, objc_name="commandQueue") +CaptureScope_commandQueue :: #force_inline proc(self: ^CaptureScope) -> ^CommandQueue { + return msgSend(^CommandQueue, self, "commandQueue") +} +@(objc_type=CaptureScope, objc_name="device") +CaptureScope_device :: #force_inline proc(self: ^CaptureScope) -> ^Device { + return msgSend(^Device, self, "device") +} +@(objc_type=CaptureScope, objc_name="endScope") +CaptureScope_endScope :: #force_inline proc(self: ^CaptureScope) { + msgSend(nil, self, "endScope") +} +@(objc_type=CaptureScope, objc_name="label") +CaptureScope_label :: #force_inline proc(self: ^CaptureScope) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=CaptureScope, objc_name="setLabel") +CaptureScope_setLabel :: #force_inline proc(self: ^CaptureScope, label: ^NS.String) { + msgSend(nil, self, "setLabel:", label) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + CommandBuffer +Class Methods: +Methods: + GPUEndTime + GPUStartTime + accelerationStructureCommandEncoder + addCompletedHandler + addScheduledHandler + blitCommandEncoder + blitCommandEncoderWithDescriptor + commandQueue + commit + computeCommandEncoder + computeCommandEncoderWithDescriptor + computeCommandEncoderWithDispatchType + device + encodeSignalEvent + encodeWaitForEvent + enqueue + error + errorOptions + kernelEndTime + kernelStartTime + label + logs + parallelRenderCommandEncoderWithDescriptor + popDebugGroup + presentDrawable + presentDrawable + presentDrawable + pushDebugGroup + renderCommandEncoderWithDescriptor + resourceStateCommandEncoder + resourceStateCommandEncoderWithDescriptor + retainedReferences + setLabel + status + waitUntilCompleted + waitUntilScheduled +*/ +@(objc_class="MTLCommandBuffer") +CommandBuffer :: struct { using _: NS.Object } + +@(objc_type=CommandBuffer, objc_name="GPUEndTime") +CommandBuffer_GPUEndTime :: #force_inline proc(self: ^CommandBuffer) -> CFTimeInterval { + return msgSend(CFTimeInterval, self, "GPUEndTime") +} +@(objc_type=CommandBuffer, objc_name="GPUStartTime") +CommandBuffer_GPUStartTime :: #force_inline proc(self: ^CommandBuffer) -> CFTimeInterval { + return msgSend(CFTimeInterval, self, "GPUStartTime") +} +@(objc_type=CommandBuffer, objc_name="accelerationStructureCommandEncoder") +CommandBuffer_accelerationStructureCommandEncoder :: #force_inline proc(self: ^CommandBuffer) -> ^AccelerationStructureCommandEncoder { + return msgSend(^AccelerationStructureCommandEncoder, self, "accelerationStructureCommandEncoder") +} +@(objc_type=CommandBuffer, objc_name="addCompletedHandler") +CommandBuffer_addCompletedHandler :: #force_inline proc(self: ^CommandBuffer, block: CommandBufferHandler) { + msgSend(nil, self, "addCompletedHandler:", block) +} +@(objc_type=CommandBuffer, objc_name="addScheduledHandler") +CommandBuffer_addScheduledHandler :: #force_inline proc(self: ^CommandBuffer, block: CommandBufferHandler) { + msgSend(nil, self, "addScheduledHandler:", block) +} +@(objc_type=CommandBuffer, objc_name="blitCommandEncoder") +CommandBuffer_blitCommandEncoder :: #force_inline proc(self: ^CommandBuffer) -> ^BlitCommandEncoder { + return msgSend(^BlitCommandEncoder, self, "blitCommandEncoder") +} +@(objc_type=CommandBuffer, objc_name="blitCommandEncoderWithDescriptor") +CommandBuffer_blitCommandEncoderWithDescriptor :: #force_inline proc(self: ^CommandBuffer, blitPassDescriptor: ^BlitPassDescriptor) -> ^BlitCommandEncoder { + return msgSend(^BlitCommandEncoder, self, "blitCommandEncoderWithDescriptor:", blitPassDescriptor) +} +@(objc_type=CommandBuffer, objc_name="commandQueue") +CommandBuffer_commandQueue :: #force_inline proc(self: ^CommandBuffer) -> ^CommandQueue { + return msgSend(^CommandQueue, self, "commandQueue") +} +@(objc_type=CommandBuffer, objc_name="commit") +CommandBuffer_commit :: #force_inline proc(self: ^CommandBuffer) { + msgSend(nil, self, "commit") +} +@(objc_type=CommandBuffer, objc_name="computeCommandEncoder") +CommandBuffer_computeCommandEncoder :: #force_inline proc(self: ^CommandBuffer) -> ^ComputeCommandEncoder { + return msgSend(^ComputeCommandEncoder, self, "computeCommandEncoder") +} +@(objc_type=CommandBuffer, objc_name="computeCommandEncoderWithDescriptor") +CommandBuffer_computeCommandEncoderWithDescriptor :: #force_inline proc(self: ^CommandBuffer, computePassDescriptor: ^ComputePassDescriptor) -> ^ComputeCommandEncoder { + return msgSend(^ComputeCommandEncoder, self, "computeCommandEncoderWithDescriptor:", computePassDescriptor) +} +@(objc_type=CommandBuffer, objc_name="computeCommandEncoderWithDispatchType") +CommandBuffer_computeCommandEncoderWithDispatchType :: #force_inline proc(self: ^CommandBuffer, dispatchType: DispatchType) -> ^ComputeCommandEncoder { + return msgSend(^ComputeCommandEncoder, self, "computeCommandEncoderWithDispatchType:", dispatchType) +} +@(objc_type=CommandBuffer, objc_name="device") +CommandBuffer_device :: #force_inline proc(self: ^CommandBuffer) -> ^Device { + return msgSend(^Device, self, "device") +} +@(objc_type=CommandBuffer, objc_name="encodeSignalEvent") +CommandBuffer_encodeSignalEvent :: #force_inline proc(self: ^CommandBuffer, event: ^Event, value: u64) { + msgSend(nil, self, "encodeSignalEvent:value:", event, value) +} +@(objc_type=CommandBuffer, objc_name="encodeWaitForEvent") +CommandBuffer_encodeWaitForEvent :: #force_inline proc(self: ^CommandBuffer, event: ^Event, value: u64) { + msgSend(nil, self, "encodeWaitForEvent:value:", event, value) +} +@(objc_type=CommandBuffer, objc_name="enqueue") +CommandBuffer_enqueue :: #force_inline proc(self: ^CommandBuffer) { + msgSend(nil, self, "enqueue") +} +@(objc_type=CommandBuffer, objc_name="error") +CommandBuffer_error :: #force_inline proc(self: ^CommandBuffer) -> ^NS.Error { + return msgSend(^NS.Error, self, "error") +} +@(objc_type=CommandBuffer, objc_name="errorOptions") +CommandBuffer_errorOptions :: #force_inline proc(self: ^CommandBuffer) -> CommandBufferErrorOption { + return msgSend(CommandBufferErrorOption, self, "errorOptions") +} +@(objc_type=CommandBuffer, objc_name="kernelEndTime") +CommandBuffer_kernelEndTime :: #force_inline proc(self: ^CommandBuffer) -> CFTimeInterval { + return msgSend(CFTimeInterval, self, "kernelEndTime") +} +@(objc_type=CommandBuffer, objc_name="kernelStartTime") +CommandBuffer_kernelStartTime :: #force_inline proc(self: ^CommandBuffer) -> CFTimeInterval { + return msgSend(CFTimeInterval, self, "kernelStartTime") +} +@(objc_type=CommandBuffer, objc_name="label") +CommandBuffer_label :: #force_inline proc(self: ^CommandBuffer) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=CommandBuffer, objc_name="logs") +CommandBuffer_logs :: #force_inline proc(self: ^CommandBuffer) -> ^LogContainer { + return msgSend(^LogContainer, self, "logs") +} +@(objc_type=CommandBuffer, objc_name="parallelRenderCommandEncoder") +CommandBuffer_parallelRenderCommandEncoder :: #force_inline proc(self: ^CommandBuffer, renderPassDescriptor: ^RenderPassDescriptor) -> ^ParallelRenderCommandEncoder { + return msgSend(^ParallelRenderCommandEncoder, self, "parallelRenderCommandEncoderWithDescriptor:", renderPassDescriptor) +} +@(objc_type=CommandBuffer, objc_name="popDebugGroup") +CommandBuffer_popDebugGroup :: #force_inline proc(self: ^CommandBuffer) { + msgSend(nil, self, "popDebugGroup") +} +@(objc_type=CommandBuffer, objc_name="presentDrawable") +CommandBuffer_presentDrawable :: #force_inline proc(self: ^CommandBuffer, drawable: ^Drawable) { + msgSend(nil, self, "presentDrawable:", drawable) +} +@(objc_type=CommandBuffer, objc_name="presentDrawableAfterMinimumDuration") +CommandBuffer_presentDrawableAfterMinimumDuration :: #force_inline proc(self: ^CommandBuffer, drawable: ^Drawable, duration: CFTimeInterval) { + msgSend(nil, self, "presentDrawable:afterMinimumDuration:", drawable, duration) +} +@(objc_type=CommandBuffer, objc_name="presentDrawableAtTime") +CommandBuffer_presentDrawableAtTime :: #force_inline proc(self: ^CommandBuffer, drawable: ^Drawable, presentationTime: CFTimeInterval) { + msgSend(nil, self, "presentDrawable:atTime:", drawable, presentationTime) +} +@(objc_type=CommandBuffer, objc_name="pushDebugGroup") +CommandBuffer_pushDebugGroup :: #force_inline proc(self: ^CommandBuffer, string: ^NS.String) { + msgSend(nil, self, "pushDebugGroup:", string) +} +@(objc_type=CommandBuffer, objc_name="renderCommandEncoderWithDescriptor") +CommandBuffer_renderCommandEncoderWithDescriptor :: #force_inline proc(self: ^CommandBuffer, renderPassDescriptor: ^RenderPassDescriptor) -> ^RenderCommandEncoder { + return msgSend(^RenderCommandEncoder, self, "renderCommandEncoderWithDescriptor:", renderPassDescriptor) +} +@(objc_type=CommandBuffer, objc_name="resourceStateCommandEncoder") +CommandBuffer_resourceStateCommandEncoder :: #force_inline proc(self: ^CommandBuffer) -> ^CommandBuffer { + return msgSend(^CommandBuffer, self, "resourceStateCommandEncoder") +} +@(objc_type=CommandBuffer, objc_name="resourceStateCommandEncoderWithDescriptor") +CommandBuffer_resourceStateCommandEncoderWithDescriptor :: #force_inline proc(self: ^CommandBuffer, resourceStatePassDescriptor: ^ResourceStatePassDescriptor) -> ^ResourceStateCommandEncoder { + return msgSend(^ResourceStateCommandEncoder, self, "resourceStateCommandEncoderWithDescriptor:", resourceStatePassDescriptor) +} +@(objc_type=CommandBuffer, objc_name="retainedReferences") +CommandBuffer_retainedReferences :: #force_inline proc(self: ^CommandBuffer) -> BOOL { + return msgSend(BOOL, self, "retainedReferences") +} +@(objc_type=CommandBuffer, objc_name="setLabel") +CommandBuffer_setLabel :: #force_inline proc(self: ^CommandBuffer, label: ^NS.String) { + msgSend(nil, self, "setLabel:", label) +} +@(objc_type=CommandBuffer, objc_name="status") +CommandBuffer_status :: #force_inline proc(self: ^CommandBuffer) -> CommandBufferStatus { + return msgSend(CommandBufferStatus, self, "status") +} +@(objc_type=CommandBuffer, objc_name="waitUntilCompleted") +CommandBuffer_waitUntilCompleted :: #force_inline proc(self: ^CommandBuffer) { + msgSend(nil, self, "waitUntilCompleted") +} +@(objc_type=CommandBuffer, objc_name="waitUntilScheduled") +CommandBuffer_waitUntilScheduled :: #force_inline proc(self: ^CommandBuffer) { + msgSend(nil, self, "waitUntilScheduled") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + CommandBufferEncoderInfo +Class Methods: +Methods: + debugSignposts + errorState + label +*/ +@(objc_class="MTLCommandBufferEncoderInfo") +CommandBufferEncoderInfo :: struct { using _: NS.Object } + +@(objc_type=CommandBufferEncoderInfo, objc_name="debugSignposts") +CommandBufferEncoderInfo_debugSignposts :: #force_inline proc(self: ^CommandBufferEncoderInfo) -> ^NS.Array { + return msgSend(^NS.Array, self, "debugSignposts") +} +@(objc_type=CommandBufferEncoderInfo, objc_name="errorState") +CommandBufferEncoderInfo_errorState :: #force_inline proc(self: ^CommandBufferEncoderInfo) -> CommandEncoderErrorState { + return msgSend(CommandEncoderErrorState, self, "errorState") +} +@(objc_type=CommandBufferEncoderInfo, objc_name="label") +CommandBufferEncoderInfo_label :: #force_inline proc(self: ^CommandBufferEncoderInfo) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + CommandEncoder +Class Methods: +Methods: + device + endEncoding + insertDebugSignpost + label + popDebugGroup + pushDebugGroup + setLabel +*/ +@(objc_class="MTLCommandEncoder") +CommandEncoder :: struct { using _: NS.Object } + +@(objc_type=CommandEncoder, objc_name="device") +CommandEncoder_device :: #force_inline proc(self: ^CommandEncoder) -> ^Device { + return msgSend(^Device, self, "device") +} +@(objc_type=CommandEncoder, objc_name="endEncoding") +CommandEncoder_endEncoding :: #force_inline proc(self: ^CommandEncoder) { + msgSend(nil, self, "endEncoding") +} +@(objc_type=CommandEncoder, objc_name="insertDebugSignpost") +CommandEncoder_insertDebugSignpost :: #force_inline proc(self: ^CommandEncoder, string: ^NS.String) { + msgSend(nil, self, "insertDebugSignpost:", string) +} +@(objc_type=CommandEncoder, objc_name="label") +CommandEncoder_label :: #force_inline proc(self: ^CommandEncoder) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=CommandEncoder, objc_name="popDebugGroup") +CommandEncoder_popDebugGroup :: #force_inline proc(self: ^CommandEncoder) { + msgSend(nil, self, "popDebugGroup") +} +@(objc_type=CommandEncoder, objc_name="pushDebugGroup") +CommandEncoder_pushDebugGroup :: #force_inline proc(self: ^CommandEncoder, string: ^NS.String) { + msgSend(nil, self, "pushDebugGroup:", string) +} +@(objc_type=CommandEncoder, objc_name="setLabel") +CommandEncoder_setLabel :: #force_inline proc(self: ^CommandEncoder, label: ^NS.String) { + msgSend(nil, self, "setLabel:", label) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + CommandQueue +Class Methods: +Methods: + commandBuffer + commandBufferWithDescriptor + commandBufferWithUnretainedReferences + device + insertDebugCaptureBoundary + label + setLabel +*/ +@(objc_class="MTLCommandQueue") +CommandQueue :: struct { using _: NS.Object } + +@(objc_type=CommandQueue, objc_name="commandBuffer") +CommandQueue_commandBuffer :: #force_inline proc(self: ^CommandQueue) -> ^CommandBuffer { + return msgSend(^CommandBuffer, self, "commandBuffer") +} +@(objc_type=CommandQueue, objc_name="commandBufferWithDescriptor") +CommandQueue_commandBufferWithDescriptor :: #force_inline proc(self: ^CommandQueue, descriptor: ^CommandBufferDescriptor) -> ^CommandQueue { + return msgSend(^CommandQueue, self, "commandBufferWithDescriptor:", descriptor) +} +@(objc_type=CommandQueue, objc_name="commandBufferWithUnretainedReferences") +CommandQueue_commandBufferWithUnretainedReferences :: #force_inline proc(self: ^CommandQueue) -> ^CommandQueue { + return msgSend(^CommandQueue, self, "commandBufferWithUnretainedReferences") +} +@(objc_type=CommandQueue, objc_name="device") +CommandQueue_device :: #force_inline proc(self: ^CommandQueue) -> ^Device { + return msgSend(^Device, self, "device") +} +@(objc_type=CommandQueue, objc_name="insertDebugCaptureBoundary") +CommandQueue_insertDebugCaptureBoundary :: #force_inline proc(self: ^CommandQueue) { + msgSend(nil, self, "insertDebugCaptureBoundary") +} +@(objc_type=CommandQueue, objc_name="label") +CommandQueue_label :: #force_inline proc(self: ^CommandQueue) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=CommandQueue, objc_name="setLabel") +CommandQueue_setLabel :: #force_inline proc(self: ^CommandQueue, label: ^NS.String) { + msgSend(nil, self, "setLabel:", label) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + ComputeCommandEncoder +Class Methods: +Methods: + dispatchThreadgroups + dispatchThreadgroupsWithIndirectBuffer + dispatchThreads + dispatchType + executeCommandsInBuffer + executeCommandsInBuffer + memoryBarrierWithResources + memoryBarrierWithScope + sampleCountersInBuffer + setAccelerationStructure + setBuffer + setBufferOffset + setBuffers + setBytes + setComputePipelineState + setImageblockWidth + setIntersectionFunctionTable + setIntersectionFunctionTables + setSamplerState + setSamplerState + setSamplerStates + setSamplerStates + setStageInRegion + setStageInRegionWithIndirectBuffer + setTexture + setTextures + setThreadgroupMemoryLength + setVisibleFunctionTable + setVisibleFunctionTables + updateFence + useHeap + useHeaps + useResource + useResources + waitForFence +*/ +@(objc_class="MTLComputeCommandEncoder") +ComputeCommandEncoder :: struct { using _: CommandEncoder } + +@(objc_type=ComputeCommandEncoder, objc_name="dispatchThreadgroups") +ComputeCommandEncoder_dispatchThreadgroups :: #force_inline proc(self: ^ComputeCommandEncoder, threadgroupsPerGrid: Size, threadsPerThreadgroup: Size) { + msgSend(nil, self, "dispatchThreadgroups:threadsPerThreadgroup:", threadgroupsPerGrid, threadsPerThreadgroup) +} +@(objc_type=ComputeCommandEncoder, objc_name="dispatchThreadgroupsWithIndirectBuffer") +ComputeCommandEncoder_dispatchThreadgroupsWithIndirectBuffer :: #force_inline proc(self: ^ComputeCommandEncoder, indirectBuffer: ^Buffer, indirectBufferOffset: NS.UInteger, threadsPerThreadgroup: Size) { + msgSend(nil, self, "dispatchThreadgroupsWithIndirectBuffer:indirectBufferOffset:threadsPerThreadgroup:", indirectBuffer, indirectBufferOffset, threadsPerThreadgroup) +} +@(objc_type=ComputeCommandEncoder, objc_name="dispatchThreads") +ComputeCommandEncoder_dispatchThreads :: #force_inline proc(self: ^ComputeCommandEncoder, threadsPerGrid: Size, threadsPerThreadgroup: Size) { + msgSend(nil, self, "dispatchThreads:threadsPerThreadgroup:", threadsPerGrid, threadsPerThreadgroup) +} +@(objc_type=ComputeCommandEncoder, objc_name="dispatchType") +ComputeCommandEncoder_dispatchType :: #force_inline proc(self: ^ComputeCommandEncoder) -> DispatchType { + return msgSend(DispatchType, self, "dispatchType") +} +@(objc_type=ComputeCommandEncoder, objc_name="executeCommandsInBuffer") +ComputeCommandEncoder_executeCommandsInBuffer :: #force_inline proc(self: ^ComputeCommandEncoder, indirectCommandbuffer: ^Buffer, indirectRangeBuffer: ^Buffer, indirectBufferOffset: NS.UInteger) { + msgSend(nil, self, "executeCommandsInBuffer:indirectBuffer:indirectBufferOffset:", indirectCommandbuffer, indirectRangeBuffer, indirectBufferOffset) +} +@(objc_type=ComputeCommandEncoder, objc_name="executeCommandsInBufferWithRange") +ComputeCommandEncoder_executeCommandsInBufferWithRange :: #force_inline proc(self: ^ComputeCommandEncoder, indirectCommandBuffer: ^Buffer, executionRange: NS.Range) { + msgSend(nil, self, "executeCommandsInBuffer:withRange:", indirectCommandBuffer, executionRange) +} +@(objc_type=ComputeCommandEncoder, objc_name="memoryBarrierWithResources") +ComputeCommandEncoder_memoryBarrierWithResources :: #force_inline proc(self: ^ComputeCommandEncoder, resources: []^Resource) { + msgSend(nil, self, "memoryBarrierWithResources:count:", raw_data(resources), NS.UInteger(len(resources))) +} +@(objc_type=ComputeCommandEncoder, objc_name="memoryBarrierWithScope") +ComputeCommandEncoder_memoryBarrierWithScope :: #force_inline proc(self: ^ComputeCommandEncoder, scope: BarrierScope) { + msgSend(nil, self, "memoryBarrierWithScope:", scope) +} +@(objc_type=ComputeCommandEncoder, objc_name="sampleCountersInBuffer") +ComputeCommandEncoder_sampleCountersInBuffer :: #force_inline proc(self: ^ComputeCommandEncoder, sampleBuffer: ^Buffer, sampleIndex: NS.UInteger, barrier: BOOL) { + msgSend(nil, self, "sampleCountersInBuffer:atSampleIndex:withBarrier:", sampleBuffer, sampleIndex, barrier) +} +@(objc_type=ComputeCommandEncoder, objc_name="setAccelerationStructure") +ComputeCommandEncoder_setAccelerationStructure :: #force_inline proc(self: ^ComputeCommandEncoder, accelerationStructure: ^AccelerationStructure, bufferIndex: NS.UInteger) { + msgSend(nil, self, "setAccelerationStructure:atBufferIndex:", accelerationStructure, bufferIndex) +} +@(objc_type=ComputeCommandEncoder, objc_name="setBuffer") +ComputeCommandEncoder_setBuffer :: #force_inline proc(self: ^ComputeCommandEncoder, buffer: ^Buffer, offset: NS.UInteger, index: NS.UInteger) { + msgSend(nil, self, "setBuffer:offset:atIndex:", buffer, offset, index) +} +@(objc_type=ComputeCommandEncoder, objc_name="setBufferOffset") +ComputeCommandEncoder_setBufferOffset :: #force_inline proc(self: ^ComputeCommandEncoder, offset: NS.UInteger, index: NS.UInteger) { + msgSend(nil, self, "setBufferOffset:atIndex:", offset, index) +} +@(objc_type=ComputeCommandEncoder, objc_name="setBuffers") +ComputeCommandEncoder_setBuffers :: #force_inline proc(self: ^ComputeCommandEncoder, buffers: []^Buffer, offsets: []NS.UInteger, range: NS.Range) { + assert(len(buffers) == len(offsets)) + assert(range.length <= NS.UInteger(len(buffers))) + msgSend(nil, self, "setBuffers:offsets:withRange:", raw_data(buffers), raw_data(offsets), range) +} +@(objc_type=ComputeCommandEncoder, objc_name="setBytes") +ComputeCommandEncoder_setBytes :: #force_inline proc(self: ^ComputeCommandEncoder, bytes: []byte, index: NS.UInteger) { + msgSend(nil, self, "setBytes:length:atIndex:", raw_data(bytes), NS.UInteger(len(bytes)), index) +} +@(objc_type=ComputeCommandEncoder, objc_name="setComputePipelineState") +ComputeCommandEncoder_setComputePipelineState :: #force_inline proc(self: ^ComputeCommandEncoder, pipelineState: ^ComputePipelineState) { + msgSend(nil, self, "setComputePipelineState:", pipelineState) +} +@(objc_type=ComputeCommandEncoder, objc_name="setImageblockWidth") +ComputeCommandEncoder_setImageblockWidth :: #force_inline proc(self: ^ComputeCommandEncoder, width: NS.UInteger, height: NS.UInteger) { + msgSend(nil, self, "setImageblockWidth:height:", width, height) +} +@(objc_type=ComputeCommandEncoder, objc_name="setIntersectionFunctionTable") +ComputeCommandEncoder_setIntersectionFunctionTable :: #force_inline proc(self: ^ComputeCommandEncoder, intersectionFunctionTable: ^IntersectionFunctionTable, bufferIndex: NS.UInteger) { + msgSend(nil, self, "setIntersectionFunctionTable:atBufferIndex:", intersectionFunctionTable, bufferIndex) +} +@(objc_type=ComputeCommandEncoder, objc_name="setIntersectionFunctionTables") +ComputeCommandEncoder_setIntersectionFunctionTables :: #force_inline proc(self: ^ComputeCommandEncoder, intersectionFunctionTables: []^IntersectionFunctionTable, range: NS.Range) { + assert(range.length <= NS.UInteger(len(intersectionFunctionTables))) + msgSend(nil, self, "setIntersectionFunctionTables:withBufferRange:", raw_data(intersectionFunctionTables), range) +} +@(objc_type=ComputeCommandEncoder, objc_name="setSamplerState") +ComputeCommandEncoder_setSamplerState :: #force_inline proc(self: ^ComputeCommandEncoder, sampler: ^SamplerState, index: NS.UInteger) { + msgSend(nil, self, "setSamplerState:atIndex:", sampler, index) +} +@(objc_type=ComputeCommandEncoder, objc_name="setSamplerStateWithLod") +ComputeCommandEncoder_setSamplerState_lodMinClamp_lodMaxClamp :: #force_inline proc(self: ^ComputeCommandEncoder, sampler: ^SamplerState, lodMinClamp: f32, lodMaxClamp: f32, index: NS.UInteger) { + msgSend(nil, self, "setSamplerState:lodMinClamp:lodMaxClamp:atIndex:", sampler, lodMinClamp, lodMaxClamp, index) +} +@(objc_type=ComputeCommandEncoder, objc_name="setSamplerStatesWithLod") +ComputeCommandEncoder_setSamplerStatesWithLod :: #force_inline proc(self: ^ComputeCommandEncoder, samplers: []^SamplerState, lodMinClamps, lodMaxClamps: []f32, range: NS.Range) { + msgSend(nil, self, "setSamplerStates:lodMinClamps:lodMaxClamps:withRange:", raw_data(samplers), raw_data(lodMinClamps), raw_data(lodMaxClamps), range) +} +@(objc_type=ComputeCommandEncoder, objc_name="setSamplerStatesWithRange") +ComputeCommandEncoder_setSamplerStatesWithRange :: #force_inline proc(self: ^ComputeCommandEncoder, samplers: []^SamplerState, range: NS.Range) { + msgSend(nil, self, "setSamplerStates:withRange:", raw_data(samplers), range) +} +@(objc_type=ComputeCommandEncoder, objc_name="setStageInRegion") +ComputeCommandEncoder_setStageInRegion :: #force_inline proc(self: ^ComputeCommandEncoder, region: Region) { + msgSend(nil, self, "setStageInRegion:", region) +} +@(objc_type=ComputeCommandEncoder, objc_name="setStageInRegionWithIndirectBuffer") +ComputeCommandEncoder_setStageInRegionWithIndirectBuffer :: #force_inline proc(self: ^ComputeCommandEncoder, indirectBuffer: ^Buffer, indirectBufferOffset: NS.UInteger) { + msgSend(nil, self, "setStageInRegionWithIndirectBuffer:indirectBufferOffset:", indirectBuffer, indirectBufferOffset) +} +@(objc_type=ComputeCommandEncoder, objc_name="setTexture") +ComputeCommandEncoder_setTexture :: #force_inline proc(self: ^ComputeCommandEncoder, texture: ^Texture, index: NS.UInteger) { + msgSend(nil, self, "setTexture:atIndex:", texture, index) +} +@(objc_type=ComputeCommandEncoder, objc_name="setTextures") +ComputeCommandEncoder_setTextures :: #force_inline proc(self: ^ComputeCommandEncoder, textures: []^Texture, range: NS.Range) { + msgSend(nil, self, "setTextures:withRange:", raw_data(textures), range) +} +@(objc_type=ComputeCommandEncoder, objc_name="setThreadgroupMemoryLength") +ComputeCommandEncoder_setThreadgroupMemoryLength :: #force_inline proc(self: ^ComputeCommandEncoder, length: NS.UInteger, index: NS.UInteger) { + msgSend(nil, self, "setThreadgroupMemoryLength:atIndex:", length, index) +} +@(objc_type=ComputeCommandEncoder, objc_name="setVisibleFunctionTable") +ComputeCommandEncoder_setVisibleFunctionTable :: #force_inline proc(self: ^ComputeCommandEncoder, visibleFunctionTable: ^VisibleFunctionTable, bufferIndex: NS.UInteger) { + msgSend(nil, self, "setVisibleFunctionTable:atBufferIndex:", visibleFunctionTable, bufferIndex) +} +@(objc_type=ComputeCommandEncoder, objc_name="setVisibleFunctionTables") +ComputeCommandEncoder_setVisibleFunctionTables :: #force_inline proc(self: ^ComputeCommandEncoder, visibleFunctionTables: []^VisibleFunctionTable, range: NS.Range) { + msgSend(nil, self, "setVisibleFunctionTables:withBufferRange:", raw_data(visibleFunctionTables), range) +} +@(objc_type=ComputeCommandEncoder, objc_name="updateFence") +ComputeCommandEncoder_updateFence :: #force_inline proc(self: ^ComputeCommandEncoder, fence: ^Fence) { + msgSend(nil, self, "updateFence:", fence) +} +@(objc_type=ComputeCommandEncoder, objc_name="useHeap") +ComputeCommandEncoder_useHeap :: #force_inline proc(self: ^ComputeCommandEncoder, heap: ^Heap) { + msgSend(nil, self, "useHeap:", heap) +} +@(objc_type=ComputeCommandEncoder, objc_name="useHeaps") +ComputeCommandEncoder_useHeaps :: #force_inline proc(self: ^ComputeCommandEncoder, heaps: []^Heap) { + msgSend(nil, self, "useHeaps:count:", raw_data(heaps), NS.UInteger(len(heaps))) +} +@(objc_type=ComputeCommandEncoder, objc_name="useResource") +ComputeCommandEncoder_useResource :: #force_inline proc(self: ^ComputeCommandEncoder, resource: ^Resource, usage: ResourceUsage) { + msgSend(nil, self, "useResource:usage:", resource, usage) +} +@(objc_type=ComputeCommandEncoder, objc_name="useResources") +ComputeCommandEncoder_useResources :: #force_inline proc(self: ^ComputeCommandEncoder, resources: []^Resource, usage: ResourceUsage) { + msgSend(nil, self, "useResources:count:usage:", raw_data(resources), NS.UInteger(len(resources)), usage) +} +@(objc_type=ComputeCommandEncoder, objc_name="waitForFence") +ComputeCommandEncoder_waitForFence :: #force_inline proc(self: ^ComputeCommandEncoder, fence: ^Fence) { + msgSend(nil, self, "waitForFence:", fence) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + ComputePipelineState +Class Methods: +Methods: + device + functionHandleWithFunction + imageblockMemoryLengthForDimensions + label + maxTotalThreadsPerThreadgroup + newComputePipelineStateWithAdditionalBinaryFunctions + newIntersectionFunctionTableWithDescriptor + newVisibleFunctionTableWithDescriptor + staticThreadgroupMemoryLength + supportIndirectCommandBuffers + threadExecutionWidth +*/ +@(objc_class="MTLComputePipelineState") +ComputePipelineState :: struct { using _: NS.Object } + +@(objc_type=ComputePipelineState, objc_name="device") +ComputePipelineState_device :: #force_inline proc(self: ^ComputePipelineState) -> ^Device { + return msgSend(^Device, self, "device") +} +@(objc_type=ComputePipelineState, objc_name="functionHandleWithFunction") +ComputePipelineState_functionHandleWithFunction :: #force_inline proc(self: ^ComputePipelineState, function: ^Function) -> ^FunctionHandle { + return msgSend(^FunctionHandle, self, "functionHandleWithFunction:", function) +} +@(objc_type=ComputePipelineState, objc_name="imageblockMemoryLengthForDimensions") +ComputePipelineState_imageblockMemoryLengthForDimensions :: #force_inline proc(self: ^ComputePipelineState, imageblockDimensions: Size) -> ^ComputePipelineState { + return msgSend(^ComputePipelineState, self, "imageblockMemoryLengthForDimensions:", imageblockDimensions) +} +@(objc_type=ComputePipelineState, objc_name="label") +ComputePipelineState_label :: #force_inline proc(self: ^ComputePipelineState) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=ComputePipelineState, objc_name="maxTotalThreadsPerThreadgroup") +ComputePipelineState_maxTotalThreadsPerThreadgroup :: #force_inline proc(self: ^ComputePipelineState) -> NS.UInteger { + return msgSend(NS.UInteger, self, "maxTotalThreadsPerThreadgroup") +} +@(objc_type=ComputePipelineState, objc_name="newComputePipelineState") +ComputePipelineState_newComputePipelineState :: #force_inline proc(self: ^ComputePipelineState, functions: ^NS.Array) -> (state: ^ComputePipelineState, error: ^NS.Error) { + state = msgSend(^ComputePipelineState, self, "newComputePipelineStateWithAdditionalBinaryFunctions:error:", functions, &error) + return +} +@(objc_type=ComputePipelineState, objc_name="newIntersectionFunctionTable") +ComputePipelineState_newIntersectionFunctionTable :: #force_inline proc(self: ^ComputePipelineState, descriptor: ^IntersectionFunctionTableDescriptor) -> ^IntersectionFunctionTable { + return msgSend(^IntersectionFunctionTable, self, "newIntersectionFunctionTableWithDescriptor:", descriptor) +} +@(objc_type=ComputePipelineState, objc_name="newVisibleFunctionTable") +ComputePipelineState_newVisibleFunctionTable :: #force_inline proc(self: ^ComputePipelineState, descriptor: ^VisibleFunctionTableDescriptor) -> ^VisibleFunctionTable { + return msgSend(^VisibleFunctionTable, self, "newVisibleFunctionTableWithDescriptor:", descriptor) +} +@(objc_type=ComputePipelineState, objc_name="staticThreadgroupMemoryLength") +ComputePipelineState_staticThreadgroupMemoryLength :: #force_inline proc(self: ^ComputePipelineState) -> NS.UInteger { + return msgSend(NS.UInteger, self, "staticThreadgroupMemoryLength") +} +@(objc_type=ComputePipelineState, objc_name="supportIndirectCommandBuffers") +ComputePipelineState_supportIndirectCommandBuffers :: #force_inline proc(self: ^ComputePipelineState) -> BOOL { + return msgSend(BOOL, self, "supportIndirectCommandBuffers") +} +@(objc_type=ComputePipelineState, objc_name="threadExecutionWidth") +ComputePipelineState_threadExecutionWidth :: #force_inline proc(self: ^ComputePipelineState) -> NS.UInteger { + return msgSend(NS.UInteger, self, "threadExecutionWidth") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + Counter +Class Methods: +Methods: + name +*/ +@(objc_class="MTLCounter") +Counter :: struct { using _: NS.Object } + +@(objc_type=Counter, objc_name="name") +Counter_name :: #force_inline proc(self: ^Counter) -> ^NS.String { + return msgSend(^NS.String, self, "name") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + CounterSampleBuffer +Class Methods: +Methods: + device + label + resolveCounterRange + sampleCount +*/ +@(objc_class="MTLCounterSampleBuffer") +CounterSampleBuffer :: struct { using _: NS.Object } + +@(objc_type=CounterSampleBuffer, objc_name="device") +CounterSampleBuffer_device :: #force_inline proc(self: ^CounterSampleBuffer) -> ^Device { + return msgSend(^Device, self, "device") +} +@(objc_type=CounterSampleBuffer, objc_name="label") +CounterSampleBuffer_label :: #force_inline proc(self: ^CounterSampleBuffer) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=CounterSampleBuffer, objc_name="resolveCounterRange") +CounterSampleBuffer_resolveCounterRange :: #force_inline proc(self: ^CounterSampleBuffer, range: NS.Range) -> ^NS.Data { + return msgSend(^NS.Data, self, "resolveCounterRange:", range) +} +@(objc_type=CounterSampleBuffer, objc_name="sampleCount") +CounterSampleBuffer_sampleCount :: #force_inline proc(self: ^CounterSampleBuffer) -> NS.UInteger { + return msgSend(NS.UInteger, self, "sampleCount") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + CounterSet +Class Methods: +Methods: + counters + name +*/ +@(objc_class="MTLCounterSet") +CounterSet :: struct { using _: NS.Object } + +@(objc_type=CounterSet, objc_name="counters") +CounterSet_counters :: #force_inline proc(self: ^CounterSet) -> ^NS.Array { + return msgSend(^NS.Array, self, "counters") +} +@(objc_type=CounterSet, objc_name="name") +CounterSet_name :: #force_inline proc(self: ^CounterSet) -> ^NS.String { + return msgSend(^NS.String, self, "name") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + DepthStencilState +Class Methods: +Methods: + device + label +*/ +@(objc_class="MTLDepthStencilState") +DepthStencilState :: struct { using _: NS.Object } + +@(objc_type=DepthStencilState, objc_name="device") +DepthStencilState_device :: #force_inline proc(self: ^DepthStencilState) -> ^Device { + return msgSend(^Device, self, "device") +} +@(objc_type=DepthStencilState, objc_name="label") +DepthStencilState_label :: #force_inline proc(self: ^DepthStencilState) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + Device +Class Methods: +Methods: + accelerationStructureSizesWithDescriptor + areBarycentricCoordsSupported + areProgrammableSamplePositionsSupported + areRasterOrderGroupsSupported + argumentBuffersSupport + convertSparsePixelRegions + convertSparseTileRegions + counterSets + currentAllocatedSize + getDefaultSamplePositions + hasUnifiedMemory + heapBufferSizeAndAlignWithLength + heapTextureSizeAndAlignWithDescriptor + isDepth24Stencil8PixelFormatSupported + isHeadless + isLowPower + isRemovable + location + locationNumber + maxArgumentBufferSamplerCount + maxBufferLength + maxThreadgroupMemoryLength + maxThreadsPerThreadgroup + maxTransferRate + minimumLinearTextureAlignmentForPixelFormat + minimumTextureBufferAlignmentForPixelFormat + name + newAccelerationStructureWithDescriptor + newAccelerationStructureWithSize + newArgumentEncoderWithArguments + newBinaryArchiveWithDescriptor + newBufferWithBytes + newBufferWithBytesNoCopy + newBufferWithLength + newCommandQueue + newCommandQueueWithMaxCommandBufferCount + newComputePipelineStateWithDescriptor + newComputePipelineStateWithDescriptor + newComputePipelineStateWithFunction + newComputePipelineStateWithFunction + newComputePipelineStateWithFunction + newComputePipelineStateWithFunction + newCounterSampleBufferWithDescriptor + newDefaultLibrary + newDefaultLibraryWithBundle + newDepthStencilStateWithDescriptor + newDynamicLibrary + newDynamicLibraryWithURL + newEvent + newFence + newHeapWithDescriptor + newIndirectCommandBufferWithDescriptor + newLibraryWithData + newLibraryWithFile + newLibraryWithSource + newLibraryWithSource + newLibraryWithURL + newRasterizationRateMapWithDescriptor + newRenderPipelineStateWithDescriptor + newRenderPipelineStateWithDescriptor + newRenderPipelineStateWithDescriptor + newRenderPipelineStateWithDescriptor + newRenderPipelineStateWithTileDescriptor + newRenderPipelineStateWithTileDescriptor + newSamplerState + newSharedEvent + newSharedEventWithHandle + newSharedTextureWithDescriptor + newSharedTextureWithHandle + newTextureWithDescriptor + newTextureWithDescriptor + peerCount + peerGroupID + peerIndex + readWriteTextureSupport + recommendedMaxWorkingSetSize + registryID + sampleTimestamps + sparseTileSizeInBytes + sparseTileSizeWithTextureType + supports32BitFloatFiltering + supports32BitMSAA + supportsBCTextureCompression + supportsCounterSampling + supportsDynamicLibraries + supportsFamily + supportsFeatureSet + supportsFunctionPointers + supportsPullModelInterpolation + supportsQueryTextureLOD + supportsRasterizationRateMapWithLayerCount + supportsRaytracing + supportsShaderBarycentricCoordinates + supportsTextureSampleCount + supportsVertexAmplificationCount +*/ +@(objc_class="MTLDevice") +Device :: struct { using _: NS.Object } + +@(objc_type=Device, objc_name="accelerationStructureSizesWithDescriptor") +Device_accelerationStructureSizesWithDescriptor :: #force_inline proc(self: ^Device, descriptor: ^AccelerationStructureDescriptor) -> AccelerationStructureSizes { + return msgSend(AccelerationStructureSizes, self, "accelerationStructureSizesWithDescriptor:", descriptor) +} +@(objc_type=Device, objc_name="areBarycentricCoordsSupported") +Device_areBarycentricCoordsSupported :: #force_inline proc(self: ^Device) -> BOOL { + return msgSend(BOOL, self, "areBarycentricCoordsSupported") +} +@(objc_type=Device, objc_name="areProgrammableSamplePositionsSupported") +Device_areProgrammableSamplePositionsSupported :: #force_inline proc(self: ^Device) -> BOOL { + return msgSend(BOOL, self, "areProgrammableSamplePositionsSupported") +} +@(objc_type=Device, objc_name="areRasterOrderGroupsSupported") +Device_areRasterOrderGroupsSupported :: #force_inline proc(self: ^Device) -> BOOL { + return msgSend(BOOL, self, "areRasterOrderGroupsSupported") +} +@(objc_type=Device, objc_name="argumentBuffersSupport") +Device_argumentBuffersSupport :: #force_inline proc(self: ^Device) -> ArgumentBuffersTier { + return msgSend(ArgumentBuffersTier, self, "argumentBuffersSupport") +} +@(objc_type=Device, objc_name="convertSparsePixelRegions") +Device_convertSparsePixelRegions :: #force_inline proc(self: ^Device, pixelRegions, tileRegions: ^Region, tileSize: Size, mode: SparseTextureRegionAlignmentMode, numRegions: NS.UInteger) { + msgSend(nil, self, "convertSparsePixelRegions:toTileRegions:withTileSize:alignmentMode:numRegions:", pixelRegions, tileRegions, tileSize, mode, numRegions) +} +@(objc_type=Device, objc_name="convertSparseTileRegions") +Device_convertSparseTileRegions :: #force_inline proc(self: ^Device, tileRegions, pixelRegions: ^Region, tileSize: Size, numRegions: NS.UInteger) { + msgSend(nil, self, "convertSparseTileRegions:toPixelRegions:withTileSize:numRegions:", tileRegions, pixelRegions, tileSize, numRegions) +} +@(objc_type=Device, objc_name="counterSets") +Device_counterSets :: #force_inline proc(self: ^Device) -> ^NS.Array { + return msgSend(^NS.Array, self, "counterSets") +} +@(objc_type=Device, objc_name="currentAllocatedSize") +Device_currentAllocatedSize :: #force_inline proc(self: ^Device) -> NS.UInteger { + return msgSend(NS.UInteger, self, "currentAllocatedSize") +} +@(objc_type=Device, objc_name="getDefaultSamplePositions") +Device_getDefaultSamplePositions :: #force_inline proc(self: ^Device, positions: []SamplePosition) { + msgSend(nil, self, "getDefaultSamplePositions:count:", raw_data(positions), NS.UInteger(len(positions))) +} +@(objc_type=Device, objc_name="hasUnifiedMemory") +Device_hasUnifiedMemory :: #force_inline proc(self: ^Device) -> BOOL { + return msgSend(BOOL, self, "hasUnifiedMemory") +} +@(objc_type=Device, objc_name="heapBufferSizeAndAlignWithLength") +Device_heapBufferSizeAndAlignWithLength :: #force_inline proc(self: ^Device, length: NS.UInteger, options: ResourceOptions) -> (size, align: NS.UInteger) { + res := msgSend(SizeAndAlign, self, "heapBufferSizeAndAlignWithLength:options:", length, options) + return res.size, res.align +} +@(objc_type=Device, objc_name="heapTextureSizeAndAlignWithDescriptor") +Device_heapTextureSizeAndAlignWithDescriptor :: #force_inline proc(self: ^Device, desc: ^TextureDescriptor) -> (size, align: NS.UInteger) { + res := msgSend(SizeAndAlign, self, "heapTextureSizeAndAlignWithDescriptor:", desc) + return res.size, res.align +} +@(objc_type=Device, objc_name="isDepth24Stencil8PixelFormatSupported") +Device_isDepth24Stencil8PixelFormatSupported :: #force_inline proc(self: ^Device) -> BOOL { + return msgSend(BOOL, self, "isDepth24Stencil8PixelFormatSupported") +} +@(objc_type=Device, objc_name="isHeadless") +Device_isHeadless :: #force_inline proc(self: ^Device) -> BOOL { + return msgSend(BOOL, self, "isHeadless") +} +@(objc_type=Device, objc_name="isLowPower") +Device_isLowPower :: #force_inline proc(self: ^Device) -> BOOL { + return msgSend(BOOL, self, "isLowPower") +} +@(objc_type=Device, objc_name="isRemovable") +Device_isRemovable :: #force_inline proc(self: ^Device) -> BOOL { + return msgSend(BOOL, self, "isRemovable") +} +@(objc_type=Device, objc_name="location") +Device_location :: #force_inline proc(self: ^Device) -> DeviceLocation { + return msgSend(DeviceLocation, self, "location") +} +@(objc_type=Device, objc_name="locationNumber") +Device_locationNumber :: #force_inline proc(self: ^Device) -> NS.UInteger { + return msgSend(NS.UInteger, self, "locationNumber") +} +@(objc_type=Device, objc_name="maxArgumentBufferSamplerCount") +Device_maxArgumentBufferSamplerCount :: #force_inline proc(self: ^Device) -> NS.UInteger { + return msgSend(NS.UInteger, self, "maxArgumentBufferSamplerCount") +} +@(objc_type=Device, objc_name="maxBufferLength") +Device_maxBufferLength :: #force_inline proc(self: ^Device) -> NS.UInteger { + return msgSend(NS.UInteger, self, "maxBufferLength") +} +@(objc_type=Device, objc_name="maxThreadgroupMemoryLength") +Device_maxThreadgroupMemoryLength :: #force_inline proc(self: ^Device) -> NS.UInteger { + return msgSend(NS.UInteger, self, "maxThreadgroupMemoryLength") +} +@(objc_type=Device, objc_name="maxThreadsPerThreadgroup") +Device_maxThreadsPerThreadgroup :: #force_inline proc(self: ^Device) -> Size { + return msgSend(Size, self, "maxThreadsPerThreadgroup") +} +@(objc_type=Device, objc_name="maxTransferRate") +Device_maxTransferRate :: #force_inline proc(self: ^Device) -> u64 { + return msgSend(u64, self, "maxTransferRate") +} +@(objc_type=Device, objc_name="minimumLinearTextureAlignmentForPixelFormat") +Device_minimumLinearTextureAlignmentForPixelFormat :: #force_inline proc(self: ^Device, format: PixelFormat) -> NS.UInteger { + return msgSend(NS.UInteger, self, "minimumLinearTextureAlignmentForPixelFormat:", format) +} +@(objc_type=Device, objc_name="minimumTextureBufferAlignmentForPixelFormat") +Device_minimumTextureBufferAlignmentForPixelFormat :: #force_inline proc(self: ^Device, format: PixelFormat) -> NS.UInteger { + return msgSend(NS.UInteger, self, "minimumTextureBufferAlignmentForPixelFormat:", format) +} +@(objc_type=Device, objc_name="name") +Device_name :: #force_inline proc(self: ^Device) -> ^NS.String { + return msgSend(^NS.String, self, "name") +} +@(objc_type=Device, objc_name="newAccelerationStructureWithDescriptor") +Device_newAccelerationStructureWithDescriptor :: #force_inline proc(self: ^Device, descriptor: ^AccelerationStructureDescriptor) -> ^AccelerationStructure { + return msgSend(^AccelerationStructure, self, "newAccelerationStructureWithDescriptor:", descriptor) +} +@(objc_type=Device, objc_name="newAccelerationStructureWithSize") +Device_newAccelerationStructureWithSize :: #force_inline proc(self: ^Device, size: NS.UInteger) -> ^AccelerationStructure { + return msgSend(^AccelerationStructure, self, "newAccelerationStructureWithSize:", size) +} +@(objc_type=Device, objc_name="newArgumentEncoderWithArguments") +Device_newArgumentEncoderWithArguments :: #force_inline proc(self: ^Device, arguments: ^NS.Array) -> ^ArgumentEncoder { + return msgSend(^ArgumentEncoder, self, "newArgumentEncoderWithArguments:", arguments) +} +@(objc_type=Device, objc_name="newBinaryArchive") +Device_newBinaryArchive :: #force_inline proc(self: ^Device, descriptor: ^BinaryArchiveDescriptor) -> (res: ^BinaryArchive, error: ^NS.Error) { + res = msgSend(^BinaryArchive, self, "newBinaryArchiveWithDescriptor:error:", descriptor, &error) + return +} +@(objc_type=Device, objc_name="newBufferWithBytes") +Device_newBufferWithBytes :: #force_inline proc(self: ^Device, bytes: []byte, options: ResourceOptions) -> ^Buffer { + return msgSend(^Buffer, self, "newBufferWithBytes:length:options:", raw_data(bytes), NS.UInteger(len(bytes)), options) +} +@(objc_type=Device, objc_name="newBufferWithBytesNoCopy") +Device_newBufferWithBytesNoCopy :: #force_inline proc(self: ^Device, bytes: []byte, options: ResourceOptions, deallocator: rawptr) -> ^Buffer { + return msgSend(^Buffer, self, "newBufferWithBytesNoCopy:length:options:deallocator:", raw_data(bytes), NS.UInteger(len(bytes)), options, deallocator) +} + +@(objc_type=Device, objc_name="newBufferWithSlice") +Device_newBufferWithSlice :: #force_inline proc(self: ^Device, slice: $S/[]$E, options: ResourceOptions) -> ^Buffer { + return Device_newBufferWithBytes(self, mem.slice_to_bytes(slice), options) +} +@(objc_type=Device, objc_name="newBufferWithSliceNoCopy") +Device_newBufferWithSliceNoCopy :: #force_inline proc(self: ^Device, slice: $S/[]$E, options: ResourceOptions, deallocator: rawptr) -> ^Buffer { + return Device_newBufferWithBytesNotCopy(self, mem.slice_to_bytes(slice), options, deallocator) +} + +@(objc_type=Device, objc_name="newBuffer") +Device_newBuffer :: #force_inline proc(self: ^Device, length: NS.UInteger, options: ResourceOptions) -> ^Buffer { + return msgSend(^Buffer, self, "newBufferWithLength:options:", length, options) +} +@(objc_type=Device, objc_name="newCommandQueue") +Device_newCommandQueue :: #force_inline proc(self: ^Device) -> ^CommandQueue { + return msgSend(^CommandQueue, self, "newCommandQueue") +} +@(objc_type=Device, objc_name="newCommandQueueWithMaxCommandBufferCount") +Device_newCommandQueueWithMaxCommandBufferCount :: #force_inline proc(self: ^Device, maxCommandBufferCount: NS.UInteger) -> ^CommandQueue { + return msgSend(^CommandQueue, self, "newCommandQueueWithMaxCommandBufferCount:", maxCommandBufferCount) +} +@(objc_type=Device, objc_name="newComputePipelineStateWithDescriptorWithCompletionHandler") +Device_newComputePipelineStateWithDescriptorWithCompletionHandler :: #force_inline proc(self: ^Device, descriptor: ^ComputePipelineDescriptor, options: PipelineOption, completionHandler: NewComputePipelineStateWithReflectionCompletionHandler) -> ^ComputePipelineState { + return msgSend(^ComputePipelineState, self, "newComputePipelineStateWithDescriptor:options:completionHandler:", descriptor, options, completionHandler) +} +@(objc_type=Device, objc_name="newComputePipelineStateWithDescriptorWithReflection") +Device_newComputePipelineStateWithDescriptorWithReflection :: #force_inline proc(self: ^Device, descriptor: ^ComputePipelineDescriptor, options: PipelineOption, reflection: ^AutoreleasedComputePipelineReflection) -> (res: ^ComputePipelineState, error: ^NS.Error) { + res = msgSend(^ComputePipelineState, self, "newComputePipelineStateWithDescriptor:options:reflection:error:", descriptor, options, reflection, &error) + return +} +@(objc_type=Device, objc_name="newComputePipelineStateWithFunctionWithCompletionHandler") +Device_newComputePipelineStateWithFunctionWithCompletionHandler :: #force_inline proc(self: ^Device, computeFunction: ^Function, completionHandler: NewComputePipelineStateCompletionHandler) -> ^ComputePipelineState { + return msgSend(^ComputePipelineState, self, "newComputePipelineStateWithFunction:completionHandler:", computeFunction, completionHandler) +} +@(objc_type=Device, objc_name="newComputePipelineStateWithFunction") +Device_newComputePipelineStateWithFunction :: #force_inline proc(self: ^Device, computeFunction: ^Function) -> (res: ^ComputePipelineState, error: ^NS.Error) { + res = msgSend(^ComputePipelineState, self, "newComputePipelineStateWithFunction:error:", computeFunction, &error) + return +} +@(objc_type=Device, objc_name="newComputePipelineStateWithFunctionWithOptionsAndCompletionHandler") +Device_newComputePipelineStateWithFunctionWithOptionsAndCompletionHandler :: #force_inline proc(self: ^Device, computeFunction: ^Function, options: PipelineOption, completionHandler: NewComputePipelineStateWithReflectionCompletionHandler) -> (res: ^ComputePipelineState) { + return msgSend(^ComputePipelineState, self, "newComputePipelineStateWithFunction:options:completionHandler:", computeFunction, options, completionHandler) +} +@(objc_type=Device, objc_name="newComputePipelineStateWithFunctionWithReflection") +Device_newComputePipelineStateWithFunctionWithReflection :: #force_inline proc(self: ^Device, computeFunction: ^Function, options: PipelineOption, reflection: ^AutoreleasedComputePipelineReflection) -> (res: ^ComputePipelineState, error: ^NS.Error) { + res = msgSend(^ComputePipelineState, self, "newComputePipelineStateWithFunction:options:reflection:error:", computeFunction, options, reflection, &error) + return +} + +@(objc_type=Device, objc_name="newComputePipelineState") +Device_newComputePipelineState :: proc{ + Device_newComputePipelineStateWithDescriptorWithCompletionHandler, + Device_newComputePipelineStateWithDescriptorWithReflection, + Device_newComputePipelineStateWithFunctionWithCompletionHandler, + Device_newComputePipelineStateWithFunction, + Device_newComputePipelineStateWithFunctionWithOptionsAndCompletionHandler, + Device_newComputePipelineStateWithFunctionWithReflection, +} + +@(objc_type=Device, objc_name="newCounterSampleBuffer") +Device_newCounterSampleBuffer :: #force_inline proc(self: ^Device, descriptor: ^CounterSampleBufferDescriptor) -> (counter: ^Counter, error: ^NS.Error) { + counter = msgSend(^Counter, self, "newCounterSampleBufferWithDescriptor:error:", descriptor, &error) + return +} +@(objc_type=Device, objc_name="newDefaultLibrary") +Device_newDefaultLibrary :: #force_inline proc(self: ^Device) -> ^Library { + return msgSend(^Library, self, "newDefaultLibrary") +} +@(objc_type=Device, objc_name="newDefaultLibraryWithBundle") +Device_newDefaultLibraryWithBundle :: #force_inline proc(self: ^Device, bundle: ^NS.Bundle) -> (library: ^Library, error: ^NS.Error) { + library = msgSend(^Library, self, "newDefaultLibraryWithBundle:error:", bundle, &error) + return +} +@(objc_type=Device, objc_name="newDepthStencilState") +Device_newDepthStencilState :: #force_inline proc(self: ^Device, descriptor: ^DepthStencilDescriptor) -> ^DepthStencilState { + return msgSend(^DepthStencilState, self, "newDepthStencilStateWithDescriptor:", descriptor) +} +@(objc_type=Device, objc_name="newDynamicLibrary") +Device_newDynamicLibrary :: #force_inline proc(self: ^Device, library: ^Library) -> (dyn_library: ^DynamicLibrary, error: ^NS.Error) { + dyn_library = msgSend(^DynamicLibrary, self, "newDynamicLibrary:error:", library, &error) + return +} +@(objc_type=Device, objc_name="newDynamicLibraryWithURL") +Device_newDynamicLibraryWithURL :: #force_inline proc(self: ^Device, url: ^NS.URL) -> (dyn_library: ^DynamicLibrary, error: ^NS.Error) { + dyn_library = msgSend(^DynamicLibrary, self, "newDynamicLibraryWithURL:error:", url, &error) + return +} +@(objc_type=Device, objc_name="newEvent") +Device_newEvent :: #force_inline proc(self: ^Device) -> ^Event { + return msgSend(^Event, self, "newEvent") +} +@(objc_type=Device, objc_name="newFence") +Device_newFence :: #force_inline proc(self: ^Device) -> ^Fence { + return msgSend(^Fence, self, "newFence") +} +@(objc_type=Device, objc_name="newHeap") +Device_newHeap :: #force_inline proc(self: ^Device, descriptor: ^HeapDescriptor) -> ^Heap { + return msgSend(^Heap, self, "newHeapWithDescriptor:", descriptor) +} +@(objc_type=Device, objc_name="newIndirectCommandBuffer") +Device_newIndirectCommandBuffer :: #force_inline proc(self: ^Device, descriptor: ^IndirectCommandBufferDescriptor, maxCount: NS.UInteger, options: ResourceOptions) -> ^IndirectCommandBuffer { + return msgSend(^IndirectCommandBuffer, self, "newIndirectCommandBufferWithDescriptor:maxCommandCount:options:", descriptor, maxCount, options) +} + +@(objc_type=Device, objc_name="newLibraryWithData") +Device_newLibraryWithData :: #force_inline proc(self: ^Device, data: dispatch_data_t) -> (library: ^Library, error: ^NS.Error) { + library = msgSend(^Library, self, "newLibraryWithData:error:", data, &error) + return +} +@(objc_type=Device, objc_name="newLibraryWithFile") +Device_newLibraryWithFile :: #force_inline proc(self: ^Device, filepath: ^NS.String) -> (library: ^Library, error: ^NS.Error) { + library = msgSend(^Library, self, "newLibraryWithFile:error:", filepath, &error) + return +} +@(objc_type=Device, objc_name="newLibraryWithSourceWithCompletionHandler") +Device_newLibraryWithSourceWithCompletionHandler :: #force_inline proc(self: ^Device, source: ^NS.String, options: ^CompileOptions, completionHandler: NewLibraryCompletionHandler) -> ^Library { + return msgSend(^Library, self, "newLibraryWithSource:options:completionHandler:", source, options, completionHandler) +} +@(objc_type=Device, objc_name="newLibraryWithSource") +Device_newLibraryWithSource :: #force_inline proc(self: ^Device, source: ^NS.String, options: ^CompileOptions) -> (library: ^Library, error: ^NS.Error) { + library = msgSend(^Library, self, "newLibraryWithSource:options:error:", source, options, &error) + return +} +@(objc_type=Device, objc_name="newLibraryWithURL") +Device_newLibraryWithURL :: #force_inline proc(self: ^Device, url: ^NS.URL) -> (library: ^Library, error: ^NS.Error) { + library = msgSend(^Library, self, "newLibraryWithURL:error:", url, &error) + return +} +@(objc_type=Device, objc_name="newLibrary") +Device_newLibrary :: proc{ + Device_newLibraryWithData, + Device_newLibraryWithFile, + Device_newLibraryWithSourceWithCompletionHandler, + Device_newLibraryWithSource, + Device_newLibraryWithURL, +} + + +@(objc_type=Device, objc_name="newRasterizationRateMap") +Device_newRasterizationRateMap :: #force_inline proc(self: ^Device, descriptor: ^RasterizationRateMapDescriptor) -> ^RasterizationRateMap { + return msgSend(^RasterizationRateMap, self, "newRasterizationRateMapWithDescriptor:", descriptor) +} + +@(objc_type=Device, objc_name="newRenderPipelineStateWithDescriptorWithCompletionHandler") +Device_newRenderPipelineStateWithDescriptorWithCompletionHandler :: #force_inline proc(self: ^Device, descriptor: ^RenderPipelineDescriptor, completionHandler: NewRenderPipelineStateCompletionHandler) -> ^RenderPipelineState { + return msgSend(^RenderPipelineState, self, "newRenderPipelineStateWithDescriptor:completionHandler:", descriptor, completionHandler) +} +@(objc_type=Device, objc_name="newRenderPipelineStateWithDescriptor") +Device_newRenderPipelineStateWithDescriptor :: #force_inline proc(self: ^Device, descriptor: ^RenderPipelineDescriptor) -> (pipeline: ^RenderPipelineState, error: ^NS.Error) { + pipeline = msgSend(^RenderPipelineState, self, "newRenderPipelineStateWithDescriptor:error:", descriptor, &error) + return +} +@(objc_type=Device, objc_name="newRenderPipelineStateWithDescriptorWithOptionsAndCompletionHandler") +Device_newRenderPipelineStateWithDescriptorWithOptionsAndCompletionHandler :: #force_inline proc(self: ^Device, descriptor: ^RenderPipelineDescriptor, options: PipelineOption, completionHandler: NewRenderPipelineStateWithReflectionCompletionHandler) -> ^RenderPipelineState { + return msgSend(^RenderPipelineState, self, "newRenderPipelineStateWithDescriptor:options:completionHandler:", descriptor, options, completionHandler) +} +@(objc_type=Device, objc_name="newRenderPipelineStateWithDescriptorWithReflection") +Device_newRenderPipelineStateWithDescriptorWithReflection :: #force_inline proc(self: ^Device, descriptor: ^RenderPipelineDescriptor, options: PipelineOption, reflection: ^AutoreleasedRenderPipelineReflection) -> (pipeline: ^RenderPipelineState, error: ^NS.Error) { + pipeline = msgSend(^RenderPipelineState, self, "newRenderPipelineStateWithDescriptor:options:reflection:error:", descriptor, options, reflection, &error) + return +} +@(objc_type=Device, objc_name="newRenderPipelineStateWithTileDescriptorWithCompletionHandler") +Device_newRenderPipelineStateWithTileDescriptorWithCompletionHandler :: #force_inline proc(self: ^Device, descriptor: ^TileRenderPipelineDescriptor, options: PipelineOption, completionHandler: NewRenderPipelineStateWithReflectionCompletionHandler) -> ^RenderPipelineState { + return msgSend(^RenderPipelineState, self, "newRenderPipelineStateWithTileDescriptor:options:completionHandler:", descriptor, options, completionHandler) +} +@(objc_type=Device, objc_name="newRenderPipelineStateWithTileDescriptorWithReflection") +Device_newRenderPipelineStateWithTileDescriptorWithReflection :: #force_inline proc(self: ^Device, descriptor: ^TileRenderPipelineDescriptor, options: PipelineOption, reflection: ^AutoreleasedRenderPipelineReflection) -> (pipeline: ^RenderPipelineState, error: ^NS.Error) { + pipeline = msgSend(^RenderPipelineState, self, "newRenderPipelineStateWithTileDescriptor:options:reflection:error:", descriptor, options, reflection, &error) + return +} +@(objc_type=Device, objc_name="newRenderPipelineState") +Device_newRenderPipelineState :: proc{ + Device_newRenderPipelineStateWithDescriptorWithCompletionHandler, + Device_newRenderPipelineStateWithDescriptor, + Device_newRenderPipelineStateWithDescriptorWithOptionsAndCompletionHandler, + Device_newRenderPipelineStateWithDescriptorWithReflection, + Device_newRenderPipelineStateWithTileDescriptorWithCompletionHandler, + Device_newRenderPipelineStateWithTileDescriptorWithReflection, +} + + +@(objc_type=Device, objc_name="newSamplerState") +Device_newSamplerState :: #force_inline proc(self: ^Device, descriptor: ^SamplerDescriptor) -> ^SamplerState { + return msgSend(^SamplerState, self, "newSamplerStateWithDescriptor:", descriptor) +} +@(objc_type=Device, objc_name="newSharedEvent") +Device_newSharedEvent :: #force_inline proc(self: ^Device) -> ^SharedEvent { + return msgSend(^SharedEvent, self, "newSharedEvent") +} +@(objc_type=Device, objc_name="newSharedEventWithHandle") +Device_newSharedEventWithHandle :: #force_inline proc(self: ^Device, sharedEventHandle: ^SharedEventHandle) -> ^SharedEvent { + return msgSend(^SharedEvent, self, "newSharedEventWithHandle:", sharedEventHandle) +} +@(objc_type=Device, objc_name="newSharedTextureWithDescriptor") +Device_newSharedTextureWithDescriptor :: #force_inline proc(self: ^Device, descriptor: ^TextureDescriptor) -> ^SharedEvent { + return msgSend(^SharedEvent, self, "newSharedTextureWithDescriptor:", descriptor) +} +@(objc_type=Device, objc_name="newSharedTextureWithHandle") +Device_newSharedTextureWithHandle :: #force_inline proc(self: ^Device, sharedHandle: ^SharedTextureHandle) -> ^SharedEvent { + return msgSend(^SharedEvent, self, "newSharedTextureWithHandle:", sharedHandle) +} +@(objc_type=Device, objc_name="newSharedTexture") +Device_newSharedTexture :: proc{ + Device_newSharedTextureWithDescriptor, + Device_newSharedTextureWithHandle, +} + +@(objc_type=Device, objc_name="newTextureWithDescriptor") +Device_newTextureWithDescriptor :: #force_inline proc(self: ^Device, desc: ^TextureDescriptor) -> ^Texture { + return msgSend(^Texture, self, "newTextureWithDescriptor:", desc) +} +@(objc_type=Device, objc_name="newTextureWithIOSurface") +Device_newTextureWithIOSurface :: #force_inline proc(self: ^Device, descriptor: ^TextureDescriptor, iosurface: IOSurfaceRef, plane: NS.UInteger) -> ^Texture { + return msgSend(^Texture, self, "newTextureWithDescriptor:iosurface:plane:", descriptor, iosurface, plane) +} +@(objc_type=Device, objc_name="newTexture") +Device_newTexture :: proc{ + Device_newTextureWithDescriptor, + Device_newTextureWithIOSurface, +} + +@(objc_type=Device, objc_name="peerCount") +Device_peerCount :: #force_inline proc(self: ^Device) -> u32 { + return msgSend(u32, self, "peerCount") +} +@(objc_type=Device, objc_name="peerGroupID") +Device_peerGroupID :: #force_inline proc(self: ^Device) -> u64 { + return msgSend(u64, self, "peerGroupID") +} +@(objc_type=Device, objc_name="peerIndex") +Device_peerIndex :: #force_inline proc(self: ^Device) -> u32 { + return msgSend(u32, self, "peerIndex") +} +@(objc_type=Device, objc_name="readWriteTextureSupport") +Device_readWriteTextureSupport :: #force_inline proc(self: ^Device) -> ReadWriteTextureTier { + return msgSend(ReadWriteTextureTier, self, "readWriteTextureSupport") +} +@(objc_type=Device, objc_name="recommendedMaxWorkingSetSize") +Device_recommendedMaxWorkingSetSize :: #force_inline proc(self: ^Device) -> u64 { + return msgSend(u64, self, "recommendedMaxWorkingSetSize") +} +@(objc_type=Device, objc_name="registryID") +Device_registryID :: #force_inline proc(self: ^Device) -> u64 { + return msgSend(u64, self, "registryID") +} +@(objc_type=Device, objc_name="sampleTimestamps") +Device_sampleTimestamps :: #force_inline proc(self: ^Device, cpuTimestamp: ^Timestamp, gpuTimestamp: ^Timestamp) { + msgSend(nil, self, "sampleTimestamps:gpuTimestamp:", cpuTimestamp, gpuTimestamp) +} +@(objc_type=Device, objc_name="sparseTileSizeInBytes") +Device_sparseTileSizeInBytes :: #force_inline proc(self: ^Device) -> NS.UInteger { + return msgSend(NS.UInteger, self, "sparseTileSizeInBytes") +} +@(objc_type=Device, objc_name="sparseTileSizeWithTextureType") +Device_sparseTileSizeWithTextureType :: #force_inline proc(self: ^Device, textureType: TextureType, pixelFormat: PixelFormat, sampleCount: NS.UInteger) -> Size { + return msgSend(Size, self, "sparseTileSizeWithTextureType:pixelFormat:sampleCount:", textureType, pixelFormat, sampleCount) +} +@(objc_type=Device, objc_name="supports32BitFloatFiltering") +Device_supports32BitFloatFiltering :: #force_inline proc(self: ^Device) -> BOOL { + return msgSend(BOOL, self, "supports32BitFloatFiltering") +} +@(objc_type=Device, objc_name="supports32BitMSAA") +Device_supports32BitMSAA :: #force_inline proc(self: ^Device) -> BOOL { + return msgSend(BOOL, self, "supports32BitMSAA") +} +@(objc_type=Device, objc_name="supportsBCTextureCompression") +Device_supportsBCTextureCompression :: #force_inline proc(self: ^Device) -> BOOL { + return msgSend(BOOL, self, "supportsBCTextureCompression") +} +@(objc_type=Device, objc_name="supportsCounterSampling") +Device_supportsCounterSampling :: #force_inline proc(self: ^Device, samplingPoint: CounterSamplingPoint) -> BOOL { + return msgSend(BOOL, self, "supportsCounterSampling:", samplingPoint) +} +@(objc_type=Device, objc_name="supportsDynamicLibraries") +Device_supportsDynamicLibraries :: #force_inline proc(self: ^Device) -> BOOL { + return msgSend(BOOL, self, "supportsDynamicLibraries") +} +@(objc_type=Device, objc_name="supportsFamily") +Device_supportsFamily :: #force_inline proc(self: ^Device, gpuFamily: GPUFamily) -> BOOL { + return msgSend(BOOL, self, "supportsFamily:", gpuFamily) +} +@(objc_type=Device, objc_name="supportsFeatureSet") +Device_supportsFeatureSet :: #force_inline proc(self: ^Device, featureSet: FeatureSet) -> BOOL { + return msgSend(BOOL, self, "supportsFeatureSet:", featureSet) +} +@(objc_type=Device, objc_name="supportsFunctionPointers") +Device_supportsFunctionPointers :: #force_inline proc(self: ^Device) -> BOOL { + return msgSend(BOOL, self, "supportsFunctionPointers") +} +@(objc_type=Device, objc_name="supportsPullModelInterpolation") +Device_supportsPullModelInterpolation :: #force_inline proc(self: ^Device) -> BOOL { + return msgSend(BOOL, self, "supportsPullModelInterpolation") +} +@(objc_type=Device, objc_name="supportsQueryTextureLOD") +Device_supportsQueryTextureLOD :: #force_inline proc(self: ^Device) -> BOOL { + return msgSend(BOOL, self, "supportsQueryTextureLOD") +} +@(objc_type=Device, objc_name="supportsRasterizationRateMapWithLayerCount") +Device_supportsRasterizationRateMapWithLayerCount :: #force_inline proc(self: ^Device, layerCount: NS.UInteger) -> BOOL { + return msgSend(BOOL, self, "supportsRasterizationRateMapWithLayerCount:", layerCount) +} +@(objc_type=Device, objc_name="supportsRaytracing") +Device_supportsRaytracing :: #force_inline proc(self: ^Device) -> BOOL { + return msgSend(BOOL, self, "supportsRaytracing") +} +@(objc_type=Device, objc_name="supportsShaderBarycentricCoordinates") +Device_supportsShaderBarycentricCoordinates :: #force_inline proc(self: ^Device) -> BOOL { + return msgSend(BOOL, self, "supportsShaderBarycentricCoordinates") +} +@(objc_type=Device, objc_name="supportsTextureSampleCount") +Device_supportsTextureSampleCount :: #force_inline proc(self: ^Device, sampleCount: NS.UInteger) -> BOOL { + return msgSend(BOOL, self, "supportsTextureSampleCount:", sampleCount) +} +@(objc_type=Device, objc_name="supportsVertexAmplificationCount") +Device_supportsVertexAmplificationCount :: #force_inline proc(self: ^Device, count: NS.UInteger) -> BOOL { + return msgSend(BOOL, self, "supportsVertexAmplificationCount:", count) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + Drawable +Class Methods: +Methods: + addPresentedHandler + drawableID + present + presentAfterMinimumDuration + presentAtTime + presentedTime +*/ +@(objc_class="MTLDrawable") +Drawable :: struct { using _: NS.Object } + +@(objc_type=Drawable, objc_name="addPresentedHandler") +Drawable_addPresentedHandler :: #force_inline proc(self: ^Drawable, block: DrawablePresentedHandler) { + msgSend(nil, self, "addPresentedHandler:", block) +} +@(objc_type=Drawable, objc_name="drawableID") +Drawable_drawableID :: #force_inline proc(self: ^Drawable) -> NS.UInteger { + return msgSend(NS.UInteger, self, "drawableID") +} +@(objc_type=Drawable, objc_name="present") +Drawable_present :: #force_inline proc(self: ^Drawable) { + msgSend(nil, self, "present") +} +@(objc_type=Drawable, objc_name="presentAfterMinimumDuration") +Drawable_presentAfterMinimumDuration :: #force_inline proc(self: ^Drawable, duration: CFTimeInterval) { + msgSend(nil, self, "presentAfterMinimumDuration:", duration) +} +@(objc_type=Drawable, objc_name="presentAtTime") +Drawable_presentAtTime :: #force_inline proc(self: ^Drawable, presentationTime: CFTimeInterval) { + msgSend(nil, self, "presentAtTime:", presentationTime) +} +@(objc_type=Drawable, objc_name="presentedTime") +Drawable_presentedTime :: #force_inline proc(self: ^Drawable) -> CFTimeInterval { + return msgSend(CFTimeInterval, self, "presentedTime") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + DynamicLibrary +Class Methods: +Methods: + device + installName + label + serializeToURL + setLabel +*/ +@(objc_class="MTLDynamicLibrary") +DynamicLibrary :: struct { using _: NS.Object } + +@(objc_type=DynamicLibrary, objc_name="device") +DynamicLibrary_device :: #force_inline proc(self: ^DynamicLibrary) -> ^Device { + return msgSend(^Device, self, "device") +} +@(objc_type=DynamicLibrary, objc_name="installName") +DynamicLibrary_installName :: #force_inline proc(self: ^DynamicLibrary) -> ^NS.String { + return msgSend(^NS.String, self, "installName") +} +@(objc_type=DynamicLibrary, objc_name="label") +DynamicLibrary_label :: #force_inline proc(self: ^DynamicLibrary) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=DynamicLibrary, objc_name="serializeToURL") +DynamicLibrary_serializeToURL :: #force_inline proc(self: ^DynamicLibrary, url: ^NS.URL) -> (ok: BOOL, error: ^NS.Error) { + ok = msgSend(BOOL, self, "serializeToURL:error:", url, &error) + return +} +@(objc_type=DynamicLibrary, objc_name="setLabel") +DynamicLibrary_setLabel :: #force_inline proc(self: ^DynamicLibrary, label: ^NS.String) { + msgSend(nil, self, "setLabel:", label) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + Event +Class Methods: +Methods: + device + label + setLabel +*/ +@(objc_class="MTLEvent") +Event :: struct { using _: NS.Object } + +@(objc_type=Event, objc_name="device") +Event_device :: #force_inline proc(self: ^Event) -> ^Device { + return msgSend(^Device, self, "device") +} +@(objc_type=Event, objc_name="label") +Event_label :: #force_inline proc(self: ^Event) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=Event, objc_name="setLabel") +Event_setLabel :: #force_inline proc(self: ^Event, label: ^NS.String) { + msgSend(nil, self, "setLabel:", label) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + Fence +Class Methods: +Methods: + device + label + setLabel +*/ +@(objc_class="MTLFence") +Fence :: struct { using _: NS.Object } + +@(objc_type=Fence, objc_name="device") +Fence_device :: #force_inline proc(self: ^Fence) -> ^Device { + return msgSend(^Device, self, "device") +} +@(objc_type=Fence, objc_name="label") +Fence_label :: #force_inline proc(self: ^Fence) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=Fence, objc_name="setLabel") +Fence_setLabel :: #force_inline proc(self: ^Fence, label: ^NS.String) { + msgSend(nil, self, "setLabel:", label) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + Function +Class Methods: +Methods: + device + functionConstantsDictionary + functionType + label + name + newArgumentEncoderWithBufferIndex + newArgumentEncoderWithBufferIndex + options + patchControlPointCount + patchType + setLabel + stageInputAttributes + vertexAttributes +*/ +@(objc_class="MTLFunction") +Function :: struct { using _: NS.Object } + +@(objc_type=Function, objc_name="device") +Function_device :: #force_inline proc(self: ^Function) -> ^Device { + return msgSend(^Device, self, "device") +} +@(objc_type=Function, objc_name="functionConstantsDictionary") +Function_functionConstantsDictionary :: #force_inline proc(self: ^Function) -> ^NS.Dictionary { + return msgSend(^NS.Dictionary, self, "functionConstantsDictionary") +} +@(objc_type=Function, objc_name="functionType") +Function_functionType :: #force_inline proc(self: ^Function) -> FunctionType { + return msgSend(FunctionType, self, "functionType") +} +@(objc_type=Function, objc_name="label") +Function_label :: #force_inline proc(self: ^Function) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=Function, objc_name="name") +Function_name :: #force_inline proc(self: ^Function) -> ^NS.String { + return msgSend(^NS.String, self, "name") +} +@(objc_type=Function, objc_name="newArgumentEncoder") +Function_newArgumentEncoder :: #force_inline proc(self: ^Function, bufferIndex: NS.UInteger) -> ^ArgumentEncoder { + return msgSend(^ArgumentEncoder, self, "newArgumentEncoderWithBufferIndex:", bufferIndex) +} +@(objc_type=Function, objc_name="newArgumentEncoderWithReflection") +Function_newArgumentEncoderWithReflection :: #force_inline proc(self: ^Function, bufferIndex: NS.UInteger, reflection: ^AutoreleasedArgument) -> ^ArgumentEncoder { + return msgSend(^ArgumentEncoder, self, "newArgumentEncoderWithBufferIndex:reflection:", bufferIndex, reflection) +} +@(objc_type=Function, objc_name="options") +Function_options :: #force_inline proc(self: ^Function) -> FunctionOptions { + return msgSend(FunctionOptions, self, "options") +} +@(objc_type=Function, objc_name="patchControlPointCount") +Function_patchControlPointCount :: #force_inline proc(self: ^Function) -> NS.UInteger { + return msgSend(NS.UInteger, self, "patchControlPointCount") +} +@(objc_type=Function, objc_name="patchType") +Function_patchType :: #force_inline proc(self: ^Function) -> PatchType { + return msgSend(PatchType, self, "patchType") +} +@(objc_type=Function, objc_name="setLabel") +Function_setLabel :: #force_inline proc(self: ^Function, label: ^NS.String) { + msgSend(nil, self, "setLabel:", label) +} +@(objc_type=Function, objc_name="stageInputAttributes") +Function_stageInputAttributes :: #force_inline proc(self: ^Function) -> ^NS.Array { + return msgSend(^NS.Array, self, "stageInputAttributes") +} +@(objc_type=Function, objc_name="vertexAttributes") +Function_vertexAttributes :: #force_inline proc(self: ^Function) -> ^NS.Array { + return msgSend(^NS.Array, self, "vertexAttributes") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + FunctionHandle +Class Methods: +Methods: + device + functionType + name +*/ +@(objc_class="MTLFunctionHandle") +FunctionHandle :: struct { using _: NS.Object } + +@(objc_type=FunctionHandle, objc_name="device") +FunctionHandle_device :: #force_inline proc(self: ^FunctionHandle) -> ^Device { + return msgSend(^Device, self, "device") +} +@(objc_type=FunctionHandle, objc_name="functionType") +FunctionHandle_functionType :: #force_inline proc(self: ^FunctionHandle) -> FunctionType { + return msgSend(FunctionType, self, "functionType") +} +@(objc_type=FunctionHandle, objc_name="name") +FunctionHandle_name :: #force_inline proc(self: ^FunctionHandle) -> ^NS.String { + return msgSend(^NS.String, self, "name") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + LogContainer +*/ + +@(objc_class="MTLLogContainer") +LogContainer :: struct { using _: NS.FastEnumeration } + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + FunctionLog +Class Methods: +Methods: + debugLocation + encoderLabel + function + type +*/ +@(objc_class="MTLFunctionLog") +FunctionLog :: struct { using _: NS.Object } + +@(objc_type=FunctionLog, objc_name="debugLocation") +FunctionLog_debugLocation :: #force_inline proc(self: ^FunctionLog) -> ^FunctionLog { + return msgSend(^FunctionLog, self, "debugLocation") +} +@(objc_type=FunctionLog, objc_name="encoderLabel") +FunctionLog_encoderLabel :: #force_inline proc(self: ^FunctionLog) -> ^NS.String { + return msgSend(^NS.String, self, "encoderLabel") +} +@(objc_type=FunctionLog, objc_name="function") +FunctionLog_function :: #force_inline proc(self: ^FunctionLog) -> ^FunctionLog { + return msgSend(^FunctionLog, self, "function") +} +@(objc_type=FunctionLog, objc_name="type") +FunctionLog_type :: #force_inline proc(self: ^FunctionLog) -> FunctionLogType { + return msgSend(FunctionLogType, self, "type") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + FunctionLogDebugLocation +Class Methods: +Methods: + URL + column + functionName + line +*/ +@(objc_class="MTLFunctionLogDebugLocation") +FunctionLogDebugLocation :: struct { using _: NS.Object } + +@(objc_type=FunctionLogDebugLocation, objc_name="URL") +FunctionLogDebugLocation_URL :: #force_inline proc(self: ^FunctionLogDebugLocation) -> ^NS.URL { + return msgSend(^NS.URL, self, "URL") +} +@(objc_type=FunctionLogDebugLocation, objc_name="column") +FunctionLogDebugLocation_column :: #force_inline proc(self: ^FunctionLogDebugLocation) -> NS.UInteger { + return msgSend(NS.UInteger, self, "column") +} +@(objc_type=FunctionLogDebugLocation, objc_name="functionName") +FunctionLogDebugLocation_functionName :: #force_inline proc(self: ^FunctionLogDebugLocation) -> ^NS.String { + return msgSend(^NS.String, self, "functionName") +} +@(objc_type=FunctionLogDebugLocation, objc_name="line") +FunctionLogDebugLocation_line :: #force_inline proc(self: ^FunctionLogDebugLocation) -> NS.UInteger { + return msgSend(NS.UInteger, self, "line") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + Heap +Class Methods: +Methods: + cpuCacheMode + currentAllocatedSize + device + hazardTrackingMode + label + maxAvailableSizeWithAlignment + newBufferWithLength + newBufferWithLength + newTextureWithDescriptor + newTextureWithDescriptor + resourceOptions + setLabel + setPurgeableState + size + storageMode + type + usedSize +*/ +@(objc_class="MTLHeap") +Heap :: struct { using _: NS.Object } + +@(objc_type=Heap, objc_name="cpuCacheMode") +Heap_cpuCacheMode :: #force_inline proc(self: ^Heap) -> CPUCacheMode { + return msgSend(CPUCacheMode, self, "cpuCacheMode") +} +@(objc_type=Heap, objc_name="currentAllocatedSize") +Heap_currentAllocatedSize :: #force_inline proc(self: ^Heap) -> NS.UInteger { + return msgSend(NS.UInteger, self, "currentAllocatedSize") +} +@(objc_type=Heap, objc_name="device") +Heap_device :: #force_inline proc(self: ^Heap) -> ^Device { + return msgSend(^Device, self, "device") +} +@(objc_type=Heap, objc_name="hazardTrackingMode") +Heap_hazardTrackingMode :: #force_inline proc(self: ^Heap) -> HazardTrackingMode { + return msgSend(HazardTrackingMode, self, "hazardTrackingMode") +} +@(objc_type=Heap, objc_name="label") +Heap_label :: #force_inline proc(self: ^Heap) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=Heap, objc_name="maxAvailableSizeWithAlignment") +Heap_maxAvailableSizeWithAlignment :: #force_inline proc(self: ^Heap, alignment: NS.UInteger) -> NS.UInteger { + return msgSend(NS.UInteger, self, "maxAvailableSizeWithAlignment:", alignment) +} +@(objc_type=Heap, objc_name="newBufferWithLength") +Heap_newBufferWithLength :: #force_inline proc(self: ^Heap, length: NS.UInteger, options: ResourceOptions) -> ^Buffer { + return msgSend(^Buffer, self, "newBufferWithLength:options:", length, options) +} +@(objc_type=Heap, objc_name="newBufferWithOptions") +Heap_newBufferWithOptions :: #force_inline proc(self: ^Heap, length: NS.UInteger, options: ResourceOptions, offset: NS.UInteger) -> ^Buffer { + return msgSend(^Buffer, self, "newBufferWithLength:options:offset:", length, options, offset) +} +@(objc_type=Heap, objc_name="newBuffer") +Heap_newBuffer :: proc{ + Heap_newBufferWithLength, + Heap_newBufferWithOptions, +} + +@(objc_type=Heap, objc_name="newTextureWithDescriptor") +Heap_newTextureWithDescriptor :: #force_inline proc(self: ^Heap, desc: ^TextureDescriptor) -> ^Texture { + return msgSend(^Texture, self, "newTextureWithDescriptor:", desc) +} +@(objc_type=Heap, objc_name="newTextureWithDescriptorAndOffset") +Heap_newTextureWithDescriptorAndOffset :: #force_inline proc(self: ^Heap, descriptor: ^TextureDescriptor, offset: NS.UInteger) -> ^Texture { + return msgSend(^Texture, self, "newTextureWithDescriptor:offset:", descriptor, offset) +} +@(objc_type=Heap, objc_name="newTexture") +Heap_newTexture :: proc{ + Heap_newTextureWithDescriptor, + Heap_newTextureWithDescriptorAndOffset, +} + +@(objc_type=Heap, objc_name="resourceOptions") +Heap_resourceOptions :: #force_inline proc(self: ^Heap) -> ResourceOptions { + return msgSend(ResourceOptions, self, "resourceOptions") +} +@(objc_type=Heap, objc_name="setLabel") +Heap_setLabel :: #force_inline proc(self: ^Heap, label: ^NS.String) { + msgSend(nil, self, "setLabel:", label) +} +@(objc_type=Heap, objc_name="setPurgeableState") +Heap_setPurgeableState :: #force_inline proc(self: ^Heap, state: PurgeableState) -> PurgeableState { + return msgSend(PurgeableState, self, "setPurgeableState:", state) +} +@(objc_type=Heap, objc_name="size") +Heap_size :: #force_inline proc(self: ^Heap) -> NS.UInteger { + return msgSend(NS.UInteger, self, "size") +} +@(objc_type=Heap, objc_name="storageMode") +Heap_storageMode :: #force_inline proc(self: ^Heap) -> StorageMode { + return msgSend(StorageMode, self, "storageMode") +} +@(objc_type=Heap, objc_name="type") +Heap_type :: #force_inline proc(self: ^Heap) -> FunctionLogType { + return msgSend(FunctionLogType, self, "type") +} +@(objc_type=Heap, objc_name="usedSize") +Heap_usedSize :: #force_inline proc(self: ^Heap) -> NS.UInteger { + return msgSend(NS.UInteger, self, "usedSize") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + IndirectCommandBuffer +Class Methods: +Methods: + indirectComputeCommandAtIndex + indirectRenderCommandAtIndex + resetWithRange + size +*/ +@(objc_class="MTLIndirectCommandBuffer") +IndirectCommandBuffer :: struct { using _: Resource } + +@(objc_type=IndirectCommandBuffer, objc_name="indirectComputeCommand") +IndirectCommandBuffer_indirectComputeCommand :: #force_inline proc(self: ^IndirectCommandBuffer, commandIndex: NS.UInteger) -> ^IndirectComputeCommand { + return msgSend(^IndirectComputeCommand, self, "indirectComputeCommandAtIndex:", commandIndex) +} +@(objc_type=IndirectCommandBuffer, objc_name="indirectRenderCommand") +IndirectCommandBuffer_indirectRenderCommand :: #force_inline proc(self: ^IndirectCommandBuffer, commandIndex: NS.UInteger) -> ^IndirectRenderCommand { + return msgSend(^IndirectRenderCommand, self, "indirectRenderCommandAtIndex:", commandIndex) +} +@(objc_type=IndirectCommandBuffer, objc_name="resetWithRange") +IndirectCommandBuffer_resetWithRange :: #force_inline proc(self: ^IndirectCommandBuffer, range: NS.Range) { + msgSend(nil, self, "resetWithRange:", range) +} +@(objc_type=IndirectCommandBuffer, objc_name="size") +IndirectCommandBuffer_size :: #force_inline proc(self: ^IndirectCommandBuffer) -> NS.UInteger { + return msgSend(NS.UInteger, self, "size") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + IndirectComputeCommand +Class Methods: +Methods: + clearBarrier + concurrentDispatchThreadgroups + concurrentDispatchThreads + reset + setBarrier + setComputePipelineState + setImageblockWidth + setKernelBuffer + setStageInRegion + setThreadgroupMemoryLength +*/ +@(objc_class="MTLIndirectComputeCommand") +IndirectComputeCommand :: struct { using _: NS.Object } + +@(objc_type=IndirectComputeCommand, objc_name="clearBarrier") +IndirectComputeCommand_clearBarrier :: #force_inline proc(self: ^IndirectComputeCommand) { + msgSend(nil, self, "clearBarrier") +} +@(objc_type=IndirectComputeCommand, objc_name="concurrentDispatchThreadgroups") +IndirectComputeCommand_concurrentDispatchThreadgroups :: #force_inline proc(self: ^IndirectComputeCommand, threadgroupsPerGrid: Size, threadsPerThreadgroup: Size) { + msgSend(nil, self, "concurrentDispatchThreadgroups:threadsPerThreadgroup:", threadgroupsPerGrid, threadsPerThreadgroup) +} +@(objc_type=IndirectComputeCommand, objc_name="concurrentDispatchThreads") +IndirectComputeCommand_concurrentDispatchThreads :: #force_inline proc(self: ^IndirectComputeCommand, threadsPerGrid: Size, threadsPerThreadgroup: Size) { + msgSend(nil, self, "concurrentDispatchThreads:threadsPerThreadgroup:", threadsPerGrid, threadsPerThreadgroup) +} +@(objc_type=IndirectComputeCommand, objc_name="reset") +IndirectComputeCommand_reset :: #force_inline proc(self: ^IndirectComputeCommand) { + msgSend(nil, self, "reset") +} +@(objc_type=IndirectComputeCommand, objc_name="setBarrier") +IndirectComputeCommand_setBarrier :: #force_inline proc(self: ^IndirectComputeCommand) { + msgSend(nil, self, "setBarrier") +} +@(objc_type=IndirectComputeCommand, objc_name="setComputePipelineState") +IndirectComputeCommand_setComputePipelineState :: #force_inline proc(self: ^IndirectComputeCommand, pipelineState: ^ComputePipelineState) { + msgSend(nil, self, "setComputePipelineState:", pipelineState) +} +@(objc_type=IndirectComputeCommand, objc_name="setImageblockWidth") +IndirectComputeCommand_setImageblockWidth :: #force_inline proc(self: ^IndirectComputeCommand, width: NS.UInteger, height: NS.UInteger) { + msgSend(nil, self, "setImageblockWidth:height:", width, height) +} +@(objc_type=IndirectComputeCommand, objc_name="setKernelBuffer") +IndirectComputeCommand_setKernelBuffer :: #force_inline proc(self: ^IndirectComputeCommand, buffer: ^Buffer, offset: NS.UInteger, index: NS.UInteger) { + msgSend(nil, self, "setKernelBuffer:offset:atIndex:", buffer, offset, index) +} +@(objc_type=IndirectComputeCommand, objc_name="setStageInRegion") +IndirectComputeCommand_setStageInRegion :: #force_inline proc(self: ^IndirectComputeCommand, region: Region) { + msgSend(nil, self, "setStageInRegion:", region) +} +@(objc_type=IndirectComputeCommand, objc_name="setThreadgroupMemoryLength") +IndirectComputeCommand_setThreadgroupMemoryLength :: #force_inline proc(self: ^IndirectComputeCommand, length: NS.UInteger, index: NS.UInteger) { + msgSend(nil, self, "setThreadgroupMemoryLength:atIndex:", length, index) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + IndirectRenderCommand +Class Methods: +Methods: + drawIndexedPatches + drawIndexedPrimitives + drawPatches + drawPrimitives + reset + setFragmentBuffer + setRenderPipelineState + setVertexBuffer +*/ +@(objc_class="MTLIndirectRenderCommand") +IndirectRenderCommand :: struct { using _: NS.Object } + +@(objc_type=IndirectRenderCommand, objc_name="drawIndexedPatches") +IndirectRenderCommand_drawIndexedPatches :: #force_inline proc(self: ^IndirectRenderCommand, numberOfPatchControlPoints: NS.UInteger, patchStart, patchCount: NS.UInteger, patchIndexBuffer: ^Buffer, patchIndexBufferOffset: NS.UInteger, controlPointIndexBuffer: ^Buffer, controlPointIndexBufferOffset: NS.UInteger, instanceCount: NS.UInteger, baseInstance: NS.UInteger, buffer: ^Buffer, offset: NS.UInteger, instanceStride: NS.UInteger) { + msgSend(nil, self, "drawIndexedPatches:patchStart:patchCount:patchIndexBuffer:patchIndexBufferOffset:controlPointIndexBuffer:controlPointIndexBufferOffset:instanceCount:baseInstance:tessellationFactorBuffer:tessellationFactorBufferOffset:tessellationFactorBufferInstanceStride:", numberOfPatchControlPoints, patchStart, patchCount, patchIndexBuffer, patchIndexBufferOffset, controlPointIndexBuffer, controlPointIndexBufferOffset, instanceCount, baseInstance, buffer, offset, instanceStride) +} +@(objc_type=IndirectRenderCommand, objc_name="drawIndexedPrimitives") +IndirectRenderCommand_drawIndexedPrimitives :: #force_inline proc(self: ^IndirectRenderCommand, primitiveType: PrimitiveType, indexCount: NS.UInteger, indexType: IndexType, indexBuffer: ^Buffer, indexBufferOffset: NS.UInteger, instanceCount: NS.UInteger, baseVertex: NS.Integer, baseInstance: NS.UInteger) { + msgSend(nil, self, "drawIndexedPrimitives:indexCount:indexType:indexBuffer:indexBufferOffset:instanceCount:baseVertex:baseInstance:", primitiveType, indexCount, indexType, indexBuffer, indexBufferOffset, instanceCount, baseVertex, baseInstance) +} +@(objc_type=IndirectRenderCommand, objc_name="drawPatches") +IndirectRenderCommand_drawPatches :: #force_inline proc(self: ^IndirectRenderCommand, numberOfPatchControlPoints: NS.UInteger, patchStart, patchCount: NS.UInteger, patchIndexBuffer: ^Buffer, patchIndexBufferOffset: NS.UInteger, instanceCount: NS.UInteger, baseInstance: NS.UInteger, buffer: ^Buffer, offset: NS.UInteger, instanceStride: NS.UInteger) { + msgSend(nil, self, "drawPatches:patchStart:patchCount:patchIndexBuffer:patchIndexBufferOffset:instanceCount:baseInstance:tessellationFactorBuffer:tessellationFactorBufferOffset:tessellationFactorBufferInstanceStride:", numberOfPatchControlPoints, patchStart, patchCount, patchIndexBuffer, patchIndexBufferOffset, instanceCount, baseInstance, buffer, offset, instanceStride) +} +@(objc_type=IndirectRenderCommand, objc_name="drawPrimitives") +IndirectRenderCommand_drawPrimitives :: #force_inline proc(self: ^IndirectRenderCommand, primitiveType: PrimitiveType, vertexStart: NS.UInteger, vertexCount: NS.UInteger, instanceCount: NS.UInteger, baseInstance: NS.UInteger = 0) { + msgSend(nil, self, "drawPrimitives:vertexStart:vertexCount:instanceCount:baseInstance:", primitiveType, vertexStart, vertexCount, instanceCount, baseInstance) +} +@(objc_type=IndirectRenderCommand, objc_name="reset") +IndirectRenderCommand_reset :: #force_inline proc(self: ^IndirectRenderCommand) { + msgSend(nil, self, "reset") +} +@(objc_type=IndirectRenderCommand, objc_name="setFragmentBuffer") +IndirectRenderCommand_setFragmentBuffer :: #force_inline proc(self: ^IndirectRenderCommand, buffer: ^Buffer, offset: NS.UInteger, index: NS.UInteger) { + msgSend(nil, self, "setFragmentBuffer:offset:atIndex:", buffer, offset, index) +} +@(objc_type=IndirectRenderCommand, objc_name="setRenderPipelineState") +IndirectRenderCommand_setRenderPipelineState :: #force_inline proc(self: ^IndirectRenderCommand, pipelineState: ^RenderPipelineState) { + msgSend(nil, self, "setRenderPipelineState:", pipelineState) +} +@(objc_type=IndirectRenderCommand, objc_name="setVertexBuffer") +IndirectRenderCommand_setVertexBuffer :: #force_inline proc(self: ^IndirectRenderCommand, buffer: ^Buffer, offset: NS.UInteger, index: NS.UInteger) { + msgSend(nil, self, "setVertexBuffer:offset:atIndex:", buffer, offset, index) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + IntersectionFunctionTable +Class Methods: +Methods: + setBuffer + setBuffers + setFunction + setFunctions + setOpaqueTriangleIntersectionFunctionWithSignature + setOpaqueTriangleIntersectionFunctionWithSignature + setVisibleFunctionTable + setVisibleFunctionTables +*/ +@(objc_class="MTLIntersectionFunctionTable") +IntersectionFunctionTable :: struct { using _: Resource } + +@(objc_type=IntersectionFunctionTable, objc_name="setBuffer") +IntersectionFunctionTable_setBuffer :: #force_inline proc(self: ^IntersectionFunctionTable, buffer: ^Buffer, offset: NS.UInteger, index: NS.UInteger) { + msgSend(nil, self, "setBuffer:offset:atIndex:", buffer, offset, index) +} +@(objc_type=IntersectionFunctionTable, objc_name="setBuffers") +IntersectionFunctionTable_setBuffers :: #force_inline proc(self: ^IntersectionFunctionTable, buffers: []^Buffer, offsets: []NS.UInteger, range: NS.Range) { + msgSend(nil, self, "setBuffers:offsets:withRange:", raw_data(buffers), raw_data(offsets), range) +} +@(objc_type=IntersectionFunctionTable, objc_name="setFunction") +IntersectionFunctionTable_setFunction :: #force_inline proc(self: ^IntersectionFunctionTable, function: ^FunctionHandle, index: NS.UInteger) { + msgSend(nil, self, "setFunction:atIndex:", function, index) +} +@(objc_type=IntersectionFunctionTable, objc_name="setFunctions") +IntersectionFunctionTable_setFunctions :: #force_inline proc(self: ^IntersectionFunctionTable, functions: []^FunctionHandle, range: NS.Range) { + msgSend(nil, self, "setFunctions:withRange:", raw_data(functions), range) +} +@(objc_type=IntersectionFunctionTable, objc_name="setOpaqueTriangleIntersectionFunctionWithSignature") +IntersectionFunctionTable_setOpaqueTriangleIntersectionFunctionWithSignature :: #force_inline proc(self: ^IntersectionFunctionTable, signature: IntersectionFunctionSignature, index: NS.UInteger) { + msgSend(nil, self, "setOpaqueTriangleIntersectionFunctionWithSignature:atIndex:", signature, index) +} +@(objc_type=IntersectionFunctionTable, objc_name="setOpaqueTriangleIntersectionFunctionWithSignatureWithRange") +IntersectionFunctionTable_setOpaqueTriangleIntersectionFunctionWithSignatureWithRange :: #force_inline proc(self: ^IntersectionFunctionTable, signature: IntersectionFunctionSignature, range: NS.Range) { + msgSend(nil, self, "setOpaqueTriangleIntersectionFunctionWithSignature:withRange:", signature, range) +} +@(objc_type=IntersectionFunctionTable, objc_name="setVisibleFunctionTable") +IntersectionFunctionTable_setVisibleFunctionTable :: #force_inline proc(self: ^IntersectionFunctionTable, visibleFunctionTable: ^VisibleFunctionTable, bufferIndex: NS.UInteger) { + msgSend(nil, self, "setVisibleFunctionTable:atBufferIndex:", visibleFunctionTable, bufferIndex) +} +@(objc_type=IntersectionFunctionTable, objc_name="setVisibleFunctionTables") +IntersectionFunctionTable_setVisibleFunctionTables :: #force_inline proc(self: ^IntersectionFunctionTable, visibleFunctionTables: []^VisibleFunctionTable, range: NS.Range) { + msgSend(nil, self, "setVisibleFunctionTables:withBufferRange:", raw_data(visibleFunctionTables), range) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + Library +Class Methods: +Methods: + device + functionNames + installName + label + newFunctionWithDescriptor + newFunctionWithDescriptor + newFunctionWithName + newFunctionWithName + newFunctionWithName + newIntersectionFunctionWithDescriptor + newIntersectionFunctionWithDescriptor + setLabel + type +*/ +@(objc_class="MTLLibrary") +Library :: struct { using _: NS.Object } + +@(objc_type=Library, objc_name="device") +Library_device :: #force_inline proc(self: ^Library) -> ^Device { + return msgSend(^Device, self, "device") +} +@(objc_type=Library, objc_name="functionNames") +Library_functionNames :: #force_inline proc(self: ^Library) -> ^NS.Array { + return msgSend(^NS.Array, self, "functionNames") +} +@(objc_type=Library, objc_name="installName") +Library_installName :: #force_inline proc(self: ^Library) -> ^NS.String { + return msgSend(^NS.String, self, "installName") +} +@(objc_type=Library, objc_name="label") +Library_label :: #force_inline proc(self: ^Library) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=Library, objc_name="newFunctionWithCompletionHandler") +Library_newFunctionWithCompletionHandler :: #force_inline proc(self: ^Library, descriptor: ^FunctionDescriptor, completionHandler: ^NS.Block) -> ^Function { + return msgSend(^Function, self, "newFunctionWithDescriptor:completionHandler:", descriptor, completionHandler) +} +@(objc_type=Library, objc_name="newFunctionWithDescriptor") +Library_newFunctionWithDescriptor :: #force_inline proc(self: ^Library, descriptor: ^FunctionDescriptor) -> (function: ^Function, error: ^NS.Error) { + function = msgSend(^Function, self, "newFunctionWithDescriptor:error:", descriptor, &error) + return +} +@(objc_type=Library, objc_name="newFunctionWithName") +Library_newFunctionWithName :: #force_inline proc(self: ^Library, functionName: ^NS.String) -> ^Function { + return msgSend(^Function, self, "newFunctionWithName:", functionName) +} +@(objc_type=Library, objc_name="newFunctionWithConstantValuesAndCompletionHandler") +Library_newFunctionWithConstantValuesAndCompletionHandler :: #force_inline proc(self: ^Library, name: ^NS.String, constantValues: ^FunctionConstantValues, completionHandler: ^NS.Block) -> ^Function { + return msgSend(^Function, self, "newFunctionWithName:constantValues:completionHandler:", name, constantValues, completionHandler) +} +@(objc_type=Library, objc_name="newFunctionWithConstantValues") +Library_newFunctionWithConstantValues :: #force_inline proc(self: ^Library, name: ^NS.String, constantValues: ^FunctionConstantValues) -> (function: ^Function, error: ^NS.Error) { + function = msgSend(^Function, self, "newFunctionWithName:constantValues:error:", name, constantValues, &error) + return +} +@(objc_type=Library, objc_name="newFunction") +Library_newFunction :: proc{ + Library_newFunctionWithCompletionHandler, + Library_newFunctionWithDescriptor, + Library_newFunctionWithName, + Library_newFunctionWithConstantValuesAndCompletionHandler, + Library_newFunctionWithConstantValues, +} + +@(objc_type=Library, objc_name="newIntersectionFunctionWithCompletionHandler") +Library_newIntersectionFunctionWithCompletionHandler :: #force_inline proc(self: ^Library, descriptor: ^IntersectionFunctionDescriptor, completionHandler: ^NS.Block) -> ^Function { + return msgSend(^Function, self, "newIntersectionFunctionWithDescriptor:completionHandler:", descriptor, completionHandler) +} +@(objc_type=Library, objc_name="newIntersectionFunction") +Library_newIntersectionFunction :: #force_inline proc(self: ^Library, descriptor: ^IntersectionFunctionDescriptor) -> (function: ^Function, error: ^NS.Error) { + function = msgSend(^Function, self, "newIntersectionFunctionWithDescriptor:error:", descriptor, &error) + return +} +@(objc_type=Library, objc_name="setLabel") +Library_setLabel :: #force_inline proc(self: ^Library, label: ^NS.String) { + msgSend(nil, self, "setLabel:", label) +} +@(objc_type=Library, objc_name="type") +Library_type :: #force_inline proc(self: ^Library) -> LibraryType { + return msgSend(LibraryType, self, "type") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + ParallelRenderCommandEncoder +Class Methods: +Methods: + renderCommandEncoder + setColorStoreAction + setColorStoreActionOptions + setDepthStoreAction + setDepthStoreActionOptions + setStencilStoreAction + setStencilStoreActionOptions +*/ +@(objc_class="MTLParallelRenderCommandEncoder") +ParallelRenderCommandEncoder :: struct { using _: CommandEncoder } + +@(objc_type=ParallelRenderCommandEncoder, objc_name="renderCommandEncoder") +ParallelRenderCommandEncoder_renderCommandEncoder :: #force_inline proc(self: ^ParallelRenderCommandEncoder) -> ^RenderCommandEncoder { + return msgSend(^RenderCommandEncoder, self, "renderCommandEncoder") +} +@(objc_type=ParallelRenderCommandEncoder, objc_name="setColorStoreAction") +ParallelRenderCommandEncoder_setColorStoreAction :: #force_inline proc(self: ^ParallelRenderCommandEncoder, storeAction: StoreAction, colorAttachmentIndex: NS.UInteger) { + msgSend(nil, self, "setColorStoreAction:atIndex:", storeAction, colorAttachmentIndex) +} +@(objc_type=ParallelRenderCommandEncoder, objc_name="setColorStoreActionOptions") +ParallelRenderCommandEncoder_setColorStoreActionOptions :: #force_inline proc(self: ^ParallelRenderCommandEncoder, storeActionOptions: StoreActionOptions, colorAttachmentIndex: NS.UInteger) { + msgSend(nil, self, "setColorStoreActionOptions:atIndex:", storeActionOptions, colorAttachmentIndex) +} +@(objc_type=ParallelRenderCommandEncoder, objc_name="setDepthStoreAction") +ParallelRenderCommandEncoder_setDepthStoreAction :: #force_inline proc(self: ^ParallelRenderCommandEncoder, storeAction: StoreAction) { + msgSend(nil, self, "setDepthStoreAction:", storeAction) +} +@(objc_type=ParallelRenderCommandEncoder, objc_name="setDepthStoreActionOptions") +ParallelRenderCommandEncoder_setDepthStoreActionOptions :: #force_inline proc(self: ^ParallelRenderCommandEncoder, storeActionOptions: StoreActionOptions) { + msgSend(nil, self, "setDepthStoreActionOptions:", storeActionOptions) +} +@(objc_type=ParallelRenderCommandEncoder, objc_name="setStencilStoreAction") +ParallelRenderCommandEncoder_setStencilStoreAction :: #force_inline proc(self: ^ParallelRenderCommandEncoder, storeAction: StoreAction) { + msgSend(nil, self, "setStencilStoreAction:", storeAction) +} +@(objc_type=ParallelRenderCommandEncoder, objc_name="setStencilStoreActionOptions") +ParallelRenderCommandEncoder_setStencilStoreActionOptions :: #force_inline proc(self: ^ParallelRenderCommandEncoder, storeActionOptions: StoreActionOptions) { + msgSend(nil, self, "setStencilStoreActionOptions:", storeActionOptions) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + RasterizationRateMap +Class Methods: +Methods: + copyParameterDataToBuffer + device + label + layerCount + mapPhysicalToScreenCoordinates + mapScreenToPhysicalCoordinates + parameterBufferSizeAndAlign + physicalGranularity + physicalSizeForLayer + screenSize +*/ +@(objc_class="MTLRasterizationRateMap") +RasterizationRateMap :: struct { using _: NS.Object } + +@(objc_type=RasterizationRateMap, objc_name="copyParameterDataToBuffer") +RasterizationRateMap_copyParameterDataToBuffer :: #force_inline proc(self: ^RasterizationRateMap, buffer: ^Buffer, offset: NS.UInteger) { + msgSend(nil, self, "copyParameterDataToBuffer:offset:", buffer, offset) +} +@(objc_type=RasterizationRateMap, objc_name="device") +RasterizationRateMap_device :: #force_inline proc(self: ^RasterizationRateMap) -> ^Device { + return msgSend(^Device, self, "device") +} +@(objc_type=RasterizationRateMap, objc_name="label") +RasterizationRateMap_label :: #force_inline proc(self: ^RasterizationRateMap) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=RasterizationRateMap, objc_name="layerCount") +RasterizationRateMap_layerCount :: #force_inline proc(self: ^RasterizationRateMap) -> NS.UInteger { + return msgSend(NS.UInteger, self, "layerCount") +} +@(objc_type=RasterizationRateMap, objc_name="mapPhysicalToScreenCoordinates") +RasterizationRateMap_mapPhysicalToScreenCoordinates :: #force_inline proc(self: ^RasterizationRateMap, physicalCoordinates: Coordinate2D, layerIndex: NS.UInteger) -> Coordinate2D { + return msgSend(Coordinate2D, self, "mapPhysicalToScreenCoordinates:forLayer:", physicalCoordinates, layerIndex) +} +@(objc_type=RasterizationRateMap, objc_name="mapScreenToPhysicalCoordinates") +RasterizationRateMap_mapScreenToPhysicalCoordinates :: #force_inline proc(self: ^RasterizationRateMap, screenCoordinates: Coordinate2D, layerIndex: NS.UInteger) -> Coordinate2D { + return msgSend(Coordinate2D, self, "mapScreenToPhysicalCoordinates:forLayer:", screenCoordinates, layerIndex) +} +@(objc_type=RasterizationRateMap, objc_name="parameterBufferSizeAndAlign") +RasterizationRateMap_parameterBufferSizeAndAlign :: #force_inline proc(self: ^RasterizationRateMap) -> (size, align: NS.UInteger) { + res := msgSend(SizeAndAlign, self, "parameterBufferSizeAndAlign") + return res.size, res.align +} +@(objc_type=RasterizationRateMap, objc_name="physicalGranularity") +RasterizationRateMap_physicalGranularity :: #force_inline proc(self: ^RasterizationRateMap) -> Size { + return msgSend(Size, self, "physicalGranularity") +} +@(objc_type=RasterizationRateMap, objc_name="physicalSizeForLayer") +RasterizationRateMap_physicalSizeForLayer :: #force_inline proc(self: ^RasterizationRateMap, layerIndex: NS.UInteger) -> Size { + return msgSend(Size, self, "physicalSizeForLayer:", layerIndex) +} +@(objc_type=RasterizationRateMap, objc_name="screenSize") +RasterizationRateMap_screenSize :: #force_inline proc(self: ^RasterizationRateMap) -> Size { + return msgSend(Size, self, "screenSize") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + RenderCommandEncoder +Class Methods: +Methods: + dispatchThreadsPerTile + drawIndexedPatches + drawIndexedPatches + drawIndexedPrimitives + drawIndexedPrimitives + drawIndexedPrimitives + drawIndexedPrimitives + drawPatches + drawPatches + drawPrimitives + drawPrimitives + drawPrimitives + drawPrimitives + executeCommandsInBuffer + executeCommandsInBuffer + memoryBarrierWithResources + memoryBarrierWithScope + sampleCountersInBuffer + setBlendColorRed + setColorStoreAction + setColorStoreActionOptions + setCullMode + setDepthBias + setDepthClipMode + setDepthStencilState + setDepthStoreAction + setDepthStoreActionOptions + setFragmentBuffer + setFragmentBufferOffset + setFragmentBuffers + setFragmentBytes + setFragmentSamplerState + setFragmentSamplerState + setFragmentSamplerStates + setFragmentSamplerStates + setFragmentTexture + setFragmentTextures + setFrontFacingWinding + setRenderPipelineState + setScissorRect + setScissorRects + setStencilFrontReferenceValue + setStencilReferenceValue + setStencilStoreAction + setStencilStoreActionOptions + setTessellationFactorBuffer + setTessellationFactorScale + setThreadgroupMemoryLength + setTileBuffer + setTileBufferOffset + setTileBuffers + setTileBytes + setTileSamplerState + setTileSamplerState + setTileSamplerStates + setTileSamplerStates + setTileTexture + setTileTextures + setTriangleFillMode + setVertexAmplificationCount + setVertexBuffer + setVertexBufferOffset + setVertexBuffers + setVertexBytes + setVertexSamplerState + setVertexSamplerState + setVertexSamplerStates + setVertexSamplerStates + setVertexTexture + setVertexTextures + setViewport + setViewports + setVisibilityResultMode + textureBarrier + tileHeight + tileWidth + updateFence + useHeap + useHeap + useHeaps + useHeaps + useResource + useResource + useResources + useResources + waitForFence +*/ +@(objc_class="MTLRenderCommandEncoder") +RenderCommandEncoder :: struct { using _: CommandEncoder } + +@(objc_type=RenderCommandEncoder, objc_name="dispatchThreadsPerTile") +RenderCommandEncoder_dispatchThreadsPerTile :: #force_inline proc(self: ^RenderCommandEncoder, threadsPerTile: Size) { + msgSend(nil, self, "dispatchThreadsPerTile:", threadsPerTile) +} +@(objc_type=RenderCommandEncoder, objc_name="drawIndexedPatchesWihtIndirect") +RenderCommandEncoder_drawIndexedPatchesWihtIndirect :: #force_inline proc(self: ^RenderCommandEncoder, numberOfPatchControlPoints: NS.UInteger, patchIndexBuffer: ^Buffer, patchIndexBufferOffset: NS.UInteger, controlPointIndexBuffer: ^Buffer, controlPointIndexBufferOffset: NS.UInteger, indirectBuffer: ^Buffer, indirectBufferOffset: NS.UInteger) { + msgSend(nil, self, "drawIndexedPatches:patchIndexBuffer:patchIndexBufferOffset:controlPointIndexBuffer:controlPointIndexBufferOffset:indirectBuffer:indirectBufferOffset:", numberOfPatchControlPoints, patchIndexBuffer, patchIndexBufferOffset, controlPointIndexBuffer, controlPointIndexBufferOffset, indirectBuffer, indirectBufferOffset) +} +@(objc_type=RenderCommandEncoder, objc_name="drawIndexPatchesWithInstances") +RenderCommandEncoder_drawIndexPatchesWithInstance :: #force_inline proc(self: ^RenderCommandEncoder, numberOfPatchControlPoints: NS.UInteger, patchStart, patchCount: NS.UInteger, patchIndexBuffer: ^Buffer, patchIndexBufferOffset: NS.UInteger, controlPointIndexBuffer: ^Buffer, controlPointIndexBufferOffset: NS.UInteger, instanceCount: NS.UInteger, baseInstance: NS.UInteger) { + msgSend(nil, self, "drawIndexedPatches:patchStart:patchCount:patchIndexBuffer:patchIndexBufferOffset:controlPointIndexBuffer:controlPointIndexBufferOffset:instanceCount:baseInstance:", numberOfPatchControlPoints, patchStart, patchCount, patchIndexBuffer, patchIndexBufferOffset, controlPointIndexBuffer, controlPointIndexBufferOffset, instanceCount, baseInstance) +} +@(objc_type=RenderCommandEncoder, objc_name="drawIndexedPrimitives") +RenderCommandEncoder_drawIndexedPrimitives :: #force_inline proc(self: ^RenderCommandEncoder, primitiveType: PrimitiveType, indexCount: NS.UInteger, indexType: IndexType, indexBuffer: ^Buffer, indexBufferOffset: NS.UInteger) { + msgSend(nil, self, "drawIndexedPrimitives:indexCount:indexType:indexBuffer:indexBufferOffset:", primitiveType, indexCount, indexType, indexBuffer, indexBufferOffset) +} +@(objc_type=RenderCommandEncoder, objc_name="drawIndexedPrimitivesWithInstanceCount") +RenderCommandEncoder_drawIndexedPrimitivesWithInstanceCount :: #force_inline proc(self: ^RenderCommandEncoder, primitiveType: PrimitiveType, indexCount: NS.UInteger, indexType: IndexType, indexBuffer: ^Buffer, indexBufferOffset: NS.UInteger, instanceCount: NS.UInteger) { + msgSend(nil, self, "drawIndexedPrimitives:indexCount:indexType:indexBuffer:indexBufferOffset:instanceCount:", primitiveType, indexCount, indexType, indexBuffer, indexBufferOffset, instanceCount) +} +@(objc_type=RenderCommandEncoder, objc_name="drawIndexPrimitivesWithBaseVertex") +RenderCommandEncoder_drawIndexPrimitivesWithBaseVertex :: #force_inline proc(self: ^RenderCommandEncoder, primitiveType: PrimitiveType, indexCount: NS.UInteger, indexType: IndexType, indexBuffer: ^Buffer, indexBufferOffset: NS.UInteger, instanceCount: NS.UInteger, baseVertex: NS.Integer, baseInstance: NS.UInteger) { + msgSend(nil, self, "drawIndexedPrimitives:indexCount:indexType:indexBuffer:indexBufferOffset:instanceCount:baseVertex:baseInstance:", primitiveType, indexCount, indexType, indexBuffer, indexBufferOffset, instanceCount, baseVertex, baseInstance) +} +@(objc_type=RenderCommandEncoder, objc_name="drawIndexPrimitivesWithIndirect") +RenderCommandEncoder_drawIndexPrimitivesWithIndirect :: #force_inline proc(self: ^RenderCommandEncoder, primitiveType: PrimitiveType, indexType: IndexType, indexBuffer: ^Buffer, indexBufferOffset: NS.UInteger, indirectBuffer: ^Buffer, indirectBufferOffset: NS.UInteger) { + msgSend(nil, self, "drawIndexedPrimitives:indexType:indexBuffer:indexBufferOffset:indirectBuffer:indirectBufferOffset:", primitiveType, indexType, indexBuffer, indexBufferOffset, indirectBuffer, indirectBufferOffset) +} +@(objc_type=RenderCommandEncoder, objc_name="drawPatches") +RenderCommandEncoder_drawPatches :: #force_inline proc(self: ^RenderCommandEncoder, numberOfPatchControlPoints: NS.UInteger, patchIndexBuffer: ^Buffer, patchIndexBufferOffset: NS.UInteger, indirectBuffer: ^Buffer, indirectBufferOffset: NS.UInteger) { + msgSend(nil, self, "drawPatches:patchIndexBuffer:patchIndexBufferOffset:indirectBuffer:indirectBufferOffset:", numberOfPatchControlPoints, patchIndexBuffer, patchIndexBufferOffset, indirectBuffer, indirectBufferOffset) +} +@(objc_type=RenderCommandEncoder, objc_name="drawPatchesWithInstances") +RenderCommandEncoder_drawPatchesWithInstance :: #force_inline proc(self: ^RenderCommandEncoder, numberOfPatchControlPoints: NS.UInteger, patchStart, patchCount: NS.UInteger, patchIndexBuffer: ^Buffer, patchIndexBufferOffset: NS.UInteger, instanceCount: NS.UInteger, baseInstance: NS.UInteger) { + msgSend(nil, self, "drawPatches:patchStart:patchCount:patchIndexBuffer:patchIndexBufferOffset:instanceCount:baseInstance:", numberOfPatchControlPoints, patchStart, patchCount, patchIndexBuffer, patchIndexBufferOffset, instanceCount, baseInstance) +} +@(objc_type=RenderCommandEncoder, objc_name="drawPrimitivesWithIndirect") +RenderCommandEncoder_drawPrimitivesWithIndirect :: #force_inline proc(self: ^RenderCommandEncoder, primitiveType: PrimitiveType, indirectBuffer: ^Buffer, indirectBufferOffset: NS.UInteger) { + msgSend(nil, self, "drawPrimitives:indirectBuffer:indirectBufferOffset:", primitiveType, indirectBuffer, indirectBufferOffset) +} +@(objc_type=RenderCommandEncoder, objc_name="drawPrimitives") +RenderCommandEncoder_drawPrimitives :: #force_inline proc(self: ^RenderCommandEncoder, primitiveType: PrimitiveType, vertexStart: NS.UInteger, vertexCount: NS.UInteger) { + msgSend(nil, self, "drawPrimitives:vertexStart:vertexCount:", primitiveType, vertexStart, vertexCount) +} +@(objc_type=RenderCommandEncoder, objc_name="drawPrimitivesWithInstanceCount") +RenderCommandEncoder_drawPrimitivesWithInstanceCount :: #force_inline proc(self: ^RenderCommandEncoder, primitiveType: PrimitiveType, vertexStart: NS.UInteger, vertexCount: NS.UInteger, instanceCount: NS.UInteger) { + msgSend(nil, self, "drawPrimitives:vertexStart:vertexCount:instanceCount:", primitiveType, vertexStart, vertexCount, instanceCount) +} +@(objc_type=RenderCommandEncoder, objc_name="drawPrimitivesWithInstances") +RenderCommandEncoder_drawPrimitivesWithInstances :: #force_inline proc(self: ^RenderCommandEncoder, primitiveType: PrimitiveType, vertexStart: NS.UInteger, vertexCount: NS.UInteger, instanceCount: NS.UInteger, baseInstance: NS.UInteger) { + msgSend(nil, self, "drawPrimitives:vertexStart:vertexCount:instanceCount:baseInstance:", primitiveType, vertexStart, vertexCount, instanceCount, baseInstance) +} +@(objc_type=RenderCommandEncoder, objc_name="executeCommandsInBuffer") +RenderCommandEncoder_executeCommandsInBuffer :: #force_inline proc(self: ^RenderCommandEncoder, indirectCommandbuffer: ^Buffer, indirectRangeBuffer: ^Buffer, indirectBufferOffset: NS.UInteger) { + msgSend(nil, self, "executeCommandsInBuffer:indirectBuffer:indirectBufferOffset:", indirectCommandbuffer, indirectRangeBuffer, indirectBufferOffset) +} +@(objc_type=RenderCommandEncoder, objc_name="executeCommandsInBufferWithRange") +RenderCommandEncoder_executeCommandsInBufferWithRange :: #force_inline proc(self: ^RenderCommandEncoder, indirectCommandBuffer: ^Buffer, executionRange: NS.Range) { + msgSend(nil, self, "executeCommandsInBuffer:withRange:", indirectCommandBuffer, executionRange) +} +@(objc_type=RenderCommandEncoder, objc_name="memoryBarrierWithResources") +RenderCommandEncoder_memoryBarrierWithResources :: #force_inline proc(self: ^RenderCommandEncoder, resources: []^Resource, after: RenderStages, before: RenderStages) { + msgSend(nil, self, "memoryBarrierWithResources:count:afterStages:beforeStages:", raw_data(resources), NS.UInteger(len(resources)), after, before) +} +@(objc_type=RenderCommandEncoder, objc_name="memoryBarrierWithScope") +RenderCommandEncoder_memoryBarrierWithScope :: #force_inline proc(self: ^RenderCommandEncoder, scope: BarrierScope, after: RenderStages, before: RenderStages) { + msgSend(nil, self, "memoryBarrierWithScope:afterStages:beforeStages:", scope, after, before) +} +@(objc_type=RenderCommandEncoder, objc_name="sampleCountersInBuffer") +RenderCommandEncoder_sampleCountersInBuffer :: #force_inline proc(self: ^RenderCommandEncoder, sampleBuffer: ^Buffer, sampleIndex: NS.UInteger, barrier: BOOL) { + msgSend(nil, self, "sampleCountersInBuffer:atSampleIndex:withBarrier:", sampleBuffer, sampleIndex, barrier) +} +@(objc_type=RenderCommandEncoder, objc_name="setBlendColorRed") +RenderCommandEncoder_setBlendColorRed :: #force_inline proc(self: ^RenderCommandEncoder, red: f32, green: f32, blue: f32, alpha: f32) { + msgSend(nil, self, "setBlendColorRed:green:blue:alpha:", red, green, blue, alpha) +} +@(objc_type=RenderCommandEncoder, objc_name="setColorStoreAction") +RenderCommandEncoder_setColorStoreAction :: #force_inline proc(self: ^RenderCommandEncoder, storeAction: StoreAction, colorAttachmentIndex: NS.UInteger) { + msgSend(nil, self, "setColorStoreAction:atIndex:", storeAction, colorAttachmentIndex) +} +@(objc_type=RenderCommandEncoder, objc_name="setColorStoreActionOptions") +RenderCommandEncoder_setColorStoreActionOptions :: #force_inline proc(self: ^RenderCommandEncoder, storeActionOptions: StoreActionOptions, colorAttachmentIndex: NS.UInteger) { + msgSend(nil, self, "setColorStoreActionOptions:atIndex:", storeActionOptions, colorAttachmentIndex) +} +@(objc_type=RenderCommandEncoder, objc_name="setCullMode") +RenderCommandEncoder_setCullMode :: #force_inline proc(self: ^RenderCommandEncoder, cullMode: CullMode) { + msgSend(nil, self, "setCullMode:", cullMode) +} +@(objc_type=RenderCommandEncoder, objc_name="setDepthBias") +RenderCommandEncoder_setDepthBias :: #force_inline proc(self: ^RenderCommandEncoder, depthBias: f32, slopeScale: f32, clamp: f32) { + msgSend(nil, self, "setDepthBias:slopeScale:clamp:", depthBias, slopeScale, clamp) +} +@(objc_type=RenderCommandEncoder, objc_name="setDepthClipMode") +RenderCommandEncoder_setDepthClipMode :: #force_inline proc(self: ^RenderCommandEncoder, depthClipMode: DepthClipMode) { + msgSend(nil, self, "setDepthClipMode:", depthClipMode) +} +@(objc_type=RenderCommandEncoder, objc_name="setDepthStencilState") +RenderCommandEncoder_setDepthStencilState :: #force_inline proc(self: ^RenderCommandEncoder, depthStencilState: ^DepthStencilState) { + msgSend(nil, self, "setDepthStencilState:", depthStencilState) +} +@(objc_type=RenderCommandEncoder, objc_name="setDepthStoreAction") +RenderCommandEncoder_setDepthStoreAction :: #force_inline proc(self: ^RenderCommandEncoder, storeAction: StoreAction) { + msgSend(nil, self, "setDepthStoreAction:", storeAction) +} +@(objc_type=RenderCommandEncoder, objc_name="setDepthStoreActionOptions") +RenderCommandEncoder_setDepthStoreActionOptions :: #force_inline proc(self: ^RenderCommandEncoder, storeActionOptions: StoreActionOptions) { + msgSend(nil, self, "setDepthStoreActionOptions:", storeActionOptions) +} +@(objc_type=RenderCommandEncoder, objc_name="setFragmentBuffer") +RenderCommandEncoder_setFragmentBuffer :: #force_inline proc(self: ^RenderCommandEncoder, buffer: ^Buffer, offset: NS.UInteger, index: NS.UInteger) { + msgSend(nil, self, "setFragmentBuffer:offset:atIndex:", buffer, offset, index) +} +@(objc_type=RenderCommandEncoder, objc_name="setFragmentBufferOffset") +RenderCommandEncoder_setFragmentBufferOffset :: #force_inline proc(self: ^RenderCommandEncoder, offset: NS.UInteger, index: NS.UInteger) { + msgSend(nil, self, "setFragmentBufferOffset:atIndex:", offset, index) +} +@(objc_type=RenderCommandEncoder, objc_name="setFragmentBuffers") +RenderCommandEncoder_setFragmentBuffers :: #force_inline proc(self: ^RenderCommandEncoder, buffers: []^Buffer, offsets: []NS.UInteger, range: NS.Range) { + msgSend(nil, self, "setFragmentBuffers:offsets:withRange:", raw_data(buffers), raw_data(offsets), range) +} +@(objc_type=RenderCommandEncoder, objc_name="setFragmentBytes") +RenderCommandEncoder_setFragmentBytes :: #force_inline proc(self: ^RenderCommandEncoder, bytes: []byte, index: NS.UInteger) { + msgSend(nil, self, "setFragmentBytes:length:atIndex:", raw_data(bytes), NS.UInteger(len(bytes)), index) +} +@(objc_type=RenderCommandEncoder, objc_name="setFragmentSamplerState") +RenderCommandEncoder_setFragmentSamplerState :: #force_inline proc(self: ^RenderCommandEncoder, sampler: ^SamplerState, index: NS.UInteger) { + msgSend(nil, self, "setFragmentSamplerState:atIndex:", sampler, index) +} +@(objc_type=RenderCommandEncoder, objc_name="setFragmentSamplerStateWithLod") +RenderCommandEncoder_setFragmentSamplerStateWithLod :: #force_inline proc(self: ^RenderCommandEncoder, sampler: ^SamplerState, lodMinClamp: f32, lodMaxClamp: f32, index: NS.UInteger) { + msgSend(nil, self, "setFragmentSamplerState:lodMinClamp:lodMaxClamp:atIndex:", sampler, lodMinClamp, lodMaxClamp, index) +} +@(objc_type=RenderCommandEncoder, objc_name="setFragmentSamplerStatesWithLod") +RenderCommandEncoder_setFragmentSamplerStatesWithLod :: #force_inline proc(self: ^RenderCommandEncoder, samplers: []^SamplerState, lodMinClamps, lodMaxClamps: []f32, range: NS.Range) { + msgSend(nil, self, "setFragmentSamplerStates:lodMinClamps:lodMaxClamps:withRange:", raw_data(samplers), raw_data(lodMinClamps), raw_data(lodMaxClamps), range) +} +@(objc_type=RenderCommandEncoder, objc_name="setFragmentSamplerStatesWithRange") +RenderCommandEncoder_setFragmentSamplerStatesWithRange :: #force_inline proc(self: ^RenderCommandEncoder, samplers: []^SamplerState, range: NS.Range) { + msgSend(nil, self, "setFragmentSamplerStates:withRange:", raw_data(samplers), range) +} +@(objc_type=RenderCommandEncoder, objc_name="setFragmentTexture") +RenderCommandEncoder_setFragmentTexture :: #force_inline proc(self: ^RenderCommandEncoder, texture: ^Texture, index: NS.UInteger) { + msgSend(nil, self, "setFragmentTexture:atIndex:", texture, index) +} +@(objc_type=RenderCommandEncoder, objc_name="setFragmentTextures") +RenderCommandEncoder_setFragmentTextures :: #force_inline proc(self: ^RenderCommandEncoder, textures: []^Texture, range: NS.Range) { + msgSend(nil, self, "setFragmentTextures:withRange:", raw_data(textures), range) +} +@(objc_type=RenderCommandEncoder, objc_name="setFrontFacingWinding") +RenderCommandEncoder_setFrontFacingWinding :: #force_inline proc(self: ^RenderCommandEncoder, frontFacingWinding: Winding) { + msgSend(nil, self, "setFrontFacingWinding:", frontFacingWinding) +} +@(objc_type=RenderCommandEncoder, objc_name="setRenderPipelineState") +RenderCommandEncoder_setRenderPipelineState :: #force_inline proc(self: ^RenderCommandEncoder, pipelineState: ^RenderPipelineState) { + msgSend(nil, self, "setRenderPipelineState:", pipelineState) +} +@(objc_type=RenderCommandEncoder, objc_name="setScissorRect") +RenderCommandEncoder_setScissorRect :: #force_inline proc(self: ^RenderCommandEncoder, rect: ScissorRect) { + msgSend(nil, self, "setScissorRect:", rect) +} +@(objc_type=RenderCommandEncoder, objc_name="setScissorRects") +RenderCommandEncoder_setScissorRects :: #force_inline proc(self: ^RenderCommandEncoder, scissorRects: []ScissorRect) { + msgSend(nil, self, "setScissorRects:count:", raw_data(scissorRects), NS.UInteger(len(scissorRects))) +} +@(objc_type=RenderCommandEncoder, objc_name="setStencilFrontReferenceValue") +RenderCommandEncoder_setStencilFrontReferenceValue :: #force_inline proc(self: ^RenderCommandEncoder, frontReferenceValue: u32, backReferenceValue: u32) { + msgSend(nil, self, "setStencilFrontReferenceValue:backReferenceValue:", frontReferenceValue, backReferenceValue) +} +@(objc_type=RenderCommandEncoder, objc_name="setStencilReferenceValue") +RenderCommandEncoder_setStencilReferenceValue :: #force_inline proc(self: ^RenderCommandEncoder, referenceValue: u32) { + msgSend(nil, self, "setStencilReferenceValue:", referenceValue) +} +@(objc_type=RenderCommandEncoder, objc_name="setStencilStoreAction") +RenderCommandEncoder_setStencilStoreAction :: #force_inline proc(self: ^RenderCommandEncoder, storeAction: StoreAction) { + msgSend(nil, self, "setStencilStoreAction:", storeAction) +} +@(objc_type=RenderCommandEncoder, objc_name="setStencilStoreActionOptions") +RenderCommandEncoder_setStencilStoreActionOptions :: #force_inline proc(self: ^RenderCommandEncoder, storeActionOptions: StoreActionOptions) { + msgSend(nil, self, "setStencilStoreActionOptions:", storeActionOptions) +} +@(objc_type=RenderCommandEncoder, objc_name="setTessellationFactorBuffer") +RenderCommandEncoder_setTessellationFactorBuffer :: #force_inline proc(self: ^RenderCommandEncoder, buffer: ^Buffer, offset: NS.UInteger, instanceStride: NS.UInteger) { + msgSend(nil, self, "setTessellationFactorBuffer:offset:instanceStride:", buffer, offset, instanceStride) +} +@(objc_type=RenderCommandEncoder, objc_name="setTessellationFactorScale") +RenderCommandEncoder_setTessellationFactorScale :: #force_inline proc(self: ^RenderCommandEncoder, scale: f32) { + msgSend(nil, self, "setTessellationFactorScale:", scale) +} +@(objc_type=RenderCommandEncoder, objc_name="setThreadgroupMemoryLength") +RenderCommandEncoder_setThreadgroupMemoryLength :: #force_inline proc(self: ^RenderCommandEncoder, length: NS.UInteger, offset: NS.UInteger, index: NS.UInteger) { + msgSend(nil, self, "setThreadgroupMemoryLength:offset:atIndex:", length, offset, index) +} +@(objc_type=RenderCommandEncoder, objc_name="setTileBuffer") +RenderCommandEncoder_setTileBuffer :: #force_inline proc(self: ^RenderCommandEncoder, buffer: ^Buffer, offset: NS.UInteger, index: NS.UInteger) { + msgSend(nil, self, "setTileBuffer:offset:atIndex:", buffer, offset, index) +} +@(objc_type=RenderCommandEncoder, objc_name="setTileBufferOffset") +RenderCommandEncoder_setTileBufferOffset :: #force_inline proc(self: ^RenderCommandEncoder, offset: NS.UInteger, index: NS.UInteger) { + msgSend(nil, self, "setTileBufferOffset:atIndex:", offset, index) +} +@(objc_type=RenderCommandEncoder, objc_name="setTileBuffers") +RenderCommandEncoder_setTileBuffers :: #force_inline proc(self: ^RenderCommandEncoder, buffers: []^Buffer, offsets: []NS.UInteger, range: NS.Range) { + msgSend(nil, self, "setTileBuffers:offsets:withRange:", raw_data(buffers), raw_data(offsets), range) +} +@(objc_type=RenderCommandEncoder, objc_name="setTileBytes") +RenderCommandEncoder_setTileBytes :: #force_inline proc(self: ^RenderCommandEncoder, bytes: []byte, index: NS.UInteger) { + msgSend(nil, self, "setTileBytes:length:atIndex:", raw_data(bytes), NS.UInteger(len(bytes)), index) +} +@(objc_type=RenderCommandEncoder, objc_name="setTileSamplerState") +RenderCommandEncoder_setTileSamplerState :: #force_inline proc(self: ^RenderCommandEncoder, sampler: ^SamplerState, index: NS.UInteger) { + msgSend(nil, self, "setTileSamplerState:atIndex:", sampler, index) +} +@(objc_type=RenderCommandEncoder, objc_name="setTileSamplerStateWithLod") +RenderCommandEncoder_setTileSamplerStateWithLod :: #force_inline proc(self: ^RenderCommandEncoder, sampler: ^SamplerState, lodMinClamp: f32, lodMaxClamp: f32, index: NS.UInteger) { + msgSend(nil, self, "setTileSamplerState:lodMinClamp:lodMaxClamp:atIndex:", sampler, lodMinClamp, lodMaxClamp, index) +} +@(objc_type=RenderCommandEncoder, objc_name="setTileSamplerStatesWithLod") +RenderCommandEncoder_setTileSamplerStatesWithLod :: #force_inline proc(self: ^RenderCommandEncoder, samplers: []^SamplerState, lodMinClamps, lodMaxClamps: []f32, range: NS.Range) { + msgSend(nil, self, "setTileSamplerStates:lodMinClamps:lodMaxClamps:withRange:", raw_data(samplers), raw_data(lodMinClamps), raw_data(lodMaxClamps), range) +} +@(objc_type=RenderCommandEncoder, objc_name="setTileSamplerStatesWithRange") +RenderCommandEncoder_setTileSamplerStatesWithRange :: #force_inline proc(self: ^RenderCommandEncoder, samplers: []^SamplerState, range: NS.Range) { + msgSend(nil, self, "setTileSamplerStates:withRange:", raw_data(samplers), range) +} +@(objc_type=RenderCommandEncoder, objc_name="setTileTexture") +RenderCommandEncoder_setTileTexture :: #force_inline proc(self: ^RenderCommandEncoder, texture: ^Texture, index: NS.UInteger) { + msgSend(nil, self, "setTileTexture:atIndex:", texture, index) +} +@(objc_type=RenderCommandEncoder, objc_name="setTileTextures") +RenderCommandEncoder_setTileTextures :: #force_inline proc(self: ^RenderCommandEncoder, textures: []^Texture, range: NS.Range) { + msgSend(nil, self, "setTileTextures:withRange:", raw_data(textures), range) +} +@(objc_type=RenderCommandEncoder, objc_name="setTriangleFillMode") +RenderCommandEncoder_setTriangleFillMode :: #force_inline proc(self: ^RenderCommandEncoder, fillMode: TriangleFillMode) { + msgSend(nil, self, "setTriangleFillMode:", fillMode) +} +@(objc_type=RenderCommandEncoder, objc_name="setVertexAmplificationCount") +RenderCommandEncoder_setVertexAmplificationCount :: #force_inline proc(self: ^RenderCommandEncoder, viewMappings: []VertexAmplificationViewMapping) { + msgSend(nil, self, "setVertexAmplificationCount:viewMappings:", NS.UInteger(len(viewMappings)), raw_data(viewMappings)) +} +@(objc_type=RenderCommandEncoder, objc_name="setVertexBuffer") +RenderCommandEncoder_setVertexBuffer :: #force_inline proc(self: ^RenderCommandEncoder, buffer: ^Buffer, offset: NS.UInteger, index: NS.UInteger) { + msgSend(nil, self, "setVertexBuffer:offset:atIndex:", buffer, offset, index) +} +@(objc_type=RenderCommandEncoder, objc_name="setVertexBufferOffset") +RenderCommandEncoder_setVertexBufferOffset :: #force_inline proc(self: ^RenderCommandEncoder, offset: NS.UInteger, index: NS.UInteger) { + msgSend(nil, self, "setVertexBufferOffset:atIndex:", offset, index) +} +@(objc_type=RenderCommandEncoder, objc_name="setVertexBuffers") +RenderCommandEncoder_setVertexBuffers :: #force_inline proc(self: ^RenderCommandEncoder, buffers: []^Buffer, offsets: []NS.UInteger, range: NS.Range) { + msgSend(nil, self, "setVertexBuffers:offsets:withRange:", raw_data(buffers), raw_data(offsets), range) +} +@(objc_type=RenderCommandEncoder, objc_name="setVertexBytes") +RenderCommandEncoder_setVertexBytes :: #force_inline proc(self: ^RenderCommandEncoder, bytes: []byte, index: NS.UInteger) { + msgSend(nil, self, "setVertexBytes:length:atIndex:", raw_data(bytes), NS.UInteger(len(bytes)), index) +} +@(objc_type=RenderCommandEncoder, objc_name="setVertexSamplerState") +RenderCommandEncoder_setVertexSamplerState :: #force_inline proc(self: ^RenderCommandEncoder, sampler: ^SamplerState, index: NS.UInteger) { + msgSend(nil, self, "setVertexSamplerState:atIndex:", sampler, index) +} +@(objc_type=RenderCommandEncoder, objc_name="setVertexSamplerStateWithLod") +RenderCommandEncoder_setVertexSamplerStateWithLod :: #force_inline proc(self: ^RenderCommandEncoder, sampler: ^SamplerState, lodMinClamp: f32, lodMaxClamp: f32, index: NS.UInteger) { + msgSend(nil, self, "setVertexSamplerState:lodMinClamp:lodMaxClamp:atIndex:", sampler, lodMinClamp, lodMaxClamp, index) +} +@(objc_type=RenderCommandEncoder, objc_name="setVertexSamplerStatesWithLod") +RenderCommandEncoder_setVertexSamplerStatesWithLod :: #force_inline proc(self: ^RenderCommandEncoder, samplers: []^SamplerState, lodMinClamps, lodMaxClamps: []f32, range: NS.Range) { + msgSend(nil, self, "setVertexSamplerStates:lodMinClamps:lodMaxClamps:withRange:", raw_data(samplers), raw_data(lodMinClamps), raw_data(lodMaxClamps), range) +} +@(objc_type=RenderCommandEncoder, objc_name="setVertexSamplerStatesWithRange") +RenderCommandEncoder_setVertexSamplerStatesWithRange :: #force_inline proc(self: ^RenderCommandEncoder, samplers: []^SamplerState, range: NS.Range) { + msgSend(nil, self, "setVertexSamplerStates:withRange:", raw_data(samplers), range) +} +@(objc_type=RenderCommandEncoder, objc_name="setVertexTexture") +RenderCommandEncoder_setVertexTexture :: #force_inline proc(self: ^RenderCommandEncoder, texture: ^Texture, index: NS.UInteger) { + msgSend(nil, self, "setVertexTexture:atIndex:", texture, index) +} +@(objc_type=RenderCommandEncoder, objc_name="setVertexTextures") +RenderCommandEncoder_setVertexTextures :: #force_inline proc(self: ^RenderCommandEncoder, textures: []^Texture, range: NS.Range) { + msgSend(nil, self, "setVertexTextures:withRange:", raw_data(textures), range) +} +@(objc_type=RenderCommandEncoder, objc_name="setViewport") +RenderCommandEncoder_setViewport :: #force_inline proc(self: ^RenderCommandEncoder, viewport: Viewport) { + msgSend(nil, self, "setViewport:", viewport) +} +@(objc_type=RenderCommandEncoder, objc_name="setViewports") +RenderCommandEncoder_setViewports :: #force_inline proc(self: ^RenderCommandEncoder, viewports: []Viewport) { + msgSend(nil, self, "setViewports:count:", raw_data(viewports), NS.UInteger(len(viewports))) +} +@(objc_type=RenderCommandEncoder, objc_name="setVisibilityResultMode") +RenderCommandEncoder_setVisibilityResultMode :: #force_inline proc(self: ^RenderCommandEncoder, mode: VisibilityResultMode, offset: NS.UInteger) { + msgSend(nil, self, "setVisibilityResultMode:offset:", mode, offset) +} +@(objc_type=RenderCommandEncoder, objc_name="textureBarrier") +RenderCommandEncoder_textureBarrier :: #force_inline proc(self: ^RenderCommandEncoder) { + msgSend(nil, self, "textureBarrier") +} +@(objc_type=RenderCommandEncoder, objc_name="tileHeight") +RenderCommandEncoder_tileHeight :: #force_inline proc(self: ^RenderCommandEncoder) -> NS.UInteger { + return msgSend(NS.UInteger, self, "tileHeight") +} +@(objc_type=RenderCommandEncoder, objc_name="tileWidth") +RenderCommandEncoder_tileWidth :: #force_inline proc(self: ^RenderCommandEncoder) -> NS.UInteger { + return msgSend(NS.UInteger, self, "tileWidth") +} +@(objc_type=RenderCommandEncoder, objc_name="updateFence") +RenderCommandEncoder_updateFence :: #force_inline proc(self: ^RenderCommandEncoder, fence: ^Fence, stages: RenderStages) { + msgSend(nil, self, "updateFence:afterStages:", fence, stages) +} +@(objc_type=RenderCommandEncoder, objc_name="useHeap") +RenderCommandEncoder_useHeap :: #force_inline proc(self: ^RenderCommandEncoder, heap: ^Heap) { + msgSend(nil, self, "useHeap:", heap) +} +@(objc_type=RenderCommandEncoder, objc_name="useHeapWithStages") +RenderCommandEncoder_useHeapWithStages :: #force_inline proc(self: ^RenderCommandEncoder, heap: ^Heap, stages: RenderStages) { + msgSend(nil, self, "useHeap:stages:", heap, stages) +} +@(objc_type=RenderCommandEncoder, objc_name="useHeaps") +RenderCommandEncoder_useHeaps :: #force_inline proc(self: ^RenderCommandEncoder, heaps: []^Heap) { + msgSend(nil, self, "useHeaps:count:", raw_data(heaps), NS.UInteger(len(heaps))) +} +@(objc_type=RenderCommandEncoder, objc_name="useHeapsWithStages") +RenderCommandEncoder_useHeapsWithStages :: #force_inline proc(self: ^RenderCommandEncoder, heaps: []^Heap, stages: RenderStages) { + msgSend(nil, self, "useHeaps:count:stages:", raw_data(heaps), NS.UInteger(len(heaps)), stages) +} +@(objc_type=RenderCommandEncoder, objc_name="useResource") +RenderCommandEncoder_useResource :: #force_inline proc(self: ^RenderCommandEncoder, resource: ^Resource, usage: ResourceUsage) { + msgSend(nil, self, "useResource:usage:", resource, usage) +} +@(objc_type=RenderCommandEncoder, objc_name="useResourceWithStages") +RenderCommandEncoder_useResourceWithStages :: #force_inline proc(self: ^RenderCommandEncoder, resource: ^Resource, usage: ResourceUsage, stages: RenderStages) { + msgSend(nil, self, "useResource:usage:stages:", resource, usage, stages) +} +@(objc_type=RenderCommandEncoder, objc_name="useResources") +RenderCommandEncoder_useResources :: #force_inline proc(self: ^RenderCommandEncoder, resources: []^Resource, usage: ResourceUsage) { + msgSend(nil, self, "useResources:count:usage:", raw_data(resources), NS.UInteger(len(resources)), usage) +} +@(objc_type=RenderCommandEncoder, objc_name="useResourcesStages") +RenderCommandEncoder_useResourcesStages :: #force_inline proc(self: ^RenderCommandEncoder, resources: []^Resource, usage: ResourceUsage, stages: RenderStages) { + msgSend(nil, self, "useResources:count:usage:stages:", raw_data(resources), NS.UInteger(len(resources)), usage, stages) +} +@(objc_type=RenderCommandEncoder, objc_name="waitForFence") +RenderCommandEncoder_waitForFence :: #force_inline proc(self: ^RenderCommandEncoder, fence: ^Fence, stages: RenderStages) { + msgSend(nil, self, "waitForFence:beforeStages:", fence, stages) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + RenderPipelineFunctionsDescriptor +*/ +@(objc_class="MTLRenderPipelineFunctionsDescriptor") +RenderPipelineFunctionsDescriptor :: struct { using _: NS.Copying(RenderPipelineFunctionsDescriptor) } + +@(objc_type=RenderPipelineFunctionsDescriptor, objc_name="alloc", objc_is_class_method=true) +RenderPipelineFunctionsDescriptor_alloc :: #force_inline proc() -> ^RenderPipelineFunctionsDescriptor { + return msgSend(^RenderPipelineFunctionsDescriptor, RenderPipelineFunctionsDescriptor, "alloc") +} + +@(objc_type=RenderPipelineFunctionsDescriptor, objc_name="init") +RenderPipelineFunctionsDescriptor_init :: #force_inline proc(self: ^RenderPipelineFunctionsDescriptor) -> ^RenderPipelineFunctionsDescriptor { + return msgSend(^RenderPipelineFunctionsDescriptor, self, "init") +} + +@(objc_type=RenderPipelineFunctionsDescriptor, objc_name="vertexAdditionalBinaryFunctions") +RenderPipelineFunctionsDescriptor_vertexAdditionalBinaryFunctions :: #force_inline proc(self: ^RenderPipelineFunctionsDescriptor) -> ^NS.Array { + return msgSend(^NS.Array, self, "vertexAdditionalBinaryFunctions") +} +@(objc_type=RenderPipelineFunctionsDescriptor, objc_name="fragmentAdditionalBinaryFunctions") +RenderPipelineFunctionsDescriptor_fragmentAdditionalBinaryFunctions :: #force_inline proc(self: ^RenderPipelineFunctionsDescriptor) -> ^NS.Array { + return msgSend(^NS.Array, self, "fragmentAdditionalBinaryFunctions") +} +@(objc_type=RenderPipelineFunctionsDescriptor, objc_name="tileAdditionalBinaryFunctions") +RenderPipelineFunctionsDescriptor_tileAdditionalBinaryFunctions :: #force_inline proc(self: ^RenderPipelineFunctionsDescriptor) -> ^NS.Array { + return msgSend(^NS.Array, self, "tileAdditionalBinaryFunctions") +} + +@(objc_type=RenderPipelineFunctionsDescriptor, objc_name="setVertexAdditionalBinaryFunctions") +RenderPipelineFunctionsDescriptor_setVertexAdditionalBinaryFunctions :: #force_inline proc(self: ^RenderPipelineFunctionsDescriptor, binaryFunctions: ^NS.Array) { + msgSend(nil, self, "setVertexAdditionalBinaryFunctions:", binaryFunctions) +} +@(objc_type=RenderPipelineFunctionsDescriptor, objc_name="setFragmentAdditionalBinaryFunctions") +RenderPipelineFunctionsDescriptor_setFragmentAdditionalBinaryFunctions :: #force_inline proc(self: ^RenderPipelineFunctionsDescriptor, binaryFunctions: ^NS.Array) { + msgSend(nil, self, "setFragmentAdditionalBinaryFunctions:", binaryFunctions) +} +@(objc_type=RenderPipelineFunctionsDescriptor, objc_name="setTileAdditionalBinaryFunctions") +RenderPipelineFunctionsDescriptor_setTileAdditionalBinaryFunctions :: #force_inline proc(self: ^RenderPipelineFunctionsDescriptor, binaryFunctions: ^NS.Array) { + msgSend(nil, self, "tileAdditionalBinaryFunctions:", binaryFunctions) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + RenderPipelineState +Class Methods: +Methods: + device + imageblockMemoryLengthForDimensions + imageblockSampleLength + label + maxTotalThreadsPerThreadgroup + supportIndirectCommandBuffers + threadgroupSizeMatchesTileSize +*/ +@(objc_class="MTLRenderPipelineState") +RenderPipelineState :: struct { using _: NS.Object } + +@(objc_type=RenderPipelineState, objc_name="device") +RenderPipelineState_device :: #force_inline proc(self: ^RenderPipelineState) -> ^Device { + return msgSend(^Device, self, "device") +} +@(objc_type=RenderPipelineState, objc_name="imageblockMemoryLengthForDimensions") +RenderPipelineState_imageblockMemoryLengthForDimensions :: #force_inline proc(self: ^RenderPipelineState, imageblockDimensions: Size) -> NS.UInteger { + return msgSend(NS.UInteger, self, "imageblockMemoryLengthForDimensions:", imageblockDimensions) +} +@(objc_type=RenderPipelineState, objc_name="imageblockSampleLength") +RenderPipelineState_imageblockSampleLength :: #force_inline proc(self: ^RenderPipelineState) -> NS.UInteger { + return msgSend(NS.UInteger, self, "imageblockSampleLength") +} +@(objc_type=RenderPipelineState, objc_name="label") +RenderPipelineState_label :: #force_inline proc(self: ^RenderPipelineState) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=RenderPipelineState, objc_name="maxTotalThreadsPerThreadgroup") +RenderPipelineState_maxTotalThreadsPerThreadgroup :: #force_inline proc(self: ^RenderPipelineState) -> NS.UInteger { + return msgSend(NS.UInteger, self, "maxTotalThreadsPerThreadgroup") +} +@(objc_type=RenderPipelineState, objc_name="supportIndirectCommandBuffers") +RenderPipelineState_supportIndirectCommandBuffers :: #force_inline proc(self: ^RenderPipelineState) -> BOOL { + return msgSend(BOOL, self, "supportIndirectCommandBuffers") +} +@(objc_type=RenderPipelineState, objc_name="threadgroupSizeMatchesTileSize") +RenderPipelineState_threadgroupSizeMatchesTileSize :: #force_inline proc(self: ^RenderPipelineState) -> BOOL { + return msgSend(BOOL, self, "threadgroupSizeMatchesTileSize") +} + +@(objc_type=RenderPipelineState, objc_name="functionHandle") +RenderPipelineState_functionHandle :: #force_inline proc(self: ^RenderPipelineState, function: ^Function, stage: RenderStages) -> ^FunctionHandle { + return msgSend(^FunctionHandle, self, "functionHandleWithFunction:stage:", function, stage) +} + +@(objc_type=RenderPipelineState, objc_name="newVisibleFunctionTable") +RenderPipelineState_newVisibleFunctionTable :: #force_inline proc(self: ^RenderPipelineState, descriptor: ^VisibleFunctionTableDescriptor, stage: RenderStages) -> ^VisibleFunctionTable { + return msgSend(^VisibleFunctionTable, self, "newVisibleFunctionTableWithDescriptor:stage:", descriptor, stage) +} + +@(objc_type=RenderPipelineState, objc_name="newIntersectionFunctionTable") +RenderPipelineState_newIntersectionFunctionTable :: #force_inline proc(self: ^RenderPipelineState, descriptor: ^IntersectionFunctionTableDescriptor, stage: RenderStages) -> ^IntersectionFunctionTable { + return msgSend(^IntersectionFunctionTable, self, "newIntersectionFunctionTable:stage:", descriptor, stage) +} + +@(objc_type=RenderPipelineState, objc_name="newRenderPipelineState") +RenderPipelineState_newRenderPipelineState :: #force_inline proc(self: ^RenderPipelineState, additionalBinaryFunctions: ^RenderPipelineFunctionsDescriptor) -> (state: ^RenderPipelineState, error: ^NS.Error) { + state = msgSend(^RenderPipelineState, self, "newRenderPipelineStateWithAdditionalBinaryFunctions:error:", additionalBinaryFunctions, &error) + return +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + Resource +Class Methods: +Methods: + allocatedSize + cpuCacheMode + device + hazardTrackingMode + heap + heapOffset + isAliasable + label + makeAliasable + resourceOptions + setLabel + setPurgeableState + storageMode +*/ +@(objc_class="MTLResource") +Resource :: struct { using _: NS.Object } + +@(objc_type=Resource, objc_name="allocatedSize") +Resource_allocatedSize :: #force_inline proc(self: ^Resource) -> NS.UInteger { + return msgSend(NS.UInteger, self, "allocatedSize") +} +@(objc_type=Resource, objc_name="cpuCacheMode") +Resource_cpuCacheMode :: #force_inline proc(self: ^Resource) -> CPUCacheMode { + return msgSend(CPUCacheMode, self, "cpuCacheMode") +} +@(objc_type=Resource, objc_name="device") +Resource_device :: #force_inline proc(self: ^Resource) -> ^Device { + return msgSend(^Device, self, "device") +} +@(objc_type=Resource, objc_name="hazardTrackingMode") +Resource_hazardTrackingMode :: #force_inline proc(self: ^Resource) -> HazardTrackingMode { + return msgSend(HazardTrackingMode, self, "hazardTrackingMode") +} +@(objc_type=Resource, objc_name="heap") +Resource_heap :: #force_inline proc(self: ^Resource) -> ^Heap { + return msgSend(^Heap, self, "heap") +} +@(objc_type=Resource, objc_name="heapOffset") +Resource_heapOffset :: #force_inline proc(self: ^Resource) -> NS.UInteger { + return msgSend(NS.UInteger, self, "heapOffset") +} +@(objc_type=Resource, objc_name="isAliasable") +Resource_isAliasable :: #force_inline proc(self: ^Resource) -> BOOL { + return msgSend(BOOL, self, "isAliasable") +} +@(objc_type=Resource, objc_name="label") +Resource_label :: #force_inline proc(self: ^Resource) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} +@(objc_type=Resource, objc_name="makeAliasable") +Resource_makeAliasable :: #force_inline proc(self: ^Resource) { + msgSend(nil, self, "makeAliasable") +} +@(objc_type=Resource, objc_name="resourceOptions") +Resource_resourceOptions :: #force_inline proc(self: ^Resource) -> ResourceOptions { + return msgSend(ResourceOptions, self, "resourceOptions") +} +@(objc_type=Resource, objc_name="setLabel") +Resource_setLabel :: #force_inline proc(self: ^Resource, label: ^NS.String) { + msgSend(nil, self, "setLabel:", label) +} +@(objc_type=Resource, objc_name="setPurgeableState") +Resource_setPurgeableState :: #force_inline proc(self: ^Resource, state: PurgeableState) -> PurgeableState { + return msgSend(PurgeableState, self, "setPurgeableState:", state) +} +@(objc_type=Resource, objc_name="storageMode") +Resource_storageMode :: #force_inline proc(self: ^Resource) -> StorageMode { + return msgSend(StorageMode, self, "storageMode") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + ResourceStateCommandEncoder +Class Methods: +Methods: + updateFence + updateTextureMapping + updateTextureMapping + updateTextureMappings + waitForFence +*/ +@(objc_class="MTLResourceStateCommandEncoder") +ResourceStateCommandEncoder :: struct { using _: CommandEncoder } + +@(objc_type=ResourceStateCommandEncoder, objc_name="updateFence") +ResourceStateCommandEncoder_updateFence :: #force_inline proc(self: ^ResourceStateCommandEncoder, fence: ^Fence) { + msgSend(nil, self, "updateFence:", fence) +} +@(objc_type=ResourceStateCommandEncoder, objc_name="updateTextureMappingIndirect") +ResourceStateCommandEncoder_updateTextureMappingIndirect :: #force_inline proc(self: ^ResourceStateCommandEncoder, texture: ^Texture, mode: SparseTextureMappingMode, indirectBuffer: ^Buffer, indirectBufferOffset: NS.UInteger) { + msgSend(nil, self, "updateTextureMapping:mode:indirectBuffer:indirectBufferOffset:", texture, mode, indirectBuffer, indirectBufferOffset) +} +@(objc_type=ResourceStateCommandEncoder, objc_name="updateTextureMapping") +ResourceStateCommandEncoder_updateTextureMapping :: #force_inline proc(self: ^ResourceStateCommandEncoder, texture: ^Texture, mode: SparseTextureMappingMode, region: Region, mipLevel: NS.UInteger, slice: NS.UInteger) { + msgSend(nil, self, "updateTextureMapping:mode:region:mipLevel:slice:", texture, mode, region, mipLevel, slice) +} +@(objc_type=ResourceStateCommandEncoder, objc_name="updateTextureMappings") +ResourceStateCommandEncoder_updateTextureMappings :: #force_inline proc(self: ^ResourceStateCommandEncoder, texture: ^Texture, mode: SparseTextureMappingMode, regions: []Region, mipLevels: []NS.UInteger, slices: NS.UInteger) { + msgSend(nil, self, "updateTextureMappings:mode:regions:mipLevels:slices:numRegions:", texture, mode, raw_data(regions), raw_data(mipLevels), slices, NS.UInteger(len(regions))) +} +@(objc_type=ResourceStateCommandEncoder, objc_name="waitForFence") +ResourceStateCommandEncoder_waitForFence :: #force_inline proc(self: ^ResourceStateCommandEncoder, fence: ^Fence) { + msgSend(nil, self, "waitForFence:", fence) +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + SamplerState +Class Methods: +Methods: + device + label +*/ +@(objc_class="MTLSamplerState") +SamplerState :: struct { using _: NS.Object } + +@(objc_type=SamplerState, objc_name="device") +SamplerState_device :: #force_inline proc(self: ^SamplerState) -> ^Device { + return msgSend(^Device, self, "device") +} +@(objc_type=SamplerState, objc_name="label") +SamplerState_label :: #force_inline proc(self: ^SamplerState) -> ^NS.String { + return msgSend(^NS.String, self, "label") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + SharedEvent +Class Methods: +Methods: + newSharedEventHandle + notifyListener + setSignaledValue + signaledValue +*/ +@(objc_class="MTLSharedEvent") +SharedEvent :: struct { using _: Event } + +@(objc_type=SharedEvent, objc_name="newSharedEventHandle") +SharedEvent_newSharedEventHandle :: #force_inline proc(self: ^SharedEvent) -> ^SharedEventHandle { + return msgSend(^SharedEventHandle, self, "newSharedEventHandle") +} +@(objc_type=SharedEvent, objc_name="notifyListener") +SharedEvent_notifyListener :: #force_inline proc(self: ^SharedEvent, listener: ^SharedEventListener, value: u64, block: SharedEventNotificationBlock) { + msgSend(nil, self, "notifyListener:atValue:block:", listener, value, block) +} +@(objc_type=SharedEvent, objc_name="setSignaledValue") +SharedEvent_setSignaledValue :: #force_inline proc(self: ^SharedEvent, signaledValue: u64) { + msgSend(nil, self, "setSignaledValue:", signaledValue) +} +@(objc_type=SharedEvent, objc_name="signaledValue") +SharedEvent_signaledValue :: #force_inline proc(self: ^SharedEvent) -> u64 { + return msgSend(u64, self, "signaledValue") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + Texture +Class Methods: +Methods: + allowGPUOptimizedContents + arrayLength + buffer + bufferBytesPerRow + bufferOffset + depth + firstMipmapInTail + getBytes + getBytes + height + iosurface + iosurfacePlane + isFramebufferOnly + isShareable + isSparse + mipmapLevelCount + newRemoteTextureViewForDevice + newSharedTextureHandle + newTextureViewWithPixelFormat + newTextureViewWithPixelFormat + newTextureViewWithPixelFormat + parentRelativeLevel + parentRelativeSlice + parentTexture + pixelFormat + remoteStorageTexture + replaceRegion + replaceRegion + rootResource + sampleCount + swizzle + tailSizeInBytes + textureType + usage + width +*/ +@(objc_class="MTLTexture") +Texture :: struct { using _: Resource } + +@(objc_type=Texture, objc_name="allowGPUOptimizedContents") +Texture_allowGPUOptimizedContents :: #force_inline proc(self: ^Texture) -> BOOL { + return msgSend(BOOL, self, "allowGPUOptimizedContents") +} +@(objc_type=Texture, objc_name="arrayLength") +Texture_arrayLength :: #force_inline proc(self: ^Texture) -> NS.UInteger { + return msgSend(NS.UInteger, self, "arrayLength") +} +@(objc_type=Texture, objc_name="buffer") +Texture_buffer :: #force_inline proc(self: ^Texture) -> ^Buffer { + return msgSend(^Buffer, self, "buffer") +} +@(objc_type=Texture, objc_name="bufferBytesPerRow") +Texture_bufferBytesPerRow :: #force_inline proc(self: ^Texture) -> NS.UInteger { + return msgSend(NS.UInteger, self, "bufferBytesPerRow") +} +@(objc_type=Texture, objc_name="bufferOffset") +Texture_bufferOffset :: #force_inline proc(self: ^Texture) -> NS.UInteger { + return msgSend(NS.UInteger, self, "bufferOffset") +} +@(objc_type=Texture, objc_name="depth") +Texture_depth :: #force_inline proc(self: ^Texture) -> NS.UInteger { + return msgSend(NS.UInteger, self, "depth") +} +@(objc_type=Texture, objc_name="firstMipmapInTail") +Texture_firstMipmapInTail :: #force_inline proc(self: ^Texture) -> NS.UInteger { + return msgSend(NS.UInteger, self, "firstMipmapInTail") +} +@(objc_type=Texture, objc_name="getBytesWithLevel") +Texture_getBytesWithLevel :: #force_inline proc(self: ^Texture, pixelBytes: rawptr, bytesPerRow: NS.UInteger, bytesPerImage: NS.UInteger, region: Region, level: NS.UInteger, slice: NS.UInteger) { + msgSend(nil, self, "getBytes:bytesPerRow:bytesPerImage:fromRegion:mipmapLevel:slice:", pixelBytes, bytesPerRow, bytesPerImage, region, level, slice) +} +@(objc_type=Texture, objc_name="getBytes") +Texture_getBytes :: #force_inline proc(self: ^Texture, pixelBytes: rawptr, bytesPerRow: NS.UInteger, region: Region, level: NS.UInteger) { + msgSend(nil, self, "getBytes:bytesPerRow:fromRegion:mipmapLevel:", pixelBytes, bytesPerRow, region, level) +} +@(objc_type=Texture, objc_name="height") +Texture_height :: #force_inline proc(self: ^Texture) -> NS.UInteger { + return msgSend(NS.UInteger, self, "height") +} +@(objc_type=Texture, objc_name="iosurface") +Texture_iosurface :: #force_inline proc(self: ^Texture) -> IOSurfaceRef { + return msgSend(IOSurfaceRef, self, "iosurface") +} +@(objc_type=Texture, objc_name="iosurfacePlane") +Texture_iosurfacePlane :: #force_inline proc(self: ^Texture) -> NS.UInteger { + return msgSend(NS.UInteger, self, "iosurfacePlane") +} +@(objc_type=Texture, objc_name="isFramebufferOnly") +Texture_isFramebufferOnly :: #force_inline proc(self: ^Texture) -> BOOL { + return msgSend(BOOL, self, "isFramebufferOnly") +} +@(objc_type=Texture, objc_name="isShareable") +Texture_isShareable :: #force_inline proc(self: ^Texture) -> BOOL { + return msgSend(BOOL, self, "isShareable") +} +@(objc_type=Texture, objc_name="isSparse") +Texture_isSparse :: #force_inline proc(self: ^Texture) -> BOOL { + return msgSend(BOOL, self, "isSparse") +} +@(objc_type=Texture, objc_name="mipmapLevelCount") +Texture_mipmapLevelCount :: #force_inline proc(self: ^Texture) -> NS.UInteger { + return msgSend(NS.UInteger, self, "mipmapLevelCount") +} +@(objc_type=Texture, objc_name="newRemoteTextureViewForDevice") +Texture_newRemoteTextureViewForDevice :: #force_inline proc(self: ^Texture, device: ^Device) -> ^Texture { + return msgSend(^Texture, self, "newRemoteTextureViewForDevice:", device) +} +@(objc_type=Texture, objc_name="newSharedTextureHandle") +Texture_newSharedTextureHandle :: #force_inline proc(self: ^Texture) -> ^SharedTextureHandle { + return msgSend(^SharedTextureHandle, self, "newSharedTextureHandle") +} +@(objc_type=Texture, objc_name="newTextureView") +Texture_newTextureView :: #force_inline proc(self: ^Texture, pixelFormat: PixelFormat) -> ^Texture { + return msgSend(^Texture, self, "newTextureViewWithPixelFormat:", pixelFormat) +} +@(objc_type=Texture, objc_name="newTextureViewWithLevels") +Texture_newTextureViewWithLevels :: #force_inline proc(self: ^Texture, pixelFormat: PixelFormat, textureType: TextureType, levelRange: NS.Range, sliceRange: NS.Range) -> ^Texture { + return msgSend(^Texture, self, "newTextureViewWithPixelFormat:textureType:levels:slices:", pixelFormat, textureType, levelRange, sliceRange) +} +@(objc_type=Texture, objc_name="newTextureViewWithLevelsAndSwizzle") +Texture_newTextureViewWithLevelsAndSwizzle :: #force_inline proc(self: ^Texture, pixelFormat: PixelFormat, textureType: TextureType, levelRange: NS.Range, sliceRange: NS.Range, swizzle: TextureSwizzleChannels) -> ^Texture { + return msgSend(^Texture, self, "newTextureViewWithPixelFormat:textureType:levels:slices:swizzle:", pixelFormat, textureType, levelRange, sliceRange, swizzle) +} +@(objc_type=Texture, objc_name="parentRelativeLevel") +Texture_parentRelativeLevel :: #force_inline proc(self: ^Texture) -> NS.UInteger { + return msgSend(NS.UInteger, self, "parentRelativeLevel") +} +@(objc_type=Texture, objc_name="parentRelativeSlice") +Texture_parentRelativeSlice :: #force_inline proc(self: ^Texture) -> NS.UInteger { + return msgSend(NS.UInteger, self, "parentRelativeSlice") +} +@(objc_type=Texture, objc_name="parentTexture") +Texture_parentTexture :: #force_inline proc(self: ^Texture) -> ^Texture { + return msgSend(^Texture, self, "parentTexture") +} +@(objc_type=Texture, objc_name="pixelFormat") +Texture_pixelFormat :: #force_inline proc(self: ^Texture) -> PixelFormat { + return msgSend(PixelFormat, self, "pixelFormat") +} +@(objc_type=Texture, objc_name="remoteStorageTexture") +Texture_remoteStorageTexture :: #force_inline proc(self: ^Texture) -> ^Texture { + return msgSend(^Texture, self, "remoteStorageTexture") +} +@(objc_type=Texture, objc_name="replaceRegionWithLevel") +Texture_replaceRegionWithLevel :: #force_inline proc(self: ^Texture, region: Region, level: NS.UInteger, slice: NS.UInteger, pixelBytes: rawptr, bytesPerRow: NS.UInteger, bytesPerImage: NS.UInteger) { + msgSend(nil, self, "replaceRegion:mipmapLevel:slice:withBytes:bytesPerRow:bytesPerImage:", region, level, slice, pixelBytes, bytesPerRow, bytesPerImage) +} +@(objc_type=Texture, objc_name="replaceRegion") +Texture_replaceRegion :: #force_inline proc(self: ^Texture, region: Region, level: NS.UInteger, pixelBytes: rawptr, bytesPerRow: NS.UInteger) { + msgSend(nil, self, "replaceRegion:mipmapLevel:withBytes:bytesPerRow:", region, level, pixelBytes, bytesPerRow) +} +@(objc_type=Texture, objc_name="rootResource") +Texture_rootResource :: #force_inline proc(self: ^Texture) -> ^Resource { + return msgSend(^Resource, self, "rootResource") +} +@(objc_type=Texture, objc_name="sampleCount") +Texture_sampleCount :: #force_inline proc(self: ^Texture) -> NS.UInteger { + return msgSend(NS.UInteger, self, "sampleCount") +} +@(objc_type=Texture, objc_name="swizzle") +Texture_swizzle :: #force_inline proc(self: ^Texture) -> TextureSwizzleChannels { + return msgSend(TextureSwizzleChannels, self, "swizzle") +} +@(objc_type=Texture, objc_name="tailSizeInBytes") +Texture_tailSizeInBytes :: #force_inline proc(self: ^Texture) -> NS.UInteger { + return msgSend(NS.UInteger, self, "tailSizeInBytes") +} +@(objc_type=Texture, objc_name="textureType") +Texture_textureType :: #force_inline proc(self: ^Texture) -> TextureType { + return msgSend(TextureType, self, "textureType") +} +@(objc_type=Texture, objc_name="usage") +Texture_usage :: #force_inline proc(self: ^Texture) -> TextureUsage { + return msgSend(TextureUsage, self, "usage") +} +@(objc_type=Texture, objc_name="width") +Texture_width :: #force_inline proc(self: ^Texture) -> NS.UInteger { + return msgSend(NS.UInteger, self, "width") +} + +//////////////////////////////////////////////////////////////////////////////// + +/* +Class: + VisibleFunctionTable +Class Methods: +Methods: + setFunction + setFunctions +*/ +@(objc_class="MTLVisibleFunctionTable") +VisibleFunctionTable :: struct { using _: Resource } + +@(objc_type=VisibleFunctionTable, objc_name="setFunction") +VisibleFunctionTable_setFunction :: #force_inline proc(self: ^VisibleFunctionTable, function: ^FunctionHandle, index: NS.UInteger) { + msgSend(nil, self, "setFunction:atIndex:", function, index) +} +@(objc_type=VisibleFunctionTable, objc_name="setFunctions") +VisibleFunctionTable_setFunctions :: #force_inline proc(self: ^VisibleFunctionTable, functions: []^FunctionHandle, range: NS.Range) { + msgSend(nil, self, "setFunctions:withRange:", raw_data(functions), range) +} + + + +// TODO: Entire FunctionStitching API (which appears not to be in been missed from the generator) + + + diff --git a/vendor/darwin/Metal/MetalEnums.odin b/vendor/darwin/Metal/MetalEnums.odin new file mode 100644 index 000000000..7d72483ff --- /dev/null +++ b/vendor/darwin/Metal/MetalEnums.odin @@ -0,0 +1,972 @@ +package objc_Metal + +import NS "vendor:darwin/Foundation" + +AccelerationStructureUsage :: distinct bit_set[AccelerationStructureUsageFlag; NS.UInteger] +AccelerationStructureUsageFlag :: enum NS.UInteger { + Refit = 0, + PreferFastBuild = 1, + ExtendedLimits = 2, +} + +AccelerationStructureInstanceOptions :: distinct bit_set[AccelerationStructureInstanceOption; u32] +AccelerationStructureInstanceOption :: enum u32 { + DisableTriangleCulling = 0, + TriangleFrontFacingWindingCounterClockwise = 1, + Opaque = 2, + NonOpaque = 3, +} + +MotionBorderMode :: enum u32 { + Clamp = 0, + Vanish = 1, +} + +AccelerationStructureInstanceDescriptorType :: enum NS.UInteger { + Default = 0, + UserID = 1, + Motion = 2, +} + + +DataType :: enum NS.UInteger { + None = 0, + Struct = 1, + Array = 2, + Float = 3, + Float2 = 4, + Float3 = 5, + Float4 = 6, + Float2x2 = 7, + Float2x3 = 8, + Float2x4 = 9, + Float3x2 = 10, + Float3x3 = 11, + Float3x4 = 12, + Float4x2 = 13, + Float4x3 = 14, + Float4x4 = 15, + Half = 16, + Half2 = 17, + Half3 = 18, + Half4 = 19, + Half2x2 = 20, + Half2x3 = 21, + Half2x4 = 22, + Half3x2 = 23, + Half3x3 = 24, + Half3x4 = 25, + Half4x2 = 26, + Half4x3 = 27, + Half4x4 = 28, + Int = 29, + Int2 = 30, + Int3 = 31, + Int4 = 32, + UInt = 33, + UInt2 = 34, + UInt3 = 35, + UInt4 = 36, + Short = 37, + Short2 = 38, + Short3 = 39, + Short4 = 40, + UShort = 41, + UShort2 = 42, + UShort3 = 43, + UShort4 = 44, + Char = 45, + Char2 = 46, + Char3 = 47, + Char4 = 48, + UChar = 49, + UChar2 = 50, + UChar3 = 51, + UChar4 = 52, + Bool = 53, + Bool2 = 54, + Bool3 = 55, + Bool4 = 56, + Texture = 58, + Sampler = 59, + Pointer = 60, + R8Unorm = 62, + R8Snorm = 63, + R16Unorm = 64, + R16Snorm = 65, + RG8Unorm = 66, + RG8Snorm = 67, + RG16Unorm = 68, + RG16Snorm = 69, + RGBA8Unorm = 70, + RGBA8Unorm_sRGB = 71, + RGBA8Snorm = 72, + RGBA16Unorm = 73, + RGBA16Snorm = 74, + RGB10A2Unorm = 75, + RG11B10Float = 76, + RGB9E5Float = 77, + RenderPipeline = 78, + ComputePipeline = 79, + IndirectCommandBuffer = 80, + Long = 81, + Long2 = 82, + Long3 = 83, + Long4 = 84, + ULong = 85, + ULong2 = 86, + ULong3 = 87, + ULong4 = 88, + VisibleFunctionTable = 115, + IntersectionFunctionTable = 116, + PrimitiveAccelerationStructure = 117, + InstanceAccelerationStructure = 118, +} + +ArgumentType :: enum NS.UInteger { + Buffer = 0, + ThreadgroupMemory = 1, + Texture = 2, + Sampler = 3, + ImageblockData = 16, + Imageblock = 17, + VisibleFunctionTable = 24, + PrimitiveAccelerationStructure = 25, + InstanceAccelerationStructure = 26, + IntersectionFunctionTable = 27, +} + +ArgumentAccess :: enum NS.UInteger { + ReadOnly = 0, + ReadWrite = 1, + WriteOnly = 2, +} + + +BinaryArchiveError :: enum NS.UInteger { + None = 0, + InvalidFile = 1, + UnexpectedElement = 2, + CompilationFailure = 3, +} + +BlitOptionFlag :: enum NS.UInteger { + DepthFromDepthStencil = 0, + StencilFromDepthStencil = 1, + RowLinearPVRTC = 2, +} +BlitOption :: distinct bit_set[BlitOptionFlag; NS.UInteger] + +CaptureError :: enum NS.Integer { + NotSupported = 1, + AlreadyCapturing = 2, + InvalidDescriptor = 3, +} + +CaptureDestination :: enum NS.Integer { + DeveloperTools = 1, + GPUTraceDocument = 2, +} + + +CommandBufferStatus :: enum NS.UInteger { + NotEnqueued = 0, + Enqueued = 1, + Committed = 2, + Scheduled = 3, + Completed = 4, + Error = 5, +} + +CommandBufferError :: enum NS.UInteger { + None = 0, + Timeout = 2, + PageFault = 3, + AccessRevoked = 4, + Blacklisted = 4, + NotPermitted = 7, + OutOfMemory = 8, + InvalidResource = 9, + Memoryless = 10, + DeviceRemoved = 11, + StackOverflow = 12, +} + +CommandBufferErrorOptionFlag :: enum NS.UInteger { + EncoderExecutionStatus = 0, +} +CommandBufferErrorOption :: distinct bit_set[CommandBufferErrorOptionFlag; NS.UInteger] + +CommandEncoderErrorState :: enum NS.Integer { + Unknown = 0, + Completed = 1, + Affected = 2, + Pending = 3, + Faulted = 4, +} + +CommandBufferHandler :: distinct rawptr + +DispatchType :: enum NS.UInteger { + Serial = 0, + Concurrent = 1, +} + +ResourceUsageFlag :: enum NS.UInteger { + Read = 0, + Write = 1, + Sample = 2, +} +ResourceUsage :: distinct bit_set[ResourceUsageFlag; NS.UInteger] + + +BarrierScopeFlag :: enum NS.UInteger { + Buffers = 0, + Textures = 1, + RenderTargets = 2, +} +BarrierScope :: distinct bit_set[BarrierScopeFlag; NS.UInteger] + + + +CounterSampleBufferError :: enum NS.Integer { + OutOfMemory = 0, + Invalid = 1, +} + +CompareFunction :: enum NS.UInteger { + Never = 0, + Less = 1, + Equal = 2, + LessEqual = 3, + Greater = 4, + NotEqual = 5, + GreaterEqual = 6, + Always = 7, +} + +StencilOperation :: enum NS.UInteger { + Keep = 0, + Zero = 1, + Replace = 2, + IncrementClamp = 3, + DecrementClamp = 4, + Invert = 5, + IncrementWrap = 6, + DecrementWrap = 7, +} + +FeatureSet :: enum NS.UInteger { + iOS_GPUFamily1_v1 = 0, + iOS_GPUFamily2_v1 = 1, + iOS_GPUFamily1_v2 = 2, + iOS_GPUFamily2_v2 = 3, + iOS_GPUFamily3_v1 = 4, + iOS_GPUFamily1_v3 = 5, + iOS_GPUFamily2_v3 = 6, + iOS_GPUFamily3_v2 = 7, + iOS_GPUFamily1_v4 = 8, + iOS_GPUFamily2_v4 = 9, + iOS_GPUFamily3_v3 = 10, + iOS_GPUFamily4_v1 = 11, + iOS_GPUFamily1_v5 = 12, + iOS_GPUFamily2_v5 = 13, + iOS_GPUFamily3_v4 = 14, + iOS_GPUFamily4_v2 = 15, + iOS_GPUFamily5_v1 = 16, + macOS_GPUFamily1_v1 = 10000, + OSX_GPUFamily1_v1 = 10000, + macOS_GPUFamily1_v2 = 10001, + OSX_GPUFamily1_v2 = 10001, + OSX_ReadWriteTextureTier2 = 10002, + macOS_ReadWriteTextureTier2 = 10002, + macOS_GPUFamily1_v3 = 10003, + macOS_GPUFamily1_v4 = 10004, + macOS_GPUFamily2_v1 = 10005, + watchOS_GPUFamily1_v1 = 20000, + WatchOS_GPUFamily1_v1 = 20000, + watchOS_GPUFamily2_v1 = 20001, + WatchOS_GPUFamily2_v1 = 20001, + tvOS_GPUFamily1_v1 = 30000, + TVOS_GPUFamily1_v1 = 30000, + tvOS_GPUFamily1_v2 = 30001, + tvOS_GPUFamily1_v3 = 30002, + tvOS_GPUFamily2_v1 = 30003, + tvOS_GPUFamily1_v4 = 30004, + tvOS_GPUFamily2_v2 = 30005, +} + +GPUFamily :: enum NS.Integer { + Apple1 = 1001, + Apple2 = 1002, + Apple3 = 1003, + Apple4 = 1004, + Apple5 = 1005, + Apple6 = 1006, + Apple7 = 1007, + Apple8 = 1008, + Mac1 = 2001, + Mac2 = 2002, + Common1 = 3001, + Common2 = 3002, + Common3 = 3003, + MacCatalyst1 = 4001, + MacCatalyst2 = 4002, +} + +DeviceLocation :: enum NS.UInteger { + BuiltIn = 0, + Slot = 1, + External = 2, + Unspecified = NS.UIntegerMax, +} + +PipelineOptionFlag :: enum NS.UInteger { + ArgumentInfo = 0, + BufferTypeInfo = 1, + FailOnBinaryArchiveMiss = 2, +} +PipelineOption :: distinct bit_set[PipelineOptionFlag; NS.UInteger] + +ReadWriteTextureTier :: enum NS.UInteger { + TierNone = 0, + Tier1 = 1, + Tier2 = 2, +} + +ArgumentBuffersTier :: enum NS.UInteger { + Tier1 = 0, + Tier2 = 1, +} + +SparseTextureRegionAlignmentMode :: enum NS.UInteger { + Outward = 0, + Inward = 1, +} + +CounterSamplingPoint :: enum NS.UInteger { + AtStageBoundary = 0, + AtDrawBoundary = 1, + AtDispatchBoundary = 2, + AtTileDispatchBoundary = 3, + AtBlitBoundary = 4, +} + +DynamicLibraryError :: enum NS.UInteger { + None = 0, + InvalidFile = 1, + CompilationFailure = 2, + UnresolvedInstallName = 3, + DependencyLoadFailure = 4, + Unsupported = 5, +} + +FunctionOption :: enum NS.UInteger { + CompileToBinary = 0, +} +FunctionOptions :: distinct bit_set[FunctionOption; NS.UInteger] + + +FunctionLogType :: enum NS.UInteger { + Validation = 0, +} + +HeapType :: enum NS.Integer { + Automatic = 0, + Placement = 1, + Sparse = 2, +} + +IndirectCommandTypeFlag :: enum NS.UInteger { + Draw = 0, + DrawIndexed = 1, + DrawPatches = 2, + DrawIndexedPatches = 3, + ConcurrentDispatch = 5, + ConcurrentDispatchThreads = 6, +} +IndirectCommandType :: distinct bit_set[IndirectCommandTypeFlag; NS.UInteger] + +IntersectionFunctionSignatureFlag :: enum NS.UInteger { + Instancing = 0, + TriangleData = 1, + WorldSpaceData = 2, + InstanceMotion = 3, + PrimitiveMotion = 4, + ExtendedLimits = 5, +} +IntersectionFunctionSignature :: distinct bit_set[IntersectionFunctionSignatureFlag; NS.UInteger] + +PatchType :: enum NS.UInteger { + None = 0, + Triangle = 1, + Quad = 2, +} + +FunctionType :: enum NS.UInteger { + Vertex = 1, + Fragment = 2, + Kernel = 3, + Visible = 5, + Intersection = 6, +} + + +LanguageVersion :: enum NS.UInteger { + Version1_0 = 65536, + Version1_1 = 65537, + Version1_2 = 65538, + Version2_0 = 131072, + Version2_1 = 131073, + Version2_2 = 131074, + Version2_3 = 131075, + Version2_4 = 131076, +} + +LibraryType :: enum NS.Integer { + Executable = 0, + Dynamic = 1, +} + +LibraryError :: enum NS.UInteger { + Unsupported = 1, + CompileFailure = 3, + CompileWarning = 4, + FunctionNotFound = 5, + FileNotFound = 6, +} + +Mutability :: enum NS.UInteger { + Default = 0, + Mutable = 1, + Immutable = 2, +} + +PixelFormat :: enum NS.UInteger { + Invalid = 0, + A8Unorm = 1, + R8Unorm = 10, + R8Unorm_sRGB = 11, + R8Snorm = 12, + R8Uint = 13, + R8Sint = 14, + R16Unorm = 20, + R16Snorm = 22, + R16Uint = 23, + R16Sint = 24, + R16Float = 25, + RG8Unorm = 30, + RG8Unorm_sRGB = 31, + RG8Snorm = 32, + RG8Uint = 33, + RG8Sint = 34, + B5G6R5Unorm = 40, + A1BGR5Unorm = 41, + ABGR4Unorm = 42, + BGR5A1Unorm = 43, + R32Uint = 53, + R32Sint = 54, + R32Float = 55, + RG16Unorm = 60, + RG16Snorm = 62, + RG16Uint = 63, + RG16Sint = 64, + RG16Float = 65, + RGBA8Unorm = 70, + RGBA8Unorm_sRGB = 71, + RGBA8Snorm = 72, + RGBA8Uint = 73, + RGBA8Sint = 74, + BGRA8Unorm = 80, + BGRA8Unorm_sRGB = 81, + RGB10A2Unorm = 90, + RGB10A2Uint = 91, + RG11B10Float = 92, + RGB9E5Float = 93, + BGR10A2Unorm = 94, + RG32Uint = 103, + RG32Sint = 104, + RG32Float = 105, + RGBA16Unorm = 110, + RGBA16Snorm = 112, + RGBA16Uint = 113, + RGBA16Sint = 114, + RGBA16Float = 115, + RGBA32Uint = 123, + RGBA32Sint = 124, + RGBA32Float = 125, + BC1_RGBA = 130, + BC1_RGBA_sRGB = 131, + BC2_RGBA = 132, + BC2_RGBA_sRGB = 133, + BC3_RGBA = 134, + BC3_RGBA_sRGB = 135, + BC4_RUnorm = 140, + BC4_RSnorm = 141, + BC5_RGUnorm = 142, + BC5_RGSnorm = 143, + BC6H_RGBFloat = 150, + BC6H_RGBUfloat = 151, + BC7_RGBAUnorm = 152, + BC7_RGBAUnorm_sRGB = 153, + PVRTC_RGB_2BPP = 160, + PVRTC_RGB_2BPP_sRGB = 161, + PVRTC_RGB_4BPP = 162, + PVRTC_RGB_4BPP_sRGB = 163, + PVRTC_RGBA_2BPP = 164, + PVRTC_RGBA_2BPP_sRGB = 165, + PVRTC_RGBA_4BPP = 166, + PVRTC_RGBA_4BPP_sRGB = 167, + EAC_R11Unorm = 170, + EAC_R11Snorm = 172, + EAC_RG11Unorm = 174, + EAC_RG11Snorm = 176, + EAC_RGBA8 = 178, + EAC_RGBA8_sRGB = 179, + ETC2_RGB8 = 180, + ETC2_RGB8_sRGB = 181, + ETC2_RGB8A1 = 182, + ETC2_RGB8A1_sRGB = 183, + ASTC_4x4_sRGB = 186, + ASTC_5x4_sRGB = 187, + ASTC_5x5_sRGB = 188, + ASTC_6x5_sRGB = 189, + ASTC_6x6_sRGB = 190, + ASTC_8x5_sRGB = 192, + ASTC_8x6_sRGB = 193, + ASTC_8x8_sRGB = 194, + ASTC_10x5_sRGB = 195, + ASTC_10x6_sRGB = 196, + ASTC_10x8_sRGB = 197, + ASTC_10x10_sRGB = 198, + ASTC_12x10_sRGB = 199, + ASTC_12x12_sRGB = 200, + ASTC_4x4_LDR = 204, + ASTC_5x4_LDR = 205, + ASTC_5x5_LDR = 206, + ASTC_6x5_LDR = 207, + ASTC_6x6_LDR = 208, + ASTC_8x5_LDR = 210, + ASTC_8x6_LDR = 211, + ASTC_8x8_LDR = 212, + ASTC_10x5_LDR = 213, + ASTC_10x6_LDR = 214, + ASTC_10x8_LDR = 215, + ASTC_10x10_LDR = 216, + ASTC_12x10_LDR = 217, + ASTC_12x12_LDR = 218, + ASTC_4x4_HDR = 222, + ASTC_5x4_HDR = 223, + ASTC_5x5_HDR = 224, + ASTC_6x5_HDR = 225, + ASTC_6x6_HDR = 226, + ASTC_8x5_HDR = 228, + ASTC_8x6_HDR = 229, + ASTC_8x8_HDR = 230, + ASTC_10x5_HDR = 231, + ASTC_10x6_HDR = 232, + ASTC_10x8_HDR = 233, + ASTC_10x10_HDR = 234, + ASTC_12x10_HDR = 235, + ASTC_12x12_HDR = 236, + GBGR422 = 240, + BGRG422 = 241, + Depth16Unorm = 250, + Depth32Float = 252, + Stencil8 = 253, + Depth24Unorm_Stencil8 = 255, + Depth32Float_Stencil8 = 260, + X32_Stencil8 = 261, + X24_Stencil8 = 262, + BGRA10_XR = 552, + BGRA10_XR_sRGB = 553, + BGR10_XR = 554, + BGR10_XR_sRGB = 555, +} + + +PrimitiveType :: enum NS.UInteger { + Point = 0, + Line = 1, + LineStrip = 2, + Triangle = 3, + TriangleStrip = 4, +} + +VisibilityResultMode :: enum NS.UInteger { + Disabled = 0, + Boolean = 1, + Counting = 2, +} + +CullMode :: enum NS.UInteger { + None = 0, + Front = 1, + Back = 2, +} + +Winding :: enum NS.UInteger { + Clockwise = 0, + CounterClockwise = 1, +} + +DepthClipMode :: enum NS.UInteger { + Clip = 0, + Clamp = 1, +} + +TriangleFillMode :: enum NS.UInteger { + Fill = 0, + Lines = 1, +} + +RenderStage :: enum NS.UInteger { + Vertex = 0, + Fragment = 1, + Tile = 2, +} +RenderStages :: distinct bit_set[RenderStage; NS.UInteger] + + +LoadAction :: enum NS.UInteger { + DontCare = 0, + Load = 1, + Clear = 2, +} + +StoreAction :: enum NS.UInteger { + DontCare = 0, + Store = 1, + MultisampleResolve = 2, + StoreAndMultisampleResolve = 3, + Unknown = 4, + CustomSampleDepthStore = 5, +} + +StoreActionOption :: enum NS.UInteger { + CustomSamplePositions = 1, +} +StoreActionOptions :: distinct bit_set[StoreActionOption; NS.UInteger] + +MultisampleDepthResolveFilter :: enum NS.UInteger { + Sample0 = 0, + Min = 1, + Max = 2, +} + +MultisampleStencilResolveFilter :: enum NS.UInteger { + Sample0 = 0, + DepthResolvedSample = 1, +} + +BlendFactor :: enum NS.UInteger { + Zero = 0, + One = 1, + SourceColor = 2, + OneMinusSourceColor = 3, + SourceAlpha = 4, + OneMinusSourceAlpha = 5, + DestinationColor = 6, + OneMinusDestinationColor = 7, + DestinationAlpha = 8, + OneMinusDestinationAlpha = 9, + SourceAlphaSaturated = 10, + BlendColor = 11, + OneMinusBlendColor = 12, + BlendAlpha = 13, + OneMinusBlendAlpha = 14, + Source1Color = 15, + OneMinusSource1Color = 16, + Source1Alpha = 17, + OneMinusSource1Alpha = 18, +} + +BlendOperation :: enum NS.UInteger { + Add = 0, + Subtract = 1, + ReverseSubtract = 2, + Min = 3, + Max = 4, +} + +ColorWriteMaskFlag :: enum NS.UInteger { + Alpha = 0, + Blue = 1, + Green = 2, + Red = 3, +} +ColorWriteMask :: distinct bit_set[ColorWriteMaskFlag; NS.UInteger] +ColorWriteMaskAll :: ColorWriteMask{.Alpha, .Blue, .Green, .Red} + +PrimitiveTopologyClass :: enum NS.UInteger { + Unspecified = 0, + Point = 1, + Line = 2, + Triangle = 3, +} + +TessellationPartitionMode :: enum NS.UInteger { + Pow2 = 0, + Integer = 1, + FractionalOdd = 2, + FractionalEven = 3, +} + +TessellationFactorStepFunction :: enum NS.UInteger { + Constant = 0, + PerPatch = 1, + PerInstance = 2, + PerPatchAndPerInstance = 3, +} + +TessellationFactorFormat :: enum NS.UInteger { + Half = 0, +} + +TessellationControlPointIndexType :: enum NS.UInteger { + None = 0, + UInt16 = 1, + UInt32 = 2, +} + +PurgeableState :: enum NS.UInteger { + KeepCurrent = 1, + NonVolatile = 2, + Volatile = 3, + Empty = 4, +} + +CPUCacheMode :: enum NS.UInteger { + DefaultCache = 0, + WriteCombined = 1, +} + +StorageMode :: enum NS.UInteger { + Shared = 0, + Managed = 1, + Private = 2, + Memoryless = 3, +} + +HazardTrackingMode :: enum NS.UInteger { + Default = 0, + Untracked = 1, + Tracked = 2, +} + +ResourceOption :: enum NS.UInteger { + CPUCacheModeWriteCombined = 0, + StorageModeManaged = 4, + StorageModePrivate = 5, + HazardTrackingModeUntracked = 8, + HazardTrackingModeTracked = 9, +} +ResourceOptions :: distinct bit_set[ResourceOption; NS.UInteger] + +ResourceStorageModeShared :: ResourceOptions{} +ResourceHazardTrackingModeDefault :: ResourceOptions{} +ResourceCPUCacheModeDefaultCache :: ResourceOptions{} +ResourceOptionCPUCacheModeDefault :: ResourceOptions{} +ResourceStorageModeMemoryless :: ResourceOptions{.StorageModeManaged, .StorageModePrivate} + +SparseTextureMappingMode :: enum NS.UInteger { + Map = 0, + Unmap = 1, +} + +SamplerMinMagFilter :: enum NS.UInteger { + Nearest = 0, + Linear = 1, +} + +SamplerMipFilter :: enum NS.UInteger { + NotMipmapped = 0, + Nearest = 1, + Linear = 2, +} + +SamplerAddressMode :: enum NS.UInteger { + ClampToEdge = 0, + MirrorClampToEdge = 1, + Repeat = 2, + MirrorRepeat = 3, + ClampToZero = 4, + ClampToBorderColor = 5, +} + +SamplerBorderColor :: enum NS.UInteger { + TransparentBlack = 0, + OpaqueBlack = 1, + OpaqueWhite = 2, +} + + +AttributeFormat :: enum NS.UInteger { + Invalid = 0, + UChar2 = 1, + UChar3 = 2, + UChar4 = 3, + Char2 = 4, + Char3 = 5, + Char4 = 6, + UChar2Normalized = 7, + UChar3Normalized = 8, + UChar4Normalized = 9, + Char2Normalized = 10, + Char3Normalized = 11, + Char4Normalized = 12, + UShort2 = 13, + UShort3 = 14, + UShort4 = 15, + Short2 = 16, + Short3 = 17, + Short4 = 18, + UShort2Normalized = 19, + UShort3Normalized = 20, + UShort4Normalized = 21, + Short2Normalized = 22, + Short3Normalized = 23, + Short4Normalized = 24, + Half2 = 25, + Half3 = 26, + Half4 = 27, + Float = 28, + Float2 = 29, + Float3 = 30, + Float4 = 31, + Int = 32, + Int2 = 33, + Int3 = 34, + Int4 = 35, + UInt = 36, + UInt2 = 37, + UInt3 = 38, + UInt4 = 39, + Int1010102Normalized = 40, + UInt1010102Normalized = 41, + UChar4Normalized_BGRA = 42, + UChar = 45, + Char = 46, + UCharNormalized = 47, + CharNormalized = 48, + UShort = 49, + Short = 50, + UShortNormalized = 51, + ShortNormalized = 52, + Half = 53, +} + +IndexType :: enum NS.UInteger { + UInt16 = 0, + UInt32 = 1, +} + +StepFunction :: enum NS.UInteger { + Constant = 0, + PerVertex = 1, + PerInstance = 2, + PerPatch = 3, + PerPatchControlPoint = 4, + ThreadPositionInGridX = 5, + ThreadPositionInGridY = 6, + ThreadPositionInGridXIndexed = 7, + ThreadPositionInGridYIndexed = 8, +} + +TextureType :: enum NS.UInteger { + Type1D = 0, + Type1DArray = 1, + Type2D = 2, + Type2DArray = 3, + Type2DMultisample = 4, + TypeCube = 5, + TypeCubeArray = 6, + Type3D = 7, + Type2DMultisampleArray = 8, + TypeTextureBuffer = 9, +} + +TextureSwizzle :: enum u8 { + Zero = 0, + One = 1, + Red = 2, + Green = 3, + Blue = 4, + Alpha = 5, +} + +TextureUsageFlag :: enum NS.UInteger { + ShaderRead = 0, + ShaderWrite = 1, + RenderTarget = 2, + PixelFormatView = 4, +} +TextureUsage :: distinct bit_set[TextureUsageFlag; NS.UInteger] + +TextureCompressionType :: enum NS.Integer { + Lossless = 0, + Lossy = 1, +} + +VertexFormat :: enum NS.UInteger { + Invalid = 0, + UChar2 = 1, + UChar3 = 2, + UChar4 = 3, + Char2 = 4, + Char3 = 5, + Char4 = 6, + UChar2Normalized = 7, + UChar3Normalized = 8, + UChar4Normalized = 9, + Char2Normalized = 10, + Char3Normalized = 11, + Char4Normalized = 12, + UShort2 = 13, + UShort3 = 14, + UShort4 = 15, + Short2 = 16, + Short3 = 17, + Short4 = 18, + UShort2Normalized = 19, + UShort3Normalized = 20, + UShort4Normalized = 21, + Short2Normalized = 22, + Short3Normalized = 23, + Short4Normalized = 24, + Half2 = 25, + Half3 = 26, + Half4 = 27, + Float = 28, + Float2 = 29, + Float3 = 30, + Float4 = 31, + Int = 32, + Int2 = 33, + Int3 = 34, + Int4 = 35, + UInt = 36, + UInt2 = 37, + UInt3 = 38, + UInt4 = 39, + Int1010102Normalized = 40, + UInt1010102Normalized = 41, + UChar4Normalized_BGRA = 42, + UChar = 45, + Char = 46, + UCharNormalized = 47, + CharNormalized = 48, + UShort = 49, + Short = 50, + UShortNormalized = 51, + ShortNormalized = 52, + Half = 53, +} + +VertexStepFunction :: enum NS.UInteger { + Constant = 0, + PerVertex = 1, + PerInstance = 2, + PerPatch = 3, + PerPatchControlPoint = 4, +} diff --git a/vendor/darwin/Metal/MetalErrors.odin b/vendor/darwin/Metal/MetalErrors.odin new file mode 100644 index 000000000..f214466e5 --- /dev/null +++ b/vendor/darwin/Metal/MetalErrors.odin @@ -0,0 +1,39 @@ +package objc_Metal + +import NS "vendor:darwin/Foundation" + +foreign import "system:Metal.framework" + +CommonCounter :: ^NS.String +CommonCounterSet :: ^NS.String +DeviceNotificationName :: ^NS.String + +foreign Metal { + @(linkage="weak") CommonCounterTimestamp: CommonCounter + @(linkage="weak") CommonCounterTessellationInputPatches: CommonCounter + @(linkage="weak") CommonCounterVertexInvocations: CommonCounter + @(linkage="weak") CommonCounterPostTessellationVertexInvocations: CommonCounter + @(linkage="weak") CommonCounterClipperInvocations: CommonCounter + @(linkage="weak") CommonCounterClipperPrimitivesOut: CommonCounter + @(linkage="weak") CommonCounterFragmentInvocations: CommonCounter + @(linkage="weak") CommonCounterFragmentsPassed: CommonCounter + @(linkage="weak") CommonCounterComputeKernelInvocations: CommonCounter + @(linkage="weak") CommonCounterTotalCycles: CommonCounter + @(linkage="weak") CommonCounterVertexCycles: CommonCounter + @(linkage="weak") CommonCounterTessellationCycles: CommonCounter + @(linkage="weak") CommonCounterPostTessellationVertexCycles: CommonCounter + @(linkage="weak") CommonCounterFragmentCycles: CommonCounter + @(linkage="weak") CommonCounterRenderTargetWriteCycles: CommonCounter +} + +foreign Metal { + @(linkage="weak") CommonCounterSetTimestamp: CommonCounterSet + @(linkage="weak") CommonCounterSetStageUtilization: CommonCounterSet + @(linkage="weak") CommonCounterSetStatistic: CommonCounterSet +} + +foreign Metal { + @(linkage="weak") DeviceWasAddedNotification: DeviceNotificationName + @(linkage="weak") DeviceRemovalRequestedNotification: DeviceNotificationName + @(linkage="weak") DeviceWasRemovedNotification: DeviceNotificationName +} \ No newline at end of file diff --git a/vendor/darwin/Metal/MetalProcedures.odin b/vendor/darwin/Metal/MetalProcedures.odin new file mode 100644 index 000000000..ca8fb1aea --- /dev/null +++ b/vendor/darwin/Metal/MetalProcedures.odin @@ -0,0 +1,19 @@ +package objc_Metal + +import NS "vendor:darwin/Foundation" + +@(require) +foreign import "system:Metal.framework" + +@(default_calling_convention="c", link_prefix="MTL") +foreign Metal { + CopyAllDevices :: proc() -> ^NS.Array --- + CopyAllDevicesWithObserver :: proc(observer: ^id, handler: DeviceNotificationHandler) -> ^NS.Array --- + CreateSystemDefaultDevice :: proc() -> ^Device --- + RemoveDeviceObserver :: proc(observer: id) --- +} + + +new :: proc($T: typeid) -> ^T where intrinsics.type_is_subtype_of(T, NS.Object) { + return T.alloc()->init() +} \ No newline at end of file diff --git a/vendor/darwin/Metal/MetalTypes.odin b/vendor/darwin/Metal/MetalTypes.odin new file mode 100644 index 000000000..cc9d25ca0 --- /dev/null +++ b/vendor/darwin/Metal/MetalTypes.odin @@ -0,0 +1,199 @@ +package objc_Metal + +import NS "vendor:darwin/Foundation" +import "core:intrinsics" + +BOOL :: NS.BOOL +id :: ^NS.Object + +CFTimeInterval :: NS.TimeInterval + +IOSurfaceRef :: distinct rawptr + +dispatch_queue_t :: id +dispatch_data_t :: id + +@(private) +msgSend :: intrinsics.objc_send + +AccelerationStructureInstanceDescriptor :: struct { + transformationMatrix: PackedFloat4x3, + options: AccelerationStructureInstanceOptions, + mask: u32, + intersectionFunctionTableOffset: u32, + accelerationStructureIndex: u32, +} + +AccelerationStructureSizes :: struct { + accelerationStructureSize: NS.Integer, + buildScratchBufferSize: NS.Integer, + refitScratchBufferSize: NS.Integer, +} + +AxisAlignedBoundingBox :: struct { + min: PackedFloat3, + max: PackedFloat3, +} + +ClearColor :: struct { + red: f64, + green: f64, + blue: f64, + alpha: f64, +} + +Coordinate2D :: struct { + x: f32, + y: f32, +} + +CounterResultStageUtilization :: struct { + totalCycles: u64, + vertexCycles: u64, + tessellationCycles: u64, + postTessellationVertexCycles: u64, + fragmentCycles: u64, + renderTargetCycles: u64, +} + +CounterResultStatistic :: struct { + tessellationInputPatches: u64, + vertexInvocations: u64, + postTessellationVertexInvocations: u64, + clipperInvocations: u64, + clipperPrimitivesOut: u64, + fragmentInvocations: u64, + fragmentsPassed: u64, + computeKernelInvocations: u64, +} + +CounterResultTimestamp :: struct { + timestamp: u64, +} + +DispatchThreadgroupsIndirectArguments :: struct { + threadgroupsPerGrid: [3]u32, +} + +DrawIndexedPrimitivesIndirectArguments :: struct { + indexCount: u32, + instanceCount: u32, + indexStart: u32, + baseVertex: i32, + baseInstance: u32, +} + +DrawPatchIndirectArguments :: struct { + patchCount: u32, + instanceCount: u32, + patchStart: u32, + baseInstance: u32, +} + +DrawPrimitivesIndirectArguments :: struct { + vertexCount: u32, + instanceCount: u32, + vertexStart: u32, + baseInstance: u32, +} + +IndirectCommandBufferExecutionRange :: struct { + location: u32, + length: u32, +} + +MapIndirectArguments :: struct { + regionOriginX: u32, + regionOriginY: u32, + regionOriginZ: u32, + regionSizeWidth: u32, + regionSizeHeight: u32, + regionSizeDepth: u32, + mipMapLevel: u32, + sliceId: u32, +} + +Origin :: distinct [3]NS.Integer + +PackedFloat3 :: distinct [3]f32 + +PackedFloat4x3 :: struct { + columns: [4]PackedFloat3, +} + +QuadTessellationFactorsHalf :: struct { + edgeTessellationFactor: [4]u16, + insideTessellationFactor: [2]u16, +} + +Region :: struct { + origin: Origin, + size: Size, +} + +SamplePosition :: distinct [2]f32 + +ScissorRect :: struct { + x: NS.Integer, + y: NS.Integer, + width: NS.Integer, + height: NS.Integer, +} + +Size :: struct { + width: NS.Integer, + height: NS.Integer, + depth: NS.Integer, +} + +SizeAndAlign :: struct { + size: NS.UInteger, + align: NS.UInteger, +} + +StageInRegionIndirectArguments :: struct { + stageInOrigin: [3]u32, + stageInSize: [3]u32, +} + +TextureSwizzleChannels :: struct { + red: TextureSwizzle, + green: TextureSwizzle, + blue: TextureSwizzle, + alpha: TextureSwizzle, +} + +TriangleTessellationFactorsHalf :: struct { + edgeTessellationFactor: [3]u16, + insideTessellationFactor: u16, +} + +VertexAmplificationViewMapping :: struct { + viewportArrayIndexOffset: u32, + renderTargetArrayIndexOffset: u32, +} + +Viewport :: struct { + originX: f64, + originY: f64, + width: f64, + height: f64, + znear: f64, + zfar: f64, +} + +Timestamp :: distinct u64 + +DeviceNotificationHandler :: ^NS.Block +AutoreleasedComputePipelineReflection :: ^ComputePipelineReflection +AutoreleasedRenderPipelineReflection :: ^RenderPipelineReflection +NewLibraryCompletionHandler :: ^NS.Block +NewRenderPipelineStateCompletionHandler :: ^NS.Block +NewRenderPipelineStateWithReflectionCompletionHandler :: ^NS.Block +NewComputePipelineStateCompletionHandler :: ^NS.Block +NewComputePipelineStateWithReflectionCompletionHandler :: ^NS.Block +SharedEventNotificationBlock :: ^NS.Block + +DrawablePresentedHandler :: ^NS.Block + +AutoreleasedArgument :: ^Argument \ No newline at end of file diff --git a/vendor/darwin/Metal/README.md b/vendor/darwin/Metal/README.md new file mode 100644 index 000000000..e61d7f7aa --- /dev/null +++ b/vendor/darwin/Metal/README.md @@ -0,0 +1,155 @@ +## About + +**metal-odin** is a low overhead Odin interface for Metal that helps developers add Metal functionality to graphics applications that are written in Odin. **metal-odin** removes the need to create a shim and allows developers to call Metal functions directly from anywhere in their existing Odin code. + +## Highlights + +- Drop in Odin alternative interface to the Metal Objective-C headers. +- Direct mapping of all Metal Objective-C classes, constants, enums and bit_sets to Odin +- No measurable overhead compared to calling Metal Objective-C headers, due to inlining of Odin procedure calls. +- No usage of wrapper containers that require additional allocations. +- Identical header files and procedure/constant/enum availability for iOS, macOS and tvOS. +- Backwards compatibility: All `MTL.Device.supports...()` procedure check if their required selectors exist and automatically return `false` if not. +- String (`ErrorDomain`) constants are `@(linkage="weak")` and automatically set to `nil` if not available. + +## Memory Allocation Policy + +**metal-odin** follows the object allocation policies of Cocoa and Cocoa Touch. Understanding those rules is especially important when using `metal-odin`, as Odin values are not eligible for automatic reference counting (ARC). + +**metal-odin** objects are reference counted. To help convey and manage object lifecycles, the following conventions are observed: + +### AutoreleasePools and Objects + +Several methods that create temporary objects in **metal-odin** add them to an `AutoreleasePool` to help manage their lifetimes. In these situations, after **metal-odin** creates the object, it adds it to an `AutoreleasePool`, which will release its objects when you release (or drain) it. + +By adding temporary objects to an AutoreleasePool, you do not need to explicitly call `release()` to deallocate them. Instead, you can rely on the `AutoreleasePool` to implicitly manage those lifetimes. + +If you create an object with a method that does not begin with `alloc`, or `copy`, the creating method adds the object to an autorelease pool. + +The typical scope of an `AutoreleasePool` is one frame of rendering for the main thread of the program. When the thread returns control to the RunLoop (an object responsible for receiving input and events from the windowing system), the pool is *drained*, releasing its objects. + +You can create and manage additional `AutoreleasePool`s at smaller scopes to reduce your program's working set, and you are required to do so for any additional threads your program creates. + +If an object's lifecycle needs to be extended beyond the `AutoreleasePool`'s scope, you can claim ownership of it (avoiding its release beyond the pool's scope) by calling its `retain()` method before its pool is drained. In these cases, you will be responsible for making the appropriate `release()` call on the object after you no longer need it. + +You can find a more-detailed introduction to the memory management rules here: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html. + +For more details about the application's RunLoop, please find its documentation here: https://developer.apple.com/documentation/foundation/nsrunloop + +### Use and debug AutoreleasePools + +When you create an autoreleased object and there is no enclosing `AutoreleasePool`, the object is leaked. + +To prevent this, you normally create an `AutoreleasePool` in your program's `main` procedure, and in the entry procedure for every thread you create. You may also create additional `AutoreleasePool`s to avoid growing your program's high memory watermark when you create several autoreleased objects, such as when rendering. + +Use the Environment Variable `OBJC_DEBUG_MISSING_POOLS=YES` to print a runtime warning when an autoreleased object is leaked because no enclosing `AutoreleasePool` is available for its thread. + +You can also run `leaks --autoreleasePools` on a memgraph file or a process ID (macOS only) to view a listing of your program's `AutoreleasePool`s and all objects they contain. + +### nil + +Similar to Objective-C, it is legal to call any method, including `retain()` and `release()`, on `nil` "objects". While calling methods on `nil` still does incur in procedure call overhead, the effective result is equivalent of a NOP. + +Conversely, do not assume that because calling a method on a pointer did not result in a crash, that the pointed-to object is valid. + +## Adding `metal-odin` to a Project + +Simply `import MTL "core:sys/darwin/Metal"`. To ensure that the selector and class symbols are linked. + +```odin +import MTL "core:sys/darwin/Metal" +``` + +## Examples + +#### Creating the device + +###### Objective-C (with automatic reference counting) + +```objc +id< MTLDevice > device = MTLCreateSystemDefaultDevice(); + +// ... +``` + +###### Objective-C + +```objc +id< MTLDevice > device = MTLCreateSystemDefaultDevice(); + +// ... + +[device release]; +``` + +###### Odin + +```odin +device := MTL.CreateSystemDefaultDevice() + +// ... + +device->release() +``` + +#### Metal function calls map directly to Odin + +###### Objective-C (with automatic reference counting) + +```objc +MTLSamplerDescriptor* samplerDescriptor = [[MTLSamplerDescriptor alloc] init]; + +[samplerDescriptor setSAddressMode: MTLSamplerAddressModeRepeat]; +[samplerDescriptor setTAddressMode: MTLSamplerAddressModeRepeat]; +[samplerDescriptor setRAddressMode: MTLSamplerAddressModeRepeat]; +[samplerDescriptor setMagFilter: MTLSamplerMinMagFilterLinear]; +[samplerDescriptor setMinFilter: MTLSamplerMinMagFilterLinear]; +[samplerDescriptor setMipFilter: MTLSamplerMipFilterLinear]; +[samplerDescriptor setSupportArgumentBuffers: YES]; + +id< MTLSamplerState > samplerState = [device newSamplerStateWithDescriptor:samplerDescriptor]; +``` + +###### Objective-C + +```objc +MTLSamplerDescriptor* samplerDescriptor = [[MTLSamplerDescriptor alloc] init]; + +[samplerDescriptor setSAddressMode: MTLSamplerAddressModeRepeat]; +[samplerDescriptor setTAddressMode: MTLSamplerAddressModeRepeat]; +[samplerDescriptor setRAddressMode: MTLSamplerAddressModeRepeat]; +[samplerDescriptor setMagFilter: MTLSamplerMinMagFilterLinear]; +[samplerDescriptor setMinFilter: MTLSamplerMinMagFilterLinear]; +[samplerDescriptor setMipFilter: MTLSamplerMipFilterLinear]; +[samplerDescriptor setSupportArgumentBuffers: YES]; + +id< MTLSamplerState > samplerState = [device newSamplerStateWithDescriptor:samplerDescriptor]; + +[samplerDescriptor release]; + +// ... + +[samplerState release]; +``` + +###### Odin + +```odin +samplerDescriptor := MTL.SamplerDescriptor.alloc()->init() + +samplerDescriptor->setSAddressMode(.Repeat) +samplerDescriptor->setTAddressMode(.Repeat) +samplerDescriptor->setRAddressMode(.Repeat) +samplerDescriptor->setMagFilter(.Linear) +samplerDescriptor->setMinFilter(.Linear) +samplerDescriptor->setMipFilter(.Linear) +samplerDescriptor->setSupportArgumentBuffers(true) + +samplerState := device->newSamplerState(samplerDescriptor) + +samplerDescriptor->release() + +// ... + +samplerState->release() +``` diff --git a/vendor/darwin/MetalKit/MetalKit.odin b/vendor/darwin/MetalKit/MetalKit.odin new file mode 100644 index 000000000..90d147983 --- /dev/null +++ b/vendor/darwin/MetalKit/MetalKit.odin @@ -0,0 +1,259 @@ +package objc_MetalKit + +import NS "vendor:darwin/Foundation" +import MTL "vendor:darwin/Metal" +import CA "vendor:darwin/QuartzCore" +import "core:intrinsics" + +@(require) +foreign import "system:MetalKit.framework" + +@(private) +msgSend :: intrinsics.objc_send + +ColorSpaceRef :: struct {} + +ViewDelegate :: struct { + drawInMTKView: proc "c" (self: ^ViewDelegate, view: ^View), + drawableSizeWillChange: proc "c" (self: ^ViewDelegate, view: ^View, size: NS.Size), + + user_data: rawptr, +} + +@(objc_class="MTKView") +View :: struct {using _: NS.View} + +@(objc_type=View, objc_name="alloc", objc_is_class_method=true) +View_alloc :: proc() -> ^View { + return msgSend(^View, View, "alloc") +} +@(objc_type=View, objc_name="initWithFrame") +View_initWithFrame :: proc(self: ^View, frame: NS.Rect, device: ^MTL.Device) -> ^View { + return msgSend(^View, self, "initWithFrame:device:", frame, device) +} +@(objc_type=View, objc_name="initWithCoder") +View_initWithCoder :: proc(self: ^View, coder: ^NS.Coder) -> ^View { + return msgSend(^View, self, "initWithCoder:", coder) +} + +@(objc_type=View, objc_name="setDevice") +View_setDevice :: proc(self: ^View, device: ^MTL.Device) { + msgSend(nil, self, "setDevice:", device) +} +@(objc_type=View, objc_name="device") +View_device :: proc(self: ^View) -> ^MTL.Device { + return msgSend(^MTL.Device, self, "device") +} + +@(objc_type=View, objc_name="draw") +View_draw :: proc(self: ^View) { + msgSend(nil, self, "draw") +} + +@(objc_type=View, objc_name="setDelegate") +View_setDelegate :: proc(self: ^View, delegate: ^ViewDelegate) { + drawDispatch :: proc "c" (self: ^NS.Value, cmd: NS.SEL, view: ^View) { + del := (^ViewDelegate)(self->pointerValue()) + del->drawInMTKView(view) + } + drawableSizeWillChange :: proc "c" (self: ^NS.Value, cmd: NS.SEL, view: ^View, size: NS.Size) { + del := (^ViewDelegate)(self->pointerValue()) + del->drawableSizeWillChange(view, size) + } + + wrapper := NS.Value.valueWithPointer(delegate) + + NS.class_addMethod(intrinsics.objc_find_class("NSValue"), intrinsics.objc_find_selector("drawInMTKView:"), auto_cast drawDispatch, "v@:@") + + cbparams :: "v@:@{CGSize=ff}" when size_of(NS.Float) == size_of(f32) else "v@:@{CGSize=dd}" + NS.class_addMethod(intrinsics.objc_find_class("NSValue"), intrinsics.objc_find_selector("mtkView:drawableSizeWillChange:"), auto_cast drawableSizeWillChange, cbparams) + + msgSend(nil, self, "setDelegate:", wrapper) +} + +@(objc_type=View, objc_name="delegate") +View_delegate :: proc(self: ^View) -> ^ViewDelegate { + wrapper := msgSend(^NS.Value, self, "delegate") + if wrapper != nil { + return (^ViewDelegate)(wrapper->pointerValue()) + } + return nil +} + +@(objc_type=View, objc_name="currentDrawable") +View_currentDrawable :: proc(self: ^View) -> ^CA.MetalDrawable { + return msgSend(^CA.MetalDrawable, self, "currentDrawable") +} + +@(objc_type=View, objc_name="setFramebufferOnly") +View_setFramebufferOnly :: proc(self: ^View, framebufferOnly: bool) { + msgSend(nil, self, "setFramebufferOnly:", framebufferOnly) +} +@(objc_type=View, objc_name="framebufferOnly") +View_framebufferOnly :: proc(self: ^View) -> bool { + return msgSend(bool, self, "framebufferOnly") +} + +@(objc_type=View, objc_name="setDepthStencilAttachmentTextureUsage") +View_setDepthStencilAttachmentTextureUsage :: proc(self: ^View, textureUsage: MTL.TextureUsage) { + msgSend(nil, self, "setDepthStencilAttachmentTextureUsage:", textureUsage) +} +@(objc_type=View, objc_name="depthStencilAttachmentTextureUsage") +View_depthStencilAttachmentTextureUsage :: proc(self: ^View) -> MTL.TextureUsage { + return msgSend(MTL.TextureUsage, self, "depthStencilAttachmentTextureUsage") +} + +@(objc_type=View, objc_name="setMultisampleColorAttachmentTextureUsage") +View_setMultisampleColorAttachmentTextureUsage :: proc(self: ^View, textureUsage: MTL.TextureUsage) { + msgSend(nil, self, "setMultisampleColorAttachmentTextureUsage:", textureUsage) +} +@(objc_type=View, objc_name="multisampleColorAttachmentTextureUsage") +View_multisampleColorAttachmentTextureUsage :: proc(self: ^View) -> MTL.TextureUsage { + return msgSend(MTL.TextureUsage, self, "multisampleColorAttachmentTextureUsage") +} + +@(objc_type=View, objc_name="setPresentsWithTransaction") +View_setPresentsWithTransaction :: proc(self: ^View, presentsWithTransaction: bool) { + msgSend(nil, self, "setPresentsWithTransaction:", presentsWithTransaction) +} +@(objc_type=View, objc_name="presentsWithTransaction") +View_presentsWithTransaction :: proc(self: ^View) -> bool { + return msgSend(bool, self, "presentsWithTransaction") +} + +@(objc_type=View, objc_name="setColorPixelFormat") +View_setColorPixelFormat :: proc(self: ^View, colorPixelFormat: MTL.PixelFormat) { + msgSend(nil, self, "setColorPixelFormat:", colorPixelFormat) +} +@(objc_type=View, objc_name="colorPixelFormat") +View_colorPixelFormat :: proc(self: ^View) -> MTL.PixelFormat { + return msgSend(MTL.PixelFormat, self, "colorPixelFormat") +} + +@(objc_type=View, objc_name="setDepthStencilPixelFormat") +View_setDepthStencilPixelFormat :: proc(self: ^View, colorPixelFormat: MTL.PixelFormat) { + msgSend(nil, self, "setDepthStencilPixelFormat:", colorPixelFormat) +} +@(objc_type=View, objc_name="depthStencilPixelFormat") +View_depthStencilPixelFormat :: proc(self: ^View) -> MTL.PixelFormat { + return msgSend(MTL.PixelFormat, self, "depthStencilPixelFormat") +} + +@(objc_type=View, objc_name="setSampleCount") +View_setSampleCount :: proc(self: ^View, sampleCount: NS.UInteger) { + msgSend(nil, self, "setSampleCount:", sampleCount) +} +@(objc_type=View, objc_name="sampleCount") +View_sampleCount :: proc(self: ^View) -> NS.UInteger { + return msgSend(NS.UInteger, self, "sampleCount") +} + +@(objc_type=View, objc_name="setClearColor") +View_setClearColor :: proc(self: ^View, clearColor: MTL.ClearColor) { + msgSend(nil, self, "setClearColor:", clearColor) +} +@(objc_type=View, objc_name="clearColor") +View_clearColor :: proc(self: ^View) -> MTL.ClearColor { + return msgSend(MTL.ClearColor, self, "clearColor") +} + +@(objc_type=View, objc_name="setClearDepth") +View_setClearDepth :: proc(self: ^View, clearDepth: f64) { + msgSend(nil, self, "setClearDepth:", clearDepth) +} +@(objc_type=View, objc_name="clearDepth") +View_clearDepth :: proc(self: ^View) -> f64 { + return msgSend(f64, self, "clearDepth") +} + +@(objc_type=View, objc_name="setClearStencil") +View_setClearStencil :: proc(self: ^View, clearStencil: u32) { + msgSend(nil, self, "setClearStencil:", clearStencil) +} +@(objc_type=View, objc_name="clearStencil") +View_clearStencil :: proc(self: ^View) -> u32 { + return msgSend(u32, self, "clearStencil") +} + +@(objc_type=View, objc_name="depthStencilTexture") +View_depthStencilTexture :: proc(self: ^View) -> ^MTL.Texture { + return msgSend(^MTL.Texture, self, "depthStencilTexture") +} +@(objc_type=View, objc_name="multisampleColorTexture") +View_multisampleColorTexture :: proc(self: ^View) -> ^MTL.Texture { + return msgSend(^MTL.Texture, self, "multisampleColorTexture") +} + +@(objc_type=View, objc_name="releaseDrawables") +View_releaseDrawables :: proc(self: ^View) { + msgSend(nil, self, "releaseDrawables") +} + +@(objc_type=View, objc_name="currentRenderPassDescriptor") +View_currentRenderPassDescriptor :: proc(self: ^View) -> ^MTL.RenderPassDescriptor { + return msgSend(^MTL.RenderPassDescriptor, self, "currentRenderPassDescriptor") +} + +@(objc_type=View, objc_name="setPreferredFramesPerSecond") +View_setPreferredFramesPerSecond :: proc(self: ^View, preferredFramesPerSecond: NS.Integer) { + msgSend(nil, self, "setPreferredFramesPerSecond:", preferredFramesPerSecond) +} +@(objc_type=View, objc_name="preferredFramesPerSecond") +View_preferredFramesPerSecond :: proc(self: ^View) -> NS.Integer { + return msgSend(NS.Integer, self, "preferredFramesPerSecond") +} + +@(objc_type=View, objc_name="setEnableSetNeedsDisplay") +View_setEnableSetNeedsDisplay :: proc(self: ^View, enableSetNeedsDisplay: bool) { + msgSend(nil, self, "setEnableSetNeedsDisplay:", enableSetNeedsDisplay) +} +@(objc_type=View, objc_name="enableSetNeedsDisplay") +View_enableSetNeedsDisplay :: proc(self: ^View) -> bool { + return msgSend(bool, self, "enableSetNeedsDisplay") +} + +@(objc_type=View, objc_name="setAutoresizeDrawable") +View_setAutoresizeDrawable :: proc(self: ^View, autoresizeDrawable: bool) { + msgSend(nil, self, "setAutoresizeDrawable:", autoresizeDrawable) +} +@(objc_type=View, objc_name="autoresizeDrawable") +View_autoresizeDrawable :: proc(self: ^View) -> bool { + return msgSend(bool, self, "autoresizeDrawable") +} + +@(objc_type=View, objc_name="setDrawableSize") +View_setDrawableSize :: proc(self: ^View, drawableSize: NS.Size) { + msgSend(nil, self, "setDrawableSize:", drawableSize) +} +@(objc_type=View, objc_name="drawableSize") +View_drawableSize :: proc(self: ^View) -> NS.Size { + return msgSend(NS.Size, self, "drawableSize") +} + +@(objc_type=View, objc_name="preferredDrawableSize") +View_preferredDrawableSize :: proc(self: ^View) -> NS.Size { + return msgSend(NS.Size, self, "preferredDrawableSize") +} + +@(objc_type=View, objc_name="preferredDevice") +View_preferredDevice :: proc(self: ^View) -> ^MTL.Device { + return msgSend(^MTL.Device, self, "preferredDevice") +} + +@(objc_type=View, objc_name="setPaused") +View_setPaused :: proc(self: ^View, isPaused: bool) { + msgSend(nil, self, "setPaused:", isPaused) +} +@(objc_type=View, objc_name="isPaused") +View_isPaused :: proc(self: ^View) -> bool { + return msgSend(bool, self, "isPaused") +} + +@(objc_type=View, objc_name="setColorSpace") +View_setColorSpace :: proc(self: ^View, colorSpace: ColorSpaceRef) { + msgSend(nil, self, "setColorSpace:", colorSpace) +} +@(objc_type=View, objc_name="colorSpace") +View_colorSpace :: proc(self: ^View) -> ColorSpaceRef { + return msgSend(ColorSpaceRef, self, "colorSpace") +} diff --git a/vendor/darwin/QuartzCore/QuartzCore.odin b/vendor/darwin/QuartzCore/QuartzCore.odin new file mode 100644 index 000000000..fb6e04b07 --- /dev/null +++ b/vendor/darwin/QuartzCore/QuartzCore.odin @@ -0,0 +1,87 @@ +package objc_QuartzCore + +import NS "vendor:darwin/Foundation" +import MTL "vendor:darwin/Metal" +import "core:intrinsics" + +@(private) +msgSend :: intrinsics.objc_send + +@(objc_class="CAMetalLayer") +MetalLayer :: struct{ using _: NS.Layer} + +@(objc_type=MetalLayer, objc_name="layer", objc_is_class_method=true) +MetalLayer_layer :: proc() -> ^MetalLayer { + return msgSend(^MetalLayer, MetalLayer, "layer") +} + +@(objc_type=MetalLayer, objc_name="device") +MetalLayer_device :: proc(self: ^MetalLayer) -> ^MTL.Device { + return msgSend(^MTL.Device, self, "device") +} +@(objc_type=MetalLayer, objc_name="setDevice") +MetalLayer_setDevice :: proc(self: ^MetalLayer, device: ^MTL.Device) { + msgSend(nil, self, "setDevice:", device) +} + + +@(objc_type=MetalLayer, objc_name="opaque") +MetalLayer_opaque :: proc(self: ^MetalLayer) -> NS.BOOL { + return msgSend(NS.BOOL, self, "opaque") +} +@(objc_type=MetalLayer, objc_name="setOpaque") +MetalLayer_setOpaque :: proc(self: ^MetalLayer, opaque: NS.BOOL) { + msgSend(nil, self, "setOpaque:", opaque) +} + +@(objc_type=MetalLayer, objc_name="preferredDevice") +MetalLayer_preferredDevice :: proc(self: ^MetalLayer) -> ^MTL.Device { + return msgSend(^MTL.Device, self, "preferredDevice") +} +@(objc_type=MetalLayer, objc_name="pixelFormat") +MetalLayer_pixelFormat :: proc(self: ^MetalLayer) -> MTL.PixelFormat { + return msgSend(MTL.PixelFormat, self, "pixelFormat") +} +@(objc_type=MetalLayer, objc_name="setPixelFormat") +MetalLayer_setPixelFormat :: proc(self: ^MetalLayer, pixelFormat: MTL.PixelFormat) { + msgSend(nil, self, "setPixelFormat:", pixelFormat) +} + +@(objc_type=MetalLayer, objc_name="framebufferOnly") +MetalLayer_framebufferOnly :: proc(self: ^MetalLayer) -> NS.BOOL { + return msgSend(NS.BOOL, self, "framebufferOnly") +} +@(objc_type=MetalLayer, objc_name="setFramebufferOnly") +MetalLayer_setFramebufferOnly :: proc(self: ^MetalLayer, ok: NS.BOOL) { + msgSend(nil, self, "setFramebufferOnly:", ok) +} + +@(objc_type=MetalLayer, objc_name="frame") +MetalLayer_frame :: proc(self: ^MetalLayer) -> NS.Rect { + return msgSend(NS.Rect, self, "frame") +} +@(objc_type=MetalLayer, objc_name="setFrame") +MetalLayer_setFrame :: proc(self: ^MetalLayer, frame: NS.Rect) { + msgSend(nil, self, "setFrame:", frame) +} + + +@(objc_type=MetalLayer, objc_name="nextDrawable") +MetalLayer_nextDrawable :: proc(self: ^MetalLayer) -> ^MetalDrawable { + return msgSend(^MetalDrawable, self, "nextDrawable") +} + + + +@(objc_class="CAMetalDrawable") +MetalDrawable :: struct { using _: MTL.Drawable } + +@(objc_type=MetalDrawable, objc_name="layer") +MetalDrawable_layer :: proc(self: ^MetalDrawable) -> ^MetalLayer { + return msgSend(^MetalLayer, self, "layer") +} + +@(objc_type=MetalDrawable, objc_name="texture") +MetalDrawable_texture :: proc(self: ^MetalDrawable) -> ^MTL.Texture { + return msgSend(^MTL.Texture, self, "texture") +} \ No newline at end of file diff --git a/vendor/directx/d3d11/d3d11.odin b/vendor/directx/d3d11/d3d11.odin new file mode 100644 index 000000000..2adb7925a --- /dev/null +++ b/vendor/directx/d3d11/d3d11.odin @@ -0,0 +1,3627 @@ +package directx_d3d11 + +foreign import "system:d3d11.lib" + +import "../dxgi" +import "../d3d_compiler" + +IUnknown :: dxgi.IUnknown +IUnknown_VTable :: dxgi.IUnknown_VTable + +HANDLE :: dxgi.HANDLE +HMODULE :: dxgi.HMODULE +HRESULT :: dxgi.HRESULT +GUID :: dxgi.GUID +IID :: dxgi.IID +SIZE_T :: dxgi.SIZE_T +BOOL :: dxgi.BOOL + +RECT :: dxgi.RECT +SIZE :: dxgi.SIZE + +IModuleInstance :: d3d_compiler.ID3D11ModuleInstance +IBlob :: d3d_compiler.ID3DBlob +IModule :: d3d_compiler.ID3D11Module + +@(default_calling_convention="stdcall", link_prefix="D3D11") +foreign d3d11 { + CreateDevice :: proc( + pAdapter: ^dxgi.IAdapter, + DriverType: DRIVER_TYPE, + Software: HMODULE, + Flags: CREATE_DEVICE_FLAGS, + pFeatureLevels: ^FEATURE_LEVEL, + FeatureLevels: u32, + SDKVersion: u32, + ppDevice: ^^IDevice, + pFeatureLevel: ^FEATURE_LEVEL, + ppImmediateContext: ^^IDeviceContext, + ) -> HRESULT --- + CreateDeviceAndSwapChain :: proc( + pAdapter: ^dxgi.IAdapter, + DriverType: DRIVER_TYPE, + Software: HMODULE, + Flags: u32, + pFeatureLevels: ^FEATURE_LEVEL, + FeatureLevels: u32, + SDKVersion: u32, + pSwapChainDesc: ^dxgi.SWAP_CHAIN_DESC, + ppSwapChain: ^^dxgi.ISwapChain, + ppDevice: ^^IDevice, + pFeatureLevel: ^FEATURE_LEVEL, + ppImmediateContext: ^^IDeviceContext, + ) -> HRESULT --- +} + +foreign d3d11 { + WKPDID_D3DDebugObjectNameW: GUID + WKPDID_CommentStringW: GUID +} + +@(link_prefix="D3D_") +foreign d3d11 { + TEXTURE_LAYOUT_ROW_MAJOR: GUID + TEXTURE_LAYOUT_64KB_STANDARD_SWIZZLE: GUID +} + +@(link_prefix="D3D11_") +foreign d3d11 { + DECODER_PROFILE_MPEG2_MOCOMP: GUID + DECODER_PROFILE_MPEG2_IDCT: GUID + DECODER_PROFILE_MPEG2_VLD: GUID + DECODER_PROFILE_MPEG1_VLD: GUID + DECODER_PROFILE_MPEG2and1_VLD: GUID + DECODER_PROFILE_H264_MOCOMP_NOFGT: GUID + DECODER_PROFILE_H264_MOCOMP_FGT: GUID + DECODER_PROFILE_H264_IDCT_NOFGT: GUID + DECODER_PROFILE_H264_IDCT_FGT: GUID + DECODER_PROFILE_H264_VLD_NOFGT: GUID + DECODER_PROFILE_H264_VLD_FGT: GUID + DECODER_PROFILE_H264_VLD_WITHFMOASO_NOFGT: GUID + DECODER_PROFILE_H264_VLD_STEREO_PROGRESSIVE_NOFGT: GUID + DECODER_PROFILE_H264_VLD_STEREO_NOFGT: GUID + DECODER_PROFILE_H264_VLD_MULTIVIEW_NOFGT: GUID + DECODER_PROFILE_WMV8_POSTPROC: GUID + DECODER_PROFILE_WMV8_MOCOMP: GUID + DECODER_PROFILE_WMV9_POSTPROC: GUID + DECODER_PROFILE_WMV9_MOCOMP: GUID + DECODER_PROFILE_WMV9_IDCT: GUID + DECODER_PROFILE_VC1_POSTPROC: GUID + DECODER_PROFILE_VC1_MOCOMP: GUID + DECODER_PROFILE_VC1_IDCT: GUID + DECODER_PROFILE_VC1_VLD: GUID + DECODER_PROFILE_VC1_D2010: GUID + DECODER_PROFILE_MPEG4PT2_VLD_SIMPLE: GUID + DECODER_PROFILE_MPEG4PT2_VLD_ADVSIMPLE_NOGMC: GUID + DECODER_PROFILE_MPEG4PT2_VLD_ADVSIMPLE_GMC: GUID + DECODER_PROFILE_HEVC_VLD_MAIN: GUID + DECODER_PROFILE_HEVC_VLD_MAIN10: GUID + DECODER_PROFILE_VP9_VLD_PROFILE0: GUID + DECODER_PROFILE_VP9_VLD_10BIT_PROFILE2: GUID + DECODER_PROFILE_VP8_VLD: GUID + + CRYPTO_TYPE_AES128_CTR: GUID + DECODER_ENCRYPTION_HW_CENC: GUID + DECODER_BITSTREAM_ENCRYPTION_TYPE_CENC: GUID + DECODER_BITSTREAM_ENCRYPTION_TYPE_CBCS: GUID + KEY_EXCHANGE_HW_PROTECTION: GUID + + AUTHENTICATED_QUERY_PROTECTION: GUID + AUTHENTICATED_QUERY_CHANNEL_TYPE: GUID + AUTHENTICATED_QUERY_DEVICE_HANDLE: GUID + AUTHENTICATED_QUERY_CRYPTO_SESSION: GUID + AUTHENTICATED_QUERY_RESTRICTED_SHARED_RESOURCE_PROCESS_COUNT: GUID + AUTHENTICATED_QUERY_RESTRICTED_SHARED_RESOURCE_PROCESS: GUID + AUTHENTICATED_QUERY_UNRESTRICTED_PROTECTED_SHARED_RESOURCE_COUNT: GUID + AUTHENTICATED_QUERY_OUTPUT_ID_COUNT: GUID + AUTHENTICATED_QUERY_OUTPUT_ID: GUID + AUTHENTICATED_QUERY_ACCESSIBILITY_ATTRIBUTES: GUID + AUTHENTICATED_QUERY_ENCRYPTION_WHEN_ACCESSIBLE_GUID_COUNT: GUID + AUTHENTICATED_QUERY_ENCRYPTION_WHEN_ACCESSIBLE_GUID: GUID + AUTHENTICATED_QUERY_CURRENT_ENCRYPTION_WHEN_ACCESSIBLE: GUID + AUTHENTICATED_CONFIGURE_INITIALIZE: GUID + AUTHENTICATED_CONFIGURE_PROTECTION: GUID + AUTHENTICATED_CONFIGURE_CRYPTO_SESSION: GUID + AUTHENTICATED_CONFIGURE_SHARED_RESOURCE: GUID + AUTHENTICATED_CONFIGURE_ENCRYPTION_WHEN_ACCESSIBLE: GUID + + KEY_EXCHANGE_RSAES_OAEP: GUID +} + +FL9_1_REQ_TEXTURE1D_U_DIMENSION :: 2048 +FL9_3_REQ_TEXTURE1D_U_DIMENSION :: 4096 +FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION :: 2048 +FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION :: 4096 +FL9_1_REQ_TEXTURECUBE_DIMENSION :: 512 +FL9_3_REQ_TEXTURECUBE_DIMENSION :: 4096 +FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION :: 256 +FL9_1_DEFAULT_MAX_ANISOTROPY :: 2 +FL9_1_IA_PRIMITIVE_MAX_COUNT :: 65535 +FL9_2_IA_PRIMITIVE_MAX_COUNT :: 1048575 +FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT :: 1 +FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT :: 4 +FL9_1_MAX_TEXTURE_REPEAT :: 128 +FL9_2_MAX_TEXTURE_REPEAT :: 2048 +FL9_3_MAX_TEXTURE_REPEAT :: 8192 + +_8BIT_INDEX_STRIP_CUT_VALUE :: 0xff +_16BIT_INDEX_STRIP_CUT_VALUE :: 0xffff +_32BIT_INDEX_STRIP_CUT_VALUE :: 0xffffffff + +ARRAY_AXIS_ADDRESS_RANGE_BIT_COUNT :: 9 + +CLIP_OR_CULL_DISTANCE_COUNT :: 8 +CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT :: 2 + +COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT :: 14 +COMMONSHADER_CONSTANT_BUFFER_COMPONENTS :: 4 +COMMONSHADER_CONSTANT_BUFFER_COMPONENT_BIT_COUNT :: 32 +COMMONSHADER_CONSTANT_BUFFER_HW_SLOT_COUNT :: 15 +COMMONSHADER_CONSTANT_BUFFER_PARTIAL_UPDATE_EXTENTS_BYTE_ALIGNMENT :: 16 +COMMONSHADER_CONSTANT_BUFFER_REGISTER_COMPONENTS :: 4 +COMMONSHADER_CONSTANT_BUFFER_REGISTER_COUNT :: 15 +COMMONSHADER_CONSTANT_BUFFER_REGISTER_READS_PER_INST :: 1 +COMMONSHADER_CONSTANT_BUFFER_REGISTER_READ_PORTS :: 1 +COMMONSHADER_FLOWCONTROL_NESTING_LIMIT :: 64 +COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_COMPONENTS :: 4 +COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_COUNT :: 1 +COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_READS_PER_INST :: 1 +COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_READ_PORTS :: 1 +COMMONSHADER_IMMEDIATE_VALUE_COMPONENT_BIT_COUNT :: 32 +COMMONSHADER_INPUT_RESOURCE_REGISTER_COMPONENTS :: 1 +COMMONSHADER_INPUT_RESOURCE_REGISTER_COUNT :: 128 +COMMONSHADER_INPUT_RESOURCE_REGISTER_READS_PER_INST :: 1 +COMMONSHADER_INPUT_RESOURCE_REGISTER_READ_PORTS :: 1 +COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT :: 128 +COMMONSHADER_SAMPLER_REGISTER_COMPONENTS :: 1 +COMMONSHADER_SAMPLER_REGISTER_COUNT :: 16 +COMMONSHADER_SAMPLER_REGISTER_READS_PER_INST :: 1 +COMMONSHADER_SAMPLER_REGISTER_READ_PORTS :: 1 +COMMONSHADER_SAMPLER_SLOT_COUNT :: 16 +COMMONSHADER_SUBROUTINE_NESTING_LIMIT :: 32 +COMMONSHADER_TEMP_REGISTER_COMPONENTS :: 4 +COMMONSHADER_TEMP_REGISTER_COMPONENT_BIT_COUNT :: 32 +COMMONSHADER_TEMP_REGISTER_COUNT :: 4096 +COMMONSHADER_TEMP_REGISTER_READS_PER_INST :: 3 +COMMONSHADER_TEMP_REGISTER_READ_PORTS :: 3 +COMMONSHADER_TEXCOORD_RANGE_REDUCTION_MAX :: 10 +COMMONSHADER_TEXCOORD_RANGE_REDUCTION_MIN :: -10 +COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE :: -8 +COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE :: 7 + +CS_4_X_BUCKET00_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 256 +CS_4_X_BUCKET00_MAX_NUM_THREADS_PER_GROUP :: 64 +CS_4_X_BUCKET01_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 240 +CS_4_X_BUCKET01_MAX_NUM_THREADS_PER_GROUP :: 68 +CS_4_X_BUCKET02_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 224 +CS_4_X_BUCKET02_MAX_NUM_THREADS_PER_GROUP :: 72 +CS_4_X_BUCKET03_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 208 +CS_4_X_BUCKET03_MAX_NUM_THREADS_PER_GROUP :: 76 +CS_4_X_BUCKET04_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 192 +CS_4_X_BUCKET04_MAX_NUM_THREADS_PER_GROUP :: 84 +CS_4_X_BUCKET05_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 176 +CS_4_X_BUCKET05_MAX_NUM_THREADS_PER_GROUP :: 92 +CS_4_X_BUCKET06_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 160 +CS_4_X_BUCKET06_MAX_NUM_THREADS_PER_GROUP :: 100 +CS_4_X_BUCKET07_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 144 +CS_4_X_BUCKET07_MAX_NUM_THREADS_PER_GROUP :: 112 +CS_4_X_BUCKET08_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 128 +CS_4_X_BUCKET08_MAX_NUM_THREADS_PER_GROUP :: 128 +CS_4_X_BUCKET09_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 112 +CS_4_X_BUCKET09_MAX_NUM_THREADS_PER_GROUP :: 144 +CS_4_X_BUCKET10_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 96 +CS_4_X_BUCKET10_MAX_NUM_THREADS_PER_GROUP :: 168 +CS_4_X_BUCKET11_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 80 +CS_4_X_BUCKET11_MAX_NUM_THREADS_PER_GROUP :: 204 +CS_4_X_BUCKET12_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 64 +CS_4_X_BUCKET12_MAX_NUM_THREADS_PER_GROUP :: 256 +CS_4_X_BUCKET13_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 48 +CS_4_X_BUCKET13_MAX_NUM_THREADS_PER_GROUP :: 340 +CS_4_X_BUCKET14_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 32 +CS_4_X_BUCKET14_MAX_NUM_THREADS_PER_GROUP :: 512 +CS_4_X_BUCKET15_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 16 +CS_4_X_BUCKET15_MAX_NUM_THREADS_PER_GROUP :: 768 +CS_4_X_DISPATCH_MAX_THREAD_GROUPS_IN_Z_DIMENSION :: 1 +CS_4_X_RAW_UAV_BYTE_ALIGNMENT :: 256 +CS_4_X_THREAD_GROUP_MAX_THREADS_PER_GROUP :: 768 +CS_4_X_THREAD_GROUP_MAX_X :: 768 +CS_4_X_THREAD_GROUP_MAX_Y :: 768 +CS_4_X_UAV_REGISTER_COUNT :: 1 + +CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION :: 65535 +CS_TGSM_REGISTER_COUNT :: 8192 +CS_TGSM_REGISTER_READS_PER_INST :: 1 +CS_TGSM_RESOURCE_REGISTER_COMPONENTS :: 1 +CS_TGSM_RESOURCE_REGISTER_READ_PORTS :: 1 +CS_THREADGROUPID_REGISTER_COMPONENTS :: 3 +CS_THREADGROUPID_REGISTER_COUNT :: 1 +CS_THREADIDINGROUPFLATTENED_REGISTER_COMPONENTS :: 1 +CS_THREADIDINGROUPFLATTENED_REGISTER_COUNT :: 1 +CS_THREADIDINGROUP_REGISTER_COMPONENTS :: 3 +CS_THREADIDINGROUP_REGISTER_COUNT :: 1 +CS_THREADID_REGISTER_COMPONENTS :: 3 +CS_THREADID_REGISTER_COUNT :: 1 +CS_THREAD_GROUP_MAX_THREADS_PER_GROUP :: 1024 +CS_THREAD_GROUP_MAX_X :: 1024 +CS_THREAD_GROUP_MAX_Y :: 1024 +CS_THREAD_GROUP_MAX_Z :: 64 +CS_THREAD_GROUP_MIN_X :: 1 +CS_THREAD_GROUP_MIN_Y :: 1 +CS_THREAD_GROUP_MIN_Z :: 1 +CS_THREAD_LOCAL_TEMP_REGISTER_POOL :: 16384 + +DEFAULT_BLEND_FACTOR_ALPHA :: 1.0 +DEFAULT_BLEND_FACTOR_BLUE :: 1.0 +DEFAULT_BLEND_FACTOR_GREEN :: 1.0 +DEFAULT_BLEND_FACTOR_RED :: 1.0 +DEFAULT_BORDER_COLOR_COMPONENT :: 0.0 +DEFAULT_DEPTH_BIAS :: 0 +DEFAULT_DEPTH_BIAS_CLAMP :: 0.0 +DEFAULT_MAX_ANISOTROPY :: 16 +DEFAULT_MIP_LOD_BIAS :: 0.0 +DEFAULT_RENDER_TARGET_ARRAY_INDEX :: 0 +DEFAULT_SAMPLE_MASK :: 0xffffffff +DEFAULT_SCISSOR_ENDX :: 0 +DEFAULT_SCISSOR_ENDY :: 0 +DEFAULT_SCISSOR_STARTX :: 0 +DEFAULT_SCISSOR_STARTY :: 0 +DEFAULT_SLOPE_SCALED_DEPTH_BIAS :: 0.0 +DEFAULT_STENCIL_READ_MASK :: 0xff +DEFAULT_STENCIL_REFERENCE :: 0 +DEFAULT_STENCIL_WRITE_MASK :: 0xff +DEFAULT_VIEWPORT_AND_SCISSORRECT_INDEX :: 0 +DEFAULT_VIEWPORT_HEIGHT :: 0 +DEFAULT_VIEWPORT_MAX_DEPTH :: 0.0 +DEFAULT_VIEWPORT_MIN_DEPTH :: 0.0 +DEFAULT_VIEWPORT_TOPLEFTX :: 0 +DEFAULT_VIEWPORT_TOPLEFTY :: 0 +DEFAULT_VIEWPORT_WIDTH :: 0 + +DS_INPUT_CONTROL_POINTS_MAX_TOTAL_SCALARS :: 3968 +DS_INPUT_CONTROL_POINT_REGISTER_COMPONENTS :: 4 +DS_INPUT_CONTROL_POINT_REGISTER_COMPONENT_BIT_COUNT :: 32 +DS_INPUT_CONTROL_POINT_REGISTER_COUNT :: 32 +DS_INPUT_CONTROL_POINT_REGISTER_READS_PER_INST :: 2 +DS_INPUT_CONTROL_POINT_REGISTER_READ_PORTS :: 1 +DS_INPUT_DOMAIN_POINT_REGISTER_COMPONENTS :: 3 +DS_INPUT_DOMAIN_POINT_REGISTER_COMPONENT_BIT_COUNT :: 32 +DS_INPUT_DOMAIN_POINT_REGISTER_COUNT :: 1 +DS_INPUT_DOMAIN_POINT_REGISTER_READS_PER_INST :: 2 +DS_INPUT_DOMAIN_POINT_REGISTER_READ_PORTS :: 1 +DS_INPUT_PATCH_CONSTANT_REGISTER_COMPONENTS :: 4 +DS_INPUT_PATCH_CONSTANT_REGISTER_COMPONENT_BIT_COUNT :: 32 +DS_INPUT_PATCH_CONSTANT_REGISTER_COUNT :: 32 +DS_INPUT_PATCH_CONSTANT_REGISTER_READS_PER_INST :: 2 +DS_INPUT_PATCH_CONSTANT_REGISTER_READ_PORTS :: 1 +DS_INPUT_PRIMITIVE_ID_REGISTER_COMPONENTS :: 1 +DS_INPUT_PRIMITIVE_ID_REGISTER_COMPONENT_BIT_COUNT :: 32 +DS_INPUT_PRIMITIVE_ID_REGISTER_COUNT :: 1 +DS_INPUT_PRIMITIVE_ID_REGISTER_READS_PER_INST :: 2 +DS_INPUT_PRIMITIVE_ID_REGISTER_READ_PORTS :: 1 +DS_OUTPUT_REGISTER_COMPONENTS :: 4 +DS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT :: 32 +DS_OUTPUT_REGISTER_COUNT :: 32 + +FLOAT16_FUSED_TOLERANCE_IN_ULP :: 0.6 +FLOAT32_MAX :: 3.402823466e+38 +FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP :: 0.6 +FLOAT_TO_SRGB_EXPONENT_DENOMINATOR :: 2.4 +FLOAT_TO_SRGB_EXPONENT_NUMERATOR :: 1.0 +FLOAT_TO_SRGB_OFFSET :: 0.055 +FLOAT_TO_SRGB_SCALE_1 :: 12.92 +FLOAT_TO_SRGB_SCALE_2 :: 1.055 +FLOAT_TO_SRGB_THRESHOLD :: 0.0031308 +FTOI_INSTRUCTION_MAX_INPUT :: 2147483647.999 +FTOI_INSTRUCTION_MIN_INPUT :: -2147483648.999 +FTOU_INSTRUCTION_MAX_INPUT :: 4294967295.999 +FTOU_INSTRUCTION_MIN_INPUT :: 0.0 +GS_INPUT_INSTANCE_ID_READS_PER_INST :: 2 +GS_INPUT_INSTANCE_ID_READ_PORTS :: 1 +GS_INPUT_INSTANCE_ID_REGISTER_COMPONENTS :: 1 +GS_INPUT_INSTANCE_ID_REGISTER_COMPONENT_BIT_COUNT :: 32 +GS_INPUT_INSTANCE_ID_REGISTER_COUNT :: 1 +GS_INPUT_PRIM_CONST_REGISTER_COMPONENTS :: 1 +GS_INPUT_PRIM_CONST_REGISTER_COMPONENT_BIT_COUNT :: 32 +GS_INPUT_PRIM_CONST_REGISTER_COUNT :: 1 +GS_INPUT_PRIM_CONST_REGISTER_READS_PER_INST :: 2 +GS_INPUT_PRIM_CONST_REGISTER_READ_PORTS :: 1 +GS_INPUT_REGISTER_COMPONENTS :: 4 +GS_INPUT_REGISTER_COMPONENT_BIT_COUNT :: 32 +GS_INPUT_REGISTER_COUNT :: 32 +GS_INPUT_REGISTER_READS_PER_INST :: 2 +GS_INPUT_REGISTER_READ_PORTS :: 1 +GS_INPUT_REGISTER_VERTICES :: 32 +GS_MAX_INSTANCE_COUNT :: 32 +GS_MAX_OUTPUT_VERTEX_COUNT_ACROSS_INSTANCES :: 1024 +GS_OUTPUT_ELEMENTS :: 32 +GS_OUTPUT_REGISTER_COMPONENTS :: 4 +GS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT :: 32 +GS_OUTPUT_REGISTER_COUNT :: 32 +HS_CONTROL_POINT_PHASE_INPUT_REGISTER_COUNT :: 32 +HS_CONTROL_POINT_PHASE_OUTPUT_REGISTER_COUNT :: 32 +HS_CONTROL_POINT_REGISTER_COMPONENTS :: 4 +HS_CONTROL_POINT_REGISTER_COMPONENT_BIT_COUNT :: 32 +HS_CONTROL_POINT_REGISTER_READS_PER_INST :: 2 +HS_CONTROL_POINT_REGISTER_READ_PORTS :: 1 +HS_FORK_PHASE_INSTANCE_COUNT_UPPER_BOUND :: 0xffffffff +HS_INPUT_FORK_INSTANCE_ID_REGISTER_COMPONENTS :: 1 +HS_INPUT_FORK_INSTANCE_ID_REGISTER_COMPONENT_BIT_COUNT :: 32 +HS_INPUT_FORK_INSTANCE_ID_REGISTER_COUNT :: 1 +HS_INPUT_FORK_INSTANCE_ID_REGISTER_READS_PER_INST :: 2 +HS_INPUT_FORK_INSTANCE_ID_REGISTER_READ_PORTS :: 1 +HS_INPUT_JOIN_INSTANCE_ID_REGISTER_COMPONENTS :: 1 +HS_INPUT_JOIN_INSTANCE_ID_REGISTER_COMPONENT_BIT_COUNT :: 32 +HS_INPUT_JOIN_INSTANCE_ID_REGISTER_COUNT :: 1 +HS_INPUT_JOIN_INSTANCE_ID_REGISTER_READS_PER_INST :: 2 +HS_INPUT_JOIN_INSTANCE_ID_REGISTER_READ_PORTS :: 1 +HS_INPUT_PRIMITIVE_ID_REGISTER_COMPONENTS :: 1 +HS_INPUT_PRIMITIVE_ID_REGISTER_COMPONENT_BIT_COUNT :: 32 +HS_INPUT_PRIMITIVE_ID_REGISTER_COUNT :: 1 +HS_INPUT_PRIMITIVE_ID_REGISTER_READS_PER_INST :: 2 +HS_INPUT_PRIMITIVE_ID_REGISTER_READ_PORTS :: 1 +HS_JOIN_PHASE_INSTANCE_COUNT_UPPER_BOUND :: 0xffffffff +HS_MAXTESSFACTOR_LOWER_BOUND :: 1.0 +HS_MAXTESSFACTOR_UPPER_BOUND :: 64.0 +HS_OUTPUT_CONTROL_POINTS_MAX_TOTAL_SCALARS :: 3968 +HS_OUTPUT_CONTROL_POINT_ID_REGISTER_COMPONENTS :: 1 +HS_OUTPUT_CONTROL_POINT_ID_REGISTER_COMPONENT_BIT_COUNT :: 32 +HS_OUTPUT_CONTROL_POINT_ID_REGISTER_COUNT :: 1 +HS_OUTPUT_CONTROL_POINT_ID_REGISTER_READS_PER_INST :: 2 +HS_OUTPUT_CONTROL_POINT_ID_REGISTER_READ_PORTS :: 1 +HS_OUTPUT_PATCH_CONSTANT_REGISTER_COMPONENTS :: 4 +HS_OUTPUT_PATCH_CONSTANT_REGISTER_COMPONENT_BIT_COUNT :: 32 +HS_OUTPUT_PATCH_CONSTANT_REGISTER_COUNT :: 32 +HS_OUTPUT_PATCH_CONSTANT_REGISTER_READS_PER_INST :: 2 +HS_OUTPUT_PATCH_CONSTANT_REGISTER_READ_PORTS :: 1 +HS_OUTPUT_PATCH_CONSTANT_REGISTER_SCALAR_COMPONENTS :: 128 +IA_DEFAULT_INDEX_BUFFER_OFFSET_IN_BYTES :: 0 +IA_DEFAULT_PRIMITIVE_TOPOLOGY :: 0 +IA_DEFAULT_VERTEX_BUFFER_OFFSET_IN_BYTES :: 0 +IA_INDEX_INPUT_RESOURCE_SLOT_COUNT :: 1 +IA_INSTANCE_ID_BIT_COUNT :: 32 +IA_INTEGER_ARITHMETIC_BIT_COUNT :: 32 +IA_PATCH_MAX_CONTROL_POINT_COUNT :: 32 +IA_PRIMITIVE_ID_BIT_COUNT :: 32 +IA_VERTEX_ID_BIT_COUNT :: 32 +IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT :: 32 +IA_VERTEX_INPUT_STRUCTURE_ELEMENTS_COMPONENTS :: 128 +IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT :: 32 +INTEGER_DIVIDE_BY_ZERO_QUOTIENT :: 0xffffffff +INTEGER_DIVIDE_BY_ZERO_REMAINDER :: 0xffffffff +KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL :: 0xffffffff +KEEP_UNORDERED_ACCESS_VIEWS :: 0xffffffff +LINEAR_GAMMA :: 1.0 +MAJOR_VERSION :: 11 +MAX_BORDER_COLOR_COMPONENT :: 1.0 +MAX_DEPTH :: 1.0 +MAX_MAXANISOTROPY :: 16 +MAX_MULTISAMPLE_SAMPLE_COUNT :: 32 +MAX_POSITION_VALUE :: 3.402823466e+34 +MAX_TEXTURE_DIMENSION_2_TO_EXP :: 17 +MINOR_VERSION :: 0 +MIN_BORDER_COLOR_COMPONENT :: 0.0 +MIN_DEPTH :: 0.0 +MIN_MAXANISOTROPY :: 0 +MIP_LOD_BIAS_MAX :: 15.99 +MIP_LOD_BIAS_MIN :: -16.0 +MIP_LOD_FRACTIONAL_BIT_COUNT :: 8 +MIP_LOD_RANGE_BIT_COUNT :: 8 +MULTISAMPLE_ANTIALIAS_LINE_WIDTH :: 1.4 +NONSAMPLE_FETCH_OUT_OF_RANGE_ACCESS_RESULT :: 0 +PIXEL_ADDRESS_RANGE_BIT_COUNT :: 15 +PRE_SCISSOR_PIXEL_ADDRESS_RANGE_BIT_COUNT :: 16 +PS_CS_UAV_REGISTER_COMPONENTS :: 1 +PS_CS_UAV_REGISTER_COUNT :: 8 +PS_CS_UAV_REGISTER_READS_PER_INST :: 1 +PS_CS_UAV_REGISTER_READ_PORTS :: 1 +PS_FRONTFACING_DEFAULT_VALUE :: 0xffffffff +PS_FRONTFACING_FALSE_VALUE :: 0 +PS_FRONTFACING_TRUE_VALUE :: 0xffffffff +PS_INPUT_REGISTER_COMPONENTS :: 4 +PS_INPUT_REGISTER_COMPONENT_BIT_COUNT :: 32 +PS_INPUT_REGISTER_COUNT :: 32 +PS_INPUT_REGISTER_READS_PER_INST :: 2 +PS_INPUT_REGISTER_READ_PORTS :: 1 +PS_LEGACY_PIXEL_CENTER_FRACTIONAL_COMPONENT :: 0.0 +PS_OUTPUT_DEPTH_REGISTER_COMPONENTS :: 1 +PS_OUTPUT_DEPTH_REGISTER_COMPONENT_BIT_COUNT :: 32 +PS_OUTPUT_DEPTH_REGISTER_COUNT :: 1 +PS_OUTPUT_MASK_REGISTER_COMPONENTS :: 1 +PS_OUTPUT_MASK_REGISTER_COMPONENT_BIT_COUNT :: 32 +PS_OUTPUT_MASK_REGISTER_COUNT :: 1 +PS_OUTPUT_REGISTER_COMPONENTS :: 4 +PS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT :: 32 +PS_OUTPUT_REGISTER_COUNT :: 8 +PS_PIXEL_CENTER_FRACTIONAL_COMPONENT :: 0.5 +RAW_UAV_SRV_BYTE_ALIGNMENT :: 16 +REQ_BLEND_OBJECT_COUNT_PER_DEVICE :: 4096 +REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP :: 27 +REQ_CONSTANT_BUFFER_ELEMENT_COUNT :: 4096 +REQ_DEPTH_STENCIL_OBJECT_COUNT_PER_DEVICE :: 4096 +REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP :: 32 +REQ_DRAW_VERTEX_COUNT_2_TO_EXP :: 32 +REQ_FILTERING_HW_ADDRESSABLE_RESOURCE_DIMENSION :: 16384 +REQ_GS_INVOCATION_32BIT_OUTPUT_COMPONENT_LIMIT :: 1024 +REQ_IMMEDIATE_CONSTANT_BUFFER_ELEMENT_COUNT :: 4096 +REQ_MAXANISOTROPY :: 16 +REQ_MIP_LEVELS :: 15 +REQ_MULTI_ELEMENT_STRUCTURE_SIZE_IN_BYTES :: 2048 +REQ_RASTERIZER_OBJECT_COUNT_PER_DEVICE :: 4096 +REQ_RENDER_TO_BUFFER_WINDOW_WIDTH :: 16384 +REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_A_TERM :: 128 +REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_B_TERM :: 0.25 +REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_C_TERM :: 2048 +REQ_RESOURCE_VIEW_COUNT_PER_DEVICE_2_TO_EXP :: 20 +REQ_SAMPLER_OBJECT_COUNT_PER_DEVICE :: 4096 +REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION :: 2048 +REQ_TEXTURE1D_U_DIMENSION :: 16384 +REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION :: 2048 +REQ_TEXTURE2D_U_OR_V_DIMENSION :: 16384 +REQ_TEXTURE3D_U_V_OR_W_DIMENSION :: 2048 +REQ_TEXTURECUBE_DIMENSION :: 16384 +RESINFO_INSTRUCTION_MISSING_COMPONENT_RETVAL :: 0 +SHADER_MAJOR_VERSION :: 5 +SHADER_MAX_INSTANCES :: 65535 +SHADER_MAX_INTERFACES :: 253 +SHADER_MAX_INTERFACE_CALL_SITES :: 4096 +SHADER_MAX_TYPES :: 65535 +SHADER_MINOR_VERSION :: 0 +SHIFT_INSTRUCTION_PAD_VALUE :: 0 +SHIFT_INSTRUCTION_SHIFT_VALUE_BIT_COUNT :: 5 +SIMULTANEOUS_RENDER_TARGET_COUNT :: 8 +SO_BUFFER_MAX_STRIDE_IN_BYTES :: 2048 +SO_BUFFER_MAX_WRITE_WINDOW_IN_BYTES :: 512 +SO_BUFFER_SLOT_COUNT :: 4 +SO_DDI_REGISTER_INDEX_DENOTING_GAP :: 0xffffffff +SO_NO_RASTERIZED_STREAM :: 0xffffffff +SO_OUTPUT_COMPONENT_COUNT :: 128 +SO_STREAM_COUNT :: 4 +SPEC_DATE_DAY :: 16 +SPEC_DATE_YEAR :: 2011 +SPEC_VERSION :: 1.07 +SRGB_GAMMA :: 2.2 +SRGB_TO_FLOAT_DENOMINATOR_1 :: 12.92 +SRGB_TO_FLOAT_DENOMINATOR_2 :: 1.055 +SRGB_TO_FLOAT_EXPONENT :: 2.4 +SRGB_TO_FLOAT_OFFSET :: 0.055 +SRGB_TO_FLOAT_THRESHOLD :: 0.04045 +SRGB_TO_FLOAT_TOLERANCE_IN_ULP :: 0.5 +STANDARD_COMPONENT_BIT_COUNT :: 32 +STANDARD_COMPONENT_BIT_COUNT_DOUBLED :: 64 +STANDARD_MAXIMUM_ELEMENT_ALIGNMENT_BYTE_MULTIPLE :: 4 +STANDARD_PIXEL_COMPONENT_COUNT :: 128 +STANDARD_PIXEL_ELEMENT_COUNT :: 32 +STANDARD_VECTOR_SIZE :: 4 +STANDARD_VERTEX_ELEMENT_COUNT :: 32 +STANDARD_VERTEX_TOTAL_COMPONENT_COUNT :: 64 +SUBPIXEL_FRACTIONAL_BIT_COUNT :: 8 +SUBTEXEL_FRACTIONAL_BIT_COUNT :: 8 +TESSELLATOR_MAX_EVEN_TESSELLATION_FACTOR :: 64 +TESSELLATOR_MAX_ISOLINE_DENSITY_TESSELLATION_FACTOR :: 64 +TESSELLATOR_MAX_ODD_TESSELLATION_FACTOR :: 63 +TESSELLATOR_MAX_TESSELLATION_FACTOR :: 64 +TESSELLATOR_MIN_EVEN_TESSELLATION_FACTOR :: 2 +TESSELLATOR_MIN_ISOLINE_DENSITY_TESSELLATION_FACTOR :: 1 +TESSELLATOR_MIN_ODD_TESSELLATION_FACTOR :: 1 +TEXEL_ADDRESS_RANGE_BIT_COUNT :: 16 +UNBOUND_MEMORY_ACCESS_RESULT :: 0 +VIEWPORT_AND_SCISSORRECT_MAX_INDEX :: 15 +VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE :: 16 +VIEWPORT_BOUNDS_MAX :: 32767 +VIEWPORT_BOUNDS_MIN :: -32768 +VS_INPUT_REGISTER_COMPONENTS :: 4 +VS_INPUT_REGISTER_COMPONENT_BIT_COUNT :: 32 +VS_INPUT_REGISTER_COUNT :: 32 +VS_INPUT_REGISTER_READS_PER_INST :: 2 +VS_INPUT_REGISTER_READ_PORTS :: 1 +VS_OUTPUT_REGISTER_COMPONENTS :: 4 +VS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT :: 32 +VS_OUTPUT_REGISTER_COUNT :: 32 +WHQL_CONTEXT_COUNT_FOR_RESOURCE_LIMIT :: 10 +WHQL_DRAWINDEXED_INDEX_COUNT_2_TO_EXP :: 25 +WHQL_DRAW_VERTEX_COUNT_2_TO_EXP :: 25 +_1_UAV_SLOT_COUNT :: 64 +_2_TILED_RESOURCE_TILE_SIZE_IN_BYTES :: 65536 +_4_VIDEO_DECODER_MAX_HISTOGRAM_COMPONENTS :: 4 +_4_VIDEO_DECODER_HISTOGRAM_OFFSET_ALIGNMENT :: 256 + +_FACD3D11 :: 0x87c + +APPEND_ALIGNED_ELEMENT :: 0xffffffff +FILTER_REDUCTION_TYPE_MASK :: 0x3 +FILTER_REDUCTION_TYPE_SHIFT :: 7 +FILTER_TYPE_MASK :: 0x3 +MIN_FILTER_SHIFT :: 4 +MAG_FILTER_SHIFT :: 2 +MIP_FILTER_SHIFT :: 0 +COMPARISON_FILTERING_BIT :: 0x80 +ANISOTROPIC_FILTERING_BIT :: 0x40 +SDK_VERSION :: 7 +RETURN_PARAMETER_INDEX :: -1 + +COMPONENT_MASK :: enum u32 { // TODO: make bit_set + X = 1, + Y = 2, + Z = 4, + W = 8, +} + +SHADER_REQUIRES :: enum u32 { // TODO: make bit_set + DOUBLES = 0x00000001, + EARLY_DEPTH_STENCIL = 0x00000002, + UAVS_AT_EVERY_STAGE = 0x00000004, + _64_UAVS = 0x00000008, + MINIMUM_PRECISION = 0x00000010, + _11_1_DOUBLE_EXTENSIONS = 0x00000020, + _11_1_SHADER_EXTENSIONS = 0x00000040, + LEVEL_9_COMPARISON_FILTERING = 0x00000080, + TILED_RESOURCES = 0x00000100, +} + +DRIVER_TYPE :: enum i32 { + UNKNOWN = 0, + HARDWARE = 1, + REFERENCE = 2, + NULL = 3, + SOFTWARE = 4, + WARP = 5, +} + +FEATURE_LEVEL :: enum i32 { + _1_0_CORE = 4096, + _9_1 = 37120, + _9_2 = 37376, + _9_3 = 37632, + _10_0 = 40960, + _10_1 = 41216, + _11_0 = 45056, + _11_1 = 45312, + _12_0 = 49152, + _12_1 = 49408, +} + +PRIMITIVE_TOPOLOGY :: enum i32 { + UNDEFINED = 0, + POINTLIST = 1, + LINELIST = 2, + LINESTRIP = 3, + TRIANGLELIST = 4, + TRIANGLESTRIP = 5, + LINELIST_ADJ = 10, + LINESTRIP_ADJ = 11, + TRIANGLELIST_ADJ = 12, + TRIANGLESTRIP_ADJ = 13, + _1_CONTROL_POINT_PATCHLIST = 33, + _2_CONTROL_POINT_PATCHLIST = 34, + _3_CONTROL_POINT_PATCHLIST = 35, + _4_CONTROL_POINT_PATCHLIST = 36, + _5_CONTROL_POINT_PATCHLIST = 37, + _6_CONTROL_POINT_PATCHLIST = 38, + _7_CONTROL_POINT_PATCHLIST = 39, + _8_CONTROL_POINT_PATCHLIST = 40, + _9_CONTROL_POINT_PATCHLIST = 41, + _10_CONTROL_POINT_PATCHLIST = 42, + _11_CONTROL_POINT_PATCHLIST = 43, + _12_CONTROL_POINT_PATCHLIST = 44, + _13_CONTROL_POINT_PATCHLIST = 45, + _14_CONTROL_POINT_PATCHLIST = 46, + _15_CONTROL_POINT_PATCHLIST = 47, + _16_CONTROL_POINT_PATCHLIST = 48, + _17_CONTROL_POINT_PATCHLIST = 49, + _18_CONTROL_POINT_PATCHLIST = 50, + _19_CONTROL_POINT_PATCHLIST = 51, + _20_CONTROL_POINT_PATCHLIST = 52, + _21_CONTROL_POINT_PATCHLIST = 53, + _22_CONTROL_POINT_PATCHLIST = 54, + _23_CONTROL_POINT_PATCHLIST = 55, + _24_CONTROL_POINT_PATCHLIST = 56, + _25_CONTROL_POINT_PATCHLIST = 57, + _26_CONTROL_POINT_PATCHLIST = 58, + _27_CONTROL_POINT_PATCHLIST = 59, + _28_CONTROL_POINT_PATCHLIST = 60, + _29_CONTROL_POINT_PATCHLIST = 61, + _30_CONTROL_POINT_PATCHLIST = 62, + _31_CONTROL_POINT_PATCHLIST = 63, + _32_CONTROL_POINT_PATCHLIST = 64, +} + +PRIMITIVE :: enum i32 { + UNDEFINED = 0, + POINT = 1, + LINE = 2, + TRIANGLE = 3, + LINE_ADJ = 6, + TRIANGLE_ADJ = 7, + _1_CONTROL_POINT_PATCH = 8, + _2_CONTROL_POINT_PATCH = 9, + _3_CONTROL_POINT_PATCH = 10, + _4_CONTROL_POINT_PATCH = 11, + _5_CONTROL_POINT_PATCH = 12, + _6_CONTROL_POINT_PATCH = 13, + _7_CONTROL_POINT_PATCH = 14, + _8_CONTROL_POINT_PATCH = 15, + _9_CONTROL_POINT_PATCH = 16, + _10_CONTROL_POINT_PATCH = 17, + _11_CONTROL_POINT_PATCH = 18, + _12_CONTROL_POINT_PATCH = 19, + _13_CONTROL_POINT_PATCH = 20, + _14_CONTROL_POINT_PATCH = 21, + _15_CONTROL_POINT_PATCH = 22, + _16_CONTROL_POINT_PATCH = 23, + _17_CONTROL_POINT_PATCH = 24, + _18_CONTROL_POINT_PATCH = 25, + _19_CONTROL_POINT_PATCH = 26, + _20_CONTROL_POINT_PATCH = 27, + _21_CONTROL_POINT_PATCH = 28, + _22_CONTROL_POINT_PATCH = 29, + _23_CONTROL_POINT_PATCH = 30, + _24_CONTROL_POINT_PATCH = 31, + _25_CONTROL_POINT_PATCH = 32, + _26_CONTROL_POINT_PATCH = 33, + _27_CONTROL_POINT_PATCH = 34, + _28_CONTROL_POINT_PATCH = 35, + _29_CONTROL_POINT_PATCH = 36, + _30_CONTROL_POINT_PATCH = 37, + _31_CONTROL_POINT_PATCH = 38, + _32_CONTROL_POINT_PATCH = 39, +} + +SRV_DIMENSION :: enum i32 { + UNKNOWN = 0, + BUFFER = 1, + TEXTURE1D = 2, + TEXTURE1DARRAY = 3, + TEXTURE2D = 4, + TEXTURE2DARRAY = 5, + TEXTURE2DMS = 6, + TEXTURE2DMSARRAY = 7, + TEXTURE3D = 8, + TEXTURECUBE = 9, + TEXTURECUBEARRAY = 10, + BUFFEREX = 11, +} + +PFN_DESTRUCTION_CALLBACK :: #type proc "c" (a0: rawptr) + + +ID3DDestructionNotifier_UUID_STRING :: "A06EB39A-50DA-425B-8C31-4EECD6C270F3" +ID3DDestructionNotifier_UUID := &IID{0xA06EB39A, 0x50DA, 0x425B, {0x8C, 0x31, 0x4E, 0xEC, 0xD6, 0xC2, 0x70, 0xF3}} +ID3DDestructionNotifier :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3ddestructionnotifier_vtable: ^ID3DDestructionNotifier_VTable, +} +ID3DDestructionNotifier_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + RegisterDestructionCallback: proc "stdcall" (this: ^ID3DDestructionNotifier, callbackFn: PFN_DESTRUCTION_CALLBACK, pData: rawptr, pCallbackID: ^u32) -> HRESULT, + UnregisterDestructionCallback: proc "stdcall" (this: ^ID3DDestructionNotifier, callbackID: u32) -> HRESULT, +} + + +SHADER_VARIABLE_CLASS :: enum i32 { + SCALAR = 0, + VECTOR = 1, + MATRIX_ROWS = 2, + MATRIX_COLUMNS = 3, + OBJECT = 4, + STRUCT = 5, + INTERFACE_CLASS = 6, + INTERFACE_POINTER = 7, +} + +SHADER_VARIABLE_FLAGS :: enum u32 { // TODO: make bit_set + USERPACKED = 0x1, + USED = 0x2, + INTERFACE_POINTER = 0x4, + INTERFACE_PARAMETER = 0x8, +} + +SHADER_VARIABLE_TYPE :: enum i32 { + VOID = 0, + BOOL = 1, + INT = 2, + FLOAT = 3, + STRING = 4, + TEXTURE = 5, + TEXTURE1D = 6, + TEXTURE2D = 7, + TEXTURE3D = 8, + TEXTURECUBE = 9, + SAMPLER = 10, + SAMPLER1D = 11, + SAMPLER2D = 12, + SAMPLER3D = 13, + SAMPLERCUBE = 14, + PIXELSHADER = 15, + VERTEXSHADER = 16, + PIXELFRAGMENT = 17, + VERTEXFRAGMENT = 18, + UINT = 19, + UINT8 = 20, + GEOMETRYSHADER = 21, + RASTERIZER = 22, + DEPTHSTENCIL = 23, + BLEND = 24, + BUFFER = 25, + CBUFFER = 26, + TBUFFER = 27, + TEXTURE1DARRAY = 28, + TEXTURE2DARRAY = 29, + RENDERTARGETVIEW = 30, + DEPTHSTENCILVIEW = 31, + TEXTURE2DMS = 32, + TEXTURE2DMSARRAY = 33, + TEXTURECUBEARRAY = 34, + HULLSHADER = 35, + DOMAINSHADER = 36, + INTERFACE_POINTER = 37, + COMPUTESHADER = 38, + DOUBLE = 39, + RWTEXTURE1D = 40, + RWTEXTURE1DARRAY = 41, + RWTEXTURE2D = 42, + RWTEXTURE2DARRAY = 43, + RWTEXTURE3D = 44, + RWBUFFER = 45, + BYTEADDRESS_BUFFER = 46, + RWBYTEADDRESS_BUFFER = 47, + STRUCTURED_BUFFER = 48, + RWSTRUCTURED_BUFFER = 49, + APPEND_STRUCTURED_BUFFER = 50, + CONSUME_STRUCTURED_BUFFER = 51, + MIN8FLOAT = 52, + MIN10FLOAT = 53, + MIN16FLOAT = 54, + MIN12INT = 55, + MIN16INT = 56, + MIN16UINT = 57, +} + +SHADER_INPUT_FLAGS :: enum u32 { // TODO: make bit_set + USERPACKED = 0x1, + COMPARISON_SAMPLER = 0x2, + TEXTURE_COMPONENT_0 = 0x4, + TEXTURE_COMPONENT_1 = 0x8, + TEXTURE_COMPONENTS = 0xc, + UNUSED = 0x10, +} + +SHADER_INPUT_TYPE :: enum i32 { + CBUFFER = 0, + TBUFFER = 1, + TEXTURE = 2, + SAMPLER = 3, + UAV_RWTYPED = 4, + STRUCTURED = 5, + UAV_RWSTRUCTURED = 6, + BYTEADDRESS = 7, + UAV_RWBYTEADDRESS = 8, + UAV_APPEND_STRUCTURED = 9, + UAV_CONSUME_STRUCTURED = 10, + UAV_RWSTRUCTURED_WITH_COUNTER = 11, + RTACCELERATIONSTRUCTURE = 12, + UAV_FEEDBACKTEXTURE = 13, +} + +SHADER_CBUFFER_FLAGS :: enum u32 { // TODO: make bit_set + USERPACKED = 0x1, +} + +CBUFFER_TYPE :: enum i32 { + CBUFFER = 0, + TBUFFER = 1, + INTERFACE_POINTERS = 2, + RESOURCE_BIND_INFO = 3, +} + +NAME :: enum i32 { + UNDEFINED = 0, + POSITION = 1, + CLIP_DISTANCE = 2, + CULL_DISTANCE = 3, + RENDER_TARGET_ARRAY_INDEX = 4, + VIEWPORT_ARRAY_INDEX = 5, + VERTEX_ID = 6, + PRIMITIVE_ID = 7, + INSTANCE_ID = 8, + IS_FRONT_FACE = 9, + SAMPLE_INDEX = 10, + FINAL_QUAD_EDGE_TESSFACTOR = 11, + FINAL_QUAD_INSIDE_TESSFACTOR = 12, + FINAL_TRI_EDGE_TESSFACTOR = 13, + FINAL_TRI_INSIDE_TESSFACTOR = 14, + FINAL_LINE_DETAIL_TESSFACTOR = 15, + FINAL_LINE_DENSITY_TESSFACTOR = 16, + BARYCENTRICS = 23, + SHADINGRATE = 24, + CULLPRIMITIVE = 25, + TARGET = 64, + DEPTH = 65, + COVERAGE = 66, + DEPTH_GREATER_EQUAL = 67, + DEPTH_LESS_EQUAL = 68, + STENCIL_REF = 69, + INNER_COVERAGE = 70, +} + +RESOURCE_RETURN_TYPE :: enum i32 { + UNORM = 1, + SNORM = 2, + SINT = 3, + UINT = 4, + FLOAT = 5, + MIXED = 6, + DOUBLE = 7, + CONTINUED = 8, +} + +REGISTER_COMPONENT_TYPE :: enum i32 { + UNKNOWN = 0, + UINT32 = 1, + SINT32 = 2, + FLOAT32 = 3, +} + +TESSELLATOR_DOMAIN :: enum i32 { + UNDEFINED = 0, + ISOLINE = 1, + TRI = 2, + QUAD = 3, +} + +TESSELLATOR_PARTITIONING :: enum i32 { + UNDEFINED = 0, + INTEGER = 1, + POW2 = 2, + FRACTIONAL_ODD = 3, + FRACTIONAL_EVEN = 4, +} + +TESSELLATOR_OUTPUT_PRIMITIVE :: enum i32 { + UNDEFINED = 0, + POINT = 1, + LINE = 2, + TRIANGLE_CW = 3, + TRIANGLE_CCW = 4, +} + +MIN_PRECISION :: enum i32 { + DEFAULT = 0, + FLOAT_16 = 1, + FLOAT_2_8 = 2, + RESERVED = 3, + SINT_16 = 4, + UINT_16 = 5, + ANY_16 = 240, + ANY_10 = 241, +} + +INTERPOLATION_MODE :: enum i32 { + UNDEFINED = 0, + CONSTANT = 1, + LINEAR = 2, + LINEAR_CENTROID = 3, + LINEAR_NOPERSPECTIVE = 4, + LINEAR_NOPERSPECTIVE_CENTROID = 5, + LINEAR_SAMPLE = 6, + LINEAR_NOPERSPECTIVE_SAMPLE = 7, +} + +PARAMETER_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + IN = 0x1, + OUT = 0x2, +} + +CDEFAULT :: struct { + _: u8, +} + +INPUT_CLASSIFICATION :: enum i32 { + VERTEX_DATA = 0, + INSTANCE_DATA = 1, +} + +INPUT_ELEMENT_DESC :: struct { + SemanticName: cstring, + SemanticIndex: u32, + Format: dxgi.FORMAT, + InputSlot: u32, + AlignedByteOffset: u32, + InputSlotClass: INPUT_CLASSIFICATION, + InstanceDataStepRate: u32, +} + +FILL_MODE :: enum i32 { + WIREFRAME = 2, + SOLID = 3, +} + +CULL_MODE :: enum i32 { + NONE = 1, + FRONT = 2, + BACK = 3, +} + +SO_DECLARATION_ENTRY :: struct { + Stream: u32, + SemanticName: cstring, + SemanticIndex: u32, + StartComponent: u8, + ComponentCount: u8, + OutputSlot: u8, +} + +VIEWPORT :: struct { + TopLeftX: f32, + TopLeftY: f32, + Width: f32, + Height: f32, + MinDepth: f32, + MaxDepth: f32, +} + +DRAW_INSTANCED_INDIRECT_ARGS :: struct { + VertexCountPerInstance: u32, + InstanceCount: u32, + StartVertexLocation: u32, + StartInstanceLocation: u32, +} + +DRAW_INDEXED_INSTANCED_INDIRECT_ARGS :: struct { + IndexCountPerInstance: u32, + InstanceCount: u32, + StartIndexLocation: u32, + BaseVertexLocation: i32, + StartInstanceLocation: u32, +} + +RESOURCE_DIMENSION :: enum i32 { + UNKNOWN = 0, + BUFFER = 1, + TEXTURE1D = 2, + TEXTURE2D = 3, + TEXTURE3D = 4, +} + +DSV_DIMENSION :: enum i32 { + UNKNOWN = 0, + TEXTURE1D = 1, + TEXTURE1DARRAY = 2, + TEXTURE2D = 3, + TEXTURE2DARRAY = 4, + TEXTURE2DMS = 5, + TEXTURE2DMSARRAY = 6, +} + +RTV_DIMENSION :: enum i32 { + UNKNOWN = 0, + BUFFER = 1, + TEXTURE1D = 2, + TEXTURE1DARRAY = 3, + TEXTURE2D = 4, + TEXTURE2DARRAY = 5, + TEXTURE2DMS = 6, + TEXTURE2DMSARRAY = 7, + TEXTURE3D = 8, +} + +UAV_DIMENSION :: enum i32 { + UNKNOWN = 0, + BUFFER = 1, + TEXTURE1D = 2, + TEXTURE1DARRAY = 3, + TEXTURE2D = 4, + TEXTURE2DARRAY = 5, + TEXTURE3D = 8, +} + +USAGE :: enum i32 { + DEFAULT = 0, + IMMUTABLE = 1, + DYNAMIC = 2, + STAGING = 3, +} + +BIND_FLAG :: enum u32 { // TODO: make bit_set + VERTEX_BUFFER = 0x1, + INDEX_BUFFER = 0x2, + CONSTANT_BUFFER = 0x4, + SHADER_RESOURCE = 0x8, + STREAM_OUTPUT = 0x10, + RENDER_TARGET = 0x20, + DEPTH_STENCIL = 0x40, + UNORDERED_ACCESS = 0x80, + DECODER = 0x200, + VIDEO_ENCODER = 0x400, +} + +CPU_ACCESS_FLAG :: enum u32 { // TODO: make bit_set + WRITE = 0x10000, + READ = 0x20000, + +} + +RESOURCE_MISC_FLAG :: enum u32 { // TODO: make bit_set + GENERATE_MIPS = 0x1, + SHARED = 0x2, + TEXTURECUBE = 0x4, + DRAWINDIRECT_ARGS = 0x10, + BUFFER_ALLOW_RAW_VIEWS = 0x20, + BUFFER_STRUCTURED = 0x40, + RESOURCE_CLAMP = 0x80, + SHARED_KEYEDMUTEX = 0x100, + GDI_COMPATIBLE = 0x200, + SHARED_NTHANDLE = 0x800, + RESTRICTED_CONTENT = 0x1000, + RESTRICT_SHARED_RESOURCE = 0x2000, + RESTRICT_SHARED_RESOURCE_DRIVER = 0x4000, + GUARDED = 0x8000, + TILE_POOL = 0x20000, + TILED = 0x40000, + HW_PROTECTED = 0x80000, +} + +MAP :: enum i32 { + READ = 1, + WRITE = 2, + READ_WRITE = 3, + WRITE_DISCARD = 4, + WRITE_NO_OVERWRITE = 5, +} + +MAP_FLAG :: enum u32 { // TODO: make bit_set + DO_NOT_WAIT = 0x100000, +} + +RAISE_FLAG :: enum u32 { // TODO: make bit_set + DRIVER_INTERNAL_ERROR = 0x1, +} + +CLEAR_FLAG :: enum u32 { // TODO: make bit_set + DEPTH = 0x1, + STENCIL = 0x2, +} + + +CRECT :: struct { + using d3d11_rect: RECT, +} + +BOX :: struct { + left: u32, + top: u32, + front: u32, + right: u32, + bottom: u32, + back: u32, +} + +CBOX :: struct { + using d3d11_box: BOX, +} + + +IDeviceChild_UUID_STRING :: "1841E5C8-16B0-489B-BCC8-44CFB0D5DEAE" +IDeviceChild_UUID := &IID{0x1841E5C8, 0x16B0, 0x489B, {0xBC, 0xC8, 0x44, 0xCF, 0xB0, 0xD5, 0xDE, 0xAE}} +IDeviceChild :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d11devicechild_vtable: ^IDeviceChild_VTable, +} +IDeviceChild_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + GetDevice: proc "stdcall" (this: ^IDeviceChild, ppDevice: ^^IDevice), + GetPrivateData: proc "stdcall" (this: ^IDeviceChild, guid: ^GUID, pDataSize: ^u32, pData: rawptr) -> HRESULT, + SetPrivateData: proc "stdcall" (this: ^IDeviceChild, guid: ^GUID, DataSize: u32, pData: rawptr) -> HRESULT, + SetPrivateDataInterface: proc "stdcall" (this: ^IDeviceChild, guid: ^GUID, pData: ^IUnknown) -> HRESULT, +} + + +COMPARISON_FUNC :: enum i32 { + NEVER = 1, + LESS = 2, + EQUAL = 3, + LESS_EQUAL = 4, + GREATER = 5, + NOT_EQUAL = 6, + GREATER_EQUAL = 7, + ALWAYS = 8, +} + +DEPTH_WRITE_MASK :: enum i32 { + ZERO = 0, + ALL = 1, +} + +STENCIL_OP :: enum i32 { + KEEP = 1, + ZERO = 2, + REPLACE = 3, + INCR_SAT = 4, + DECR_SAT = 5, + INVERT = 6, + INCR = 7, + DECR = 8, +} + +DEPTH_STENCILOP_DESC :: struct { + StencilFailOp: STENCIL_OP, + StencilDepthFailOp: STENCIL_OP, + StencilPassOp: STENCIL_OP, + StencilFunc: COMPARISON_FUNC, +} + +DEPTH_STENCIL_DESC :: struct { + DepthEnable: BOOL, + DepthWriteMask: DEPTH_WRITE_MASK, + DepthFunc: COMPARISON_FUNC, + StencilEnable: BOOL, + StencilReadMask: u8, + StencilWriteMask: u8, + FrontFace: DEPTH_STENCILOP_DESC, + BackFace: DEPTH_STENCILOP_DESC, +} + +CDEPTH_STENCIL_DESC :: struct { + using d3d11_depth_stencil_desc: DEPTH_STENCIL_DESC, +} + + +IDepthStencilState_UUID_STRING :: "03823EFB-8D8F-4E1C-9AA2-F64BB2CBFDF1" +IDepthStencilState_UUID := &IID{0x03823EFB, 0x8D8F, 0x4E1C, {0x9A, 0xA2, 0xF6, 0x4B, 0xB2, 0xCB, 0xFD, 0xF1}} +IDepthStencilState :: struct #raw_union { + #subtype id3d11devicechild: IDeviceChild, + using id3d11depthstencilstate_vtable: ^IDepthStencilState_VTable, +} +IDepthStencilState_VTable :: struct { + using id3d11devicechild_vtable: IDeviceChild_VTable, + GetDesc: proc "stdcall" (this: ^IDepthStencilState, pDesc: ^DEPTH_STENCIL_DESC), +} + + +BLEND :: enum i32 { + ZERO = 1, + ONE = 2, + SRC_COLOR = 3, + INV_SRC_COLOR = 4, + SRC_ALPHA = 5, + INV_SRC_ALPHA = 6, + DEST_ALPHA = 7, + INV_DEST_ALPHA = 8, + DEST_COLOR = 9, + INV_DEST_COLOR = 10, + SRC_ALPHA_SAT = 11, + BLEND_FACTOR = 14, + INV_BLEND_FACTOR = 15, + SRC1_COLOR = 16, + INV_SRC1_COLOR = 17, + SRC1_ALPHA = 18, + INV_SRC1_ALPHA = 19, +} + +BLEND_OP :: enum i32 { + ADD = 1, + SUBTRACT = 2, + REV_SUBTRACT = 3, + MIN = 4, + MAX = 5, +} + +COLOR_WRITE_ENABLE :: enum i32 { // TODO: make bit_set + RED = 1, + GREEN = 2, + BLUE = 4, + ALPHA = 8, + ALL = 15, +} + +RENDER_TARGET_BLEND_DESC :: struct { + BlendEnable: BOOL, + SrcBlend: BLEND, + DestBlend: BLEND, + BlendOp: BLEND_OP, + SrcBlendAlpha: BLEND, + DestBlendAlpha: BLEND, + BlendOpAlpha: BLEND_OP, + RenderTargetWriteMask: u8, +} + +BLEND_DESC :: struct { + AlphaToCoverageEnable: BOOL, + IndependentBlendEnable: BOOL, + RenderTarget: [8]RENDER_TARGET_BLEND_DESC, +} + +CBLEND_DESC :: struct { + using d3d11_blend_desc: BLEND_DESC, +} + + +IBlendState_UUID_STRING :: "75B68FAA-347D-4159-8F45-A0640F01CD9A" +IBlendState_UUID := &IID{0x75B68FAA, 0x347D, 0x4159, {0x8F, 0x45, 0xA0, 0x64, 0x0F, 0x01, 0xCD, 0x9A}} +IBlendState :: struct #raw_union { + #subtype id3d11devicechild: IDeviceChild, + using id3d11blendstate_vtable: ^IBlendState_VTable, +} +IBlendState_VTable :: struct { + using id3d11devicechild_vtable: IDeviceChild_VTable, + GetDesc: proc "stdcall" (this: ^IBlendState, pDesc: ^BLEND_DESC), +} + + +RASTERIZER_DESC :: struct { + FillMode: FILL_MODE, + CullMode: CULL_MODE, + FrontCounterClockwise: BOOL, + DepthBias: i32, + DepthBiasClamp: f32, + SlopeScaledDepthBias: f32, + DepthClipEnable: BOOL, + ScissorEnable: BOOL, + MultisampleEnable: BOOL, + AntialiasedLineEnable: BOOL, +} + +CRASTERIZER_DESC :: struct { + using d3d11_rasterizer_desc: RASTERIZER_DESC, +} + + +IRasterizerState_UUID_STRING :: "9BB4AB81-AB1A-4D8F-B506-FC04200B6EE7" +IRasterizerState_UUID := &IID{0x9BB4AB81, 0xAB1A, 0x4D8F, {0xB5, 0x06, 0xFC, 0x04, 0x20, 0x0B, 0x6E, 0xE7}} +IRasterizerState :: struct #raw_union { + #subtype id3d11devicechild: IDeviceChild, + using id3d11rasterizerstate_vtable: ^IRasterizerState_VTable, +} +IRasterizerState_VTable :: struct { + using id3d11devicechild_vtable: IDeviceChild_VTable, + GetDesc: proc "stdcall" (this: ^IRasterizerState, pDesc: ^RASTERIZER_DESC), +} + + +SUBRESOURCE_DATA :: struct { + pSysMem: rawptr, + SysMemPitch: u32, + SysMemSlicePitch: u32, +} + +MAPPED_SUBRESOURCE :: struct { + pData: rawptr, + RowPitch: u32, + DepthPitch: u32, +} + + +IResource_UUID_STRING :: "DC8E63F3-D12B-4952-B47B-5E45026A862D" +IResource_UUID := &IID{0xDC8E63F3, 0xD12B, 0x4952, {0xB4, 0x7B, 0x5E, 0x45, 0x02, 0x6A, 0x86, 0x2D}} +IResource :: struct #raw_union { + #subtype id3d11devicechild: IDeviceChild, + using id3d11resource_vtable: ^IResource_VTable, +} +IResource_VTable :: struct { + using id3d11devicechild_vtable: IDeviceChild_VTable, + GetType: proc "stdcall" (this: ^IResource, pResourceDimension: ^RESOURCE_DIMENSION), + SetEvictionPriority: proc "stdcall" (this: ^IResource, EvictionPriority: u32), + GetEvictionPriority: proc "stdcall" (this: ^IResource) -> u32, +} + + +BUFFER_DESC :: struct { + ByteWidth: u32, + Usage: USAGE, + BindFlags: BIND_FLAG, + CPUAccessFlags: CPU_ACCESS_FLAG, + MiscFlags: RESOURCE_MISC_FLAG, + StructureByteStride: u32, +} + +CBUFFER_DESC :: struct { + using d3d11_buffer_desc: BUFFER_DESC, +} + + +IBuffer_UUID_STRING :: "48570B85-D1EE-4FCD-A250-EB350722B037" +IBuffer_UUID := &IID{0x48570B85, 0xD1EE, 0x4FCD, {0xA2, 0x50, 0xEB, 0x35, 0x07, 0x22, 0xB0, 0x37}} +IBuffer :: struct #raw_union { + #subtype id3d11resource: IResource, + using id3d11buffer_vtable: ^IBuffer_VTable, +} +IBuffer_VTable :: struct { + using id3d11resource_vtable: IResource_VTable, + GetDesc: proc "stdcall" (this: ^IBuffer, pDesc: ^BUFFER_DESC), +} + + +TEXTURE1D_DESC :: struct { + Width: u32, + MipLevels: u32, + ArraySize: u32, + Format: dxgi.FORMAT, + Usage: USAGE, + BindFlags: BIND_FLAG, + CPUAccessFlags: CPU_ACCESS_FLAG, + MiscFlags: RESOURCE_MISC_FLAG, +} + +CTEXTURE1D_DESC :: struct { + using d3d11_texture1d_desc: TEXTURE1D_DESC, +} + + +ITexture1D_UUID_STRING :: "F8FB5C27-C6B3-4F75-A4C8-439AF2EF564C" +ITexture1D_UUID := &IID{0xF8FB5C27, 0xC6B3, 0x4F75, {0xA4, 0xC8, 0x43, 0x9A, 0xF2, 0xEF, 0x56, 0x4C}} +ITexture1D :: struct #raw_union { + #subtype id3d11resource: IResource, + using id3d11texture1d_vtable: ^ITexture1D_VTable, +} +ITexture1D_VTable :: struct { + using id3d11resource_vtable: IResource_VTable, + GetDesc: proc "stdcall" (this: ^ITexture1D, pDesc: ^TEXTURE1D_DESC), +} + + +TEXTURE2D_DESC :: struct { + Width: u32, + Height: u32, + MipLevels: u32, + ArraySize: u32, + Format: dxgi.FORMAT, + SampleDesc: dxgi.SAMPLE_DESC, + Usage: USAGE, + BindFlags: BIND_FLAG, + CPUAccessFlags: CPU_ACCESS_FLAG, + MiscFlags: RESOURCE_MISC_FLAG, +} + +CTEXTURE2D_DESC :: struct { + using d3d11_texture2d_desc: TEXTURE2D_DESC, +} + + +ITexture2D_UUID_STRING :: "6F15AAF2-D208-4E89-9AB4-489535D34F9C" +ITexture2D_UUID := &IID{0x6F15AAF2, 0xD208, 0x4E89, {0x9A, 0xB4, 0x48, 0x95, 0x35, 0xD3, 0x4F, 0x9C}} +ITexture2D :: struct #raw_union { + #subtype id3d11resource: IResource, + using id3d11texture2d_vtable: ^ITexture2D_VTable, +} +ITexture2D_VTable :: struct { + using id3d11resource_vtable: IResource_VTable, + GetDesc: proc "stdcall" (this: ^ITexture2D, pDesc: ^TEXTURE2D_DESC), +} + + +TEXTURE3D_DESC :: struct { + Width: u32, + Height: u32, + Depth: u32, + MipLevels: u32, + Format: dxgi.FORMAT, + Usage: USAGE, + BindFlags: BIND_FLAG, + CPUAccessFlags: CPU_ACCESS_FLAG, + MiscFlags: RESOURCE_MISC_FLAG, +} + +CTEXTURE3D_DESC :: struct { + using d3d11_texture3d_desc: TEXTURE3D_DESC, +} + + +ITexture3D_UUID_STRING :: "037E866E-F56D-4357-A8AF-9DABBE6E250E" +ITexture3D_UUID := &IID{0x037E866E, 0xF56D, 0x4357, {0xA8, 0xAF, 0x9D, 0xAB, 0xBE, 0x6E, 0x25, 0x0E}} +ITexture3D :: struct #raw_union { + #subtype id3d11resource: IResource, + using id3d11texture3d_vtable: ^ITexture3D_VTable, +} +ITexture3D_VTable :: struct { + using id3d11resource_vtable: IResource_VTable, + GetDesc: proc "stdcall" (this: ^ITexture3D, pDesc: ^TEXTURE3D_DESC), +} + + +TEXTURECUBE_FACE :: enum i32 { + POSITIVE_X = 0, + NEGATIVE_X = 1, + POSITIVE_Y = 2, + NEGATIVE_Y = 3, + POSITIVE_Z = 4, + NEGATIVE_Z = 5, +} + + +IView_UUID_STRING :: "839D1216-BB2E-412B-B7F4-A9DBEBE08ED1" +IView_UUID := &IID{0x839D1216, 0xBB2E, 0x412B, {0xB7, 0xF4, 0xA9, 0xDB, 0xEB, 0xE0, 0x8E, 0xD1}} +IView :: struct #raw_union { + #subtype id3d11devicechild: IDeviceChild, + using id3d11view_vtable: ^IView_VTable, +} +IView_VTable :: struct { + using id3d11devicechild_vtable: IDeviceChild_VTable, + GetResource: proc "stdcall" (this: ^IView, ppResource: ^^IResource), +} + + +BUFFER_SRV :: struct { + using _: struct #raw_union { + FirstElement: u32, + ElementOffset: u32, + }, + using _: struct #raw_union { + NumElements: u32, + ElementWidth: u32, + }, +} + +BUFFEREX_SRV_FLAG :: enum u32 { // TODO: make bit_set + RAW = 0x1, +} + +BUFFEREX_SRV :: struct { + FirstElement: u32, + NumElements: u32, + Flags: u32, +} + +TEX1D_SRV :: struct { + MostDetailedMip: u32, + MipLevels: u32, +} + +TEX1D_ARRAY_SRV :: struct { + MostDetailedMip: u32, + MipLevels: u32, + FirstArraySlice: u32, + ArraySize: u32, +} + +TEX2D_SRV :: struct { + MostDetailedMip: u32, + MipLevels: u32, +} + +TEX2D_ARRAY_SRV :: struct { + MostDetailedMip: u32, + MipLevels: u32, + FirstArraySlice: u32, + ArraySize: u32, +} + +TEX3D_SRV :: struct { + MostDetailedMip: u32, + MipLevels: u32, +} + +TEXCUBE_SRV :: struct { + MostDetailedMip: u32, + MipLevels: u32, +} + +TEXCUBE_ARRAY_SRV :: struct { + MostDetailedMip: u32, + MipLevels: u32, + First2DArrayFace: u32, + NumCubes: u32, +} + +TEX2DMS_SRV :: struct { + UnusedField_NothingToDefine: u32, +} + +TEX2DMS_ARRAY_SRV :: struct { + FirstArraySlice: u32, + ArraySize: u32, +} + +SHADER_RESOURCE_VIEW_DESC :: struct { + Format: dxgi.FORMAT, + ViewDimension: SRV_DIMENSION, + using _: struct #raw_union { + Buffer: BUFFER_SRV, + Texture1D: TEX1D_SRV, + Texture1DArray: TEX1D_ARRAY_SRV, + Texture2D: TEX2D_SRV, + Texture2DArray: TEX2D_ARRAY_SRV, + Texture2DMS: TEX2DMS_SRV, + Texture2DMSArray: TEX2DMS_ARRAY_SRV, + Texture3D: TEX3D_SRV, + TextureCube: TEXCUBE_SRV, + TextureCubeArray: TEXCUBE_ARRAY_SRV, + BufferEx: BUFFEREX_SRV, + }, +} + +CSHADER_RESOURCE_VIEW_DESC :: struct { + using d3d11_shader_resource_view_desc: SHADER_RESOURCE_VIEW_DESC, +} + + +IShaderResourceView_UUID_STRING :: "B0E06FE0-8192-4E1A-B1CA-36D7414710B2" +IShaderResourceView_UUID := &IID{0xB0E06FE0, 0x8192, 0x4E1A, {0xB1, 0xCA, 0x36, 0xD7, 0x41, 0x47, 0x10, 0xB2}} +IShaderResourceView :: struct #raw_union { + #subtype id3d11view: IView, + using id3d11shaderresourceview_vtable: ^IShaderResourceView_VTable, +} +IShaderResourceView_VTable :: struct { + using id3d11view_vtable: IView_VTable, + GetDesc: proc "stdcall" (this: ^IShaderResourceView, pDesc: ^SHADER_RESOURCE_VIEW_DESC), +} + + +BUFFER_RTV :: struct { + using _: struct #raw_union { + FirstElement: u32, + ElementOffset: u32, + }, + using _: struct #raw_union { + NumElements: u32, + ElementWidth: u32, + }, +} + +TEX1D_RTV :: struct { + MipSlice: u32, +} + +TEX1D_ARRAY_RTV :: struct { + MipSlice: u32, + FirstArraySlice: u32, + ArraySize: u32, +} + +TEX2D_RTV :: struct { + MipSlice: u32, +} + +TEX2DMS_RTV :: struct { + UnusedField_NothingToDefine: u32, +} + +TEX2D_ARRAY_RTV :: struct { + MipSlice: u32, + FirstArraySlice: u32, + ArraySize: u32, +} + +TEX2DMS_ARRAY_RTV :: struct { + FirstArraySlice: u32, + ArraySize: u32, +} + +TEX3D_RTV :: struct { + MipSlice: u32, + FirstWSlice: u32, + WSize: u32, +} + +RENDER_TARGET_VIEW_DESC :: struct { + Format: dxgi.FORMAT, + ViewDimension: RTV_DIMENSION, + using _: struct #raw_union { + Buffer: BUFFER_RTV, + Texture1D: TEX1D_RTV, + Texture1DArray: TEX1D_ARRAY_RTV, + Texture2D: TEX2D_RTV, + Texture2DArray: TEX2D_ARRAY_RTV, + Texture2DMS: TEX2DMS_RTV, + Texture2DMSArray: TEX2DMS_ARRAY_RTV, + Texture3D: TEX3D_RTV, + }, +} + +CRENDER_TARGET_VIEW_DESC :: struct { + using d3d11_render_target_view_desc: RENDER_TARGET_VIEW_DESC, +} + + +IRenderTargetView_UUID_STRING :: "DFDBA067-0B8D-4865-875B-D7B4516CC164" +IRenderTargetView_UUID := &IID{0xDFDBA067, 0x0B8D, 0x4865, {0x87, 0x5B, 0xD7, 0xB4, 0x51, 0x6C, 0xC1, 0x64}} +IRenderTargetView :: struct #raw_union { + #subtype id3d11view: IView, + using id3d11rendertargetview_vtable: ^IRenderTargetView_VTable, +} +IRenderTargetView_VTable :: struct { + using id3d11view_vtable: IView_VTable, + GetDesc: proc "stdcall" (this: ^IRenderTargetView, pDesc: ^RENDER_TARGET_VIEW_DESC), +} + + +CVIEWPORT :: struct { + using d3d11_viewport: VIEWPORT, +} + +TEX1D_DSV :: struct { + MipSlice: u32, +} + +TEX1D_ARRAY_DSV :: struct { + MipSlice: u32, + FirstArraySlice: u32, + ArraySize: u32, +} + +TEX2D_DSV :: struct { + MipSlice: u32, +} + +TEX2D_ARRAY_DSV :: struct { + MipSlice: u32, + FirstArraySlice: u32, + ArraySize: u32, +} + +TEX2DMS_DSV :: struct { + UnusedField_NothingToDefine: u32, +} + +TEX2DMS_ARRAY_DSV :: struct { + FirstArraySlice: u32, + ArraySize: u32, +} + +DSV_FLAG :: enum u32 { // TODO: make bit_set + DEPTH = 0x1, + STENCIL = 0x2, +} + +DEPTH_STENCIL_VIEW_DESC :: struct { + Format: dxgi.FORMAT, + ViewDimension: DSV_DIMENSION, + Flags: u32, + using _: struct #raw_union { + Texture1D: TEX1D_DSV, + Texture1DArray: TEX1D_ARRAY_DSV, + Texture2D: TEX2D_DSV, + Texture2DArray: TEX2D_ARRAY_DSV, + Texture2DMS: TEX2DMS_DSV, + Texture2DMSArray: TEX2DMS_ARRAY_DSV, + }, +} + +CDEPTH_STENCIL_VIEW_DESC :: struct { + using d3d11_depth_stencil_view_desc: DEPTH_STENCIL_VIEW_DESC, +} + + +IDepthStencilView_UUID_STRING :: "9FDAC92A-1876-48C3-AFAD-25B94F84A9B6" +IDepthStencilView_UUID := &IID{0x9FDAC92A, 0x1876, 0x48C3, {0xAF, 0xAD, 0x25, 0xB9, 0x4F, 0x84, 0xA9, 0xB6}} +IDepthStencilView :: struct #raw_union { + #subtype id3d11view: IView, + using id3d11depthstencilview_vtable: ^IDepthStencilView_VTable, +} +IDepthStencilView_VTable :: struct { + using id3d11view_vtable: IView_VTable, + GetDesc: proc "stdcall" (this: ^IDepthStencilView, pDesc: ^DEPTH_STENCIL_VIEW_DESC), +} + + +BUFFER_UAV_FLAG :: enum u32 { // TODO: make bit_set + RAW = 0x1, + APPEND = 0x2, + COUNTER = 0x4, +} + +BUFFER_UAV :: struct { + FirstElement: u32, + NumElements: u32, + Flags: u32, +} + +TEX1D_UAV :: struct { + MipSlice: u32, +} + +TEX1D_ARRAY_UAV :: struct { + MipSlice: u32, + FirstArraySlice: u32, + ArraySize: u32, +} + +TEX2D_UAV :: struct { + MipSlice: u32, +} + +TEX2D_ARRAY_UAV :: struct { + MipSlice: u32, + FirstArraySlice: u32, + ArraySize: u32, +} + +TEX3D_UAV :: struct { + MipSlice: u32, + FirstWSlice: u32, + WSize: u32, +} + +UNORDERED_ACCESS_VIEW_DESC :: struct { + Format: dxgi.FORMAT, + ViewDimension: UAV_DIMENSION, + using _: struct #raw_union { + Buffer: BUFFER_UAV, + Texture1D: TEX1D_UAV, + Texture1DArray: TEX1D_ARRAY_UAV, + Texture2D: TEX2D_UAV, + Texture2DArray: TEX2D_ARRAY_UAV, + Texture3D: TEX3D_UAV, + }, +} + +CUNORDERED_ACCESS_VIEW_DESC :: struct { + using d3d11_unordered_access_view_desc: UNORDERED_ACCESS_VIEW_DESC, +} + + +IUnorderedAccessView_UUID_STRING :: "28ACF509-7F5C-48F6-8611-F316010A6380" +IUnorderedAccessView_UUID := &IID{0x28ACF509, 0x7F5C, 0x48F6, {0x86, 0x11, 0xF3, 0x16, 0x01, 0x0A, 0x63, 0x80}} +IUnorderedAccessView :: struct #raw_union { + #subtype id3d11view: IView, + using id3d11unorderedaccessview_vtable: ^IUnorderedAccessView_VTable, +} +IUnorderedAccessView_VTable :: struct { + using id3d11view_vtable: IView_VTable, + GetDesc: proc "stdcall" (this: ^IUnorderedAccessView, pDesc: ^UNORDERED_ACCESS_VIEW_DESC), +} + + + +IVertexShader_UUID_STRING :: "3B301D64-D678-4289-8897-22F8928B72F3" +IVertexShader_UUID := &IID{0x3B301D64, 0xD678, 0x4289, {0x88, 0x97, 0x22, 0xF8, 0x92, 0x8B, 0x72, 0xF3}} +IVertexShader :: struct { + using id3d11devicechild: IDeviceChild, +} + + +IHullShader_UUID_STRING :: "8E5C6061-628A-4C8E-8264-BBE45CB3D5DD" +IHullShader_UUID := &IID{0x8E5C6061, 0x628A, 0x4C8E, {0x82, 0x64, 0xBB, 0xE4, 0x5C, 0xB3, 0xD5, 0xDD}} +IHullShader :: struct { + using id3d11devicechild: IDeviceChild, +} + + +IDomainShader_UUID_STRING :: "F582C508-0F36-490C-9977-31EECE268CFA" +IDomainShader_UUID := &IID{0xF582C508, 0x0F36, 0x490C, {0x99, 0x77, 0x31, 0xEE, 0xCE, 0x26, 0x8C, 0xFA}} +IDomainShader :: struct { + using id3d11devicechild: IDeviceChild, +} + + +IGeometryShader_UUID_STRING :: "38325B96-EFFB-4022-BA02-2E795B70275C" +IGeometryShader_UUID := &IID{0x38325B96, 0xEFFB, 0x4022, {0xBA, 0x02, 0x2E, 0x79, 0x5B, 0x70, 0x27, 0x5C}} +IGeometryShader :: struct { + using id3d11devicechild: IDeviceChild, +} + + +IPixelShader_UUID_STRING :: "EA82E40D-51DC-4F33-93D4-DB7C9125AE8C" +IPixelShader_UUID := &IID{0xEA82E40D, 0x51DC, 0x4F33, {0x93, 0xD4, 0xDB, 0x7C, 0x91, 0x25, 0xAE, 0x8C}} +IPixelShader :: struct { + using id3d11devicechild: IDeviceChild, +} + + +IComputeShader_UUID_STRING :: "4F5B196E-C2BD-495E-BD01-1FDED38E4969" +IComputeShader_UUID := &IID{0x4F5B196E, 0xC2BD, 0x495E, {0xBD, 0x01, 0x1F, 0xDE, 0xD3, 0x8E, 0x49, 0x69}} +IComputeShader :: struct { + using id3d11devicechild: IDeviceChild, +} + + +IInputLayout_UUID_STRING :: "E4819DDC-4CF0-4025-BD26-5DE82A3E07B7" +IInputLayout_UUID := &IID{0xE4819DDC, 0x4CF0, 0x4025, {0xBD, 0x26, 0x5D, 0xE8, 0x2A, 0x3E, 0x07, 0xB7}} +IInputLayout :: struct { + using id3d11devicechild: IDeviceChild, +} + +FILTER :: enum i32 { + MIN_MAG_MIP_POINT = 0, + MIN_MAG_POINT_MIP_LINEAR = 1, + MIN_POINT_MAG_LINEAR_MIP_POINT = 4, + MIN_POINT_MAG_MIP_LINEAR = 5, + MIN_LINEAR_MAG_MIP_POINT = 16, + MIN_LINEAR_MAG_POINT_MIP_LINEAR = 17, + MIN_MAG_LINEAR_MIP_POINT = 20, + MIN_MAG_MIP_LINEAR = 21, + ANISOTROPIC = 85, + COMPARISON_MIN_MAG_MIP_POINT = 128, + COMPARISON_MIN_MAG_POINT_MIP_LINEAR = 129, + COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT = 132, + COMPARISON_MIN_POINT_MAG_MIP_LINEAR = 133, + COMPARISON_MIN_LINEAR_MAG_MIP_POINT = 144, + COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 145, + COMPARISON_MIN_MAG_LINEAR_MIP_POINT = 148, + COMPARISON_MIN_MAG_MIP_LINEAR = 149, + COMPARISON_ANISOTROPIC = 213, + MINIMUM_MIN_MAG_MIP_POINT = 256, + MINIMUM_MIN_MAG_POINT_MIP_LINEAR = 257, + MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT = 260, + MINIMUM_MIN_POINT_MAG_MIP_LINEAR = 261, + MINIMUM_MIN_LINEAR_MAG_MIP_POINT = 272, + MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 273, + MINIMUM_MIN_MAG_LINEAR_MIP_POINT = 276, + MINIMUM_MIN_MAG_MIP_LINEAR = 277, + MINIMUM_ANISOTROPIC = 341, + MAXIMUM_MIN_MAG_MIP_POINT = 384, + MAXIMUM_MIN_MAG_POINT_MIP_LINEAR = 385, + MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT = 388, + MAXIMUM_MIN_POINT_MAG_MIP_LINEAR = 389, + MAXIMUM_MIN_LINEAR_MAG_MIP_POINT = 400, + MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 401, + MAXIMUM_MIN_MAG_LINEAR_MIP_POINT = 404, + MAXIMUM_MIN_MAG_MIP_LINEAR = 405, + MAXIMUM_ANISOTROPIC = 469, +} + +FILTER_TYPE :: enum i32 { + POINT = 0, + LINEAR = 1, +} + +FILTER_REDUCTION_TYPE :: enum i32 { + STANDARD = 0, + COMPARISON = 1, + MINIMUM = 2, + MAXIMUM = 3, +} + +TEXTURE_ADDRESS_MODE :: enum i32 { + WRAP = 1, + MIRROR = 2, + CLAMP = 3, + BORDER = 4, + MIRROR_ONCE = 5, +} + +SAMPLER_DESC :: struct { + Filter: FILTER, + AddressU: TEXTURE_ADDRESS_MODE, + AddressV: TEXTURE_ADDRESS_MODE, + AddressW: TEXTURE_ADDRESS_MODE, + MipLODBias: f32, + MaxAnisotropy: u32, + ComparisonFunc: COMPARISON_FUNC, + BorderColor: [4]f32, + MinLOD: f32, + MaxLOD: f32, +} + +CSAMPLER_DESC :: struct { + using d3d11_sampler_desc: SAMPLER_DESC, +} + + +ISamplerState_UUID_STRING :: "DA6FEA51-564C-4487-9810-F0D0F9B4E3A5" +ISamplerState_UUID := &IID{0xDA6FEA51, 0x564C, 0x4487, {0x98, 0x10, 0xF0, 0xD0, 0xF9, 0xB4, 0xE3, 0xA5}} +ISamplerState :: struct #raw_union { + #subtype id3d11devicechild: IDeviceChild, + using id3d11samplerstate_vtable: ^ISamplerState_VTable, +} +ISamplerState_VTable :: struct { + using id3d11devicechild_vtable: IDeviceChild_VTable, + GetDesc: proc "stdcall" (this: ^ISamplerState, pDesc: ^SAMPLER_DESC), +} + + +FORMAT_SUPPORT :: enum i32 { // TODO: make bit_set + BUFFER = 1, + IA_VERTEX_BUFFER = 2, + IA_INDEX_BUFFER = 4, + SO_BUFFER = 8, + TEXTURE1D = 16, + TEXTURE2D = 32, + TEXTURE3D = 64, + TEXTURECUBE = 128, + SHADER_LOAD = 256, + SHADER_SAMPLE = 512, + SHADER_SAMPLE_COMPARISON = 1024, + SHADER_SAMPLE_MONO_TEXT = 2048, + MIP = 4096, + MIP_AUTOGEN = 8192, + RENDER_TARGET = 16384, + BLENDABLE = 32768, + DEPTH_STENCIL = 65536, + CPU_LOCKABLE = 131072, + MULTISAMPLE_RESOLVE = 262144, + DISPLAY = 524288, + CAST_WITHIN_BIT_LAYOUT = 1048576, + MULTISAMPLE_RENDERTARGET = 2097152, + MULTISAMPLE_LOAD = 4194304, + SHADER_GATHER = 8388608, + BACK_BUFFER_CAST = 16777216, + TYPED_UNORDERED_ACCESS_VIEW = 33554432, + SHADER_GATHER_COMPARISON = 67108864, + DECODER_OUTPUT = 134217728, + VIDEO_PROCESSOR_OUTPUT = 268435456, + VIDEO_PROCESSOR_INPUT = 536870912, + VIDEO_ENCODER = 1073741824, +} + +FORMAT_SUPPORT2 :: enum i32 { // TODO: make bit_set + UAV_ATOMIC_ADD = 1, + UAV_ATOMIC_BITWISE_OPS = 2, + UAV_ATOMIC_COMPARE_STORE_OR_COMPARE_EXCHANGE = 4, + UAV_ATOMIC_EXCHANGE = 8, + UAV_ATOMIC_SIGNED_MIN_OR_MAX = 16, + UAV_ATOMIC_UNSIGNED_MIN_OR_MAX = 32, + UAV_TYPED_LOAD = 64, + UAV_TYPED_STORE = 128, + OUTPUT_MERGER_LOGIC_OP = 256, + TILED = 512, + SHAREABLE = 1024, + MULTIPLANE_OVERLAY = 16384, +} + + +IAsynchronous_UUID_STRING :: "4B35D0CD-1E15-4258-9C98-1B1333F6DD3B" +IAsynchronous_UUID := &IID{0x4B35D0CD, 0x1E15, 0x4258, {0x9C, 0x98, 0x1B, 0x13, 0x33, 0xF6, 0xDD, 0x3B}} +IAsynchronous :: struct #raw_union { + #subtype id3d11devicechild: IDeviceChild, + using id3d11asynchronous_vtable: ^IAsynchronous_VTable, +} +IAsynchronous_VTable :: struct { + using id3d11devicechild_vtable: IDeviceChild_VTable, + GetDataSize: proc "stdcall" (this: ^IAsynchronous) -> u32, +} + + +ASYNC_GETDATA_FLAG :: enum u32 { // TODO: make bit_set + DONOTFLUSH = 0x1, +} + +QUERY :: enum i32 { + EVENT = 0, + OCCLUSION = 1, + TIMESTAMP = 2, + TIMESTAMP_DISJOINT = 3, + PIPELINE_STATISTICS = 4, + OCCLUSION_PREDICATE = 5, + SO_STATISTICS = 6, + SO_OVERFLOW_PREDICATE = 7, + SO_STATISTICS_STREAM0 = 8, + SO_OVERFLOW_PREDICATE_STREAM0 = 9, + SO_STATISTICS_STREAM1 = 10, + SO_OVERFLOW_PREDICATE_STREAM1 = 11, + SO_STATISTICS_STREAM2 = 12, + SO_OVERFLOW_PREDICATE_STREAM2 = 13, + SO_STATISTICS_STREAM3 = 14, + SO_OVERFLOW_PREDICATE_STREAM3 = 15, +} + +QUERY_MISC_FLAG :: enum u32 { // TODO: make bit_set + QUERY_MISC_PREDICATEHINT = 0x1, +} + +QUERY_DESC :: struct { + Query: QUERY, + MiscFlags: RESOURCE_MISC_FLAG, +} + +CQUERY_DESC :: struct { + using d3d11_query_desc: QUERY_DESC, +} + + +IQuery_UUID_STRING :: "D6C00747-87B7-425E-B84D-44D108560AFD" +IQuery_UUID := &IID{0xD6C00747, 0x87B7, 0x425E, {0xB8, 0x4D, 0x44, 0xD1, 0x08, 0x56, 0x0A, 0xFD}} +IQuery :: struct #raw_union { + #subtype id3d11asynchronous: IAsynchronous, + using id3d11query_vtable: ^IQuery_VTable, +} +IQuery_VTable :: struct { + using id3d11asynchronous_vtable: IAsynchronous_VTable, + GetDesc: proc "stdcall" (this: ^IQuery, pDesc: ^QUERY_DESC), +} + + + +IPredicate_UUID_STRING :: "9EB576DD-9F77-4D86-81AA-8BAB5FE490E2" +IPredicate_UUID := &IID{0x9EB576DD, 0x9F77, 0x4D86, {0x81, 0xAA, 0x8B, 0xAB, 0x5F, 0xE4, 0x90, 0xE2}} +IPredicate :: struct { + using id3d11query: IQuery, +} + +QUERY_DATA_TIMESTAMP_DISJOINT :: struct { + Frequency: u64, + Disjoint: BOOL, +} + +QUERY_DATA_PIPELINE_STATISTICS :: struct { + IAVertices: u64, + IAPrimitives: u64, + VSInvocations: u64, + GSInvocations: u64, + GSPrimitives: u64, + CInvocations: u64, + CPrimitives: u64, + PSInvocations: u64, + HSInvocations: u64, + DSInvocations: u64, + CSInvocations: u64, +} + +QUERY_DATA_SO_STATISTICS :: struct { + NumPrimitivesWritten: u64, + PrimitivesStorageNeeded: u64, +} + +COUNTER :: enum i32 { + DEVICE_DEPENDENT_0 = 1073741824, +} + +COUNTER_TYPE :: enum i32 { + FLOAT32 = 0, + UINT16 = 1, + UINT32 = 2, + UINT64 = 3, +} + +COUNTER_DESC :: struct { + Counter: COUNTER, + MiscFlags: RESOURCE_MISC_FLAG, +} + +CCOUNTER_DESC :: struct { + using d3d11_counter_desc: COUNTER_DESC, +} + +COUNTER_INFO :: struct { + LastDeviceDependentCounter: COUNTER, + NumSimultaneousCounters: u32, + NumDetectableParallelUnits: u8, +} + + +ICounter_UUID_STRING :: "6E8C49FB-A371-4770-B440-29086022B741" +ICounter_UUID := &IID{0x6E8C49FB, 0xA371, 0x4770, {0xB4, 0x40, 0x29, 0x08, 0x60, 0x22, 0xB7, 0x41}} +ICounter :: struct #raw_union { + #subtype id3d11asynchronous: IAsynchronous, + using id3d11counter_vtable: ^ICounter_VTable, +} +ICounter_VTable :: struct { + using id3d11asynchronous_vtable: IAsynchronous_VTable, + GetDesc: proc "stdcall" (this: ^ICounter, pDesc: ^COUNTER_DESC), +} + + +STANDARD_MULTISAMPLE_QUALITY_LEVELS :: enum i32 { + STANDARD_MULTISAMPLE_PATTERN = -1, + CENTER_MULTISAMPLE_PATTERN = -2, +} + +DEVICE_CONTEXT_TYPE :: enum i32 { + IMMEDIATE = 0, + DEFERRED = 1, +} + +CLASS_INSTANCE_DESC :: struct { + InstanceId: u32, + InstanceIndex: u32, + TypeId: u32, + ConstantBuffer: u32, + BaseConstantBufferOffset: u32, + BaseTexture: u32, + BaseSampler: u32, + Created: BOOL, +} + + +IClassInstance_UUID_STRING :: "A6CD7FAA-B0B7-4A2F-9436-8662A65797CB" +IClassInstance_UUID := &IID{0xA6CD7FAA, 0xB0B7, 0x4A2F, {0x94, 0x36, 0x86, 0x62, 0xA6, 0x57, 0x97, 0xCB}} +IClassInstance :: struct #raw_union { + #subtype id3d11devicechild: IDeviceChild, + using id3d11classinstance_vtable: ^IClassInstance_VTable, +} +IClassInstance_VTable :: struct { + using id3d11devicechild_vtable: IDeviceChild_VTable, + GetClassLinkage: proc "stdcall" (this: ^IClassInstance, ppLinkage: ^^IClassLinkage), + GetDesc: proc "stdcall" (this: ^IClassInstance, pDesc: ^CLASS_INSTANCE_DESC), + GetInstanceName: proc "stdcall" (this: ^IClassInstance, pInstanceName: cstring, pBufferLength: ^SIZE_T), + GetTypeName: proc "stdcall" (this: ^IClassInstance, pTypeName: cstring, pBufferLength: ^SIZE_T), +} + + + +IClassLinkage_UUID_STRING :: "DDF57CBA-9543-46E4-A12B-F207A0FE7FED" +IClassLinkage_UUID := &IID{0xDDF57CBA, 0x9543, 0x46E4, {0xA1, 0x2B, 0xF2, 0x07, 0xA0, 0xFE, 0x7F, 0xED}} +IClassLinkage :: struct #raw_union { + #subtype id3d11devicechild: IDeviceChild, + using id3d11classlinkage_vtable: ^IClassLinkage_VTable, +} +IClassLinkage_VTable :: struct { + using id3d11devicechild_vtable: IDeviceChild_VTable, + GetClassInstance: proc "stdcall" (this: ^IClassLinkage, pClassInstanceName: cstring, InstanceIndex: u32, ppInstance: ^^IClassInstance) -> HRESULT, + CreateClassInstance: proc "stdcall" (this: ^IClassLinkage, pClassTypeName: cstring, ConstantBufferOffset: u32, ConstantVectorOffset: u32, TextureOffset: u32, SamplerOffset: u32, ppInstance: ^^IClassInstance) -> HRESULT, +} + + + +ICommandList_UUID_STRING :: "A24BC4D1-769E-43F7-8013-98FF566C18E2" +ICommandList_UUID := &IID{0xA24BC4D1, 0x769E, 0x43F7, {0x80, 0x13, 0x98, 0xFF, 0x56, 0x6C, 0x18, 0xE2}} +ICommandList :: struct #raw_union { + #subtype id3d11devicechild: IDeviceChild, + using id3d11commandlist_vtable: ^ICommandList_VTable, +} +ICommandList_VTable :: struct { + using id3d11devicechild_vtable: IDeviceChild_VTable, + GetContextFlags: proc "stdcall" (this: ^ICommandList) -> u32, +} + + +FEATURE :: enum i32 { + THREADING = 0, + DOUBLES = 1, + FORMAT_SUPPORT = 2, + FORMAT_SUPPORT2 = 3, + D3D10_X_HARDWARE_OPTIONS = 4, + OPTIONS = 5, + ARCHITECTURE_INFO = 6, + D3D9_OPTIONS = 7, + SHADER_MIN_PRECISION_SUPPORT = 8, + D3D9_SHADOW_SUPPORT = 9, + OPTIONS1 = 10, + D3D9_SIMPLE_INSTANCING_SUPPORT = 11, + MARKER_SUPPORT = 12, + D3D9_OPTIONS1 = 13, + OPTIONS2 = 14, + OPTIONS3 = 15, + GPU_VIRTUAL_ADDRESS_SUPPORT = 16, + OPTIONS4 = 17, + SHADER_CACHE = 18, + OPTIONS5 = 19, +} + +FEATURE_DATA_THREADING :: struct { + DriverConcurrentCreates: BOOL, + DriverCommandLists: BOOL, +} + +FEATURE_DATA_DOUBLES :: struct { + DoublePrecisionFloatShaderOps: BOOL, +} + +FEATURE_DATA_FORMAT_SUPPORT :: struct { + InFormat: dxgi.FORMAT, + OutFormatSupport: u32, +} + +FEATURE_DATA_FORMAT_SUPPORT2 :: struct { + InFormat: dxgi.FORMAT, + OutFormatSupport2: u32, +} + +FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS :: struct { + ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x: BOOL, +} + +FEATURE_DATA_OPTIONS :: struct { + OutputMergerLogicOp: BOOL, + UAVOnlyRenderingForcedSampleCount: BOOL, + DiscardAPIsSeenByDriver: BOOL, + FlagsForUpdateAndCopySeenByDriver: BOOL, + ClearView: BOOL, + CopyWithOverlap: BOOL, + ConstantBufferPartialUpdate: BOOL, + ConstantBufferOffsetting: BOOL, + MapNoOverwriteOnDynamicConstantBuffer: BOOL, + MapNoOverwriteOnDynamicBufferSRV: BOOL, + MultisampleRTVWithForcedSampleCountOne: BOOL, + SAD4ShaderInstructions: BOOL, + ExtendedDoublesShaderInstructions: BOOL, + ExtendedResourceSharing: BOOL, +} + +FEATURE_DATA_ARCHITECTURE_INFO :: struct { + TileBasedDeferredRenderer: BOOL, +} + +FEATURE_DATA_D3D9_OPTIONS :: struct { + FullNonPow2TextureSupport: BOOL, +} + +FEATURE_DATA_D3D9_SHADOW_SUPPORT :: struct { + SupportsDepthAsTextureWithLessEqualComparisonFilter: BOOL, +} + +SHADER_MIN_PRECISION_SUPPORT :: enum i32 { + _10_BIT = 1, + _16_BIT = 2, +} + +FEATURE_DATA_SHADER_MIN_PRECISION_SUPPORT :: struct { + PixelShaderMinPrecision: u32, + AllOtherShaderStagesMinPrecision: u32, +} + +TILED_RESOURCES_TIER :: enum i32 { + TILED_RESOURCES_NOT_SUPPORTED = 0, + _1 = 1, + _2 = 2, + _3 = 3, +} + +FEATURE_DATA_OPTIONS1 :: struct { + TiledResourcesTier: TILED_RESOURCES_TIER, + MinMaxFiltering: BOOL, + ClearViewAlsoSupportsDepthOnlyFormats: BOOL, + MapOnDefaultBuffers: BOOL, +} + +FEATURE_DATA_D3D9_SIMPLE_INSTANCING_SUPPORT :: struct { + SimpleInstancingSupported: BOOL, +} + +FEATURE_DATA_MARKER_SUPPORT :: struct { + Profile: BOOL, +} + +FEATURE_DATA_D3D9_OPTIONS1 :: struct { + FullNonPow2TextureSupported: BOOL, + DepthAsTextureWithLessEqualComparisonFilterSupported: BOOL, + SimpleInstancingSupported: BOOL, + TextureCubeFaceRenderTargetWithNonCubeDepthStencilSupported: BOOL, +} + +CONSERVATIVE_RASTERIZATION_TIER :: enum i32 { + CONSERVATIVE_RASTERIZATION_NOT_SUPPORTED = 0, + _1 = 1, + _2 = 2, + _3 = 3, +} + +FEATURE_DATA_OPTIONS2 :: struct { + PSSpecifiedStencilRefSupported: BOOL, + TypedUAVLoadAdditionalFormats: BOOL, + ROVsSupported: BOOL, + ConservativeRasterizationTier: CONSERVATIVE_RASTERIZATION_TIER, + TiledResourcesTier: TILED_RESOURCES_TIER, + MapOnDefaultTextures: BOOL, + StandardSwizzle: BOOL, + UnifiedMemoryArchitecture: BOOL, +} + +FEATURE_DATA_OPTIONS3 :: struct { + VPAndRTArrayIndexFromAnyShaderFeedingRasterizer: BOOL, +} + +FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT :: struct { + MaxGPUVirtualAddressBitsPerResource: u32, + MaxGPUVirtualAddressBitsPerProcess: u32, +} + +SHADER_CACHE_SUPPORT_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + AUTOMATIC_INPROC_CACHE = 0x1, + AUTOMATIC_DISK_CACHE = 0x2, +} + +FEATURE_DATA_SHADER_CACHE :: struct { + SupportFlags: u32, +} + +SHARED_RESOURCE_TIER :: enum i32 { + _0 = 0, + _1 = 1, + _2 = 2, + _3 = 3, +} + +FEATURE_DATA_OPTIONS5 :: struct { + SharedResourceTier: SHARED_RESOURCE_TIER, +} + + +IDeviceContext_UUID_STRING :: "C0BFA96C-E089-44FB-8EAF-26F8796190DA" +IDeviceContext_UUID := &IID{0xC0BFA96C, 0xE089, 0x44FB, {0x8E, 0xAF, 0x26, 0xF8, 0x79, 0x61, 0x90, 0xDA}} +IDeviceContext :: struct #raw_union { + #subtype id3d11devicechild: IDeviceChild, + using id3d11devicecontext_vtable: ^IDeviceContext_VTable, +} +IDeviceContext_VTable :: struct { + using id3d11devicechild_vtable: IDeviceChild_VTable, + VSSetConstantBuffers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumBuffers: u32, ppConstantBuffers: ^^IBuffer), + PSSetShaderResources: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumViews: u32, ppShaderResourceViews: ^^IShaderResourceView), + PSSetShader: proc "stdcall" (this: ^IDeviceContext, pPixelShader: ^IPixelShader, ppClassInstances: ^^IClassInstance, NumClassInstances: u32), + PSSetSamplers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumSamplers: u32, ppSamplers: ^^ISamplerState), + VSSetShader: proc "stdcall" (this: ^IDeviceContext, pVertexShader: ^IVertexShader, ppClassInstances: ^^IClassInstance, NumClassInstances: u32), + DrawIndexed: proc "stdcall" (this: ^IDeviceContext, IndexCount: u32, StartIndexLocation: u32, BaseVertexLocation: i32), + Draw: proc "stdcall" (this: ^IDeviceContext, VertexCount: u32, StartVertexLocation: u32), + Map: proc "stdcall" (this: ^IDeviceContext, pResource: ^IResource, Subresource: u32, MapType: MAP, MapFlags: u32, pMappedResource: ^MAPPED_SUBRESOURCE) -> HRESULT, + Unmap: proc "stdcall" (this: ^IDeviceContext, pResource: ^IResource, Subresource: u32), + PSSetConstantBuffers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumBuffers: u32, ppConstantBuffers: ^^IBuffer), + IASetInputLayout: proc "stdcall" (this: ^IDeviceContext, pInputLayout: ^IInputLayout), + IASetVertexBuffers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumBuffers: u32, ppVertexBuffers: ^^IBuffer, pStrides: ^u32, pOffsets: ^u32), + IASetIndexBuffer: proc "stdcall" (this: ^IDeviceContext, pIndexBuffer: ^IBuffer, Format: dxgi.FORMAT, Offset: u32), + DrawIndexedInstanced: proc "stdcall" (this: ^IDeviceContext, IndexCountPerInstance: u32, InstanceCount: u32, StartIndexLocation: u32, BaseVertexLocation: i32, StartInstanceLocation: u32), + DrawInstanced: proc "stdcall" (this: ^IDeviceContext, VertexCountPerInstance: u32, InstanceCount: u32, StartVertexLocation: u32, StartInstanceLocation: u32), + GSSetConstantBuffers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumBuffers: u32, ppConstantBuffers: ^^IBuffer), + GSSetShader: proc "stdcall" (this: ^IDeviceContext, pShader: ^IGeometryShader, ppClassInstances: ^^IClassInstance, NumClassInstances: u32), + IASetPrimitiveTopology: proc "stdcall" (this: ^IDeviceContext, Topology: PRIMITIVE_TOPOLOGY), + VSSetShaderResources: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumViews: u32, ppShaderResourceViews: ^^IShaderResourceView), + VSSetSamplers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumSamplers: u32, ppSamplers: ^^ISamplerState), + Begin: proc "stdcall" (this: ^IDeviceContext, pAsync: ^IAsynchronous), + End: proc "stdcall" (this: ^IDeviceContext, pAsync: ^IAsynchronous), + GetData: proc "stdcall" (this: ^IDeviceContext, pAsync: ^IAsynchronous, pData: rawptr, DataSize: u32, GetDataFlags: u32) -> HRESULT, + SetPredication: proc "stdcall" (this: ^IDeviceContext, pPredicate: ^IPredicate, PredicateValue: BOOL), + GSSetShaderResources: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumViews: u32, ppShaderResourceViews: ^^IShaderResourceView), + GSSetSamplers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumSamplers: u32, ppSamplers: ^^ISamplerState), + OMSetRenderTargets: proc "stdcall" (this: ^IDeviceContext, NumViews: u32, ppRenderTargetViews: ^^IRenderTargetView, pDepthStencilView: ^IDepthStencilView), + OMSetRenderTargetsAndUnorderedAccessViews: proc "stdcall" (this: ^IDeviceContext, NumRTVs: u32, ppRenderTargetViews: ^^IRenderTargetView, pDepthStencilView: ^IDepthStencilView, UAVStartSlot: u32, NumUAVs: u32, ppUnorderedAccessViews: ^^IUnorderedAccessView, pUAVInitialCounts: ^u32), + OMSetBlendState: proc "stdcall" (this: ^IDeviceContext, pBlendState: ^IBlendState, BlendFactor: ^[4]f32, SampleMask: u32), + OMSetDepthStencilState: proc "stdcall" (this: ^IDeviceContext, pDepthStencilState: ^IDepthStencilState, StencilRef: u32), + SOSetTargets: proc "stdcall" (this: ^IDeviceContext, NumBuffers: u32, ppSOTargets: ^^IBuffer, pOffsets: ^u32), + DrawAuto: proc "stdcall" (this: ^IDeviceContext), + DrawIndexedInstancedIndirect: proc "stdcall" (this: ^IDeviceContext, pBufferForArgs: ^IBuffer, AlignedByteOffsetForArgs: u32), + DrawInstancedIndirect: proc "stdcall" (this: ^IDeviceContext, pBufferForArgs: ^IBuffer, AlignedByteOffsetForArgs: u32), + Dispatch: proc "stdcall" (this: ^IDeviceContext, ThreadGroupCountX: u32, ThreadGroupCountY: u32, ThreadGroupCountZ: u32), + DispatchIndirect: proc "stdcall" (this: ^IDeviceContext, pBufferForArgs: ^IBuffer, AlignedByteOffsetForArgs: u32), + RSSetState: proc "stdcall" (this: ^IDeviceContext, pRasterizerState: ^IRasterizerState), + RSSetViewports: proc "stdcall" (this: ^IDeviceContext, NumViewports: u32, pViewports: ^VIEWPORT), + RSSetScissorRects: proc "stdcall" (this: ^IDeviceContext, NumRects: u32, pRects: ^RECT), + CopySubresourceRegion: proc "stdcall" (this: ^IDeviceContext, pDstResource: ^IResource, DstSubresource: u32, DstX: u32, DstY: u32, DstZ: u32, pSrcResource: ^IResource, SrcSubresource: u32, pSrcBox: ^BOX), + CopyResource: proc "stdcall" (this: ^IDeviceContext, pDstResource: ^IResource, pSrcResource: ^IResource), + UpdateSubresource: proc "stdcall" (this: ^IDeviceContext, pDstResource: ^IResource, DstSubresource: u32, pDstBox: ^BOX, pSrcData: rawptr, SrcRowPitch: u32, SrcDepthPitch: u32), + CopyStructureCount: proc "stdcall" (this: ^IDeviceContext, pDstBuffer: ^IBuffer, DstAlignedByteOffset: u32, pSrcView: ^IUnorderedAccessView), + ClearRenderTargetView: proc "stdcall" (this: ^IDeviceContext, pRenderTargetView: ^IRenderTargetView, ColorRGBA: ^[4]f32), + ClearUnorderedAccessViewUint: proc "stdcall" (this: ^IDeviceContext, pUnorderedAccessView: ^IUnorderedAccessView, Values: ^[4]u32), + ClearUnorderedAccessViewFloat: proc "stdcall" (this: ^IDeviceContext, pUnorderedAccessView: ^IUnorderedAccessView, Values: ^[4]f32), + ClearDepthStencilView: proc "stdcall" (this: ^IDeviceContext, pDepthStencilView: ^IDepthStencilView, ClearFlags: CLEAR_FLAG, Depth: f32, Stencil: u8), + GenerateMips: proc "stdcall" (this: ^IDeviceContext, pShaderResourceView: ^IShaderResourceView), + SetResourceMinLOD: proc "stdcall" (this: ^IDeviceContext, pResource: ^IResource, MinLOD: f32), + GetResourceMinLOD: proc "stdcall" (this: ^IDeviceContext, pResource: ^IResource) -> f32, + ResolveSubresource: proc "stdcall" (this: ^IDeviceContext, pDstResource: ^IResource, DstSubresource: u32, pSrcResource: ^IResource, SrcSubresource: u32, Format: dxgi.FORMAT), + ExecuteCommandList: proc "stdcall" (this: ^IDeviceContext, pCommandList: ^ICommandList, RestoreContextState: BOOL), + HSSetShaderResources: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumViews: u32, ppShaderResourceViews: ^^IShaderResourceView), + HSSetShader: proc "stdcall" (this: ^IDeviceContext, pHullShader: ^IHullShader, ppClassInstances: ^^IClassInstance, NumClassInstances: u32), + HSSetSamplers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumSamplers: u32, ppSamplers: ^^ISamplerState), + HSSetConstantBuffers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumBuffers: u32, ppConstantBuffers: ^^IBuffer), + DSSetShaderResources: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumViews: u32, ppShaderResourceViews: ^^IShaderResourceView), + DSSetShader: proc "stdcall" (this: ^IDeviceContext, pDomainShader: ^IDomainShader, ppClassInstances: ^^IClassInstance, NumClassInstances: u32), + DSSetSamplers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumSamplers: u32, ppSamplers: ^^ISamplerState), + DSSetConstantBuffers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumBuffers: u32, ppConstantBuffers: ^^IBuffer), + CSSetShaderResources: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumViews: u32, ppShaderResourceViews: ^^IShaderResourceView), + CSSetUnorderedAccessViews: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumUAVs: u32, ppUnorderedAccessViews: ^^IUnorderedAccessView, pUAVInitialCounts: ^u32), + CSSetShader: proc "stdcall" (this: ^IDeviceContext, pComputeShader: ^IComputeShader, ppClassInstances: ^^IClassInstance, NumClassInstances: u32), + CSSetSamplers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumSamplers: u32, ppSamplers: ^^ISamplerState), + CSSetConstantBuffers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumBuffers: u32, ppConstantBuffers: ^^IBuffer), + VSGetConstantBuffers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumBuffers: u32, ppConstantBuffers: ^^IBuffer), + PSGetShaderResources: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumViews: u32, ppShaderResourceViews: ^^IShaderResourceView), + PSGetShader: proc "stdcall" (this: ^IDeviceContext, ppPixelShader: ^^IPixelShader, ppClassInstances: ^^IClassInstance, pNumClassInstances: ^u32), + PSGetSamplers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumSamplers: u32, ppSamplers: ^^ISamplerState), + VSGetShader: proc "stdcall" (this: ^IDeviceContext, ppVertexShader: ^^IVertexShader, ppClassInstances: ^^IClassInstance, pNumClassInstances: ^u32), + PSGetConstantBuffers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumBuffers: u32, ppConstantBuffers: ^^IBuffer), + IAGetInputLayout: proc "stdcall" (this: ^IDeviceContext, ppInputLayout: ^^IInputLayout), + IAGetVertexBuffers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumBuffers: u32, ppVertexBuffers: ^^IBuffer, pStrides: ^u32, pOffsets: ^u32), + IAGetIndexBuffer: proc "stdcall" (this: ^IDeviceContext, pIndexBuffer: ^^IBuffer, Format: ^dxgi.FORMAT, Offset: ^u32), + GSGetConstantBuffers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumBuffers: u32, ppConstantBuffers: ^^IBuffer), + GSGetShader: proc "stdcall" (this: ^IDeviceContext, ppGeometryShader: ^^IGeometryShader, ppClassInstances: ^^IClassInstance, pNumClassInstances: ^u32), + IAGetPrimitiveTopology: proc "stdcall" (this: ^IDeviceContext, pTopology: ^PRIMITIVE_TOPOLOGY), + VSGetShaderResources: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumViews: u32, ppShaderResourceViews: ^^IShaderResourceView), + VSGetSamplers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumSamplers: u32, ppSamplers: ^^ISamplerState), + GetPredication: proc "stdcall" (this: ^IDeviceContext, ppPredicate: ^^IPredicate, pPredicateValue: ^BOOL), + GSGetShaderResources: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumViews: u32, ppShaderResourceViews: ^^IShaderResourceView), + GSGetSamplers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumSamplers: u32, ppSamplers: ^^ISamplerState), + OMGetRenderTargets: proc "stdcall" (this: ^IDeviceContext, NumViews: u32, ppRenderTargetViews: ^^IRenderTargetView, ppDepthStencilView: ^^IDepthStencilView), + OMGetRenderTargetsAndUnorderedAccessViews: proc "stdcall" (this: ^IDeviceContext, NumRTVs: u32, ppRenderTargetViews: ^^IRenderTargetView, ppDepthStencilView: ^^IDepthStencilView, UAVStartSlot: u32, NumUAVs: u32, ppUnorderedAccessViews: ^^IUnorderedAccessView), + OMGetBlendState: proc "stdcall" (this: ^IDeviceContext, ppBlendState: ^^IBlendState, BlendFactor: ^[4]f32, pSampleMask: ^u32), + OMGetDepthStencilState: proc "stdcall" (this: ^IDeviceContext, ppDepthStencilState: ^^IDepthStencilState, pStencilRef: ^u32), + SOGetTargets: proc "stdcall" (this: ^IDeviceContext, NumBuffers: u32, ppSOTargets: ^^IBuffer), + RSGetState: proc "stdcall" (this: ^IDeviceContext, ppRasterizerState: ^^IRasterizerState), + RSGetViewports: proc "stdcall" (this: ^IDeviceContext, pNumViewports: ^u32, pViewports: ^VIEWPORT), + RSGetScissorRects: proc "stdcall" (this: ^IDeviceContext, pNumRects: ^u32, pRects: ^RECT), + HSGetShaderResources: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumViews: u32, ppShaderResourceViews: ^^IShaderResourceView), + HSGetShader: proc "stdcall" (this: ^IDeviceContext, ppHullShader: ^^IHullShader, ppClassInstances: ^^IClassInstance, pNumClassInstances: ^u32), + HSGetSamplers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumSamplers: u32, ppSamplers: ^^ISamplerState), + HSGetConstantBuffers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumBuffers: u32, ppConstantBuffers: ^^IBuffer), + DSGetShaderResources: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumViews: u32, ppShaderResourceViews: ^^IShaderResourceView), + DSGetShader: proc "stdcall" (this: ^IDeviceContext, ppDomainShader: ^^IDomainShader, ppClassInstances: ^^IClassInstance, pNumClassInstances: ^u32), + DSGetSamplers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumSamplers: u32, ppSamplers: ^^ISamplerState), + DSGetConstantBuffers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumBuffers: u32, ppConstantBuffers: ^^IBuffer), + CSGetShaderResources: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumViews: u32, ppShaderResourceViews: ^^IShaderResourceView), + CSGetUnorderedAccessViews: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumUAVs: u32, ppUnorderedAccessViews: ^^IUnorderedAccessView), + CSGetShader: proc "stdcall" (this: ^IDeviceContext, ppComputeShader: ^^IComputeShader, ppClassInstances: ^^IClassInstance, pNumClassInstances: ^u32), + CSGetSamplers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumSamplers: u32, ppSamplers: ^^ISamplerState), + CSGetConstantBuffers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumBuffers: u32, ppConstantBuffers: ^^IBuffer), + ClearState: proc "stdcall" (this: ^IDeviceContext), + Flush: proc "stdcall" (this: ^IDeviceContext), + GetType: proc "stdcall" (this: ^IDeviceContext) -> DEVICE_CONTEXT_TYPE, + GetContextFlags: proc "stdcall" (this: ^IDeviceContext) -> u32, + FinishCommandList: proc "stdcall" (this: ^IDeviceContext, RestoreDeferredContextState: BOOL, ppCommandList: ^^ICommandList) -> HRESULT, +} + + +CVIDEO_DEFAULT :: struct { + _: u8, +} + +APP_DEPRECATED_HRESULT :: HRESULT + + +VIDEO_DECODER_DESC :: struct { + Guid: GUID, + SampleWidth: u32, + SampleHeight: u32, + OutputFormat: dxgi.FORMAT, +} + +VIDEO_DECODER_CONFIG :: struct { + guidConfigBitstreamEncryption: GUID, + guidConfigMBcontrolEncryption: GUID, + guidConfigResidDiffEncryption: GUID, + ConfigBitstreamRaw: u32, + ConfigMBcontrolRasterOrder: u32, + ConfigResidDiffHost: u32, + ConfigSpatialResid8: u32, + ConfigResid8Subtraction: u32, + ConfigSpatialHost8or9Clipping: u32, + ConfigSpatialResidInterleaved: u32, + ConfigIntraResidUnsigned: u32, + ConfigResidDiffAccelerator: u32, + ConfigHostInverseScan: u32, + ConfigSpecificIDCT: u32, + Config4GroupedCoefs: u32, + ConfigMinRenderTargetBuffCount: u16, + ConfigDecoderSpecific: u16, +} + +VIDEO_DECODER_BUFFER_TYPE :: enum i32 { + PICTURE_PARAMETERS = 0, + MACROBLOCK_CONTROL = 1, + RESIDUAL_DIFFERENCE = 2, + DEBLOCKING_CONTROL = 3, + INVERSE_QUANTIZATION_MATRIX = 4, + SLICE_CONTROL = 5, + BITSTREAM = 6, + MOTION_VECTOR = 7, + FILM_GRAIN = 8, +} + +AES_CTR_IV :: struct { + IV: u64, + Count: u64, +} + +ENCRYPTED_BLOCK_INFO :: struct { + NumEncryptedBytesAtBeginning: u32, + NumBytesInSkipPattern: u32, + NumBytesInEncryptPattern: u32, +} + +VIDEO_DECODER_BUFFER_DESC :: struct { + BufferType: VIDEO_DECODER_BUFFER_TYPE, + BufferIndex: u32, + DataOffset: u32, + DataSize: u32, + FirstMBaddress: u32, + NumMBsInBuffer: u32, + Width: u32, + Height: u32, + Stride: u32, + ReservedBits: u32, + + pIV: rawptr, + IVSize: u32, + PartialEncryption: BOOL, + EncryptedBlockInfo: ENCRYPTED_BLOCK_INFO, +} + +VIDEO_DECODER_EXTENSION :: struct { + Function: u32, + + pPrivateInputData: rawptr, + PrivateInputDataSize: u32, + + pPrivateOutputData: rawptr, + PrivateOutputDataSize: u32, + ResourceCount: u32, + + ppResourceList: ^^IResource, +} + + +IVideoDecoder_UUID_STRING :: "3C9C5B51-995D-48D1-9B8D-FA5CAEDED65C" +IVideoDecoder_UUID := &IID{0x3C9C5B51, 0x995D, 0x48D1, {0x9B, 0x8D, 0xFA, 0x5C, 0xAE, 0xDE, 0xD6, 0x5C}} +IVideoDecoder :: struct #raw_union { + #subtype id3d11devicechild: IDeviceChild, + using id3d11videodecoder_vtable: ^IVideoDecoder_VTable, +} +IVideoDecoder_VTable :: struct { + using id3d11devicechild_vtable: IDeviceChild_VTable, + GetCreationParameters: proc "stdcall" (this: ^IVideoDecoder, pVideoDesc: ^VIDEO_DECODER_DESC, pConfig: ^VIDEO_DECODER_CONFIG) -> HRESULT, + GetDriverHandle: proc "stdcall" (this: ^IVideoDecoder, pDriverHandle: ^HANDLE) -> HRESULT, +} + + +VIDEO_PROCESSOR_FORMAT_SUPPORT :: enum i32 { + INPUT = 1, + OUTPUT = 2, +} + +VIDEO_PROCESSOR_DEVICE_CAPS :: enum i32 { // TODO: make bit_set + LINEAR_SPACE = 1, + xvYCC = 2, + RGB_RANGE_CONVERSION = 4, + YCbCr_MATRIX_CONVERSION = 8, + NOMINAL_RANGE = 16, +} + +VIDEO_PROCESSOR_FEATURE_CAPS :: enum i32 { // TODO: make bit_set + ALPHA_FILL = 1, + CONSTRICTION = 2, + LUMA_KEY = 4, + ALPHA_PALETTE = 8, + LEGACY = 16, + STEREO = 32, + ROTATION = 64, + ALPHA_STREAM = 128, + PIXEL_ASPECT_RATIO = 256, + MIRROR = 512, + SHADER_USAGE = 1024, + METADATA_HDR10 = 2048, +} + +VIDEO_PROCESSOR_FILTER_CAPS :: enum i32 { // TODO: make bit_set + BRIGHTNESS = 1, + CONTRAST = 2, + HUE = 4, + SATURATION = 8, + NOISE_REDUCTION = 16, + EDGE_ENHANCEMENT = 32, + ANAMORPHIC_SCALING = 64, + STEREO_ADJUSTMENT = 128, +} + +VIDEO_PROCESSOR_FORMAT_CAPS :: enum i32 { // TODO: make bit_set + RGB_INTERLACED = 1, + RGB_PROCAMP = 2, + RGB_LUMA_KEY = 4, + PALETTE_INTERLACED = 8, +} + +VIDEO_PROCESSOR_AUTO_STREAM_CAPS :: enum i32 { // TODO: make bit_set + DENOISE = 1, + DERINGING = 2, + EDGE_ENHANCEMENT = 4, + COLOR_CORRECTION = 8, + FLESH_TONE_MAPPING = 16, + IMAGE_STABILIZATION = 32, + SUPER_RESOLUTION = 64, + ANAMORPHIC_SCALING = 128, +} + +VIDEO_PROCESSOR_STEREO_CAPS :: enum i32 { // TODO: make bit_set + MONO_OFFSET = 1, + ROW_INTERLEAVED = 2, + COLUMN_INTERLEAVED = 4, + CHECKERBOARD = 8, + FLIP_MODE = 16, +} + +VIDEO_PROCESSOR_CAPS :: struct { + DeviceCaps: u32, + FeatureCaps: u32, + FilterCaps: u32, + InputFormatCaps: u32, + AutoStreamCaps: u32, + StereoCaps: u32, + RateConversionCapsCount: u32, + MaxInputStreams: u32, + MaxStreamStates: u32, +} + +VIDEO_PROCESSOR_PROCESSOR_CAPS :: enum i32 { // TODO: make bit_set + DEINTERLACE_BLEND = 1, + DEINTERLACE_BOB = 2, + DEINTERLACE_ADAPTIVE = 4, + DEINTERLACE_MOTION_COMPENSATION = 8, + INVERSE_TELECINE = 16, + FRAME_RATE_CONVERSION = 32, +} + +VIDEO_PROCESSOR_ITELECINE_CAPS :: enum i32 { + _32 = 1, + _22 = 2, + _2224 = 4, + _2332 = 8, + _32322 = 16, + _55 = 32, + _64 = 64, + _87 = 128, + _222222222223 = 256, + OTHER = -2147483648, +} + +VIDEO_PROCESSOR_RATE_CONVERSION_CAPS :: struct { + PastFrames: u32, + FutureFrames: u32, + ProcessorCaps: u32, + ITelecineCaps: u32, + CustomRateCount: u32, +} + +CONTENT_PROTECTION_CAPS :: enum i32 { + SOFTWARE = 1, + HARDWARE = 2, + PROTECTION_ALWAYS_ON = 4, + PARTIAL_DECRYPTION = 8, + CONTENT_KEY = 16, + FRESHEN_SESSION_KEY = 32, + ENCRYPTED_READ_BACK = 64, + ENCRYPTED_READ_BACK_KEY = 128, + SEQUENTIAL_CTR_IV = 256, + ENCRYPT_SLICEDATA_ONLY = 512, + DECRYPTION_BLT = 1024, + HARDWARE_PROTECT_UNCOMPRESSED = 2048, + HARDWARE_PROTECTED_MEMORY_PAGEABLE = 4096, + HARDWARE_TEARDOWN = 8192, + HARDWARE_DRM_COMMUNICATION = 16384, + HARDWARE_DRM_COMMUNICATION_MULTI_THREADED = 32768, +} + + +VIDEO_CONTENT_PROTECTION_CAPS :: struct { + Caps: u32, + KeyExchangeTypeCount: u32, + BlockAlignmentSize: u32, + ProtectedMemorySize: u64, +} + +VIDEO_PROCESSOR_CUSTOM_RATE :: struct { + CustomRate: dxgi.RATIONAL, + OutputFrames: u32, + InputInterlaced: BOOL, + InputFramesOrFields: u32, +} + +VIDEO_PROCESSOR_FILTER :: enum i32 { + BRIGHTNESS = 0, + CONTRAST = 1, + HUE = 2, + SATURATION = 3, + NOISE_REDUCTION = 4, + EDGE_ENHANCEMENT = 5, + ANAMORPHIC_SCALING = 6, + STEREO_ADJUSTMENT = 7, +} + +VIDEO_PROCESSOR_FILTER_RANGE :: struct { + Minimum: i32, + Maximum: i32, + Default: i32, + Multiplier: f32, +} + +VIDEO_FRAME_FORMAT :: enum i32 { + PROGRESSIVE = 0, + INTERLACED_TOP_FIELD_FIRST = 1, + INTERLACED_BOTTOM_FIELD_FIRST = 2, +} + +VIDEO_USAGE :: enum i32 { + PLAYBACK_NORMAL = 0, + OPTIMAL_SPEED = 1, + OPTIMAL_QUALITY = 2, +} + +VIDEO_PROCESSOR_CONTENT_DESC :: struct { + InputFrameFormat: VIDEO_FRAME_FORMAT, + InputFrameRate: dxgi.RATIONAL, + InputWidth: u32, + InputHeight: u32, + OutputFrameRate: dxgi.RATIONAL, + OutputWidth: u32, + OutputHeight: u32, + Usage: VIDEO_USAGE, +} + + +IVideoProcessorEnumerator_UUID_STRING :: "31627037-53AB-4200-9061-05FAA9AB45F9" +IVideoProcessorEnumerator_UUID := &IID{0x31627037, 0x53AB, 0x4200, {0x90, 0x61, 0x05, 0xFA, 0xA9, 0xAB, 0x45, 0xF9}} +IVideoProcessorEnumerator :: struct #raw_union { + #subtype id3d11devicechild: IDeviceChild, + using id3d11videoprocessorenumerator_vtable: ^IVideoProcessorEnumerator_VTable, +} +IVideoProcessorEnumerator_VTable :: struct { + using id3d11devicechild_vtable: IDeviceChild_VTable, + GetVideoProcessorContentDesc: proc "stdcall" (this: ^IVideoProcessorEnumerator, pContentDesc: ^VIDEO_PROCESSOR_CONTENT_DESC) -> HRESULT, + CheckVideoProcessorFormat: proc "stdcall" (this: ^IVideoProcessorEnumerator, Format: dxgi.FORMAT, pFlags: ^u32) -> HRESULT, + GetVideoProcessorCaps: proc "stdcall" (this: ^IVideoProcessorEnumerator, pCaps: ^VIDEO_PROCESSOR_CAPS) -> HRESULT, + GetVideoProcessorRateConversionCaps: proc "stdcall" (this: ^IVideoProcessorEnumerator, TypeIndex: u32, pCaps: ^VIDEO_PROCESSOR_RATE_CONVERSION_CAPS) -> HRESULT, + GetVideoProcessorCustomRate: proc "stdcall" (this: ^IVideoProcessorEnumerator, TypeIndex: u32, CustomRateIndex: u32, pRate: ^VIDEO_PROCESSOR_CUSTOM_RATE) -> HRESULT, + GetVideoProcessorFilterRange: proc "stdcall" (this: ^IVideoProcessorEnumerator, Filter: VIDEO_PROCESSOR_FILTER, pRange: ^VIDEO_PROCESSOR_FILTER_RANGE) -> HRESULT, +} + + +VIDEO_COLOR_RGBA :: struct { + R: f32, + G: f32, + B: f32, + A: f32, +} + +VIDEO_COLOR_YCbCrA :: struct { + Y: f32, + Cb: f32, + Cr: f32, + A: f32, +} + +VIDEO_COLOR :: struct { + using _: struct #raw_union { + YCbCr: VIDEO_COLOR_YCbCrA, + RGBA: VIDEO_COLOR_RGBA, + }, +} + +VIDEO_PROCESSOR_NOMINAL_RANGE :: enum i32 { + UNDEFINED = 0, + _16_235 = 1, + _0_255 = 2, +} + +VIDEO_PROCESSOR_COLOR_SPACE_FLAG :: enum u32 { + Usage = 0, + RGB_Range = 1, + YCbCr_Matrix = 2, + YCbCr_xvYCC = 3, + Nominal_Range = 4, + Reserved = 6, +} + +VIDEO_PROCESSOR_COLOR_SPACE :: distinct bit_set[VIDEO_PROCESSOR_COLOR_SPACE_FLAG; u32] + +VIDEO_PROCESSOR_ALPHA_FILL_MODE :: enum i32 { + OPAQUE = 0, + BACKGROUND = 1, + DESTINATION = 2, + SOURCE_STREAM = 3, +} + +VIDEO_PROCESSOR_OUTPUT_RATE :: enum i32 { + NORMAL = 0, + HALF = 1, + CUSTOM = 2, +} + +VIDEO_PROCESSOR_STEREO_FORMAT :: enum i32 { + MONO = 0, + HORIZONTAL = 1, + VERTICAL = 2, + SEPARATE = 3, + MONO_OFFSET = 4, + ROW_INTERLEAVED = 5, + COLUMN_INTERLEAVED = 6, + CHECKERBOARD = 7, +} + +VIDEO_PROCESSOR_STEREO_FLIP_MODE :: enum i32 { + NONE = 0, + FRAME0 = 1, + FRAME1 = 2, +} + +VIDEO_PROCESSOR_ROTATION :: enum i32 { + IDENTITY = 0, + _90 = 1, + _180 = 2, + _270 = 3, +} + +VIDEO_PROCESSOR_STREAM :: struct { + Enable: BOOL, + OutputIndex: u32, + InputFrameOrField: u32, + PastFrames: u32, + FutureFrames: u32, + + ppPastSurfaces: ^^IVideoProcessorInputView, + pInputSurface: ^IVideoProcessorInputView, + + ppFutureSurfaces: ^^IVideoProcessorInputView, + + ppPastSurfacesRight: ^^IVideoProcessorInputView, + pInputSurfaceRight: ^IVideoProcessorInputView, + + ppFutureSurfacesRight: ^^IVideoProcessorInputView, +} + + +IVideoProcessor_UUID_STRING :: "1D7B0652-185F-41C6-85CE-0C5BE3D4AE6C" +IVideoProcessor_UUID := &IID{0x1D7B0652, 0x185F, 0x41C6, {0x85, 0xCE, 0x0C, 0x5B, 0xE3, 0xD4, 0xAE, 0x6C}} +IVideoProcessor :: struct #raw_union { + #subtype id3d11devicechild: IDeviceChild, + using id3d11videoprocessor_vtable: ^IVideoProcessor_VTable, +} +IVideoProcessor_VTable :: struct { + using id3d11devicechild_vtable: IDeviceChild_VTable, + GetContentDesc: proc "stdcall" (this: ^IVideoProcessor, pDesc: ^VIDEO_PROCESSOR_CONTENT_DESC), + GetRateConversionCaps: proc "stdcall" (this: ^IVideoProcessor, pCaps: ^VIDEO_PROCESSOR_RATE_CONVERSION_CAPS), +} + + +OMAC :: struct { + Omac: [16]u8, +} + +AUTHENTICATED_CHANNEL_TYPE :: enum i32 { + D3D11 = 1, + DRIVER_SOFTWARE = 2, + DRIVER_HARDWARE = 3, +} + + +IAuthenticatedChannel_UUID_STRING :: "3015A308-DCBD-47AA-A747-192486D14D4A" +IAuthenticatedChannel_UUID := &IID{0x3015A308, 0xDCBD, 0x47AA, {0xA7, 0x47, 0x19, 0x24, 0x86, 0xD1, 0x4D, 0x4A}} +IAuthenticatedChannel :: struct #raw_union { + #subtype id3d11devicechild: IDeviceChild, + using id3d11authenticatedchannel_vtable: ^IAuthenticatedChannel_VTable, +} +IAuthenticatedChannel_VTable :: struct { + using id3d11devicechild_vtable: IDeviceChild_VTable, + GetCertificateSize: proc "stdcall" (this: ^IAuthenticatedChannel, pCertificateSize: ^u32) -> HRESULT, + GetCertificate: proc "stdcall" (this: ^IAuthenticatedChannel, CertificateSize: u32, pCertificate: cstring) -> HRESULT, + GetChannelHandle: proc "stdcall" (this: ^IAuthenticatedChannel, pChannelHandle: ^HANDLE), +} + + +AUTHENTICATED_QUERY_INPUT :: struct { + QueryType: GUID, + hChannel: HANDLE, + SequenceNumber: u32, +} + +AUTHENTICATED_QUERY_OUTPUT :: struct { + omac: OMAC, + QueryType: GUID, + hChannel: HANDLE, + SequenceNumber: u32, + ReturnCode: HRESULT, +} + +AUTHENTICATED_PROTECTION_FLAG :: enum u32 { + ProtectionEnabled = 0, + OverlayOrFullscreenRequired = 1, + Reserved = 2, +} +AUTHENTICATED_PROTECTION_FLAGS :: distinct bit_set[AUTHENTICATED_PROTECTION_FLAG; u32] + +AUTHENTICATED_QUERY_PROTECTION_OUTPUT :: struct { + Output: AUTHENTICATED_QUERY_OUTPUT, + ProtectionFlags: AUTHENTICATED_PROTECTION_FLAGS, +} + +AUTHENTICATED_QUERY_CHANNEL_TYPE_OUTPUT :: struct { + Output: AUTHENTICATED_QUERY_OUTPUT, + ChannelType: AUTHENTICATED_CHANNEL_TYPE, +} + +AUTHENTICATED_QUERY_DEVICE_HANDLE_OUTPUT :: struct { + Output: AUTHENTICATED_QUERY_OUTPUT, + DeviceHandle: HANDLE, +} + +AUTHENTICATED_QUERY_CRYPTO_SESSION_INPUT :: struct { + Input: AUTHENTICATED_QUERY_INPUT, + DecoderHandle: HANDLE, +} + +AUTHENTICATED_QUERY_CRYPTO_SESSION_OUTPUT :: struct { + Output: AUTHENTICATED_QUERY_OUTPUT, + DecoderHandle: HANDLE, + CryptoSessionHandle: HANDLE, + DeviceHandle: HANDLE, +} + +AUTHENTICATED_QUERY_RESTRICTED_SHARED_RESOURCE_PROCESS_COUNT_OUTPUT :: struct { + Output: AUTHENTICATED_QUERY_OUTPUT, + RestrictedSharedResourceProcessCount: u32, +} + +AUTHENTICATED_QUERY_RESTRICTED_SHARED_RESOURCE_PROCESS_INPUT :: struct { + Input: AUTHENTICATED_QUERY_INPUT, + ProcessIndex: u32, +} + +AUTHENTICATED_PROCESS_IDENTIFIER_TYPE :: enum i32 { + UNKNOWN = 0, + DWM = 1, + HANDLE = 2, +} + +AUTHENTICATED_QUERY_RESTRICTED_SHARED_RESOURCE_PROCESS_OUTPUT :: struct { + Output: AUTHENTICATED_QUERY_OUTPUT, + ProcessIndex: u32, + ProcessIdentifier: AUTHENTICATED_PROCESS_IDENTIFIER_TYPE, + ProcessHandle: HANDLE, +} + +AUTHENTICATED_QUERY_UNRESTRICTED_PROTECTED_SHARED_RESOURCE_COUNT_OUTPUT :: struct { + Output: AUTHENTICATED_QUERY_OUTPUT, + UnrestrictedProtectedSharedResourceCount: u32, +} + +AUTHENTICATED_QUERY_OUTPUT_ID_COUNT_INPUT :: struct { + Input: AUTHENTICATED_QUERY_INPUT, + DeviceHandle: HANDLE, + CryptoSessionHandle: HANDLE, +} + +AUTHENTICATED_QUERY_OUTPUT_ID_COUNT_OUTPUT :: struct { + Output: AUTHENTICATED_QUERY_OUTPUT, + DeviceHandle: HANDLE, + CryptoSessionHandle: HANDLE, + OutputIDCount: u32, +} + +AUTHENTICATED_QUERY_OUTPUT_ID_INPUT :: struct { + Input: AUTHENTICATED_QUERY_INPUT, + DeviceHandle: HANDLE, + CryptoSessionHandle: HANDLE, + OutputIDIndex: u32, +} + +AUTHENTICATED_QUERY_OUTPUT_ID_OUTPUT :: struct { + Output: AUTHENTICATED_QUERY_OUTPUT, + DeviceHandle: HANDLE, + CryptoSessionHandle: HANDLE, + OutputIDIndex: u32, + OutputID: u64, +} + +BUS_TYPE :: enum i32 { + OTHER = 0, + PCI = 1, + PCIX = 2, + PCIEXPRESS = 3, + AGP = 4, + NSIDE_OF_CHIPSET = 65536, + RACKS_ON_MOTHER_BOARD_TO_CHIP = 131072, + RACKS_ON_MOTHER_BOARD_TO_SOCKET = 196608, + AUGHTER_BOARD_CONNECTOR = 262144, + AUGHTER_BOARD_CONNECTOR_INSIDE_OF_NUAE = 327680, + ON_STANDARD = -2147483648, +} + +AUTHENTICATED_QUERY_ACESSIBILITY_OUTPUT :: struct { + Output: AUTHENTICATED_QUERY_OUTPUT, + BusType: BUS_TYPE, + AccessibleInContiguousBlocks: BOOL, + AccessibleInNonContiguousBlocks: BOOL, +} + +AUTHENTICATED_QUERY_ACCESSIBILITY_OUTPUT :: AUTHENTICATED_QUERY_ACESSIBILITY_OUTPUT + +AUTHENTICATED_QUERY_ACCESSIBILITY_ENCRYPTION_GUID_COUNT_OUTPUT :: struct { + Output: AUTHENTICATED_QUERY_OUTPUT, + EncryptionGuidCount: u32, +} + +AUTHENTICATED_QUERY_ACCESSIBILITY_ENCRYPTION_GUID_INPUT :: struct { + Input: AUTHENTICATED_QUERY_INPUT, + EncryptionGuidIndex: u32, +} + +AUTHENTICATED_QUERY_ACCESSIBILITY_ENCRYPTION_GUID_OUTPUT :: struct { + Output: AUTHENTICATED_QUERY_OUTPUT, + EncryptionGuidIndex: u32, + EncryptionGuid: GUID, +} + +AUTHENTICATED_QUERY_CURRENT_ACCESSIBILITY_ENCRYPTION_OUTPUT :: struct { + Output: AUTHENTICATED_QUERY_OUTPUT, + EncryptionGuid: GUID, +} + +AUTHENTICATED_CONFIGURE_INPUT :: struct { + omac: OMAC, + ConfigureType: GUID, + hChannel: HANDLE, + SequenceNumber: u32, +} + +AUTHENTICATED_CONFIGURE_OUTPUT :: struct { + omac: OMAC, + ConfigureType: GUID, + hChannel: HANDLE, + SequenceNumber: u32, + ReturnCode: HRESULT, +} + +AUTHENTICATED_CONFIGURE_INITIALIZE_INPUT :: struct { + Parameters: AUTHENTICATED_CONFIGURE_INPUT, + StartSequenceQuery: u32, + StartSequenceConfigure: u32, +} + +AUTHENTICATED_CONFIGURE_PROTECTION_INPUT :: struct { + Parameters: AUTHENTICATED_CONFIGURE_INPUT, + Protections: AUTHENTICATED_PROTECTION_FLAGS, +} + +AUTHENTICATED_CONFIGURE_CRYPTO_SESSION_INPUT :: struct { + Parameters: AUTHENTICATED_CONFIGURE_INPUT, + DecoderHandle: HANDLE, + CryptoSessionHandle: HANDLE, + DeviceHandle: HANDLE, +} + +AUTHENTICATED_CONFIGURE_SHARED_RESOURCE_INPUT :: struct { + Parameters: AUTHENTICATED_CONFIGURE_INPUT, + ProcessType: AUTHENTICATED_PROCESS_IDENTIFIER_TYPE, + ProcessHandle: HANDLE, + AllowAccess: BOOL, +} + +AUTHENTICATED_CONFIGURE_ACCESSIBLE_ENCRYPTION_INPUT :: struct { + Parameters: AUTHENTICATED_CONFIGURE_INPUT, + EncryptionGuid: GUID, +} + + + +ICryptoSession_UUID_STRING :: "9B32F9AD-BDCC-40A6-A39D-D5C865845720" +ICryptoSession_UUID := &IID{0x9B32F9AD, 0xBDCC, 0x40A6, {0xA3, 0x9D, 0xD5, 0xC8, 0x65, 0x84, 0x57, 0x20}} +ICryptoSession :: struct #raw_union { + #subtype id3d11devicechild: IDeviceChild, + using id3d11cryptosession_vtable: ^ICryptoSession_VTable, +} +ICryptoSession_VTable :: struct { + using id3d11devicechild_vtable: IDeviceChild_VTable, + GetCryptoType: proc "stdcall" (this: ^ICryptoSession, pCryptoType: ^GUID), + GetDecoderProfile: proc "stdcall" (this: ^ICryptoSession, pDecoderProfile: ^GUID), + GetCertificateSize: proc "stdcall" (this: ^ICryptoSession, pCertificateSize: ^u32) -> HRESULT, + GetCertificate: proc "stdcall" (this: ^ICryptoSession, CertificateSize: u32, pCertificate: cstring) -> HRESULT, + GetCryptoSessionHandle: proc "stdcall" (this: ^ICryptoSession, pCryptoSessionHandle: ^HANDLE), +} + + +VDOV_DIMENSION :: enum i32 { + UNKNOWN = 0, + TEXTURE2D = 1, +} + +TEX2D_VDOV :: struct { + ArraySlice: u32, +} + +VIDEO_DECODER_OUTPUT_VIEW_DESC :: struct { + DecodeProfile: GUID, + ViewDimension: VDOV_DIMENSION, + using _: struct #raw_union { + Texture2D: TEX2D_VDOV, + }, +} + + +IVideoDecoderOutputView_UUID_STRING :: "C2931AEA-2A85-4F20-860F-FBA1FD256E18" +IVideoDecoderOutputView_UUID := &IID{0xC2931AEA, 0x2A85, 0x4F20, {0x86, 0x0F, 0xFB, 0xA1, 0xFD, 0x25, 0x6E, 0x18}} +IVideoDecoderOutputView :: struct #raw_union { + #subtype id3d11view: IView, + using id3d11videodecoderoutputview_vtable: ^IVideoDecoderOutputView_VTable, +} +IVideoDecoderOutputView_VTable :: struct { + using id3d11view_vtable: IView_VTable, + GetDesc: proc "stdcall" (this: ^IVideoDecoderOutputView, pDesc: ^VIDEO_DECODER_OUTPUT_VIEW_DESC), +} + + +VPIV_DIMENSION :: enum i32 { + UNKNOWN = 0, + TEXTURE2D = 1, +} + +TEX2D_VPIV :: struct { + MipSlice: u32, + ArraySlice: u32, +} + +VIDEO_PROCESSOR_INPUT_VIEW_DESC :: struct { + FourCC: u32, + ViewDimension: VPIV_DIMENSION, + using _: struct #raw_union { + Texture2D: TEX2D_VPIV, + }, +} + + +IVideoProcessorInputView_UUID_STRING :: "11EC5A5F-51DC-4945-AB34-6E8C21300EA5" +IVideoProcessorInputView_UUID := &IID{0x11EC5A5F, 0x51DC, 0x4945, {0xAB, 0x34, 0x6E, 0x8C, 0x21, 0x30, 0x0E, 0xA5}} +IVideoProcessorInputView :: struct #raw_union { + #subtype id3d11view: IView, + using id3d11videoprocessorinputview_vtable: ^IVideoProcessorInputView_VTable, +} +IVideoProcessorInputView_VTable :: struct { + using id3d11view_vtable: IView_VTable, + GetDesc: proc "stdcall" (this: ^IVideoProcessorInputView, pDesc: ^VIDEO_PROCESSOR_INPUT_VIEW_DESC), +} + + +VPOV_DIMENSION :: enum i32 { + UNKNOWN = 0, + TEXTURE2D = 1, + TEXTURE2DARRAY = 2, +} + +TEX2D_VPOV :: struct { + MipSlice: u32, +} + +TEX2D_ARRAY_VPOV :: struct { + MipSlice: u32, + FirstArraySlice: u32, + ArraySize: u32, +} + +VIDEO_PROCESSOR_OUTPUT_VIEW_DESC :: struct { + ViewDimension: VPOV_DIMENSION, + using _: struct #raw_union { + Texture2D: TEX2D_VPOV, + Texture2DArray: TEX2D_ARRAY_VPOV, + }, +} + + +IVideoProcessorOutputView_UUID_STRING :: "A048285E-25A9-4527-BD93-D68B68C44254" +IVideoProcessorOutputView_UUID := &IID{0xA048285E, 0x25A9, 0x4527, {0xBD, 0x93, 0xD6, 0x8B, 0x68, 0xC4, 0x42, 0x54}} +IVideoProcessorOutputView :: struct #raw_union { + #subtype id3d11view: IView, + using id3d11videoprocessoroutputview_vtable: ^IVideoProcessorOutputView_VTable, +} +IVideoProcessorOutputView_VTable :: struct { + using id3d11view_vtable: IView_VTable, + GetDesc: proc "stdcall" (this: ^IVideoProcessorOutputView, pDesc: ^VIDEO_PROCESSOR_OUTPUT_VIEW_DESC), +} + + + +IVideoContext_UUID_STRING :: "61F21C45-3C0E-4A74-9CEA-67100D9AD5E4" +IVideoContext_UUID := &IID{0x61F21C45, 0x3C0E, 0x4A74, {0x9C, 0xEA, 0x67, 0x10, 0x0D, 0x9A, 0xD5, 0xE4}} +IVideoContext :: struct #raw_union { + #subtype id3d11devicechild: IDeviceChild, + using id3d11videocontext_vtable: ^IVideoContext_VTable, +} +IVideoContext_VTable :: struct { + using id3d11devicechild_vtable: IDeviceChild_VTable, + GetDecoderBuffer: proc "stdcall" (this: ^IVideoContext, pDecoder: ^IVideoDecoder, Type: VIDEO_DECODER_BUFFER_TYPE, pBufferSize: ^u32, ppBuffer: ^rawptr) -> HRESULT, + ReleaseDecoderBuffer: proc "stdcall" (this: ^IVideoContext, pDecoder: ^IVideoDecoder, Type: VIDEO_DECODER_BUFFER_TYPE) -> HRESULT, + DecoderBeginFrame: proc "stdcall" (this: ^IVideoContext, pDecoder: ^IVideoDecoder, pView: ^IVideoDecoderOutputView, ContentKeySize: u32, pContentKey: rawptr) -> HRESULT, + DecoderEndFrame: proc "stdcall" (this: ^IVideoContext, pDecoder: ^IVideoDecoder) -> HRESULT, + SubmitDecoderBuffers: proc "stdcall" (this: ^IVideoContext, pDecoder: ^IVideoDecoder, NumBuffers: u32, pBufferDesc: ^VIDEO_DECODER_BUFFER_DESC) -> HRESULT, + DecoderExtension: proc "stdcall" (this: ^IVideoContext, pDecoder: ^IVideoDecoder, pExtensionData: ^VIDEO_DECODER_EXTENSION) -> APP_DEPRECATED_HRESULT, + VideoProcessorSetOutputTargetRect: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, Enable: BOOL, pRect: ^RECT), + VideoProcessorSetOutputBackgroundColor: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, YCbCr: BOOL, pColor: ^VIDEO_COLOR), + VideoProcessorSetOutputColorSpace: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, pColorSpace: ^VIDEO_PROCESSOR_COLOR_SPACE), + VideoProcessorSetOutputAlphaFillMode: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, AlphaFillMode: VIDEO_PROCESSOR_ALPHA_FILL_MODE, StreamIndex: u32), + VideoProcessorSetOutputConstriction: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, Enable: BOOL, Size: SIZE), + VideoProcessorSetOutputStereoMode: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, Enable: BOOL), + VideoProcessorSetOutputExtension: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, pExtensionGuid: ^GUID, DataSize: u32, pData: rawptr) -> APP_DEPRECATED_HRESULT, + VideoProcessorGetOutputTargetRect: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, Enabled: ^BOOL, pRect: ^RECT), + VideoProcessorGetOutputBackgroundColor: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, pYCbCr: ^BOOL, pColor: ^VIDEO_COLOR), + VideoProcessorGetOutputColorSpace: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, pColorSpace: ^VIDEO_PROCESSOR_COLOR_SPACE), + VideoProcessorGetOutputAlphaFillMode: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, pAlphaFillMode: ^VIDEO_PROCESSOR_ALPHA_FILL_MODE, pStreamIndex: ^u32), + VideoProcessorGetOutputConstriction: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, pEnabled: ^BOOL, pSize: ^SIZE), + VideoProcessorGetOutputStereoMode: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, pEnabled: ^BOOL), + VideoProcessorGetOutputExtension: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, pExtensionGuid: ^GUID, DataSize: u32, pData: rawptr) -> APP_DEPRECATED_HRESULT, + VideoProcessorSetStreamFrameFormat: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, FrameFormat: VIDEO_FRAME_FORMAT), + VideoProcessorSetStreamColorSpace: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, pColorSpace: ^VIDEO_PROCESSOR_COLOR_SPACE), + VideoProcessorSetStreamOutputRate: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, OutputRate: VIDEO_PROCESSOR_OUTPUT_RATE, RepeatFrame: BOOL, pCustomRate: ^dxgi.RATIONAL), + VideoProcessorSetStreamSourceRect: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, Enable: BOOL, pRect: ^RECT), + VideoProcessorSetStreamDestRect: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, Enable: BOOL, pRect: ^RECT), + VideoProcessorSetStreamAlpha: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, Enable: BOOL, Alpha: f32), + VideoProcessorSetStreamPalette: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, Count: u32, pEntries: ^u32), + VideoProcessorSetStreamPixelAspectRatio: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, Enable: BOOL, pSourceAspectRatio: ^dxgi.RATIONAL, pDestinationAspectRatio: ^dxgi.RATIONAL), + VideoProcessorSetStreamLumaKey: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, Enable: BOOL, Lower: f32, Upper: f32), + VideoProcessorSetStreamStereoFormat: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, Enable: BOOL, Format: VIDEO_PROCESSOR_STEREO_FORMAT, LeftViewFrame0: BOOL, BaseViewFrame0: BOOL, FlipMode: VIDEO_PROCESSOR_STEREO_FLIP_MODE, MonoOffset: i32), + VideoProcessorSetStreamAutoProcessingMode: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, Enable: BOOL), + VideoProcessorSetStreamFilter: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, Filter: VIDEO_PROCESSOR_FILTER, Enable: BOOL, Level: i32), + VideoProcessorSetStreamExtension: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, pExtensionGuid: ^GUID, DataSize: u32, pData: rawptr) -> APP_DEPRECATED_HRESULT, + VideoProcessorGetStreamFrameFormat: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, pFrameFormat: ^VIDEO_FRAME_FORMAT), + VideoProcessorGetStreamColorSpace: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, pColorSpace: ^VIDEO_PROCESSOR_COLOR_SPACE), + VideoProcessorGetStreamOutputRate: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, pOutputRate: ^VIDEO_PROCESSOR_OUTPUT_RATE, pRepeatFrame: ^BOOL, pCustomRate: ^dxgi.RATIONAL), + VideoProcessorGetStreamSourceRect: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, pEnabled: ^BOOL, pRect: ^RECT), + VideoProcessorGetStreamDestRect: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, pEnabled: ^BOOL, pRect: ^RECT), + VideoProcessorGetStreamAlpha: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, pEnabled: ^BOOL, pAlpha: ^f32), + VideoProcessorGetStreamPalette: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, Count: u32, pEntries: ^u32), + VideoProcessorGetStreamPixelAspectRatio: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, pEnabled: ^BOOL, pSourceAspectRatio: ^dxgi.RATIONAL, pDestinationAspectRatio: ^dxgi.RATIONAL), + VideoProcessorGetStreamLumaKey: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, pEnabled: ^BOOL, pLower: ^f32, pUpper: ^f32), + VideoProcessorGetStreamStereoFormat: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, pEnable: ^BOOL, pFormat: ^VIDEO_PROCESSOR_STEREO_FORMAT, pLeftViewFrame0: ^BOOL, pBaseViewFrame0: ^BOOL, pFlipMode: ^VIDEO_PROCESSOR_STEREO_FLIP_MODE, MonoOffset: ^i32), + VideoProcessorGetStreamAutoProcessingMode: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, pEnabled: ^BOOL), + VideoProcessorGetStreamFilter: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, Filter: VIDEO_PROCESSOR_FILTER, pEnabled: ^BOOL, pLevel: ^i32), + VideoProcessorGetStreamExtension: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, pExtensionGuid: ^GUID, DataSize: u32, pData: rawptr) -> APP_DEPRECATED_HRESULT, + VideoProcessorBlt: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, pView: ^IVideoProcessorOutputView, OutputFrame: u32, StreamCount: u32, pStreams: ^VIDEO_PROCESSOR_STREAM) -> HRESULT, + NegotiateCryptoSessionKeyExchange: proc "stdcall" (this: ^IVideoContext, pCryptoSession: ^ICryptoSession, DataSize: u32, pData: rawptr) -> HRESULT, + EncryptionBlt: proc "stdcall" (this: ^IVideoContext, pCryptoSession: ^ICryptoSession, pSrcSurface: ^ITexture2D, pDstSurface: ^ITexture2D, IVSize: u32, pIV: rawptr), + DecryptionBlt: proc "stdcall" (this: ^IVideoContext, pCryptoSession: ^ICryptoSession, pSrcSurface: ^ITexture2D, pDstSurface: ^ITexture2D, pEncryptedBlockInfo: ^ENCRYPTED_BLOCK_INFO, ContentKeySize: u32, pContentKey: rawptr, IVSize: u32, pIV: rawptr), + StartSessionKeyRefresh: proc "stdcall" (this: ^IVideoContext, pCryptoSession: ^ICryptoSession, RandomNumberSize: u32, pRandomNumber: rawptr), + FinishSessionKeyRefresh: proc "stdcall" (this: ^IVideoContext, pCryptoSession: ^ICryptoSession), + GetEncryptionBltKey: proc "stdcall" (this: ^IVideoContext, pCryptoSession: ^ICryptoSession, KeySize: u32, pReadbackKey: rawptr) -> HRESULT, + NegotiateAuthenticatedChannelKeyExchange: proc "stdcall" (this: ^IVideoContext, pChannel: ^IAuthenticatedChannel, DataSize: u32, pData: rawptr) -> HRESULT, + QueryAuthenticatedChannel: proc "stdcall" (this: ^IVideoContext, pChannel: ^IAuthenticatedChannel, InputSize: u32, pInput: rawptr, OutputSize: u32, pOutput: rawptr) -> HRESULT, + ConfigureAuthenticatedChannel: proc "stdcall" (this: ^IVideoContext, pChannel: ^IAuthenticatedChannel, InputSize: u32, pInput: rawptr, pOutput: ^AUTHENTICATED_CONFIGURE_OUTPUT) -> HRESULT, + VideoProcessorSetStreamRotation: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, Enable: BOOL, Rotation: VIDEO_PROCESSOR_ROTATION), + VideoProcessorGetStreamRotation: proc "stdcall" (this: ^IVideoContext, pVideoProcessor: ^IVideoProcessor, StreamIndex: u32, pEnable: ^BOOL, pRotation: ^VIDEO_PROCESSOR_ROTATION), +} + + + +IVideoDevice_UUID_STRING :: "10EC4D5B-975A-4689-B9E4-D0AAC30FE333" +IVideoDevice_UUID := &IID{0x10EC4D5B, 0x975A, 0x4689, {0xB9, 0xE4, 0xD0, 0xAA, 0xC3, 0x0F, 0xE3, 0x33}} +IVideoDevice :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d11videodevice_vtable: ^IVideoDevice_VTable, +} +IVideoDevice_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + CreateVideoDecoder: proc "stdcall" (this: ^IVideoDevice, pVideoDesc: ^VIDEO_DECODER_DESC, pConfig: ^VIDEO_DECODER_CONFIG, ppDecoder: ^^IVideoDecoder) -> HRESULT, + CreateVideoProcessor: proc "stdcall" (this: ^IVideoDevice, pEnum: ^IVideoProcessorEnumerator, RateConversionIndex: u32, ppVideoProcessor: ^^IVideoProcessor) -> HRESULT, + CreateAuthenticatedChannel: proc "stdcall" (this: ^IVideoDevice, ChannelType: AUTHENTICATED_CHANNEL_TYPE, ppAuthenticatedChannel: ^^IAuthenticatedChannel) -> HRESULT, + CreateCryptoSession: proc "stdcall" (this: ^IVideoDevice, pCryptoType: ^GUID, pDecoderProfile: ^GUID, pKeyExchangeType: ^GUID, ppCryptoSession: ^^ICryptoSession) -> HRESULT, + CreateVideoDecoderOutputView: proc "stdcall" (this: ^IVideoDevice, pResource: ^IResource, pDesc: ^VIDEO_DECODER_OUTPUT_VIEW_DESC, ppVDOVView: ^^IVideoDecoderOutputView) -> HRESULT, + CreateVideoProcessorInputView: proc "stdcall" (this: ^IVideoDevice, pResource: ^IResource, pEnum: ^IVideoProcessorEnumerator, pDesc: ^VIDEO_PROCESSOR_INPUT_VIEW_DESC, ppVPIView: ^^IVideoProcessorInputView) -> HRESULT, + CreateVideoProcessorOutputView: proc "stdcall" (this: ^IVideoDevice, pResource: ^IResource, pEnum: ^IVideoProcessorEnumerator, pDesc: ^VIDEO_PROCESSOR_OUTPUT_VIEW_DESC, ppVPOView: ^^IVideoProcessorOutputView) -> HRESULT, + CreateVideoProcessorEnumerator: proc "stdcall" (this: ^IVideoDevice, pDesc: ^VIDEO_PROCESSOR_CONTENT_DESC, ppEnum: ^^IVideoProcessorEnumerator) -> HRESULT, + GetVideoDecoderProfileCount: proc "stdcall" (this: ^IVideoDevice) -> u32, + GetVideoDecoderProfile: proc "stdcall" (this: ^IVideoDevice, Index: u32, pDecoderProfile: ^GUID) -> HRESULT, + CheckVideoDecoderFormat: proc "stdcall" (this: ^IVideoDevice, pDecoderProfile: ^GUID, Format: dxgi.FORMAT, pSupported: ^BOOL) -> HRESULT, + GetVideoDecoderConfigCount: proc "stdcall" (this: ^IVideoDevice, pDesc: ^VIDEO_DECODER_DESC, pCount: ^u32) -> HRESULT, + GetVideoDecoderConfig: proc "stdcall" (this: ^IVideoDevice, pDesc: ^VIDEO_DECODER_DESC, Index: u32, pConfig: ^VIDEO_DECODER_CONFIG) -> HRESULT, + GetContentProtectionCaps: proc "stdcall" (this: ^IVideoDevice, pCryptoType: ^GUID, pDecoderProfile: ^GUID, pCaps: ^VIDEO_CONTENT_PROTECTION_CAPS) -> HRESULT, + CheckCryptoKeyExchange: proc "stdcall" (this: ^IVideoDevice, pCryptoType: ^GUID, pDecoderProfile: ^GUID, Index: u32, pKeyExchangeType: ^GUID) -> HRESULT, + SetPrivateData: proc "stdcall" (this: ^IVideoDevice, guid: ^GUID, DataSize: u32, pData: rawptr) -> HRESULT, + SetPrivateDataInterface: proc "stdcall" (this: ^IVideoDevice, guid: ^GUID, pData: ^IUnknown) -> HRESULT, +} + + + +IDevice_UUID_STRING :: "DB6F6DDB-AC77-4E88-8253-819DF9BBF140" +IDevice_UUID := &IID{0xDB6F6DDB, 0xAC77, 0x4E88, {0x82, 0x53, 0x81, 0x9D, 0xF9, 0xBB, 0xF1, 0x40}} +IDevice :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d11device_vtable: ^IDevice_VTable, +} +IDevice_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + CreateBuffer: proc "stdcall" (this: ^IDevice, pDesc: ^BUFFER_DESC, pInitialData: ^SUBRESOURCE_DATA, ppBuffer: ^^IBuffer) -> HRESULT, + CreateTexture1D: proc "stdcall" (this: ^IDevice, pDesc: ^TEXTURE1D_DESC, pInitialData: ^SUBRESOURCE_DATA, ppTexture1D: ^^ITexture1D) -> HRESULT, + CreateTexture2D: proc "stdcall" (this: ^IDevice, pDesc: ^TEXTURE2D_DESC, pInitialData: ^SUBRESOURCE_DATA, ppTexture2D: ^^ITexture2D) -> HRESULT, + CreateTexture3D: proc "stdcall" (this: ^IDevice, pDesc: ^TEXTURE3D_DESC, pInitialData: ^SUBRESOURCE_DATA, ppTexture3D: ^^ITexture3D) -> HRESULT, + CreateShaderResourceView: proc "stdcall" (this: ^IDevice, pResource: ^IResource, pDesc: ^SHADER_RESOURCE_VIEW_DESC, ppSRView: ^^IShaderResourceView) -> HRESULT, + CreateUnorderedAccessView: proc "stdcall" (this: ^IDevice, pResource: ^IResource, pDesc: ^UNORDERED_ACCESS_VIEW_DESC, ppUAView: ^^IUnorderedAccessView) -> HRESULT, + CreateRenderTargetView: proc "stdcall" (this: ^IDevice, pResource: ^IResource, pDesc: ^RENDER_TARGET_VIEW_DESC, ppRTView: ^^IRenderTargetView) -> HRESULT, + CreateDepthStencilView: proc "stdcall" (this: ^IDevice, pResource: ^IResource, pDesc: ^DEPTH_STENCIL_VIEW_DESC, ppDepthStencilView: ^^IDepthStencilView) -> HRESULT, + CreateInputLayout: proc "stdcall" (this: ^IDevice, pInputElementDescs: ^INPUT_ELEMENT_DESC, NumElements: u32, pShaderBytecodeWithInputSignature: rawptr, BytecodeLength: SIZE_T, ppInputLayout: ^^IInputLayout) -> HRESULT, + CreateVertexShader: proc "stdcall" (this: ^IDevice, pShaderBytecode: rawptr, BytecodeLength: SIZE_T, pClassLinkage: ^IClassLinkage, ppVertexShader: ^^IVertexShader) -> HRESULT, + CreateGeometryShader: proc "stdcall" (this: ^IDevice, pShaderBytecode: rawptr, BytecodeLength: SIZE_T, pClassLinkage: ^IClassLinkage, ppGeometryShader: ^^IGeometryShader) -> HRESULT, + CreateGeometryShaderWithStreamOutput: proc "stdcall" (this: ^IDevice, pShaderBytecode: rawptr, BytecodeLength: SIZE_T, pSODeclaration: ^SO_DECLARATION_ENTRY, NumEntries: u32, pBufferStrides: ^u32, NumStrides: u32, RasterizedStream: u32, pClassLinkage: ^IClassLinkage, ppGeometryShader: ^^IGeometryShader) -> HRESULT, + CreatePixelShader: proc "stdcall" (this: ^IDevice, pShaderBytecode: rawptr, BytecodeLength: SIZE_T, pClassLinkage: ^IClassLinkage, ppPixelShader: ^^IPixelShader) -> HRESULT, + CreateHullShader: proc "stdcall" (this: ^IDevice, pShaderBytecode: rawptr, BytecodeLength: SIZE_T, pClassLinkage: ^IClassLinkage, ppHullShader: ^^IHullShader) -> HRESULT, + CreateDomainShader: proc "stdcall" (this: ^IDevice, pShaderBytecode: rawptr, BytecodeLength: SIZE_T, pClassLinkage: ^IClassLinkage, ppDomainShader: ^^IDomainShader) -> HRESULT, + CreateComputeShader: proc "stdcall" (this: ^IDevice, pShaderBytecode: rawptr, BytecodeLength: SIZE_T, pClassLinkage: ^IClassLinkage, ppComputeShader: ^^IComputeShader) -> HRESULT, + CreateClassLinkage: proc "stdcall" (this: ^IDevice, ppLinkage: ^^IClassLinkage) -> HRESULT, + CreateBlendState: proc "stdcall" (this: ^IDevice, pBlendStateDesc: ^BLEND_DESC, ppBlendState: ^^IBlendState) -> HRESULT, + CreateDepthStencilState: proc "stdcall" (this: ^IDevice, pDepthStencilDesc: ^DEPTH_STENCIL_DESC, ppDepthStencilState: ^^IDepthStencilState) -> HRESULT, + CreateRasterizerState: proc "stdcall" (this: ^IDevice, pRasterizerDesc: ^RASTERIZER_DESC, ppRasterizerState: ^^IRasterizerState) -> HRESULT, + CreateSamplerState: proc "stdcall" (this: ^IDevice, pSamplerDesc: ^SAMPLER_DESC, ppSamplerState: ^^ISamplerState) -> HRESULT, + CreateQuery: proc "stdcall" (this: ^IDevice, pQueryDesc: ^QUERY_DESC, ppQuery: ^^IQuery) -> HRESULT, + CreatePredicate: proc "stdcall" (this: ^IDevice, pPredicateDesc: ^QUERY_DESC, ppPredicate: ^^IPredicate) -> HRESULT, + CreateCounter: proc "stdcall" (this: ^IDevice, pCounterDesc: ^COUNTER_DESC, ppCounter: ^^ICounter) -> HRESULT, + CreateDeferredContext: proc "stdcall" (this: ^IDevice, ContextFlags: u32, ppDeferredContext: ^^IDeviceContext) -> HRESULT, + OpenSharedResource: proc "stdcall" (this: ^IDevice, hResource: HANDLE, ReturnedInterface: ^IID, ppResource: ^rawptr) -> HRESULT, + CheckFormatSupport: proc "stdcall" (this: ^IDevice, Format: dxgi.FORMAT, pFormatSupport: ^u32) -> HRESULT, + CheckMultisampleQualityLevels: proc "stdcall" (this: ^IDevice, Format: dxgi.FORMAT, SampleCount: u32, pNumQualityLevels: ^u32) -> HRESULT, + CheckCounterInfo: proc "stdcall" (this: ^IDevice, pCounterInfo: ^COUNTER_INFO), + CheckCounter: proc "stdcall" (this: ^IDevice, pDesc: ^COUNTER_DESC, pType: ^COUNTER_TYPE, pActiveCounters: ^u32, szName: cstring, pNameLength: ^u32, szUnits: ^u8, pUnitsLength: ^u32, szDescription: cstring, pDescriptionLength: ^u32) -> HRESULT, + CheckFeatureSupport: proc "stdcall" (this: ^IDevice, Feature: FEATURE, pFeatureSupportData: rawptr, FeatureSupportDataSize: u32) -> HRESULT, + GetPrivateData: proc "stdcall" (this: ^IDevice, guid: ^GUID, pDataSize: ^u32, pData: rawptr) -> HRESULT, + SetPrivateData: proc "stdcall" (this: ^IDevice, guid: ^GUID, DataSize: u32, pData: rawptr) -> HRESULT, + SetPrivateDataInterface: proc "stdcall" (this: ^IDevice, guid: ^GUID, pData: ^IUnknown) -> HRESULT, + GetFeatureLevel: proc "stdcall" (this: ^IDevice) -> FEATURE_LEVEL, + GetCreationFlags: proc "stdcall" (this: ^IDevice) -> u32, + GetDeviceRemovedReason: proc "stdcall" (this: ^IDevice) -> HRESULT, + GetImmediateContext: proc "stdcall" (this: ^IDevice, ppImmediateContext: ^^IDeviceContext), + SetExceptionMode: proc "stdcall" (this: ^IDevice, RaiseFlags: u32) -> HRESULT, + GetExceptionMode: proc "stdcall" (this: ^IDevice) -> u32, +} + + +CREATE_DEVICE_FLAGS :: distinct bit_set[CREATE_DEVICE_FLAG; u32] +CREATE_DEVICE_FLAG :: enum u32 { // TODO: make bit_set + SINGLETHREADED = 0, + DEBUG = 1, + SWITCH_TO_REF = 2, + PREVENT_INTERNAL_THREADING_OPTIMIZATIONS = 3, + BGRA_SUPPORT = 5, + DEBUGGABLE = 6, + PREVENT_ALTERING_LAYER_SETTINGS_FROM_REGISTRY = 7, + DISABLE_GPU_TIMEOUT = 8, + VIDEO_SUPPORT = 12, +} + +PFN_CREATE_DEVICE :: #type proc "c" (a0: ^dxgi.IAdapter, a1: DRIVER_TYPE, a2: HMODULE, a3: u32, a4: ^FEATURE_LEVEL, a5: u32, a6: u32, a7: ^^IDevice, a8: ^FEATURE_LEVEL, a9: ^^IDeviceContext) -> HRESULT +PFN_CREATE_DEVICE_AND_SWAP_CHAIN :: #type proc "c" (a0: ^dxgi.IAdapter, a1: DRIVER_TYPE, a2: HMODULE, a3: u32, a4: ^FEATURE_LEVEL, a5: u32, a6: u32, a7: ^dxgi.SWAP_CHAIN_DESC, a8: ^^dxgi.ISwapChain, a9: ^^IDevice, a10: ^FEATURE_LEVEL, a11: ^^IDeviceContext) -> HRESULT + +SHADER_VERSION_TYPE :: enum i32 { + PIXEL_SHADER = 0, + VERTEX_SHADER = 1, + GEOMETRY_SHADER = 2, + + HULL_SHADER = 3, + DOMAIN_SHADER = 4, + COMPUTE_SHADER = 5, + + RESERVED0 = 65520, +} + +SIGNATURE_PARAMETER_DESC :: struct { + SemanticName: cstring, + SemanticIndex: u32, + Register: u32, + SystemValueType: NAME, + ComponentType: REGISTER_COMPONENT_TYPE, + Mask: u8, + + ReadWriteMask: u8, + + Stream: u32, + MinPrecision: MIN_PRECISION, +} + +SHADER_BUFFER_DESC :: struct { + Name: cstring, + Type: CBUFFER_TYPE, + Variables: u32, + Size: u32, + uFlags: u32, +} + +SHADER_VARIABLE_DESC :: struct { + Name: cstring, + StartOffset: u32, + Size: u32, + uFlags: u32, + DefaultValue: rawptr, + StartTexture: u32, + TextureSize: u32, + StartSampler: u32, + SamplerSize: u32, +} + +SHADER_TYPE_DESC :: struct { + Class: SHADER_VARIABLE_CLASS, + Type: SHADER_VARIABLE_TYPE, + Rows: u32, + Columns: u32, + Elements: u32, + Members: u32, + Offset: u32, + Name: cstring, +} + +SHADER_DESC :: struct { + Version: u32, + Creator: cstring, + Flags: u32, + + ConstantBuffers: u32, + BoundResources: u32, + InputParameters: u32, + OutputParameters: u32, + + InstructionCount: u32, + TempRegisterCount: u32, + TempArrayCount: u32, + DefCount: u32, + DclCount: u32, + TextureNormalInstructions: u32, + TextureLoadInstructions: u32, + TextureCompInstructions: u32, + TextureBiasInstructions: u32, + TextureGradientInstructions: u32, + FloatInstructionCount: u32, + IntInstructionCount: u32, + UintInstructionCount: u32, + StaticFlowControlCount: u32, + DynamicFlowControlCount: u32, + MacroInstructionCount: u32, + ArrayInstructionCount: u32, + CutInstructionCount: u32, + EmitInstructionCount: u32, + GSOutputTopology: PRIMITIVE_TOPOLOGY, + GSMaxOutputVertexCount: u32, + InputPrimitive: PRIMITIVE, + PatchConstantParameters: u32, + cGSInstanceCount: u32, + cControlPoints: u32, + HSOutputPrimitive: TESSELLATOR_OUTPUT_PRIMITIVE, + HSPartitioning: TESSELLATOR_PARTITIONING, + TessellatorDomain: TESSELLATOR_DOMAIN, + + cBarrierInstructions: u32, + cInterlockedInstructions: u32, + cTextureStoreInstructions: u32, +} + +SHADER_INPUT_BIND_DESC :: struct { + Name: cstring, + Type: SHADER_INPUT_TYPE, + BindPoint: u32, + BindCount: u32, + + uFlags: u32, + ReturnType: RESOURCE_RETURN_TYPE, + Dimension: SRV_DIMENSION, + NumSamples: u32, +} + +LIBRARY_DESC :: struct { + Creator: cstring, + Flags: u32, + FunctionCount: u32, +} + +FUNCTION_DESC :: struct { + Version: u32, + Creator: cstring, + Flags: u32, + + ConstantBuffers: u32, + BoundResources: u32, + + InstructionCount: u32, + TempRegisterCount: u32, + TempArrayCount: u32, + DefCount: u32, + DclCount: u32, + TextureNormalInstructions: u32, + TextureLoadInstructions: u32, + TextureCompInstructions: u32, + TextureBiasInstructions: u32, + TextureGradientInstructions: u32, + FloatInstructionCount: u32, + IntInstructionCount: u32, + UintInstructionCount: u32, + StaticFlowControlCount: u32, + DynamicFlowControlCount: u32, + MacroInstructionCount: u32, + ArrayInstructionCount: u32, + MovInstructionCount: u32, + MovcInstructionCount: u32, + ConversionInstructionCount: u32, + BitwiseInstructionCount: u32, + MinFeatureLevel: FEATURE_LEVEL, + RequiredFeatureFlags: u64, + + Name: cstring, + FunctionParameterCount: i32, + HasReturn: BOOL, + Has10Level9VertexShader: BOOL, + Has10Level9PixelShader: BOOL, +} + +PARAMETER_DESC :: struct { + Name: cstring, + SemanticName: cstring, + Type: SHADER_VARIABLE_TYPE, + Class: SHADER_VARIABLE_CLASS, + Rows: u32, + Columns: u32, + InterpolationMode: INTERPOLATION_MODE, + Flags: PARAMETER_FLAGS, + + FirstInRegister: u32, + FirstInComponent: u32, + FirstOutRegister: u32, + FirstOutComponent: u32, +} + +IShaderReflectionType :: struct { + using vtable: ^IShaderReflectionType_VTable, +} +IShaderReflectionType_VTable :: struct { + GetDesc: proc "stdcall" (this: ^IShaderReflectionType, pDesc: ^SHADER_TYPE_DESC) -> HRESULT, + GetMemberTypeByIndex: proc "stdcall" (this: ^IShaderReflectionType, Index: u32) -> ^IShaderReflectionType, + GetMemberTypeByName: proc "stdcall" (this: ^IShaderReflectionType, Name: cstring) -> ^IShaderReflectionType, + GetMemberTypeName: proc "stdcall" (this: ^IShaderReflectionType, Index: u32) -> cstring, + IsEqual: proc "stdcall" (this: ^IShaderReflectionType, pType: ^IShaderReflectionType) -> HRESULT, + GetSubType: proc "stdcall" (this: ^IShaderReflectionType) -> ^IShaderReflectionType, + GetBaseClass: proc "stdcall" (this: ^IShaderReflectionType) -> ^IShaderReflectionType, + GetNumInterfaces: proc "stdcall" (this: ^IShaderReflectionType) -> u32, + GetInterfaceByIndex: proc "stdcall" (this: ^IShaderReflectionType, uIndex: u32) -> ^IShaderReflectionType, + IsOfType: proc "stdcall" (this: ^IShaderReflectionType, pType: ^IShaderReflectionType) -> HRESULT, + ImplementsInterface: proc "stdcall" (this: ^IShaderReflectionType, pBase: ^IShaderReflectionType) -> HRESULT, +} + +IShaderReflectionVariable :: struct { + using vtable: ^IShaderReflectionVariable_VTable, +} +IShaderReflectionVariable_VTable :: struct { + GetDesc: proc "stdcall" (this: ^IShaderReflectionVariable, pDesc: ^SHADER_VARIABLE_DESC) -> HRESULT, + GetType: proc "stdcall" (this: ^IShaderReflectionVariable) -> ^IShaderReflectionType, + GetBuffer: proc "stdcall" (this: ^IShaderReflectionVariable) -> ^IShaderReflectionConstantBuffer, + GetInterfaceSlot: proc "stdcall" (this: ^IShaderReflectionVariable, uArrayIndex: u32) -> u32, +} + +IShaderReflectionConstantBuffer :: struct { + using vtable: ^IShaderReflectionConstantBuffer_VTable, +} +IShaderReflectionConstantBuffer_VTable :: struct { + GetDesc: proc "stdcall" (this: ^IShaderReflectionConstantBuffer, pDesc: ^SHADER_BUFFER_DESC) -> HRESULT, + GetVariableByIndex: proc "stdcall" (this: ^IShaderReflectionConstantBuffer, Index: u32) -> ^IShaderReflectionVariable, + GetVariableByName: proc "stdcall" (this: ^IShaderReflectionConstantBuffer, Name: cstring) -> ^IShaderReflectionVariable, +} + + +IShaderReflection :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d11shaderreflection_vtable: ^IShaderReflection_VTable, +} +IShaderReflection_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + GetDesc: proc "stdcall" (this: ^IShaderReflection, pDesc: ^SHADER_DESC) -> HRESULT, + GetConstantBufferByIndex: proc "stdcall" (this: ^IShaderReflection, Index: u32) -> ^IShaderReflectionConstantBuffer, + GetConstantBufferByName: proc "stdcall" (this: ^IShaderReflection, Name: cstring) -> ^IShaderReflectionConstantBuffer, + GetResourceBindingDesc: proc "stdcall" (this: ^IShaderReflection, ResourceIndex: u32, pDesc: ^SHADER_INPUT_BIND_DESC) -> HRESULT, + GetInputParameterDesc: proc "stdcall" (this: ^IShaderReflection, ParameterIndex: u32, pDesc: ^SIGNATURE_PARAMETER_DESC) -> HRESULT, + GetOutputParameterDesc: proc "stdcall" (this: ^IShaderReflection, ParameterIndex: u32, pDesc: ^SIGNATURE_PARAMETER_DESC) -> HRESULT, + GetPatchConstantParameterDesc: proc "stdcall" (this: ^IShaderReflection, ParameterIndex: u32, pDesc: ^SIGNATURE_PARAMETER_DESC) -> HRESULT, + GetVariableByName: proc "stdcall" (this: ^IShaderReflection, Name: cstring) -> ^IShaderReflectionVariable, + GetResourceBindingDescByName: proc "stdcall" (this: ^IShaderReflection, Name: cstring, pDesc: ^SHADER_INPUT_BIND_DESC) -> HRESULT, + GetMovInstructionCount: proc "stdcall" (this: ^IShaderReflection) -> u32, + GetMovcInstructionCount: proc "stdcall" (this: ^IShaderReflection) -> u32, + GetConversionInstructionCount: proc "stdcall" (this: ^IShaderReflection) -> u32, + GetBitwiseInstructionCount: proc "stdcall" (this: ^IShaderReflection) -> u32, + GetGSInputPrimitive: proc "stdcall" (this: ^IShaderReflection) -> PRIMITIVE, + IsSampleFrequencyShader: proc "stdcall" (this: ^IShaderReflection) -> BOOL, + GetNumInterfaceSlots: proc "stdcall" (this: ^IShaderReflection) -> u32, + GetMinFeatureLevel: proc "stdcall" (this: ^IShaderReflection, pLevel: ^FEATURE_LEVEL) -> HRESULT, + GetThreadGroupSize: proc "stdcall" (this: ^IShaderReflection, pSizeX: ^u32, pSizeY: ^u32, pSizeZ: ^u32) -> u32, + GetRequiresFlags: proc "stdcall" (this: ^IShaderReflection) -> u64, +} + + +ILibraryReflection :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d11libraryreflection_vtable: ^ILibraryReflection_VTable, +} +ILibraryReflection_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + GetDesc: proc "stdcall" (this: ^ILibraryReflection, pDesc: ^LIBRARY_DESC) -> HRESULT, + GetFunctionByIndex: proc "stdcall" (this: ^ILibraryReflection, FunctionIndex: i32) -> ^IFunctionReflection, +} + +IFunctionReflection :: struct { + using vtable: ^IFunctionReflection_VTable, +} +IFunctionReflection_VTable :: struct { + GetDesc: proc "stdcall" (this: ^IFunctionReflection, pDesc: ^FUNCTION_DESC) -> HRESULT, + GetConstantBufferByIndex: proc "stdcall" (this: ^IFunctionReflection, BufferIndex: u32) -> ^IShaderReflectionConstantBuffer, + GetConstantBufferByName: proc "stdcall" (this: ^IFunctionReflection, Name: cstring) -> ^IShaderReflectionConstantBuffer, + GetResourceBindingDesc: proc "stdcall" (this: ^IFunctionReflection, ResourceIndex: u32, pDesc: ^SHADER_INPUT_BIND_DESC) -> HRESULT, + GetVariableByName: proc "stdcall" (this: ^IFunctionReflection, Name: cstring) -> ^IShaderReflectionVariable, + GetResourceBindingDescByName: proc "stdcall" (this: ^IFunctionReflection, Name: cstring, pDesc: ^SHADER_INPUT_BIND_DESC) -> HRESULT, + GetFunctionParameter: proc "stdcall" (this: ^IFunctionReflection, ParameterIndex: i32) -> ^IFunctionParameterReflection, +} + +IFunctionParameterReflection :: struct { + using vtable: ^IFunctionParameterReflection_VTable, +} +IFunctionParameterReflection_VTable :: struct { + GetDesc: proc "stdcall" (this: ^IFunctionParameterReflection, pDesc: ^PARAMETER_DESC) -> HRESULT, +} + + +ILinkingNode :: struct { + using iunknown: IUnknown, +} + +IFunctionLinkingGraph :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d11functionlinkinggraph_vtable: ^IFunctionLinkingGraph_VTable, +} +IFunctionLinkingGraph_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + CreateModuleInstance: proc "stdcall" (this: ^IFunctionLinkingGraph, ppModuleInstance: ^^IModuleInstance, ppErrorBuffer: ^^IBlob) -> HRESULT, + SetInputSignature: proc "stdcall" (this: ^IFunctionLinkingGraph, pInputParameters: ^PARAMETER_DESC, cInputParameters: u32, ppInputNode: ^^ILinkingNode) -> HRESULT, + SetOutputSignature: proc "stdcall" (this: ^IFunctionLinkingGraph, pOutputParameters: ^PARAMETER_DESC, cOutputParameters: u32, ppOutputNode: ^^ILinkingNode) -> HRESULT, + CallFunction: proc "stdcall" (this: ^IFunctionLinkingGraph, pModuleInstanceNamespace: cstring, pModuleWithFunctionPrototype: ^IModule, pFunctionName: cstring, ppCallNode: ^^ILinkingNode) -> HRESULT, + PassValue: proc "stdcall" (this: ^IFunctionLinkingGraph, pSrcNode: ^ILinkingNode, SrcParameterIndex: i32, pDstNode: ^ILinkingNode, DstParameterIndex: i32) -> HRESULT, + PassValueWithSwizzle: proc "stdcall" (this: ^IFunctionLinkingGraph, pSrcNode: ^ILinkingNode, SrcParameterIndex: i32, pSrcSwizzle: ^u8, pDstNode: ^ILinkingNode, DstParameterIndex: i32, pDstSwizzle: ^u8) -> HRESULT, + GetLastError: proc "stdcall" (this: ^IFunctionLinkingGraph, ppErrorBuffer: ^^IBlob) -> HRESULT, + GenerateHlsl: proc "stdcall" (this: ^IFunctionLinkingGraph, uFlags: u32, ppBuffer: ^^IBlob) -> HRESULT, +} diff --git a/vendor/directx/d3d12/d3d12.odin b/vendor/directx/d3d12/d3d12.odin new file mode 100644 index 000000000..f3885ed63 --- /dev/null +++ b/vendor/directx/d3d12/d3d12.odin @@ -0,0 +1,5102 @@ +package directx_d3d12 + +foreign import "system:d3d12.lib" + +import "../dxgi" +import "../d3d_compiler" +import win32 "core:sys/windows" + +IUnknown :: dxgi.IUnknown +IUnknown_VTable :: dxgi.IUnknown_VTable + +HANDLE :: dxgi.HANDLE +HMODULE :: dxgi.HMODULE +HRESULT :: dxgi.HRESULT +HWND :: dxgi.HWND +LUID :: dxgi.LUID +UUID :: dxgi.UUID +GUID :: dxgi.GUID +IID :: dxgi.IID +SIZE_T :: dxgi.SIZE_T +BOOL :: dxgi.BOOL + +RECT :: dxgi.RECT + +IModuleInstance :: d3d_compiler.ID3D11ModuleInstance +IBlob :: d3d_compiler.ID3DBlob +IModule :: d3d_compiler.ID3D11Module + +@(default_calling_convention="stdcall", link_prefix="D3D12") +foreign d3d12 { + CreateDevice :: proc(pAdapter: ^IUnknown, MinimumFeatureLevel: FEATURE_LEVEL, riid: ^IID, ppDevice: ^rawptr) -> HRESULT --- + CreateRootSignatureDeserializer :: proc(pSrcData: rawptr, SrcDataSizeInBytes: SIZE_T, pRootSignatureDeserializerInterface: ^IID, ppRootSignatureDeserializer: ^rawptr) -> HRESULT --- + CreateVersionedRootSignatureDeserializer :: proc(pSrcData: rawptr, SrcDataSizeInBytes: SIZE_T, pRootSignatureDeserializerInterface: ^IID, ppRootSignatureDeserializer: ^rawptr) -> HRESULT --- + EnableExperimentalFeatures :: proc(NumFeatures: u32, pIIDs: ^IID, pConfigurationStructs: rawptr, pConfigurationStructSizes: ^u32) -> HRESULT --- + GetDebugInterface :: proc(riid: ^IID, ppvDebug: ^rawptr) -> HRESULT --- + SerializeRootSignature :: proc(pRootSignature: ^ROOT_SIGNATURE_DESC, Version: ROOT_SIGNATURE_VERSION, ppBlob: ^^IBlob, ppErrorBlob: ^^IBlob) -> HRESULT --- + SerializeVersionedRootSignature :: proc(pRootSignature: ^VERSIONED_ROOT_SIGNATURE_DESC, ppBlob: ^^IBlob, ppErrorBlob: ^^IBlob) -> HRESULT --- +} + +foreign d3d12 { + WKPDID_D3DDebugObjectNameW: GUID + WKPDID_CommentStringW: GUID + + @(link_name="DXGI_DEBUG_D3D12") + DEBUG_D3D12: GUID + + @(link_name="D3D12_PROTECTED_RESOURCES_SESSION_HARDWARE_PROTECTED") + PROTECTED_RESOURCES_SESSION_HARDWARE_PROTECTED: GUID +} + +@(link_prefix="D3D_") +foreign d3d12 { + TEXTURE_LAYOUT_ROW_MAJOR: GUID + TEXTURE_LAYOUT_64KB_STANDARD_SWIZZLE: GUID +} + +@(link_prefix="D3D12") +foreign d3d12 { + ExperimentalShaderModels: UUID + TiledResourceTier4: UUID + MetaCommand: UUID +} + + +DRIVER_TYPE :: enum i32 { + UNKNOWN = 0, + HARDWARE = 1, + REFERENCE = 2, + NULL = 3, + SOFTWARE = 4, + WARP = 5, +} + +FEATURE_LEVEL :: enum i32 { + _1_0_CORE = 4096, + _9_1 = 37120, + _9_2 = 37376, + _9_3 = 37632, + _10_0 = 40960, + _10_1 = 41216, + _11_0 = 45056, + _11_1 = 45312, + _12_0 = 49152, + _12_1 = 49408, +} + +PRIMITIVE_TOPOLOGY :: enum i32 { + UNDEFINED = 0, + POINTLIST = 1, + LINELIST = 2, + LINESTRIP = 3, + TRIANGLELIST = 4, + TRIANGLESTRIP = 5, + LINELIST_ADJ = 10, + LINESTRIP_ADJ = 11, + TRIANGLELIST_ADJ = 12, + TRIANGLESTRIP_ADJ = 13, + _1_CONTROL_POINT_PATCHLIST = 33, + _2_CONTROL_POINT_PATCHLIST = 34, + _3_CONTROL_POINT_PATCHLIST = 35, + _4_CONTROL_POINT_PATCHLIST = 36, + _5_CONTROL_POINT_PATCHLIST = 37, + _6_CONTROL_POINT_PATCHLIST = 38, + _7_CONTROL_POINT_PATCHLIST = 39, + _8_CONTROL_POINT_PATCHLIST = 40, + _9_CONTROL_POINT_PATCHLIST = 41, + _10_CONTROL_POINT_PATCHLIST = 42, + _11_CONTROL_POINT_PATCHLIST = 43, + _12_CONTROL_POINT_PATCHLIST = 44, + _13_CONTROL_POINT_PATCHLIST = 45, + _14_CONTROL_POINT_PATCHLIST = 46, + _15_CONTROL_POINT_PATCHLIST = 47, + _16_CONTROL_POINT_PATCHLIST = 48, + _17_CONTROL_POINT_PATCHLIST = 49, + _18_CONTROL_POINT_PATCHLIST = 50, + _19_CONTROL_POINT_PATCHLIST = 51, + _20_CONTROL_POINT_PATCHLIST = 52, + _21_CONTROL_POINT_PATCHLIST = 53, + _22_CONTROL_POINT_PATCHLIST = 54, + _23_CONTROL_POINT_PATCHLIST = 55, + _24_CONTROL_POINT_PATCHLIST = 56, + _25_CONTROL_POINT_PATCHLIST = 57, + _26_CONTROL_POINT_PATCHLIST = 58, + _27_CONTROL_POINT_PATCHLIST = 59, + _28_CONTROL_POINT_PATCHLIST = 60, + _29_CONTROL_POINT_PATCHLIST = 61, + _30_CONTROL_POINT_PATCHLIST = 62, + _31_CONTROL_POINT_PATCHLIST = 63, + _32_CONTROL_POINT_PATCHLIST = 64, +} + +PRIMITIVE :: enum i32 { + UNDEFINED = 0, + POINT = 1, + LINE = 2, + TRIANGLE = 3, + LINE_ADJ = 6, + TRIANGLE_ADJ = 7, + _1_CONTROL_POINT_PATCH = 8, + _2_CONTROL_POINT_PATCH = 9, + _3_CONTROL_POINT_PATCH = 10, + _4_CONTROL_POINT_PATCH = 11, + _5_CONTROL_POINT_PATCH = 12, + _6_CONTROL_POINT_PATCH = 13, + _7_CONTROL_POINT_PATCH = 14, + _8_CONTROL_POINT_PATCH = 15, + _9_CONTROL_POINT_PATCH = 16, + _10_CONTROL_POINT_PATCH = 17, + _11_CONTROL_POINT_PATCH = 18, + _12_CONTROL_POINT_PATCH = 19, + _13_CONTROL_POINT_PATCH = 20, + _14_CONTROL_POINT_PATCH = 21, + _15_CONTROL_POINT_PATCH = 22, + _16_CONTROL_POINT_PATCH = 23, + _17_CONTROL_POINT_PATCH = 24, + _18_CONTROL_POINT_PATCH = 25, + _19_CONTROL_POINT_PATCH = 26, + _20_CONTROL_POINT_PATCH = 27, + _21_CONTROL_POINT_PATCH = 28, + _22_CONTROL_POINT_PATCH = 29, + _23_CONTROL_POINT_PATCH = 30, + _24_CONTROL_POINT_PATCH = 31, + _25_CONTROL_POINT_PATCH = 32, + _26_CONTROL_POINT_PATCH = 33, + _27_CONTROL_POINT_PATCH = 34, + _28_CONTROL_POINT_PATCH = 35, + _29_CONTROL_POINT_PATCH = 36, + _30_CONTROL_POINT_PATCH = 37, + _31_CONTROL_POINT_PATCH = 38, + _32_CONTROL_POINT_PATCH = 39, +} + +SRV_DIMENSION :: enum i32 { + UNKNOWN = 0, + BUFFER = 1, + TEXTURE1D = 2, + TEXTURE1DARRAY = 3, + TEXTURE2D = 4, + TEXTURE2DARRAY = 5, + TEXTURE2DMS = 6, + TEXTURE2DMSARRAY = 7, + TEXTURE3D = 8, + TEXTURECUBE = 9, + TEXTURECUBEARRAY = 10, + BUFFEREX = 11, + RAYTRACING_ACCELERATION_STRUCTURE = 11, +} + +PFN_DESTRUCTION_CALLBACK :: #type proc "c" (a0: rawptr) + + +ID3DDestructionNotifier_UUID :: "a06eb39a-50da-425b-8c31-4eecd6c270f3" +ID3DDestructionNotifier :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3ddestructionnotifier_vtable: ^ID3DDestructionNotifier_VTable, +} +ID3DDestructionNotifier_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + RegisterDestructionCallback: proc "stdcall" (this: ^ID3DDestructionNotifier, callbackFn: PFN_DESTRUCTION_CALLBACK, pData: rawptr, pCallbackID: ^u32) -> HRESULT, + UnregisterDestructionCallback: proc "stdcall" (this: ^ID3DDestructionNotifier, callbackID: u32) -> HRESULT, +} + +SHADER_VARIABLE_CLASS :: enum i32 { + SCALAR = 0, + VECTOR = 1, + MATRIX_ROWS = 2, + MATRIX_COLUMNS = 3, + OBJECT = 4, + STRUCT = 5, + INTERFACE_CLASS = 6, + INTERFACE_POINTER = 7, +} + +SHADER_VARIABLE_FLAGS :: enum u32 { // TODO: make bit_set + USERPACKED = 0x1, + USED = 0x2, + INTERFACE_POINTER = 0x4, + INTERFACE_PARAMETER = 0x8, +} + +SHADER_VARIABLE_TYPE :: enum i32 { + VOID = 0, + BOOL = 1, + INT = 2, + FLOAT = 3, + STRING = 4, + TEXTURE = 5, + TEXTURE1D = 6, + TEXTURE2D = 7, + TEXTURE3D = 8, + TEXTURECUBE = 9, + SAMPLER = 10, + SAMPLER1D = 11, + SAMPLER2D = 12, + SAMPLER3D = 13, + SAMPLERCUBE = 14, + PIXELSHADER = 15, + VERTEXSHADER = 16, + PIXELFRAGMENT = 17, + VERTEXFRAGMENT = 18, + UINT = 19, + UINT8 = 20, + GEOMETRYSHADER = 21, + RASTERIZER = 22, + DEPTHSTENCIL = 23, + BLEND = 24, + BUFFER = 25, + CBUFFER = 26, + TBUFFER = 27, + TEXTURE1DARRAY = 28, + TEXTURE2DARRAY = 29, + RENDERTARGETVIEW = 30, + DEPTHSTENCILVIEW = 31, + TEXTURE2DMS = 32, + TEXTURE2DMSARRAY = 33, + TEXTURECUBEARRAY = 34, + HULLSHADER = 35, + DOMAINSHADER = 36, + INTERFACE_POINTER = 37, + COMPUTESHADER = 38, + DOUBLE = 39, + RWTEXTURE1D = 40, + RWTEXTURE1DARRAY = 41, + RWTEXTURE2D = 42, + RWTEXTURE2DARRAY = 43, + RWTEXTURE3D = 44, + RWBUFFER = 45, + BYTEADDRESS_BUFFER = 46, + RWBYTEADDRESS_BUFFER = 47, + STRUCTURED_BUFFER = 48, + RWSTRUCTURED_BUFFER = 49, + APPEND_STRUCTURED_BUFFER = 50, + CONSUME_STRUCTURED_BUFFER = 51, + MIN8FLOAT = 52, + MIN10FLOAT = 53, + MIN16FLOAT = 54, + MIN12INT = 55, + MIN16INT = 56, + MIN16UINT = 57, +} + +SHADER_INPUT_FLAGS :: enum u32 { // TODO: make bit_set + USERPACKED = 0x1, + COMPARISON_SAMPLER = 0x2, + TEXTURE_COMPONENT_0 = 0x4, + TEXTURE_COMPONENT_1 = 0x8, + TEXTURE_COMPONENTS = 0xc, + UNUSED = 0x10, +} + +SHADER_INPUT_TYPE :: enum i32 { + CBUFFER = 0, + TBUFFER = 1, + TEXTURE = 2, + SAMPLER = 3, + UAV_RWTYPED = 4, + STRUCTURED = 5, + UAV_RWSTRUCTURED = 6, + BYTEADDRESS = 7, + UAV_RWBYTEADDRESS = 8, + UAV_APPEND_STRUCTURED = 9, + UAV_CONSUME_STRUCTURED = 10, + UAV_RWSTRUCTURED_WITH_COUNTER = 11, + RTACCELERATIONSTRUCTURE = 12, + UAV_FEEDBACKTEXTURE = 13, +} + +SHADER_CBUFFER_FLAGS :: enum u32 { // TODO: make bit_set + USERPACKED = 0x1, +} + +CBUFFER_TYPE :: enum i32 { + CBUFFER = 0, + TBUFFER = 1, + INTERFACE_POINTERS = 2, + RESOURCE_BIND_INFO = 3, +} + +NAME :: enum i32 { + UNDEFINED = 0, + POSITION = 1, + CLIP_DISTANCE = 2, + CULL_DISTANCE = 3, + RENDER_TARGET_ARRAY_INDEX = 4, + VIEWPORT_ARRAY_INDEX = 5, + VERTEX_ID = 6, + PRIMITIVE_ID = 7, + INSTANCE_ID = 8, + IS_FRONT_FACE = 9, + SAMPLE_INDEX = 10, + FINAL_QUAD_EDGE_TESSFACTOR = 11, + FINAL_QUAD_INSIDE_TESSFACTOR = 12, + FINAL_TRI_EDGE_TESSFACTOR = 13, + FINAL_TRI_INSIDE_TESSFACTOR = 14, + FINAL_LINE_DETAIL_TESSFACTOR = 15, + FINAL_LINE_DENSITY_TESSFACTOR = 16, + BARYCENTRICS = 23, + SHADINGRATE = 24, + CULLPRIMITIVE = 25, + TARGET = 64, + DEPTH = 65, + COVERAGE = 66, + DEPTH_GREATER_EQUAL = 67, + DEPTH_LESS_EQUAL = 68, + STENCIL_REF = 69, + INNER_COVERAGE = 70, +} + +RESOURCE_RETURN_TYPE :: enum i32 { + UNORM = 1, + SNORM = 2, + SINT = 3, + UINT = 4, + FLOAT = 5, + MIXED = 6, + DOUBLE = 7, + CONTINUED = 8, +} + +REGISTER_COMPONENT_TYPE :: enum i32 { + UNKNOWN = 0, + UINT32 = 1, + SINT32 = 2, + FLOAT32 = 3, +} + +TESSELLATOR_DOMAIN :: enum i32 { + UNDEFINED = 0, + ISOLINE = 1, + TRI = 2, + QUAD = 3, +} + +TESSELLATOR_PARTITIONING :: enum i32 { + UNDEFINED = 0, + INTEGER = 1, + POW2 = 2, + FRACTIONAL_ODD = 3, + FRACTIONAL_EVEN = 4, +} + +TESSELLATOR_OUTPUT_PRIMITIVE :: enum i32 { + UNDEFINED = 0, + POINT = 1, + LINE = 2, + TRIANGLE_CW = 3, + TRIANGLE_CCW = 4, +} + +MIN_PRECISION :: enum i32 { + DEFAULT = 0, + FLOAT_16 = 1, + FLOAT_2_8 = 2, + RESERVED = 3, + SINT_16 = 4, + UINT_16 = 5, + ANY_16 = 240, + ANY_10 = 241, +} + +INTERPOLATION_MODE :: enum i32 { + UNDEFINED = 0, + CONSTANT = 1, + LINEAR = 2, + LINEAR_CENTROID = 3, + LINEAR_NOPERSPECTIVE = 4, + LINEAR_NOPERSPECTIVE_CENTROID = 5, + LINEAR_SAMPLE = 6, + LINEAR_NOPERSPECTIVE_SAMPLE = 7, +} + +PARAMETER_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + IN = 0x1, + OUT = 0x2, +} + + +GPU_VIRTUAL_ADDRESS :: u64 + +COMMAND_LIST_TYPE :: enum i32 { + DIRECT = 0, + BUNDLE = 1, + COMPUTE = 2, + COPY = 3, + VIDEO_DECODE = 4, + VIDEO_PROCESS = 5, + VIDEO_ENCODE = 6, +} + +COMMAND_QUEUE_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + DISABLE_GPU_TIMEOUT = 0x1, +} + +COMMAND_QUEUE_PRIORITY :: enum i32 { + NORMAL = 0, + HIGH = 100, + GLOBAL_REALTIME = 10000, +} + +COMMAND_QUEUE_DESC :: struct { + Type: COMMAND_LIST_TYPE, + Priority: i32, + Flags: COMMAND_QUEUE_FLAGS, + NodeMask: u32, +} + +PRIMITIVE_TOPOLOGY_TYPE :: enum i32 { + UNDEFINED = 0, + POINT = 1, + LINE = 2, + TRIANGLE = 3, + PATCH = 4, +} + +INPUT_CLASSIFICATION :: enum i32 { + PER_VERTEX_DATA = 0, + PER_INSTANCE_DATA = 1, +} + +INPUT_ELEMENT_DESC :: struct { + SemanticName: cstring, + SemanticIndex: u32, + Format: dxgi.FORMAT, + InputSlot: u32, + AlignedByteOffset: u32, + InputSlotClass: INPUT_CLASSIFICATION, + InstanceDataStepRate: u32, +} + +FILL_MODE :: enum i32 { + WIREFRAME = 2, + SOLID = 3, +} + +CULL_MODE :: enum i32 { + NONE = 1, + FRONT = 2, + BACK = 3, +} + +SO_DECLARATION_ENTRY :: struct { + Stream: u32, + SemanticName: cstring, + SemanticIndex: u32, + StartComponent: u8, + ComponentCount: u8, + OutputSlot: u8, +} + +VIEWPORT :: struct { + TopLeftX: f32, + TopLeftY: f32, + Width: f32, + Height: f32, + MinDepth: f32, + MaxDepth: f32, +} + +BOX :: struct { + left: u32, + top: u32, + front: u32, + right: u32, + bottom: u32, + back: u32, +} + +COMPARISON_FUNC :: enum i32 { + NEVER = 1, + LESS = 2, + EQUAL = 3, + LESS_EQUAL = 4, + GREATER = 5, + NOT_EQUAL = 6, + GREATER_EQUAL = 7, + ALWAYS = 8, +} + +DEPTH_WRITE_MASK :: enum i32 { + ZERO = 0, + ALL = 1, +} + +STENCIL_OP :: enum i32 { + KEEP = 1, + ZERO = 2, + REPLACE = 3, + INCR_SAT = 4, + DECR_SAT = 5, + INVERT = 6, + INCR = 7, + DECR = 8, +} + +DEPTH_STENCILOP_DESC :: struct { + StencilFailOp: STENCIL_OP, + StencilDepthFailOp: STENCIL_OP, + StencilPassOp: STENCIL_OP, + StencilFunc: COMPARISON_FUNC, +} + +DEPTH_STENCIL_DESC :: struct { + DepthEnable: BOOL, + DepthWriteMask: DEPTH_WRITE_MASK, + DepthFunc: COMPARISON_FUNC, + StencilEnable: BOOL, + StencilReadMask: u8, + StencilWriteMask: u8, + FrontFace: DEPTH_STENCILOP_DESC, + BackFace: DEPTH_STENCILOP_DESC, +} + +DEPTH_STENCIL_DESC1 :: struct { + DepthEnable: BOOL, + DepthWriteMask: DEPTH_WRITE_MASK, + DepthFunc: COMPARISON_FUNC, + StencilEnable: BOOL, + StencilReadMask: u8, + StencilWriteMask: u8, + FrontFace: DEPTH_STENCILOP_DESC, + BackFace: DEPTH_STENCILOP_DESC, + DepthBoundsTestEnable: BOOL, +} + +BLEND :: enum i32 { + ZERO = 1, + ONE = 2, + SRC_COLOR = 3, + INV_SRC_COLOR = 4, + SRC_ALPHA = 5, + INV_SRC_ALPHA = 6, + DEST_ALPHA = 7, + INV_DEST_ALPHA = 8, + DEST_COLOR = 9, + INV_DEST_COLOR = 10, + SRC_ALPHA_SAT = 11, + BLEND_FACTOR = 14, + INV_BLEND_FACTOR = 15, + SRC1_COLOR = 16, + INV_SRC1_COLOR = 17, + SRC1_ALPHA = 18, + INV_SRC1_ALPHA = 19, +} + +BLEND_OP :: enum i32 { + ADD = 1, + SUBTRACT = 2, + REV_SUBTRACT = 3, + MIN = 4, + MAX = 5, +} + +COLOR_WRITE_ENABLE :: enum i32 { // TODO: make bit_set + RED = 1, + GREEN = 2, + BLUE = 4, + ALPHA = 8, + ALL = 15, +} + +LOGIC_OP :: enum i32 { + CLEAR = 0, + SET = 1, + COPY = 2, + COPY_INVERTED = 3, + NOOP = 4, + INVERT = 5, + AND = 6, + NAND = 7, + OR = 8, + NOR = 9, + XOR = 10, + EQUIV = 11, + AND_REVERSE = 12, + AND_INVERTED = 13, + OR_REVERSE = 14, + OR_INVERTED = 15, +} + +RENDER_TARGET_BLEND_DESC :: struct { + BlendEnable: BOOL, + LogicOpEnable: BOOL, + SrcBlend: BLEND, + DestBlend: BLEND, + BlendOp: BLEND_OP, + SrcBlendAlpha: BLEND, + DestBlendAlpha: BLEND, + BlendOpAlpha: BLEND_OP, + LogicOp: LOGIC_OP, + RenderTargetWriteMask: u8, +} + +BLEND_DESC :: struct { + AlphaToCoverageEnable: BOOL, + IndependentBlendEnable: BOOL, + RenderTarget: [8]RENDER_TARGET_BLEND_DESC, +} + +CONSERVATIVE_RASTERIZATION_MODE :: enum i32 { + OFF = 0, + ON = 1, +} + +RASTERIZER_DESC :: struct { + FillMode: FILL_MODE, + CullMode: CULL_MODE, + FrontCounterClockwise: BOOL, + DepthBias: i32, + DepthBiasClamp: f32, + SlopeScaledDepthBias: f32, + DepthClipEnable: BOOL, + MultisampleEnable: BOOL, + AntialiasedLineEnable: BOOL, + ForcedSampleCount: u32, + ConservativeRaster: CONSERVATIVE_RASTERIZATION_MODE, +} + + +IObject_UUID :: "c4fec28f-7966-4e95-9f94-f431cb56c3b8" +IObject :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12object_vtable: ^IObject_VTable, +} +IObject_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + GetPrivateData: proc "stdcall" (this: ^IObject, guid: ^GUID, pDataSize: ^u32, pData: rawptr) -> HRESULT, + SetPrivateData: proc "stdcall" (this: ^IObject, guid: ^GUID, DataSize: u32, pData: rawptr) -> HRESULT, + SetPrivateDataInterface: proc "stdcall" (this: ^IObject, guid: ^GUID, pData: ^IUnknown) -> HRESULT, + SetName: proc "stdcall" (this: ^IObject, Name: [^]u16) -> HRESULT, +} + + +IDeviceChild_UUID :: "905db94b-a00c-4140-9df5-2b64ca9ea357" +IDeviceChild :: struct #raw_union { + #subtype id3d12object: IObject, + using id3d12devicechild_vtable: ^IDeviceChild_VTable, +} +IDeviceChild_VTable :: struct { + using id3d12object_vtable: IObject_VTable, + GetDevice: proc "stdcall" (this: ^IDeviceChild, riid: ^IID, ppvDevice: ^rawptr) -> HRESULT, +} + + +IRootSignature_UUID :: "c54a6b66-72df-4ee8-8be5-a946a1429214" +IRootSignature :: struct { + using id3d12devicechild: IDeviceChild, +} + +SHADER_BYTECODE :: struct { + pShaderBytecode: rawptr, + BytecodeLength: SIZE_T, +} + +STREAM_OUTPUT_DESC :: struct { + pSODeclaration: ^SO_DECLARATION_ENTRY, + NumEntries: u32, + pBufferStrides: ^u32, + NumStrides: u32, + RasterizedStream: u32, +} + +INPUT_LAYOUT_DESC :: struct { + pInputElementDescs: ^INPUT_ELEMENT_DESC, + NumElements: u32, +} + +INDEX_BUFFER_STRIP_CUT_VALUE :: enum i32 { + DISABLED = 0, + _0xFFFF = 1, + _0xFFFFFFFF = 2, +} + +CACHED_PIPELINE_STATE :: struct { + pCachedBlob: rawptr, + CachedBlobSizeInBytes: SIZE_T, +} + +PIPELINE_STATE_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + TOOL_DEBUG = 0x1, +} + +GRAPHICS_PIPELINE_STATE_DESC :: struct { + pRootSignature: ^IRootSignature, + VS: SHADER_BYTECODE, + PS: SHADER_BYTECODE, + DS: SHADER_BYTECODE, + HS: SHADER_BYTECODE, + GS: SHADER_BYTECODE, + StreamOutput: STREAM_OUTPUT_DESC, + BlendState: BLEND_DESC, + SampleMask: u32, + RasterizerState: RASTERIZER_DESC, + DepthStencilState: DEPTH_STENCIL_DESC, + InputLayout: INPUT_LAYOUT_DESC, + IBStripCutValue: INDEX_BUFFER_STRIP_CUT_VALUE, + PrimitiveTopologyType: PRIMITIVE_TOPOLOGY_TYPE, + NumRenderTargets: u32, + RTVFormats: [8]dxgi.FORMAT, + DSVFormat: dxgi.FORMAT, + SampleDesc: dxgi.SAMPLE_DESC, + NodeMask: u32, + CachedPSO: CACHED_PIPELINE_STATE, + Flags: PIPELINE_STATE_FLAGS, +} + +COMPUTE_PIPELINE_STATE_DESC :: struct { + pRootSignature: ^IRootSignature, + CS: SHADER_BYTECODE, + NodeMask: u32, + CachedPSO: CACHED_PIPELINE_STATE, + Flags: PIPELINE_STATE_FLAGS, +} + +RT_FORMAT_ARRAY :: struct { + RTFormats: [8]dxgi.FORMAT, + NumRenderTargets: u32, +} + +PIPELINE_STATE_STREAM_DESC :: struct { + SizeInBytes: SIZE_T, + pPipelineStateSubobjectStream: rawptr, +} + +PIPELINE_STATE_SUBOBJECT_TYPE :: enum i32 { + ROOT_SIGNATURE = 0, + VS = 1, + PS = 2, + DS = 3, + HS = 4, + GS = 5, + CS = 6, + STREAM_OUTPUT = 7, + BLEND = 8, + SAMPLE_MASK = 9, + RASTERIZER = 10, + DEPTH_STENCIL = 11, + INPUT_LAYOUT = 12, + IB_STRIP_CUT_VALUE = 13, + PRIMITIVE_TOPOLOGY = 14, + RENDER_TARGET_FORMATS = 15, + DEPTH_STENCIL_FORMAT = 16, + SAMPLE_DESC = 17, + NODE_MASK = 18, + CACHED_PSO = 19, + FLAGS = 20, + DEPTH_STENCIL1 = 21, + VIEW_INSTANCING = 22, + AS = 24, + MS = 25, + MAX_VALID = 26, +} + +FEATURE :: enum i32 { + OPTIONS = 0, + ARCHITECTURE = 1, + FEATURE_LEVELS = 2, + FORMAT_SUPPORT = 3, + MULTISAMPLE_QUALITY_LEVELS = 4, + FORMAT_INFO = 5, + GPU_VIRTUAL_ADDRESS_SUPPORT = 6, + SHADER_MODEL = 7, + OPTIONS1 = 8, + PROTECTED_RESOURCE_SESSION_SUPPORT = 10, + ROOT_SIGNATURE = 12, + ARCHITECTURE1 = 16, + OPTIONS2 = 18, + SHADER_CACHE = 19, + COMMAND_QUEUE_PRIORITY = 20, + OPTIONS3 = 21, + EXISTING_HEAPS = 22, + OPTIONS4 = 23, + SERIALIZATION = 24, + CROSS_NODE = 25, + OPTIONS5 = 27, + OPTIONS6 = 30, + QUERY_META_COMMAND = 31, + OPTIONS7 = 32, + PROTECTED_RESOURCE_SESSION_TYPE_COUNT = 33, + PROTECTED_RESOURCE_SESSION_TYPES = 34, +} + +SHADER_MIN_PRECISION_SUPPORT :: enum i32 { + NONE = 0, + _10_BIT = 1, + _16_BIT = 2, +} + +TILED_RESOURCES_TIER :: enum i32 { + NOT_SUPPORTED = 0, + _1 = 1, + _2 = 2, + _3 = 3, + _4 = 4, +} + +RESOURCE_BINDING_TIER :: enum i32 { + _1 = 1, + _2 = 2, + _3 = 3, +} + +CONSERVATIVE_RASTERIZATION_TIER :: enum i32 { + NOT_SUPPORTED = 0, + _1 = 1, + _2 = 2, + _3 = 3, +} + +FORMAT_SUPPORT1 :: enum i32 { // TODO: make bit_set + NONE = 0, + BUFFER = 1, + IA_VERTEX_BUFFER = 2, + IA_INDEX_BUFFER = 4, + SO_BUFFER = 8, + TEXTURE1D = 16, + TEXTURE2D = 32, + TEXTURE3D = 64, + TEXTURECUBE = 128, + SHADER_LOAD = 256, + SHADER_SAMPLE = 512, + SHADER_SAMPLE_COMPARISON = 1024, + SHADER_SAMPLE_MONO_TEXT = 2048, + MIP = 4096, + RENDER_TARGET = 16384, + BLENDABLE = 32768, + DEPTH_STENCIL = 65536, + MULTISAMPLE_RESOLVE = 262144, + DISPLAY = 524288, + CAST_WITHIN_BIT_LAYOUT = 1048576, + MULTISAMPLE_RENDERTARGET = 2097152, + MULTISAMPLE_LOAD = 4194304, + SHADER_GATHER = 8388608, + BACK_BUFFER_CAST = 16777216, + TYPED_UNORDERED_ACCESS_VIEW = 33554432, + SHADER_GATHER_COMPARISON = 67108864, + DECODER_OUTPUT = 134217728, + VIDEO_PROCESSOR_OUTPUT = 268435456, + VIDEO_PROCESSOR_INPUT = 536870912, + VIDEO_ENCODER = 1073741824, +} + +FORMAT_SUPPORT2 :: enum i32 { // TODO: make bit_set + NONE = 0, + UAV_ATOMIC_ADD = 1, + UAV_ATOMIC_BITWISE_OPS = 2, + UAV_ATOMIC_COMPARE_STORE_OR_COMPARE_EXCHANGE = 4, + UAV_ATOMIC_EXCHANGE = 8, + UAV_ATOMIC_SIGNED_MIN_OR_MAX = 16, + UAV_ATOMIC_UNSIGNED_MIN_OR_MAX = 32, + UAV_TYPED_LOAD = 64, + UAV_TYPED_STORE = 128, + OUTPUT_MERGER_LOGIC_OP = 256, + TILED = 512, + MULTIPLANE_OVERLAY = 16384, + SAMPLER_FEEDBACK = 32768, +} + +MULTISAMPLE_QUALITY_LEVEL_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + TILED_RESOURCE = 0x1, +} + +CROSS_NODE_SHARING_TIER :: enum i32 { + NOT_SUPPORTED = 0, + _1_EMULATED = 1, + _1 = 2, + _2 = 3, + _3 = 4, +} + +RESOURCE_HEAP_TIER :: enum i32 { + _1 = 1, + _2 = 2, +} + +PROGRAMMABLE_SAMPLE_POSITIONS_TIER :: enum i32 { + NOT_SUPPORTED = 0, + _1 = 1, + _2 = 2, +} + +VIEW_INSTANCING_TIER :: enum i32 { + NOT_SUPPORTED = 0, + _1 = 1, + _2 = 2, + _3 = 3, +} + +FEATURE_DATA_OPTIONS :: struct { + DoublePrecisionFloatShaderOps: BOOL, + OutputMergerLogicOp: BOOL, + MinPrecisionSupport: SHADER_MIN_PRECISION_SUPPORT, + TiledResourcesTier: TILED_RESOURCES_TIER, + ResourceBindingTier: RESOURCE_BINDING_TIER, + PSSpecifiedStencilRefSupported: BOOL, + TypedUAVLoadAdditionalFormats: BOOL, + ROVsSupported: BOOL, + ConservativeRasterizationTier: CONSERVATIVE_RASTERIZATION_TIER, + MaxGPUVirtualAddressBitsPerResource: u32, + StandardSwizzle64KBSupported: BOOL, + CrossNodeSharingTier: CROSS_NODE_SHARING_TIER, + CrossAdapterRowMajorTextureSupported: BOOL, + VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation: BOOL, + ResourceHeapTier: RESOURCE_HEAP_TIER, +} + +FEATURE_DATA_OPTIONS1 :: struct { + WaveOps: BOOL, + WaveLaneCountMin: u32, + WaveLaneCountMax: u32, + TotalLaneCount: u32, + ExpandedComputeResourceStates: BOOL, + Int64ShaderOps: BOOL, +} + +FEATURE_DATA_OPTIONS2 :: struct { + DepthBoundsTestSupported: BOOL, + ProgrammableSamplePositionsTier: PROGRAMMABLE_SAMPLE_POSITIONS_TIER, +} + +ROOT_SIGNATURE_VERSION :: enum i32 { + _1 = 1, + _1_0 = 1, + _1_1 = 2, +} + +FEATURE_DATA_ROOT_SIGNATURE :: struct { + HighestVersion: ROOT_SIGNATURE_VERSION, +} + +FEATURE_DATA_ARCHITECTURE :: struct { + NodeIndex: u32, + TileBasedRenderer: BOOL, + UMA: BOOL, + CacheCoherentUMA: BOOL, +} + +FEATURE_DATA_ARCHITECTURE1 :: struct { + NodeIndex: u32, + TileBasedRenderer: BOOL, + UMA: BOOL, + CacheCoherentUMA: BOOL, + IsolatedMMU: BOOL, +} + +FEATURE_DATA_FEATURE_LEVELS :: struct { + NumFeatureLevels: u32, + pFeatureLevelsRequested: ^FEATURE_LEVEL, + MaxSupportedFeatureLevel: FEATURE_LEVEL, +} + +SHADER_MODEL :: enum i32 { + _5_1 = 81, + _6_0 = 96, + _6_1 = 97, + _6_2 = 98, + _6_3 = 99, + _6_4 = 100, + _6_5 = 101, + _6_6 = 102, +} + +FEATURE_DATA_SHADER_MODEL :: struct { + HighestShaderModel: SHADER_MODEL, +} + +FEATURE_DATA_FORMAT_SUPPORT :: struct { + Format: dxgi.FORMAT, + Support1: FORMAT_SUPPORT1, + Support2: FORMAT_SUPPORT2, +} + +FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS :: struct { + Format: dxgi.FORMAT, + SampleCount: u32, + Flags: MULTISAMPLE_QUALITY_LEVEL_FLAGS, + NumQualityLevels: u32, +} + +FEATURE_DATA_FORMAT_INFO :: struct { + Format: dxgi.FORMAT, + PlaneCount: u8, +} + +FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT :: struct { + MaxGPUVirtualAddressBitsPerResource: u32, + MaxGPUVirtualAddressBitsPerProcess: u32, +} + +SHADER_CACHE_SUPPORT_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + SINGLE_PSO = 0x1, + LIBRARY = 0x2, + AUTOMATIC_INPROC_CACHE = 0x4, + AUTOMATIC_DISK_CACHE = 0x8, +} + +FEATURE_DATA_SHADER_CACHE :: struct { + SupportFlags: SHADER_CACHE_SUPPORT_FLAGS, +} + +FEATURE_DATA_COMMAND_QUEUE_PRIORITY :: struct { + CommandListType: COMMAND_LIST_TYPE, + Priority: u32, + PriorityForTypeIsSupported: BOOL, +} + +COMMAND_LIST_SUPPORT_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + DIRECT = 0x1, + BUNDLE = 0x2, + COMPUTE = 0x4, + COPY = 0x8, + VIDEO_DECODE = 0x10, + VIDEO_PROCESS = 0x20, + VIDEO_ENCODE = 0x40, +} + +FEATURE_DATA_OPTIONS3 :: struct { + CopyQueueTimestampQueriesSupported: BOOL, + CastingFullyTypedFormatSupported: BOOL, + WriteBufferImmediateSupportFlags: COMMAND_LIST_SUPPORT_FLAGS, + ViewInstancingTier: VIEW_INSTANCING_TIER, + BarycentricsSupported: BOOL, +} + +FEATURE_DATA_EXISTING_HEAPS :: struct { + Supported: BOOL, +} + +SHARED_RESOURCE_COMPATIBILITY_TIER :: enum i32 { + _0 = 0, + _1 = 1, + _2 = 2, +} + +FEATURE_DATA_OPTIONS4 :: struct { + MSAA64KBAlignedTextureSupported: BOOL, + SharedResourceCompatibilityTier: SHARED_RESOURCE_COMPATIBILITY_TIER, + Native16BitShaderOpsSupported: BOOL, +} + +HEAP_SERIALIZATION_TIER :: enum i32 { + _0 = 0, + _10 = 10, +} + +FEATURE_DATA_SERIALIZATION :: struct { + NodeIndex: u32, + HeapSerializationTier: HEAP_SERIALIZATION_TIER, +} + +FEATURE_DATA_CROSS_NODE :: struct { + SharingTier: CROSS_NODE_SHARING_TIER, + AtomicShaderInstructions: BOOL, +} + +RENDER_PASS_TIER :: enum i32 { + _0 = 0, + _1 = 1, + _2 = 2, +} + +RAYTRACING_TIER :: enum i32 { + NOT_SUPPORTED = 0, + _1_0 = 10, + _1_1 = 11, +} + +FEATURE_DATA_OPTIONS5 :: struct { + SRVOnlyTiledResourceTier3: BOOL, + RenderPassesTier: RENDER_PASS_TIER, + RaytracingTier: RAYTRACING_TIER, +} + +VARIABLE_SHADING_RATE_TIER :: enum i32 { + NOT_SUPPORTED = 0, + _1 = 1, + _2 = 2, +} + +FEATURE_DATA_OPTIONS6 :: struct { + AdditionalShadingRatesSupported: BOOL, + PerPrimitiveShadingRateSupportedWithViewportIndexing: BOOL, + VariableShadingRateTier: VARIABLE_SHADING_RATE_TIER, + ShadingRateImageTileSize: u32, + BackgroundProcessingSupported: BOOL, +} + +MESH_SHADER_TIER :: enum i32 { + NOT_SUPPORTED = 0, + _1 = 10, +} + +SAMPLER_FEEDBACK_TIER :: enum i32 { + NOT_SUPPORTED = 0, + _0_9 = 90, + _1_0 = 100, +} + +FEATURE_DATA_OPTIONS7 :: struct { + MeshShaderTier: MESH_SHADER_TIER, + SamplerFeedbackTier: SAMPLER_FEEDBACK_TIER, +} + +FEATURE_DATA_QUERY_META_COMMAND :: struct { + CommandId: GUID, + NodeMask: u32, + pQueryInputData: rawptr, + QueryInputDataSizeInBytes: SIZE_T, + pQueryOutputData: rawptr, + QueryOutputDataSizeInBytes: SIZE_T, +} + +RESOURCE_ALLOCATION_INFO :: struct { + SizeInBytes: u64, + Alignment: u64, +} + +RESOURCE_ALLOCATION_INFO1 :: struct { + Offset: u64, + Alignment: u64, + SizeInBytes: u64, +} + +HEAP_TYPE :: enum i32 { + DEFAULT = 1, + UPLOAD = 2, + READBACK = 3, + CUSTOM = 4, +} + +CPU_PAGE_PROPERTY :: enum i32 { + UNKNOWN = 0, + NOT_AVAILABLE = 1, + WRITE_COMBINE = 2, + WRITE_BACK = 3, +} + +MEMORY_POOL :: enum i32 { + UNKNOWN = 0, + L0 = 1, + L1 = 2, +} + +HEAP_PROPERTIES :: struct { + Type: HEAP_TYPE, + CPUPageProperty: CPU_PAGE_PROPERTY, + MemoryPoolPreference: MEMORY_POOL, + CreationNodeMask: u32, + VisibleNodeMask: u32, +} + +HEAP_FLAGS :: enum u32 { // TODO: make bit_set ??? + NONE = 0x0, + SHARED = 0x1, + DENY_BUFFERS = 0x4, + ALLOW_DISPLAY = 0x8, + SHARED_CROSS_ADAPTER = 0x20, + DENY_RT_DS_TEXTURES = 0x40, + DENY_NON_RT_DS_TEXTURES = 0x80, + HARDWARE_PROTECTED = 0x100, + ALLOW_WRITE_WATCH = 0x200, + ALLOW_SHADER_ATOMICS = 0x400, + CREATE_NOT_RESIDENT = 0x800, + CREATE_NOT_ZEROED = 0x1000, + ALLOW_ALL_BUFFERS_AND_TEXTURES = 0x0, + ALLOW_ONLY_BUFFERS = 0xc0, + ALLOW_ONLY_NON_RT_DS_TEXTURES = 0x44, + ALLOW_ONLY_RT_DS_TEXTURES = 0x84, +} + +HEAP_DESC :: struct { + SizeInBytes: u64, + Properties: HEAP_PROPERTIES, + Alignment: u64, + Flags: HEAP_FLAGS, +} + +RESOURCE_DIMENSION :: enum i32 { + UNKNOWN = 0, + BUFFER = 1, + TEXTURE1D = 2, + TEXTURE2D = 3, + TEXTURE3D = 4, +} + +TEXTURE_LAYOUT :: enum i32 { + UNKNOWN = 0, + ROW_MAJOR = 1, + _64KB_UNDEFINED_SWIZZLE = 2, + _64KB_STANDARD_SWIZZLE = 3, +} + +RESOURCE_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + ALLOW_RENDER_TARGET = 0x1, + ALLOW_DEPTH_STENCIL = 0x2, + ALLOW_UNORDERED_ACCESS = 0x4, + DENY_SHADER_RESOURCE = 0x8, + ALLOW_CROSS_ADAPTER = 0x10, + ALLOW_SIMULTANEOUS_ACCESS = 0x20, + VIDEO_DECODE_REFERENCE_ONLY = 0x40, +} + +MIP_REGION :: struct { + Width: u32, + Height: u32, + Depth: u32, +} + +RESOURCE_DESC :: struct { + Dimension: RESOURCE_DIMENSION, + Alignment: u64, + Width: u64, + Height: u32, + DepthOrArraySize: u16, + MipLevels: u16, + Format: dxgi.FORMAT, + SampleDesc: dxgi.SAMPLE_DESC, + Layout: TEXTURE_LAYOUT, + Flags: RESOURCE_FLAGS, +} + +RESOURCE_DESC1 :: struct { + Dimension: RESOURCE_DIMENSION, + Alignment: u64, + Width: u64, + Height: u32, + DepthOrArraySize: u16, + MipLevels: u16, + Format: dxgi.FORMAT, + SampleDesc: dxgi.SAMPLE_DESC, + Layout: TEXTURE_LAYOUT, + Flags: RESOURCE_FLAGS, + SamplerFeedbackMipRegion: MIP_REGION, +} + +DEPTH_STENCIL_VALUE :: struct { + Depth: f32, + Stencil: u8, +} + +CLEAR_VALUE :: struct { + Format: dxgi.FORMAT, + using _: struct #raw_union { + Color: [4]f32, + DepthStencil: DEPTH_STENCIL_VALUE, + }, +} + +RANGE :: struct { + Begin: SIZE_T, + End: SIZE_T, +} + +RANGE_UINT64 :: struct { + Begin: u64, + End: u64, +} + +SUBRESOURCE_RANGE_UINT64 :: struct { + Subresource: u32, + Range: RANGE_UINT64, +} + +SUBRESOURCE_INFO :: struct { + Offset: u64, + RowPitch: u32, + DepthPitch: u32, +} + +TILED_RESOURCE_COORDINATE :: struct { + X: u32, + Y: u32, + Z: u32, + Subresource: u32, +} + +TILE_REGION_SIZE :: struct { + NumTiles: u32, + UseBox: BOOL, + Width: u32, + Height: u16, + Depth: u16, +} + +TILE_RANGE_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + NULL = 0x1, + SKIP = 0x2, + REUSE_SINGLE_TILE = 0x4, +} + +SUBRESOURCE_TILING :: struct { + WidthInTiles: u32, + HeightInTiles: u16, + DepthInTiles: u16, + StartTileIndexInOverallResource: u32, +} + +TILE_SHAPE :: struct { + WidthInTexels: u32, + HeightInTexels: u32, + DepthInTexels: u32, +} + +PACKED_MIP_INFO :: struct { + NumStandardMips: u8, + NumPackedMips: u8, + NumTilesForPackedMips: u32, + StartTileIndexInOverallResource: u32, +} + +TILE_MAPPING_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + NO_HAZARD = 0x1, +} + +TILE_COPY_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + NO_HAZARD = 0x1, + LINEAR_BUFFER_TO_SWIZZLED_TILED_RESOURCE = 0x2, + SWIZZLED_TILED_RESOURCE_TO_LINEAR_BUFFER = 0x4, +} + +RESOURCE_STATES :: enum i32 { // TODO: make bit_set + COMMON = 0, + VERTEX_AND_CONSTANT_BUFFER = 1, + INDEX_BUFFER = 2, + RENDER_TARGET = 4, + UNORDERED_ACCESS = 8, + DEPTH_WRITE = 16, + DEPTH_READ = 32, + NON_PIXEL_SHADER_RESOURCE = 64, + PIXEL_SHADER_RESOURCE = 128, + STREAM_OUT = 256, + INDIRECT_ARGUMENT = 512, + COPY_DEST = 1024, + COPY_SOURCE = 2048, + RESOLVE_DEST = 4096, + RESOLVE_SOURCE = 8192, + RAYTRACING_ACCELERATION_STRUCTURE = 4194304, + SHADING_RATE_SOURCE = 16777216, + GENERIC_READ = 2755, + PRESENT = 0, + PREDICATION = 512, + VIDEO_DECODE_READ = 65536, + VIDEO_DECODE_WRITE = 131072, + VIDEO_PROCESS_READ = 262144, + VIDEO_PROCESS_WRITE = 524288, + VIDEO_ENCODE_READ = 2097152, + VIDEO_ENCODE_WRITE = 8388608, +} + +RESOURCE_BARRIER_TYPE :: enum i32 { + TRANSITION = 0, + ALIASING = 1, + UAV = 2, +} + +RESOURCE_TRANSITION_BARRIER :: struct { + pResource: ^IResource, + Subresource: u32, + StateBefore: RESOURCE_STATES, + StateAfter: RESOURCE_STATES, +} + +RESOURCE_ALIASING_BARRIER :: struct { + pResourceBefore: ^IResource, + pResourceAfter: ^IResource, +} + +RESOURCE_UAV_BARRIER :: struct { + pResource: ^IResource, +} + +RESOURCE_BARRIER_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + BEGIN_ONLY = 0x1, + END_ONLY = 0x2, +} + +RESOURCE_BARRIER :: struct { + Type: RESOURCE_BARRIER_TYPE, + Flags: RESOURCE_BARRIER_FLAGS, + using _: struct #raw_union { + Transition: RESOURCE_TRANSITION_BARRIER, + Aliasing: RESOURCE_ALIASING_BARRIER, + UAV: RESOURCE_UAV_BARRIER, + }, +} + +SUBRESOURCE_FOOTPRINT :: struct { + Format: dxgi.FORMAT, + Width: u32, + Height: u32, + Depth: u32, + RowPitch: u32, +} + +PLACED_SUBRESOURCE_FOOTPRINT :: struct { + Offset: u64, + Footprint: SUBRESOURCE_FOOTPRINT, +} + +TEXTURE_COPY_TYPE :: enum i32 { + SUBRESOURCE_INDEX = 0, + PLACED_FOOTPRINT = 1, +} + +TEXTURE_COPY_LOCATION :: struct { + pResource: ^IResource, + Type: TEXTURE_COPY_TYPE, +} + +RESOLVE_MODE :: enum i32 { + DECOMPRESS = 0, + MIN = 1, + MAX = 2, + AVERAGE = 3, + ENCODE_SAMPLER_FEEDBACK = 4, + DECODE_SAMPLER_FEEDBACK = 5, +} + +SAMPLE_POSITION :: struct { + X: i8, + Y: i8, +} + +VIEW_INSTANCE_LOCATION :: struct { + ViewportArrayIndex: u32, + RenderTargetArrayIndex: u32, +} + +VIEW_INSTANCING_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + ENABLE_VIEW_INSTANCE_MASKING = 0x1, +} + +VIEW_INSTANCING_DESC :: struct { + ViewInstanceCount: u32, + pViewInstanceLocations: ^VIEW_INSTANCE_LOCATION, + Flags: VIEW_INSTANCING_FLAGS, +} + +SHADER_COMPONENT_MAPPING :: enum i32 { + FROM_MEMORY_COMPONENT_0 = 0, + FROM_MEMORY_COMPONENT_1 = 1, + FROM_MEMORY_COMPONENT_2 = 2, + FROM_MEMORY_COMPONENT_3 = 3, + FORCE_VALUE_0 = 4, + FORCE_VALUE_1 = 5, +} + +BUFFER_SRV_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + RAW = 0x1, +} + +BUFFER_SRV :: struct { + FirstElement: u64, + NumElements: u32, + StructureByteStride: u32, + Flags: BUFFER_SRV_FLAGS, +} + +TEX1D_SRV :: struct { + MostDetailedMip: u32, + MipLevels: u32, + ResourceMinLODClamp: f32, +} + +TEX1D_ARRAY_SRV :: struct { + MostDetailedMip: u32, + MipLevels: u32, + FirstArraySlice: u32, + ArraySize: u32, + ResourceMinLODClamp: f32, +} + +TEX2D_SRV :: struct { + MostDetailedMip: u32, + MipLevels: u32, + PlaneSlice: u32, + ResourceMinLODClamp: f32, +} + +TEX2D_ARRAY_SRV :: struct { + MostDetailedMip: u32, + MipLevels: u32, + FirstArraySlice: u32, + ArraySize: u32, + PlaneSlice: u32, + ResourceMinLODClamp: f32, +} + +TEX3D_SRV :: struct { + MostDetailedMip: u32, + MipLevels: u32, + ResourceMinLODClamp: f32, +} + +TEXCUBE_SRV :: struct { + MostDetailedMip: u32, + MipLevels: u32, + ResourceMinLODClamp: f32, +} + +TEXCUBE_ARRAY_SRV :: struct { + MostDetailedMip: u32, + MipLevels: u32, + First2DArrayFace: u32, + NumCubes: u32, + ResourceMinLODClamp: f32, +} + +TEX2DMS_SRV :: struct { + UnusedField_NothingToDefine: u32, +} + +TEX2DMS_ARRAY_SRV :: struct { + FirstArraySlice: u32, + ArraySize: u32, +} + +RAYTRACING_ACCELERATION_STRUCTURE_SRV :: struct { + Location: GPU_VIRTUAL_ADDRESS, +} + +SHADER_RESOURCE_VIEW_DESC :: struct { + Format: dxgi.FORMAT, + ViewDimension: SRV_DIMENSION, + Shader4ComponentMapping: u32, + using _: struct #raw_union { + Buffer: BUFFER_SRV, + Texture1D: TEX1D_SRV, + Texture1DArray: TEX1D_ARRAY_SRV, + Texture2D: TEX2D_SRV, + Texture2DArray: TEX2D_ARRAY_SRV, + Texture2DMS: TEX2DMS_SRV, + Texture2DMSArray: TEX2DMS_ARRAY_SRV, + Texture3D: TEX3D_SRV, + TextureCube: TEXCUBE_SRV, + TextureCubeArray: TEXCUBE_ARRAY_SRV, + RaytracingAccelerationStructure: RAYTRACING_ACCELERATION_STRUCTURE_SRV, + }, +} + +CONSTANT_BUFFER_VIEW_DESC :: struct { + BufferLocation: GPU_VIRTUAL_ADDRESS, + SizeInBytes: u32, +} + +FILTER :: enum i32 { + MIN_MAG_MIP_POINT = 0, + MIN_MAG_POINT_MIP_LINEAR = 1, + MIN_POINT_MAG_LINEAR_MIP_POINT = 4, + MIN_POINT_MAG_MIP_LINEAR = 5, + MIN_LINEAR_MAG_MIP_POINT = 16, + MIN_LINEAR_MAG_POINT_MIP_LINEAR = 17, + MIN_MAG_LINEAR_MIP_POINT = 20, + MIN_MAG_MIP_LINEAR = 21, + ANISOTROPIC = 85, + COMPARISON_MIN_MAG_MIP_POINT = 128, + COMPARISON_MIN_MAG_POINT_MIP_LINEAR = 129, + COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT = 132, + COMPARISON_MIN_POINT_MAG_MIP_LINEAR = 133, + COMPARISON_MIN_LINEAR_MAG_MIP_POINT = 144, + COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 145, + COMPARISON_MIN_MAG_LINEAR_MIP_POINT = 148, + COMPARISON_MIN_MAG_MIP_LINEAR = 149, + COMPARISON_ANISOTROPIC = 213, + MINIMUM_MIN_MAG_MIP_POINT = 256, + MINIMUM_MIN_MAG_POINT_MIP_LINEAR = 257, + MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT = 260, + MINIMUM_MIN_POINT_MAG_MIP_LINEAR = 261, + MINIMUM_MIN_LINEAR_MAG_MIP_POINT = 272, + MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 273, + MINIMUM_MIN_MAG_LINEAR_MIP_POINT = 276, + MINIMUM_MIN_MAG_MIP_LINEAR = 277, + MINIMUM_ANISOTROPIC = 341, + MAXIMUM_MIN_MAG_MIP_POINT = 384, + MAXIMUM_MIN_MAG_POINT_MIP_LINEAR = 385, + MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT = 388, + MAXIMUM_MIN_POINT_MAG_MIP_LINEAR = 389, + MAXIMUM_MIN_LINEAR_MAG_MIP_POINT = 400, + MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 401, + MAXIMUM_MIN_MAG_LINEAR_MIP_POINT = 404, + MAXIMUM_MIN_MAG_MIP_LINEAR = 405, + MAXIMUM_ANISOTROPIC = 469, +} + +FILTER_TYPE :: enum i32 { + POINT = 0, + LINEAR = 1, +} + +FILTER_REDUCTION_TYPE :: enum i32 { + STANDARD = 0, + COMPARISON = 1, + MINIMUM = 2, + MAXIMUM = 3, +} + +TEXTURE_ADDRESS_MODE :: enum i32 { + WRAP = 1, + MIRROR = 2, + CLAMP = 3, + BORDER = 4, + MIRROR_ONCE = 5, +} + +SAMPLER_DESC :: struct { + Filter: FILTER, + AddressU: TEXTURE_ADDRESS_MODE, + AddressV: TEXTURE_ADDRESS_MODE, + AddressW: TEXTURE_ADDRESS_MODE, + MipLODBias: f32, + MaxAnisotropy: u32, + ComparisonFunc: COMPARISON_FUNC, + BorderColor: [4]f32, + MinLOD: f32, + MaxLOD: f32, +} + +BUFFER_UAV_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + RAW = 0x1, +} + +BUFFER_UAV :: struct { + FirstElement: u64, + NumElements: u32, + StructureByteStride: u32, + CounterOffsetInBytes: u64, + Flags: BUFFER_UAV_FLAGS, +} + +TEX1D_UAV :: struct { + MipSlice: u32, +} + +TEX1D_ARRAY_UAV :: struct { + MipSlice: u32, + FirstArraySlice: u32, + ArraySize: u32, +} + +TEX2D_UAV :: struct { + MipSlice: u32, + PlaneSlice: u32, +} + +TEX2D_ARRAY_UAV :: struct { + MipSlice: u32, + FirstArraySlice: u32, + ArraySize: u32, + PlaneSlice: u32, +} + +TEX3D_UAV :: struct { + MipSlice: u32, + FirstWSlice: u32, + WSize: u32, +} + +UAV_DIMENSION :: enum i32 { + UNKNOWN = 0, + BUFFER = 1, + TEXTURE1D = 2, + TEXTURE1DARRAY = 3, + TEXTURE2D = 4, + TEXTURE2DARRAY = 5, + TEXTURE3D = 8, +} + +UNORDERED_ACCESS_VIEW_DESC :: struct { + Format: dxgi.FORMAT, + ViewDimension: UAV_DIMENSION, + using _: struct #raw_union { + Buffer: BUFFER_UAV, + Texture1D: TEX1D_UAV, + Texture1DArray: TEX1D_ARRAY_UAV, + Texture2D: TEX2D_UAV, + Texture2DArray: TEX2D_ARRAY_UAV, + Texture3D: TEX3D_UAV, + }, +} + +BUFFER_RTV :: struct { + FirstElement: u64, + NumElements: u32, +} + +TEX1D_RTV :: struct { + MipSlice: u32, +} + +TEX1D_ARRAY_RTV :: struct { + MipSlice: u32, + FirstArraySlice: u32, + ArraySize: u32, +} + +TEX2D_RTV :: struct { + MipSlice: u32, + PlaneSlice: u32, +} + +TEX2DMS_RTV :: struct { + UnusedField_NothingToDefine: u32, +} + +TEX2D_ARRAY_RTV :: struct { + MipSlice: u32, + FirstArraySlice: u32, + ArraySize: u32, + PlaneSlice: u32, +} + +TEX2DMS_ARRAY_RTV :: struct { + FirstArraySlice: u32, + ArraySize: u32, +} + +TEX3D_RTV :: struct { + MipSlice: u32, + FirstWSlice: u32, + WSize: u32, +} + +RTV_DIMENSION :: enum i32 { + UNKNOWN = 0, + BUFFER = 1, + TEXTURE1D = 2, + TEXTURE1DARRAY = 3, + TEXTURE2D = 4, + TEXTURE2DARRAY = 5, + TEXTURE2DMS = 6, + TEXTURE2DMSARRAY = 7, + TEXTURE3D = 8, +} + +RENDER_TARGET_VIEW_DESC :: struct { + Format: dxgi.FORMAT, + ViewDimension: RTV_DIMENSION, + using _: struct #raw_union { + Buffer: BUFFER_RTV, + Texture1D: TEX1D_RTV, + Texture1DArray: TEX1D_ARRAY_RTV, + Texture2D: TEX2D_RTV, + Texture2DArray: TEX2D_ARRAY_RTV, + Texture2DMS: TEX2DMS_RTV, + Texture2DMSArray: TEX2DMS_ARRAY_RTV, + Texture3D: TEX3D_RTV, + }, +} + +TEX1D_DSV :: struct { + MipSlice: u32, +} + +TEX1D_ARRAY_DSV :: struct { + MipSlice: u32, + FirstArraySlice: u32, + ArraySize: u32, +} + +TEX2D_DSV :: struct { + MipSlice: u32, +} + +TEX2D_ARRAY_DSV :: struct { + MipSlice: u32, + FirstArraySlice: u32, + ArraySize: u32, +} + +TEX2DMS_DSV :: struct { + UnusedField_NothingToDefine: u32, +} + +TEX2DMS_ARRAY_DSV :: struct { + FirstArraySlice: u32, + ArraySize: u32, +} + +DSV_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + READ_ONLY_DEPTH = 0x1, + READ_ONLY_STENCIL = 0x2, +} + +DSV_DIMENSION :: enum i32 { + UNKNOWN = 0, + TEXTURE1D = 1, + TEXTURE1DARRAY = 2, + TEXTURE2D = 3, + TEXTURE2DARRAY = 4, + TEXTURE2DMS = 5, + TEXTURE2DMSARRAY = 6, +} + +DEPTH_STENCIL_VIEW_DESC :: struct { + Format: dxgi.FORMAT, + ViewDimension: DSV_DIMENSION, + Flags: DSV_FLAGS, + using _: struct #raw_union { + Texture1D: TEX1D_DSV, + Texture1DArray: TEX1D_ARRAY_DSV, + Texture2D: TEX2D_DSV, + Texture2DArray: TEX2D_ARRAY_DSV, + Texture2DMS: TEX2DMS_DSV, + Texture2DMSArray: TEX2DMS_ARRAY_DSV, + }, +} + +CLEAR_FLAGS :: enum u32 { // TODO: make bit_set + DEPTH = 0x1, + STENCIL = 0x2, +} + +FENCE_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + SHARED = 0x1, + SHARED_CROSS_ADAPTER = 0x2, + NON_MONITORED = 0x4, +} + +DESCRIPTOR_HEAP_TYPE :: enum i32 { + CBV_SRV_UAV = 0, + SAMPLER = 1, + RTV = 2, + DSV = 3, + NUM_TYPES = 4, +} + +DESCRIPTOR_HEAP_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + SHADER_VISIBLE = 0x1, +} + +DESCRIPTOR_HEAP_DESC :: struct { + Type: DESCRIPTOR_HEAP_TYPE, + NumDescriptors: u32, + Flags: DESCRIPTOR_HEAP_FLAGS, + NodeMask: u32, +} + +DESCRIPTOR_RANGE_TYPE :: enum i32 { + SRV = 0, + UAV = 1, + CBV = 2, + SAMPLER = 3, +} + +DESCRIPTOR_RANGE :: struct { + RangeType: DESCRIPTOR_RANGE_TYPE, + NumDescriptors: u32, + BaseShaderRegister: u32, + RegisterSpace: u32, + OffsetInDescriptorsFromTableStart: u32, +} + +ROOT_DESCRIPTOR_TABLE :: struct { + NumDescriptorRanges: u32, + pDescriptorRanges: ^DESCRIPTOR_RANGE, +} + +ROOT_CONSTANTS :: struct { + ShaderRegister: u32, + RegisterSpace: u32, + Num32BitValues: u32, +} + +ROOT_DESCRIPTOR :: struct { + ShaderRegister: u32, + RegisterSpace: u32, +} + +SHADER_VISIBILITY :: enum i32 { + ALL = 0, + VERTEX = 1, + HULL = 2, + DOMAIN = 3, + GEOMETRY = 4, + PIXEL = 5, + AMPLIFICATION = 6, + MESH = 7, +} + +ROOT_PARAMETER_TYPE :: enum i32 { + DESCRIPTOR_TABLE = 0, + _32BIT_CONSTANTS = 1, + CBV = 2, + SRV = 3, + UAV = 4, +} + +ROOT_PARAMETER :: struct { + ParameterType: ROOT_PARAMETER_TYPE, + using _: struct #raw_union { + DescriptorTable: ROOT_DESCRIPTOR_TABLE, + Constants: ROOT_CONSTANTS, + Descriptor: ROOT_DESCRIPTOR, + }, + ShaderVisibility: SHADER_VISIBILITY, +} + +ROOT_SIGNATURE_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT = 0x1, + DENY_VERTEX_SHADER_ROOT_ACCESS = 0x2, + DENY_HULL_SHADER_ROOT_ACCESS = 0x4, + DENY_DOMAIN_SHADER_ROOT_ACCESS = 0x8, + DENY_GEOMETRY_SHADER_ROOT_ACCESS = 0x10, + DENY_PIXEL_SHADER_ROOT_ACCESS = 0x20, + ALLOW_STREAM_OUTPUT = 0x40, + LOCAL_ROOT_SIGNATURE = 0x80, + DENY_AMPLIFICATION_SHADER_ROOT_ACCESS = 0x100, + DENY_MESH_SHADER_ROOT_ACCESS = 0x200, +} + +STATIC_BORDER_COLOR :: enum i32 { + TRANSPARENT_BLACK = 0, + OPAQUE_BLACK = 1, + OPAQUE_WHITE = 2, +} + +STATIC_SAMPLER_DESC :: struct { + Filter: FILTER, + AddressU: TEXTURE_ADDRESS_MODE, + AddressV: TEXTURE_ADDRESS_MODE, + AddressW: TEXTURE_ADDRESS_MODE, + MipLODBias: f32, + MaxAnisotropy: u32, + ComparisonFunc: COMPARISON_FUNC, + BorderColor: STATIC_BORDER_COLOR, + MinLOD: f32, + MaxLOD: f32, + ShaderRegister: u32, + RegisterSpace: u32, + ShaderVisibility: SHADER_VISIBILITY, +} + +ROOT_SIGNATURE_DESC :: struct { + NumParameters: u32, + pParameters: ^ROOT_PARAMETER, + NumStaticSamplers: u32, + pStaticSamplers: ^STATIC_SAMPLER_DESC, + Flags: ROOT_SIGNATURE_FLAGS, +} + +DESCRIPTOR_RANGE_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + DESCRIPTORS_VOLATILE = 0x1, + DATA_VOLATILE = 0x2, + DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4, + DATA_STATIC = 0x8, + DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS = 0x10000, +} + +DESCRIPTOR_RANGE1 :: struct { + RangeType: DESCRIPTOR_RANGE_TYPE, + NumDescriptors: u32, + BaseShaderRegister: u32, + RegisterSpace: u32, + Flags: DESCRIPTOR_RANGE_FLAGS, + OffsetInDescriptorsFromTableStart: u32, +} + +ROOT_DESCRIPTOR_TABLE1 :: struct { + NumDescriptorRanges: u32, + pDescriptorRanges: ^DESCRIPTOR_RANGE1, +} + +ROOT_DESCRIPTOR_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + DATA_VOLATILE = 0x2, + DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4, + DATA_STATIC = 0x8, +} + +ROOT_DESCRIPTOR1 :: struct { + ShaderRegister: u32, + RegisterSpace: u32, + Flags: ROOT_DESCRIPTOR_FLAGS, +} + +ROOT_PARAMETER1 :: struct { + ParameterType: ROOT_PARAMETER_TYPE, + using _: struct #raw_union { + DescriptorTable: ROOT_DESCRIPTOR_TABLE1, + Constants: ROOT_CONSTANTS, + Descriptor: ROOT_DESCRIPTOR1, + }, + ShaderVisibility: SHADER_VISIBILITY, +} + +ROOT_SIGNATURE_DESC1 :: struct { + NumParameters: u32, + pParameters: ^ROOT_PARAMETER1, + NumStaticSamplers: u32, + pStaticSamplers: ^STATIC_SAMPLER_DESC, + Flags: ROOT_SIGNATURE_FLAGS, +} + +VERSIONED_ROOT_SIGNATURE_DESC :: struct { + Version: ROOT_SIGNATURE_VERSION, + using _: struct #raw_union { + Desc_1_0: ROOT_SIGNATURE_DESC, + Desc_1_1: ROOT_SIGNATURE_DESC1, + }, +} + + +IRootSignatureDeserializer_UUID :: "34AB647B-3CC8-46AC-841B-C0965645C046" +IRootSignatureDeserializer :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12rootsignaturedeserializer_vtable: ^IRootSignatureDeserializer_VTable, +} +IRootSignatureDeserializer_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + GetRootSignatureDesc: proc "stdcall" (this: ^IRootSignatureDeserializer) -> ^ROOT_SIGNATURE_DESC, +} + + +IVersionedRootSignatureDeserializer_UUID :: "7F91CE67-090C-4BB7-B78E-ED8FF2E31DA0" +IVersionedRootSignatureDeserializer :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12versionedrootsignaturedeserializer_vtable: ^IVersionedRootSignatureDeserializer_VTable, +} +IVersionedRootSignatureDeserializer_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + GetRootSignatureDescAtVersion: proc "stdcall" (this: ^IVersionedRootSignatureDeserializer, convertToVersion: ROOT_SIGNATURE_VERSION, ppDesc: ^^VERSIONED_ROOT_SIGNATURE_DESC) -> HRESULT, + GetUnconvertedRootSignatureDesc: proc "stdcall" (this: ^IVersionedRootSignatureDeserializer) -> ^VERSIONED_ROOT_SIGNATURE_DESC, +} + +PFN_SERIALIZE_ROOT_SIGNATURE :: #type proc "c" (a0: ^ROOT_SIGNATURE_DESC, a1: ROOT_SIGNATURE_VERSION, a2: ^^IBlob, a3: ^^IBlob) -> HRESULT +PFN_CREATE_ROOT_SIGNATURE_DESERIALIZER :: #type proc "c" (a0: rawptr, a1: SIZE_T, a2: ^IID, a3: ^rawptr) -> HRESULT +PFN_SERIALIZE_VERSIONED_ROOT_SIGNATURE :: #type proc "c" (a0: ^VERSIONED_ROOT_SIGNATURE_DESC, a1: ^^IBlob, a2: ^^IBlob) -> HRESULT +PFN_CREATE_VERSIONED_ROOT_SIGNATURE_DESERIALIZER :: #type proc "c" (a0: rawptr, a1: SIZE_T, a2: ^IID, a3: ^rawptr) -> HRESULT + + +CPU_DESCRIPTOR_HANDLE :: struct { + ptr: SIZE_T, +} + +GPU_DESCRIPTOR_HANDLE :: struct { + ptr: u64, +} + +DISCARD_REGION :: struct { + NumRects: u32, + pRects: ^RECT, + FirstSubresource: u32, + NumSubresources: u32, +} + +QUERY_HEAP_TYPE :: enum i32 { + OCCLUSION = 0, + TIMESTAMP = 1, + PIPELINE_STATISTICS = 2, + SO_STATISTICS = 3, + VIDEO_DECODE_STATISTICS = 4, + COPY_QUEUE_TIMESTAMP = 5, +} + +QUERY_HEAP_DESC :: struct { + Type: QUERY_HEAP_TYPE, + Count: u32, + NodeMask: u32, +} + +QUERY_TYPE :: enum i32 { + OCCLUSION = 0, + BINARY_OCCLUSION = 1, + TIMESTAMP = 2, + PIPELINE_STATISTICS = 3, + SO_STATISTICS_STREAM0 = 4, + SO_STATISTICS_STREAM1 = 5, + SO_STATISTICS_STREAM2 = 6, + SO_STATISTICS_STREAM3 = 7, + VIDEO_DECODE_STATISTICS = 8, +} + +PREDICATION_OP :: enum i32 { + EQUAL_ZERO = 0, + NOT_EQUAL_ZERO = 1, +} + +QUERY_DATA_PIPELINE_STATISTICS :: struct { + IAVertices: u64, + IAPrimitives: u64, + VSInvocations: u64, + GSInvocations: u64, + GSPrimitives: u64, + CInvocations: u64, + CPrimitives: u64, + PSInvocations: u64, + HSInvocations: u64, + DSInvocations: u64, + CSInvocations: u64, +} + +QUERY_DATA_SO_STATISTICS :: struct { + NumPrimitivesWritten: u64, + PrimitivesStorageNeeded: u64, +} + +STREAM_OUTPUT_BUFFER_VIEW :: struct { + BufferLocation: GPU_VIRTUAL_ADDRESS, + SizeInBytes: u64, + BufferFilledSizeLocation: GPU_VIRTUAL_ADDRESS, +} + +DRAW_ARGUMENTS :: struct { + VertexCountPerInstance: u32, + InstanceCount: u32, + StartVertexLocation: u32, + StartInstanceLocation: u32, +} + +DRAW_INDEXED_ARGUMENTS :: struct { + IndexCountPerInstance: u32, + InstanceCount: u32, + StartIndexLocation: u32, + BaseVertexLocation: i32, + StartInstanceLocation: u32, +} + +DISPATCH_ARGUMENTS :: struct { + ThreadGroupCountX: u32, + ThreadGroupCountY: u32, + ThreadGroupCountZ: u32, +} + +VERTEX_BUFFER_VIEW :: struct { + BufferLocation: GPU_VIRTUAL_ADDRESS, + SizeInBytes: u32, + StrideInBytes: u32, +} + +INDEX_BUFFER_VIEW :: struct { + BufferLocation: GPU_VIRTUAL_ADDRESS, + SizeInBytes: u32, + Format: dxgi.FORMAT, +} + +INDIRECT_ARGUMENT_TYPE :: enum i32 { + DRAW = 0, + DRAW_INDEXED = 1, + DISPATCH = 2, + VERTEX_BUFFER_VIEW = 3, + INDEX_BUFFER_VIEW = 4, + CONSTANT = 5, + CONSTANT_BUFFER_VIEW = 6, + SHADER_RESOURCE_VIEW = 7, + UNORDERED_ACCESS_VIEW = 8, + DISPATCH_RAYS = 9, + DISPATCH_MESH = 10, +} + +INDIRECT_ARGUMENT_DESC :: struct { + Type: INDIRECT_ARGUMENT_TYPE, + using _: struct #raw_union { + VertexBuffer: struct { + Slot: u32, + }, + Constant: struct { + RootParameterIndex: u32, + DestOffsetIn32BitValues: u32, + Num32BitValuesToSet: u32, + }, + ConstantBufferView: struct { + RootParameterIndex: u32, + }, + ShaderResourceView: struct { + RootParameterIndex: u32, + }, + UnorderedAccessView: struct { + RootParameterIndex: u32, + }, + }, +} + +COMMAND_SIGNATURE_DESC :: struct { + ByteStride: u32, + NumArgumentDescs: u32, + pArgumentDescs: ^INDIRECT_ARGUMENT_DESC, + NodeMask: u32, +} + + +IPageable_UUID :: "63ee58fb-1268-4835-86da-f008ce62f0d6" +IPageable :: struct { + using id3d12devicechild: IDeviceChild, +} + + +IHeap_UUID :: "6b3b2502-6e51-45b3-90ee-9884265e8df3" +IHeap :: struct #raw_union { + #subtype id3d12pageable: IPageable, + using id3d12heap_vtable: ^IHeap_VTable, +} +IHeap_VTable :: struct { + using id3d12devicechild_vtable: IDeviceChild_VTable, + GetDesc: proc "stdcall" (this: ^IHeap) -> HEAP_DESC, +} + + +IResource_UUID :: "696442be-a72e-4059-bc79-5b5c98040fad" +IResource :: struct #raw_union { + #subtype id3d12pageable: IPageable, + using id3d12resource_vtable: ^IResource_VTable, +} +IResource_VTable :: struct { + using id3d12devicechild_vtable: IDeviceChild_VTable, + Map: proc "stdcall" (this: ^IResource, Subresource: u32, pReadRange: ^RANGE, ppData: ^rawptr) -> HRESULT, + Unmap: proc "stdcall" (this: ^IResource, Subresource: u32, pWrittenRange: ^RANGE), + GetDesc: proc "stdcall" (this: ^IResource) -> RESOURCE_DESC, + GetGPUVirtualAddress: proc "stdcall" (this: ^IResource) -> GPU_VIRTUAL_ADDRESS, + WriteToSubresource: proc "stdcall" (this: ^IResource, DstSubresource: u32, pDstBox: ^BOX, pSrcData: rawptr, SrcRowPitch: u32, SrcDepthPitch: u32) -> HRESULT, + ReadFromSubresource: proc "stdcall" (this: ^IResource, pDstData: rawptr, DstRowPitch: u32, DstDepthPitch: u32, SrcSubresource: u32, pSrcBox: ^BOX) -> HRESULT, + GetHeapProperties: proc "stdcall" (this: ^IResource, pHeapProperties: ^HEAP_PROPERTIES, pHeapFlags: ^HEAP_FLAGS) -> HRESULT, +} + + +ICommandAllocator_UUID :: "6102dee4-af59-4b09-b999-b44d73f09b24" +ICommandAllocator :: struct #raw_union { + #subtype id3d12pageable: IPageable, + using id3d12commandallocator_vtable: ^ICommandAllocator_VTable, +} +ICommandAllocator_VTable :: struct { + using id3d12devicechild_vtable: IDeviceChild_VTable, + Reset: proc "stdcall" (this: ^ICommandAllocator) -> HRESULT, +} + + +IFence_UUID :: "0a753dcf-c4d8-4b91-adf6-be5a60d95a76" +IFence :: struct #raw_union { + #subtype id3d12pageable: IPageable, + using id3d12fence_vtable: ^IFence_VTable, +} +IFence_VTable :: struct { + using id3d12devicechild_vtable: IDeviceChild_VTable, + GetCompletedValue: proc "stdcall" (this: ^IFence) -> u64, + SetEventOnCompletion: proc "stdcall" (this: ^IFence, Value: u64, hEvent: HANDLE) -> HRESULT, + Signal: proc "stdcall" (this: ^IFence, Value: u64) -> HRESULT, +} + + +IFence1_UUID :: "433685fe-e22b-4ca0-a8db-b5b4f4dd0e4a" +IFence1 :: struct #raw_union { + #subtype id3d12fence: IFence, + using id3d12fence1_vtable: ^IFence1_VTable, +} +IFence1_VTable :: struct { + #subtype id3d12fence_vtable: IFence_VTable, + GetCreationFlags: proc "stdcall" (this: ^IFence1) -> FENCE_FLAGS, +} + + +IPipelineState_UUID :: "765a30f3-f624-4c6f-a828-ace948622445" +IPipelineState :: struct #raw_union { + #subtype id3d12pageable: IPageable, + using id3d12pipelinestate_vtable: ^IPipelineState_VTable, +} +IPipelineState_VTable :: struct { + using id3d12devicechild_vtable: IDeviceChild_VTable, + GetCachedBlob: proc "stdcall" (this: ^IPipelineState, ppBlob: ^^IBlob) -> HRESULT, +} + + +IDescriptorHeap_UUID :: "8efb471d-616c-4f49-90f7-127bb763fa51" +IDescriptorHeap :: struct #raw_union { + #subtype id3d12pageable: IPageable, + using id3d12descriptorheap_vtable: ^IDescriptorHeap_VTable, +} +IDescriptorHeap_VTable :: struct { + using id3d12devicechild_vtable: IDeviceChild_VTable, + GetDesc: proc "stdcall" (this: ^IDescriptorHeap) -> DESCRIPTOR_HEAP_DESC, + GetCPUDescriptorHandleForHeapStart: proc "stdcall" (this: ^IDescriptorHeap) -> CPU_DESCRIPTOR_HANDLE, + GetGPUDescriptorHandleForHeapStart: proc "stdcall" (this: ^IDescriptorHeap) -> GPU_DESCRIPTOR_HANDLE, +} + + +IQueryHeap_UUID :: "0d9658ae-ed45-469e-a61d-970ec583cab4" +IQueryHeap :: struct { + #subtype id3d12pageable: IPageable, +} + + +ICommandSignature_UUID :: "c36a797c-ec80-4f0a-8985-a7b2475082d1" +ICommandSignature :: struct { + #subtype id3d12pageable: IPageable, +} + + +ICommandList_UUID :: "7116d91c-e7e4-47ce-b8c6-ec8168f437e5" +ICommandList :: struct #raw_union { + #subtype id3d12devicechild: IDeviceChild, + using id3d12commandlist_vtable: ^ICommandList_VTable, +} +ICommandList_VTable :: struct { + using id3d12devicechild_vtable: IDeviceChild_VTable, + GetType: proc "stdcall" (this: ^ICommandList) -> COMMAND_LIST_TYPE, +} + + +IGraphicsCommandList_UUID :: "5b160d0f-ac1b-4185-8ba8-b3ae42a5a455" +IGraphicsCommandList :: struct #raw_union { + #subtype id3d12commandlist: ICommandList, + using id3d12graphicscommandlist_vtable: ^IGraphicsCommandList_VTable, +} +IGraphicsCommandList_VTable :: struct { + using id3d12commandlist_vtable: ICommandList_VTable, + Close: proc "stdcall" (this: ^IGraphicsCommandList) -> HRESULT, + Reset: proc "stdcall" (this: ^IGraphicsCommandList, pAllocator: ^ICommandAllocator, pInitialState: ^IPipelineState) -> HRESULT, + ClearState: proc "stdcall" (this: ^IGraphicsCommandList, pPipelineState: ^IPipelineState), + DrawInstanced: proc "stdcall" (this: ^IGraphicsCommandList, VertexCountPerInstance: u32, InstanceCount: u32, StartVertexLocation: u32, StartInstanceLocation: u32), + DrawIndexedInstanced: proc "stdcall" (this: ^IGraphicsCommandList, IndexCountPerInstance: u32, InstanceCount: u32, StartIndexLocation: u32, BaseVertexLocation: i32, StartInstanceLocation: u32), + Dispatch: proc "stdcall" (this: ^IGraphicsCommandList, ThreadGroupCountX: u32, ThreadGroupCountY: u32, ThreadGroupCountZ: u32), + CopyBufferRegion: proc "stdcall" (this: ^IGraphicsCommandList, pDstBuffer: ^IResource, DstOffset: u64, pSrcBuffer: ^IResource, SrcOffset: u64, NumBytes: u64), + CopyTextureRegion: proc "stdcall" (this: ^IGraphicsCommandList, pDst: ^TEXTURE_COPY_LOCATION, DstX: u32, DstY: u32, DstZ: u32, pSrc: ^TEXTURE_COPY_LOCATION, pSrcBox: ^BOX), + CopyResource: proc "stdcall" (this: ^IGraphicsCommandList, pDstResource: ^IResource, pSrcResource: ^IResource), + CopyTiles: proc "stdcall" (this: ^IGraphicsCommandList, pTiledResource: ^IResource, pTileRegionStartCoordinate: ^TILED_RESOURCE_COORDINATE, pTileRegionSize: ^TILE_REGION_SIZE, pBuffer: ^IResource, BufferStartOffsetInBytes: u64, Flags: TILE_COPY_FLAGS), + ResolveSubresource: proc "stdcall" (this: ^IGraphicsCommandList, pDstResource: ^IResource, DstSubresource: u32, pSrcResource: ^IResource, SrcSubresource: u32, Format: dxgi.FORMAT), + IASetPrimitiveTopology: proc "stdcall" (this: ^IGraphicsCommandList, PrimitiveTopology: PRIMITIVE_TOPOLOGY), + RSSetViewports: proc "stdcall" (this: ^IGraphicsCommandList, NumViewports: u32, pViewports: ^VIEWPORT), + RSSetScissorRects: proc "stdcall" (this: ^IGraphicsCommandList, NumRects: u32, pRects: ^RECT), + OMSetBlendFactor: proc "stdcall" (this: ^IGraphicsCommandList, BlendFactor: ^[4]f32), + OMSetStencilRef: proc "stdcall" (this: ^IGraphicsCommandList, StencilRef: u32), + SetPipelineState: proc "stdcall" (this: ^IGraphicsCommandList, pPipelineState: ^IPipelineState), + ResourceBarrier: proc "stdcall" (this: ^IGraphicsCommandList, NumBarriers: u32, pBarriers: ^RESOURCE_BARRIER), + ExecuteBundle: proc "stdcall" (this: ^IGraphicsCommandList, pCommandList: ^IGraphicsCommandList), + SetDescriptorHeaps: proc "stdcall" (this: ^IGraphicsCommandList, NumDescriptorHeaps: u32, ppDescriptorHeaps: ^^IDescriptorHeap), + SetComputeRootSignature: proc "stdcall" (this: ^IGraphicsCommandList, pRootSignature: ^IRootSignature), + SetGraphicsRootSignature: proc "stdcall" (this: ^IGraphicsCommandList, pRootSignature: ^IRootSignature), + SetComputeRootDescriptorTable: proc "stdcall" (this: ^IGraphicsCommandList, RootParameterIndex: u32, BaseDescriptor: GPU_DESCRIPTOR_HANDLE), + SetGraphicsRootDescriptorTable: proc "stdcall" (this: ^IGraphicsCommandList, RootParameterIndex: u32, BaseDescriptor: GPU_DESCRIPTOR_HANDLE), + SetComputeRoot32BitConstant: proc "stdcall" (this: ^IGraphicsCommandList, RootParameterIndex: u32, SrcData: u32, DestOffsetIn32BitValues: u32), + SetGraphicsRoot32BitConstant: proc "stdcall" (this: ^IGraphicsCommandList, RootParameterIndex: u32, SrcData: u32, DestOffsetIn32BitValues: u32), + SetComputeRoot32BitConstants: proc "stdcall" (this: ^IGraphicsCommandList, RootParameterIndex: u32, Num32BitValuesToSet: u32, pSrcData: rawptr, DestOffsetIn32BitValues: u32), + SetGraphicsRoot32BitConstants: proc "stdcall" (this: ^IGraphicsCommandList, RootParameterIndex: u32, Num32BitValuesToSet: u32, pSrcData: rawptr, DestOffsetIn32BitValues: u32), + SetComputeRootConstantBufferView: proc "stdcall" (this: ^IGraphicsCommandList, RootParameterIndex: u32, BufferLocation: GPU_VIRTUAL_ADDRESS), + SetGraphicsRootConstantBufferView: proc "stdcall" (this: ^IGraphicsCommandList, RootParameterIndex: u32, BufferLocation: GPU_VIRTUAL_ADDRESS), + SetComputeRootShaderResourceView: proc "stdcall" (this: ^IGraphicsCommandList, RootParameterIndex: u32, BufferLocation: GPU_VIRTUAL_ADDRESS), + SetGraphicsRootShaderResourceView: proc "stdcall" (this: ^IGraphicsCommandList, RootParameterIndex: u32, BufferLocation: GPU_VIRTUAL_ADDRESS), + SetComputeRootUnorderedAccessView: proc "stdcall" (this: ^IGraphicsCommandList, RootParameterIndex: u32, BufferLocation: GPU_VIRTUAL_ADDRESS), + SetGraphicsRootUnorderedAccessView: proc "stdcall" (this: ^IGraphicsCommandList, RootParameterIndex: u32, BufferLocation: GPU_VIRTUAL_ADDRESS), + IASetIndexBuffer: proc "stdcall" (this: ^IGraphicsCommandList, pView: ^INDEX_BUFFER_VIEW), + IASetVertexBuffers: proc "stdcall" (this: ^IGraphicsCommandList, StartSlot: u32, NumViews: u32, pViews: ^VERTEX_BUFFER_VIEW), + SOSetTargets: proc "stdcall" (this: ^IGraphicsCommandList, StartSlot: u32, NumViews: u32, pViews: ^STREAM_OUTPUT_BUFFER_VIEW), + OMSetRenderTargets: proc "stdcall" (this: ^IGraphicsCommandList, NumRenderTargetDescriptors: u32, pRenderTargetDescriptors: ^CPU_DESCRIPTOR_HANDLE, RTsSingleHandleToDescriptorRange: BOOL, pDepthStencilDescriptor: ^CPU_DESCRIPTOR_HANDLE), + ClearDepthStencilView: proc "stdcall" (this: ^IGraphicsCommandList, DepthStencilView: CPU_DESCRIPTOR_HANDLE, ClearFlags: CLEAR_FLAGS, Depth: f32, Stencil: u8, NumRects: u32, pRects: ^RECT), + ClearRenderTargetView: proc "stdcall" (this: ^IGraphicsCommandList, RenderTargetView: CPU_DESCRIPTOR_HANDLE, ColorRGBA: ^[4]f32, NumRects: u32, pRects: ^RECT), + ClearUnorderedAccessViewUint: proc "stdcall" (this: ^IGraphicsCommandList, ViewGPUHandleInCurrentHeap: GPU_DESCRIPTOR_HANDLE, ViewCPUHandle: CPU_DESCRIPTOR_HANDLE, pResource: ^IResource, Values: ^[4]u32, NumRects: u32, pRects: ^RECT), + ClearUnorderedAccessViewFloat: proc "stdcall" (this: ^IGraphicsCommandList, ViewGPUHandleInCurrentHeap: GPU_DESCRIPTOR_HANDLE, ViewCPUHandle: CPU_DESCRIPTOR_HANDLE, pResource: ^IResource, Values: ^[4]f32, NumRects: u32, pRects: ^RECT), + DiscardResource: proc "stdcall" (this: ^IGraphicsCommandList, pResource: ^IResource, pRegion: ^DISCARD_REGION), + BeginQuery: proc "stdcall" (this: ^IGraphicsCommandList, pQueryHeap: ^IQueryHeap, Type: QUERY_TYPE, Index: u32), + EndQuery: proc "stdcall" (this: ^IGraphicsCommandList, pQueryHeap: ^IQueryHeap, Type: QUERY_TYPE, Index: u32), + ResolveQueryData: proc "stdcall" (this: ^IGraphicsCommandList, pQueryHeap: ^IQueryHeap, Type: QUERY_TYPE, StartIndex: u32, NumQueries: u32, pDestinationBuffer: ^IResource, AlignedDestinationBufferOffset: u64), + SetPredication: proc "stdcall" (this: ^IGraphicsCommandList, pBuffer: ^IResource, AlignedBufferOffset: u64, Operation: PREDICATION_OP), + SetMarker: proc "stdcall" (this: ^IGraphicsCommandList, Metadata: u32, pData: rawptr, Size: u32), + BeginEvent: proc "stdcall" (this: ^IGraphicsCommandList, Metadata: u32, pData: rawptr, Size: u32), + EndEvent: proc "stdcall" (this: ^IGraphicsCommandList), + ExecuteIndirect: proc "stdcall" (this: ^IGraphicsCommandList, pCommandSignature: ^ICommandSignature, MaxCommandCount: u32, pArgumentBuffer: ^IResource, ArgumentBufferOffset: u64, pCountBuffer: ^IResource, CountBufferOffset: u64), +} + + +IGraphicsCommandList1_UUID :: "553103fb-1fe7-4557-bb38-946d7d0e7ca7" +IGraphicsCommandList1 :: struct #raw_union { + #subtype id3d12graphicscommandlist: IGraphicsCommandList, + using id3d12graphicscommandlist1_vtable: ^IGraphicsCommandList1_VTable, +} +IGraphicsCommandList1_VTable :: struct { + using id3d12graphicscommandlist_vtable: IGraphicsCommandList_VTable, + AtomicCopyBufferUINT: proc "stdcall" (this: ^IGraphicsCommandList1, pDstBuffer: ^IResource, DstOffset: u64, pSrcBuffer: ^IResource, SrcOffset: u64, Dependencies: u32, ppDependentResources: ^^IResource, pDependentSubresourceRanges: ^SUBRESOURCE_RANGE_UINT64), + AtomicCopyBufferUINT64: proc "stdcall" (this: ^IGraphicsCommandList1, pDstBuffer: ^IResource, DstOffset: u64, pSrcBuffer: ^IResource, SrcOffset: u64, Dependencies: u32, ppDependentResources: ^^IResource, pDependentSubresourceRanges: ^SUBRESOURCE_RANGE_UINT64), + OMSetDepthBounds: proc "stdcall" (this: ^IGraphicsCommandList1, Min: f32, Max: f32), + SetSamplePositions: proc "stdcall" (this: ^IGraphicsCommandList1, NumSamplesPerPixel: u32, NumPixels: u32, pSamplePositions: ^SAMPLE_POSITION), + ResolveSubresourceRegion: proc "stdcall" (this: ^IGraphicsCommandList1, pDstResource: ^IResource, DstSubresource: u32, DstX: u32, DstY: u32, pSrcResource: ^IResource, SrcSubresource: u32, pSrcRect: ^RECT, Format: dxgi.FORMAT, ResolveMode: RESOLVE_MODE), + SetViewInstanceMask: proc "stdcall" (this: ^IGraphicsCommandList1, Mask: u32), +} + +WRITEBUFFERIMMEDIATE_PARAMETER :: struct { + Dest: GPU_VIRTUAL_ADDRESS, + Value: u32, +} + +WRITEBUFFERIMMEDIATE_MODE :: enum i32 { + DEFAULT = 0, + MARKER_IN = 1, + MARKER_OUT = 2, +} + + +IGraphicsCommandList2_UUID :: "38C3E585-FF17-412C-9150-4FC6F9D72A28" +IGraphicsCommandList2 :: struct #raw_union { + #subtype id3d12graphicscommandlist1: IGraphicsCommandList1, + using id3d12graphicscommandlist2_vtable: ^IGraphicsCommandList2_VTable, +} +IGraphicsCommandList2_VTable :: struct { + using id3d12graphicscommandlist1_vtable: IGraphicsCommandList1_VTable, + WriteBufferImmediate: proc "stdcall" (this: ^IGraphicsCommandList2, Count: u32, pParams: ^WRITEBUFFERIMMEDIATE_PARAMETER, pModes: ^WRITEBUFFERIMMEDIATE_MODE), +} + + +ICommandQueue_UUID :: "0ec870a6-5d7e-4c22-8cfc-5baae07616ed" +ICommandQueue :: struct #raw_union { + #subtype id3d12pageable: IPageable, + using id3d12commandqueue_vtable: ^ICommandQueue_VTable, +} +ICommandQueue_VTable :: struct { + using id3d12devicechild_vtable: IDeviceChild_VTable, + UpdateTileMappings: proc "stdcall" (this: ^ICommandQueue, pResource: ^IResource, NumResourceRegions: u32, pResourceRegionStartCoordinates: ^TILED_RESOURCE_COORDINATE, pResourceRegionSizes: ^TILE_REGION_SIZE, pHeap: ^IHeap, NumRanges: u32, pRangeFlags: ^TILE_RANGE_FLAGS, pHeapRangeStartOffsets: ^u32, pRangeTileCounts: ^u32, Flags: TILE_MAPPING_FLAGS), + CopyTileMappings: proc "stdcall" (this: ^ICommandQueue, pDstResource: ^IResource, pDstRegionStartCoordinate: ^TILED_RESOURCE_COORDINATE, pSrcResource: ^IResource, pSrcRegionStartCoordinate: ^TILED_RESOURCE_COORDINATE, pRegionSize: ^TILE_REGION_SIZE, Flags: TILE_MAPPING_FLAGS), + ExecuteCommandLists: proc "stdcall" (this: ^ICommandQueue, NumCommandLists: u32, ppCommandLists: ^^ICommandList), + SetMarker: proc "stdcall" (this: ^ICommandQueue, Metadata: u32, pData: rawptr, Size: u32), + BeginEvent: proc "stdcall" (this: ^ICommandQueue, Metadata: u32, pData: rawptr, Size: u32), + EndEvent: proc "stdcall" (this: ^ICommandQueue), + Signal: proc "stdcall" (this: ^ICommandQueue, pFence: ^IFence, Value: u64) -> HRESULT, + Wait: proc "stdcall" (this: ^ICommandQueue, pFence: ^IFence, Value: u64) -> HRESULT, + GetTimestampFrequency: proc "stdcall" (this: ^ICommandQueue, pFrequency: ^u64) -> HRESULT, + GetClockCalibration: proc "stdcall" (this: ^ICommandQueue, pGpuTimestamp: ^u64, pCpuTimestamp: ^u64) -> HRESULT, + GetDesc: proc "stdcall" (this: ^ICommandQueue) -> COMMAND_QUEUE_DESC, +} + + +IDevice_UUID :: "189819f1-1db6-4b57-be54-1821339b85f7" +IDevice :: struct #raw_union { + #subtype id3d12object: IObject, + using id3d12device_vtable: ^IDevice_VTable, +} +IDevice_VTable :: struct { + using id3d12object_vtable: IObject_VTable, + GetNodeCount: proc "stdcall" (this: ^IDevice) -> u32, + CreateCommandQueue: proc "stdcall" (this: ^IDevice, pDesc: ^COMMAND_QUEUE_DESC, riid: ^IID, ppCommandQueue: ^rawptr) -> HRESULT, + CreateCommandAllocator: proc "stdcall" (this: ^IDevice, type: COMMAND_LIST_TYPE, riid: ^IID, ppCommandAllocator: ^rawptr) -> HRESULT, + CreateGraphicsPipelineState: proc "stdcall" (this: ^IDevice, pDesc: ^GRAPHICS_PIPELINE_STATE_DESC, riid: ^IID, ppPipelineState: ^rawptr) -> HRESULT, + CreateComputePipelineState: proc "stdcall" (this: ^IDevice, pDesc: ^COMPUTE_PIPELINE_STATE_DESC, riid: ^IID, ppPipelineState: ^rawptr) -> HRESULT, + CreateCommandList: proc "stdcall" (this: ^IDevice, nodeMask: u32, type: COMMAND_LIST_TYPE, pCommandAllocator: ^ICommandAllocator, pInitialState: ^IPipelineState, riid: ^IID, ppCommandList: ^rawptr) -> HRESULT, + CheckFeatureSupport: proc "stdcall" (this: ^IDevice, Feature: FEATURE, pFeatureSupportData: rawptr, FeatureSupportDataSize: u32) -> HRESULT, + CreateDescriptorHeap: proc "stdcall" (this: ^IDevice, pDescriptorHeapDesc: ^DESCRIPTOR_HEAP_DESC, riid: ^IID, ppvHeap: ^rawptr) -> HRESULT, + GetDescriptorHandleIncrementSize: proc "stdcall" (this: ^IDevice, DescriptorHeapType: DESCRIPTOR_HEAP_TYPE) -> u32, + CreateRootSignature: proc "stdcall" (this: ^IDevice, nodeMask: u32, pBlobWithRootSignature: rawptr, blobLengthInBytes: SIZE_T, riid: ^IID, ppvRootSignature: ^rawptr) -> HRESULT, + CreateConstantBufferView: proc "stdcall" (this: ^IDevice, pDesc: ^CONSTANT_BUFFER_VIEW_DESC, DestDescriptor: CPU_DESCRIPTOR_HANDLE), + CreateShaderResourceView: proc "stdcall" (this: ^IDevice, pResource: ^IResource, pDesc: ^SHADER_RESOURCE_VIEW_DESC, DestDescriptor: CPU_DESCRIPTOR_HANDLE), + CreateUnorderedAccessView: proc "stdcall" (this: ^IDevice, pResource: ^IResource, pCounterResource: ^IResource, pDesc: ^UNORDERED_ACCESS_VIEW_DESC, DestDescriptor: CPU_DESCRIPTOR_HANDLE), + CreateRenderTargetView: proc "stdcall" (this: ^IDevice, pResource: ^IResource, pDesc: ^RENDER_TARGET_VIEW_DESC, DestDescriptor: CPU_DESCRIPTOR_HANDLE), + CreateDepthStencilView: proc "stdcall" (this: ^IDevice, pResource: ^IResource, pDesc: ^DEPTH_STENCIL_VIEW_DESC, DestDescriptor: CPU_DESCRIPTOR_HANDLE), + CreateSampler: proc "stdcall" (this: ^IDevice, pDesc: ^SAMPLER_DESC, DestDescriptor: CPU_DESCRIPTOR_HANDLE), + CopyDescriptors: proc "stdcall" (this: ^IDevice, NumDestDescriptorRanges: u32, pDestDescriptorRangeStarts: ^CPU_DESCRIPTOR_HANDLE, pDestDescriptorRangeSizes: ^u32, NumSrcDescriptorRanges: u32, pSrcDescriptorRangeStarts: ^CPU_DESCRIPTOR_HANDLE, pSrcDescriptorRangeSizes: ^u32, DescriptorHeapsType: DESCRIPTOR_HEAP_TYPE), + CopyDescriptorsSimple: proc "stdcall" (this: ^IDevice, NumDescriptors: u32, DestDescriptorRangeStart: CPU_DESCRIPTOR_HANDLE, SrcDescriptorRangeStart: CPU_DESCRIPTOR_HANDLE, DescriptorHeapsType: DESCRIPTOR_HEAP_TYPE), + GetResourceAllocationInfo: proc "stdcall" (this: ^IDevice, visibleMask: u32, numResourceDescs: u32, pResourceDescs: ^RESOURCE_DESC) -> RESOURCE_ALLOCATION_INFO, + GetCustomHeapProperties: proc "stdcall" (this: ^IDevice, nodeMask: u32, heapType: HEAP_TYPE) -> HEAP_PROPERTIES, + CreateCommittedResource: proc "stdcall" (this: ^IDevice, pHeapProperties: ^HEAP_PROPERTIES, HeapFlags: HEAP_FLAGS, pDesc: ^RESOURCE_DESC, InitialResourceState: RESOURCE_STATES, pOptimizedClearValue: ^CLEAR_VALUE, riidResource: ^IID, ppvResource: ^rawptr) -> HRESULT, + CreateHeap: proc "stdcall" (this: ^IDevice, pDesc: ^HEAP_DESC, riid: ^IID, ppvHeap: ^rawptr) -> HRESULT, + CreatePlacedResource: proc "stdcall" (this: ^IDevice, pHeap: ^IHeap, HeapOffset: u64, pDesc: ^RESOURCE_DESC, InitialState: RESOURCE_STATES, pOptimizedClearValue: ^CLEAR_VALUE, riid: ^IID, ppvResource: ^rawptr) -> HRESULT, + CreateReservedResource: proc "stdcall" (this: ^IDevice, pDesc: ^RESOURCE_DESC, InitialState: RESOURCE_STATES, pOptimizedClearValue: ^CLEAR_VALUE, riid: ^IID, ppvResource: ^rawptr) -> HRESULT, + CreateSharedHandle: proc "stdcall" (this: ^IDevice, pObject: ^IDeviceChild, pAttributes: ^win32.SECURITY_ATTRIBUTES, Access: u32, Name: [^]u16, pHandle: ^HANDLE) -> HRESULT, + OpenSharedHandle: proc "stdcall" (this: ^IDevice, NTHandle: HANDLE, riid: ^IID, ppvObj: ^rawptr) -> HRESULT, + OpenSharedHandleByName: proc "stdcall" (this: ^IDevice, Name: [^]u16, Access: u32, pNTHandle: ^HANDLE) -> HRESULT, + MakeResident: proc "stdcall" (this: ^IDevice, NumObjects: u32, ppObjects: ^^IPageable) -> HRESULT, + Evict: proc "stdcall" (this: ^IDevice, NumObjects: u32, ppObjects: ^^IPageable) -> HRESULT, + CreateFence: proc "stdcall" (this: ^IDevice, InitialValue: u64, Flags: FENCE_FLAGS, riid: ^IID, ppFence: ^rawptr) -> HRESULT, + GetDeviceRemovedReason: proc "stdcall" (this: ^IDevice) -> HRESULT, + GetCopyableFootprints: proc "stdcall" (this: ^IDevice, pResourceDesc: ^RESOURCE_DESC, FirstSubresource: u32, NumSubresources: u32, BaseOffset: u64, pLayouts: ^PLACED_SUBRESOURCE_FOOTPRINT, pNumRows: ^u32, pRowSizeInBytes: ^u64, pTotalBytes: ^u64), + CreateQueryHeap: proc "stdcall" (this: ^IDevice, pDesc: ^QUERY_HEAP_DESC, riid: ^IID, ppvHeap: ^rawptr) -> HRESULT, + SetStablePowerState: proc "stdcall" (this: ^IDevice, Enable: BOOL) -> HRESULT, + CreateCommandSignature: proc "stdcall" (this: ^IDevice, pDesc: ^COMMAND_SIGNATURE_DESC, pRootSignature: ^IRootSignature, riid: ^IID, ppvCommandSignature: ^rawptr) -> HRESULT, + GetResourceTiling: proc "stdcall" (this: ^IDevice, pTiledResource: ^IResource, pNumTilesForEntireResource: ^u32, pPackedMipDesc: ^PACKED_MIP_INFO, pStandardTileShapeForNonPackedMips: ^TILE_SHAPE, pNumSubresourceTilings: ^u32, FirstSubresourceTilingToGet: u32, pSubresourceTilingsForNonPackedMips: ^SUBRESOURCE_TILING), + GetAdapterLuid: proc "stdcall" (this: ^IDevice) -> LUID, +} + + +IPipelineLibrary_UUID :: "c64226a8-9201-46af-b4cc-53fb9ff7414f" +IPipelineLibrary :: struct #raw_union { + #subtype id3d12devicechild: IDeviceChild, + using id3d12pipelinelibrary_vtable: ^IPipelineLibrary_VTable, +} +IPipelineLibrary_VTable :: struct { + using id3d12devicechild_vtable: IDeviceChild_VTable, + StorePipeline: proc "stdcall" (this: ^IPipelineLibrary, pName: [^]u16, pPipeline: ^IPipelineState) -> HRESULT, + LoadGraphicsPipeline: proc "stdcall" (this: ^IPipelineLibrary, pName: [^]u16, pDesc: ^GRAPHICS_PIPELINE_STATE_DESC, riid: ^IID, ppPipelineState: ^rawptr) -> HRESULT, + LoadComputePipeline: proc "stdcall" (this: ^IPipelineLibrary, pName: [^]u16, pDesc: ^COMPUTE_PIPELINE_STATE_DESC, riid: ^IID, ppPipelineState: ^rawptr) -> HRESULT, + GetSerializedSize: proc "stdcall" (this: ^IPipelineLibrary) -> SIZE_T, + Serialize: proc "stdcall" (this: ^IPipelineLibrary, pData: rawptr, DataSizeInBytes: SIZE_T) -> HRESULT, +} + + +IPipelineLibrary1_UUID :: "80eabf42-2568-4e5e-bd82-c37f86961dc3" +IPipelineLibrary1 :: struct #raw_union { + #subtype id3d12pipelinelibrary: IPipelineLibrary, + using id3d12pipelinelibrary1_vtable: ^IPipelineLibrary1_VTable, +} +IPipelineLibrary1_VTable :: struct { + using id3d12pipelinelibrary_vtable: IPipelineLibrary_VTable, + LoadPipeline: proc "stdcall" (this: ^IPipelineLibrary1, pName: [^]u16, pDesc: ^PIPELINE_STATE_STREAM_DESC, riid: ^IID, ppPipelineState: ^rawptr) -> HRESULT, +} + +MULTIPLE_FENCE_WAIT_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + ANY = 0x1, + ALL = 0x0, +} + +RESIDENCY_PRIORITY :: enum i32 { + MINIMUM = 671088640, + LOW = 1342177280, + NORMAL = 2013265920, + HIGH = -1610547200, + MAXIMUM = -939524096, +} + + +IDevice1_UUID :: "77acce80-638e-4e65-8895-c1f23386863e" +IDevice1 :: struct #raw_union { + #subtype id3d12device: IDevice, + using id3d12device1_vtable: ^IDevice1_VTable, +} +IDevice1_VTable :: struct { + using id3d12device_vtable: IDevice_VTable, + CreatePipelineLibrary: proc "stdcall" (this: ^IDevice1, pLibraryBlob: rawptr, BlobLength: SIZE_T, riid: ^IID, ppPipelineLibrary: ^rawptr) -> HRESULT, + SetEventOnMultipleFenceCompletion: proc "stdcall" (this: ^IDevice1, ppFences: ^^IFence, pFenceValues: ^u64, NumFences: u32, Flags: MULTIPLE_FENCE_WAIT_FLAGS, hEvent: HANDLE) -> HRESULT, + SetResidencyPriority: proc "stdcall" (this: ^IDevice1, NumObjects: u32, ppObjects: ^^IPageable, pPriorities: ^RESIDENCY_PRIORITY) -> HRESULT, +} + + +IDevice2_UUID :: "30baa41e-b15b-475c-a0bb-1af5c5b64328" +IDevice2 :: struct #raw_union { + #subtype id3d12device1: IDevice1, + using id3d12device2_vtable: ^IDevice2_VTable, +} +IDevice2_VTable :: struct { + using id3d12device1_vtable: IDevice1_VTable, + CreatePipelineState: proc "stdcall" (this: ^IDevice2, pDesc: ^PIPELINE_STATE_STREAM_DESC, riid: ^IID, ppPipelineState: ^rawptr) -> HRESULT, +} + +RESIDENCY_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + DENY_OVERBUDGET = 0x1, +} + + +IDevice3_UUID :: "81dadc15-2bad-4392-93c5-101345c4aa98" +IDevice3 :: struct #raw_union { + #subtype id3d12device2: IDevice2, + using id3d12device3_vtable: ^IDevice3_VTable, +} +IDevice3_VTable :: struct { + using id3d12device2_vtable: IDevice2_VTable, + OpenExistingHeapFromAddress: proc "stdcall" (this: ^IDevice3, pAddress: rawptr, riid: ^IID, ppvHeap: ^rawptr) -> HRESULT, + OpenExistingHeapFromFileMapping: proc "stdcall" (this: ^IDevice3, hFileMapping: HANDLE, riid: ^IID, ppvHeap: ^rawptr) -> HRESULT, + EnqueueMakeResident: proc "stdcall" (this: ^IDevice3, Flags: RESIDENCY_FLAGS, NumObjects: u32, ppObjects: ^^IPageable, pFenceToSignal: ^IFence, FenceValueToSignal: u64) -> HRESULT, +} + +COMMAND_LIST_FLAGS :: enum u32 { // TODO: make bit_set + COMMAND_LIST_FLAG_NONE = 0x0, +} + +COMMAND_POOL_FLAGS :: enum u32 { // TODO: make bit_set + COMMAND_POOL_FLAG_NONE = 0x0, +} + +COMMAND_RECORDER_FLAGS :: enum u32 { // TODO: make bit_set + COMMAND_RECORDER_FLAG_NONE = 0x0, +} + +PROTECTED_SESSION_STATUS :: enum i32 { + OK = 0, + INVALID = 1, +} + + +IProtectedSession_UUID :: "A1533D18-0AC1-4084-85B9-89A96116806B" +IProtectedSession :: struct #raw_union { + #subtype id3d12devicechild: IDeviceChild, + using id3d12protectedsession_vtable: ^IProtectedSession_VTable, +} +IProtectedSession_VTable :: struct { + using id3d12devicechild_vtable: IDeviceChild_VTable, + GetStatusFence: proc "stdcall" (this: ^IProtectedSession, riid: ^IID, ppFence: ^rawptr) -> HRESULT, + GetSessionStatus: proc "stdcall" (this: ^IProtectedSession) -> PROTECTED_SESSION_STATUS, +} + +PROTECTED_RESOURCE_SESSION_SUPPORT_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + SUPPORTED = 0x1, +} + +FEATURE_DATA_PROTECTED_RESOURCE_SESSION_SUPPORT :: struct { + NodeIndex: u32, + Support: PROTECTED_RESOURCE_SESSION_SUPPORT_FLAGS, +} + +PROTECTED_RESOURCE_SESSION_FLAGS :: enum u32 { // TODO: make bit_set + PROTECTED_RESOURCE_SESSION_FLAG_NONE = 0x0, +} + +PROTECTED_RESOURCE_SESSION_DESC :: struct { + NodeMask: u32, + Flags: PROTECTED_RESOURCE_SESSION_FLAGS, +} + + +IProtectedResourceSession_UUID :: "6CD696F4-F289-40CC-8091-5A6C0A099C3D" +IProtectedResourceSession :: struct #raw_union { + #subtype id3d12protectedsession: IProtectedSession, + using id3d12protectedresourcesession_vtable: ^IProtectedResourceSession_VTable, +} +IProtectedResourceSession_VTable :: struct { + using id3d12protectedsession_vtable: IProtectedSession_VTable, + GetDesc: proc "stdcall" (this: ^IProtectedResourceSession) -> PROTECTED_RESOURCE_SESSION_DESC, +} + + +IDevice4_UUID :: "e865df17-a9ee-46f9-a463-3098315aa2e5" +IDevice4 :: struct #raw_union { + #subtype id3d12device3: IDevice3, + using id3d12device4_vtable: ^IDevice4_VTable, +} +IDevice4_VTable :: struct { + using id3d12device3_vtable: IDevice3_VTable, + CreateCommandList1: proc "stdcall" (this: ^IDevice4, nodeMask: u32, type: COMMAND_LIST_TYPE, flags: COMMAND_LIST_FLAGS, riid: ^IID, ppCommandList: ^rawptr) -> HRESULT, + CreateProtectedResourceSession: proc "stdcall" (this: ^IDevice4, pDesc: ^PROTECTED_RESOURCE_SESSION_DESC, riid: ^IID, ppSession: ^rawptr) -> HRESULT, + CreateCommittedResource1: proc "stdcall" (this: ^IDevice4, pHeapProperties: ^HEAP_PROPERTIES, HeapFlags: HEAP_FLAGS, pDesc: ^RESOURCE_DESC, InitialResourceState: RESOURCE_STATES, pOptimizedClearValue: ^CLEAR_VALUE, pProtectedSession: ^IProtectedResourceSession, riidResource: ^IID, ppvResource: ^rawptr) -> HRESULT, + CreateHeap1: proc "stdcall" (this: ^IDevice4, pDesc: ^HEAP_DESC, pProtectedSession: ^IProtectedResourceSession, riid: ^IID, ppvHeap: ^rawptr) -> HRESULT, + CreateReservedResource1: proc "stdcall" (this: ^IDevice4, pDesc: ^RESOURCE_DESC, InitialState: RESOURCE_STATES, pOptimizedClearValue: ^CLEAR_VALUE, pProtectedSession: ^IProtectedResourceSession, riid: ^IID, ppvResource: ^rawptr) -> HRESULT, + GetResourceAllocationInfo1: proc "stdcall" (this: ^IDevice4, visibleMask: u32, numResourceDescs: u32, pResourceDescs: ^RESOURCE_DESC, pResourceAllocationInfo1: ^RESOURCE_ALLOCATION_INFO1) -> RESOURCE_ALLOCATION_INFO, +} + +LIFETIME_STATE :: enum i32 { + IN_USE = 0, + NOT_IN_USE = 1, +} + + +ILifetimeOwner_UUID :: "e667af9f-cd56-4f46-83ce-032e595d70a8" +ILifetimeOwner :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12lifetimeowner_vtable: ^ILifetimeOwner_VTable, +} +ILifetimeOwner_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + LifetimeStateUpdated: proc "stdcall" (this: ^ILifetimeOwner, NewState: LIFETIME_STATE), +} + + +ISwapChainAssistant_UUID :: "f1df64b6-57fd-49cd-8807-c0eb88b45c8f" +ISwapChainAssistant :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12swapchainassistant_vtable: ^ISwapChainAssistant_VTable, +} +ISwapChainAssistant_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + GetLUID: proc "stdcall" (this: ^ISwapChainAssistant) -> LUID, + GetSwapChainObject: proc "stdcall" (this: ^ISwapChainAssistant, riid: ^IID, ppv: ^rawptr) -> HRESULT, + GetCurrentResourceAndCommandQueue: proc "stdcall" (this: ^ISwapChainAssistant, riidResource: ^IID, ppvResource: ^rawptr, riidQueue: ^IID, ppvQueue: ^rawptr) -> HRESULT, + InsertImplicitSync: proc "stdcall" (this: ^ISwapChainAssistant) -> HRESULT, +} + + +ILifetimeTracker_UUID :: "3fd03d36-4eb1-424a-a582-494ecb8ba813" +ILifetimeTracker :: struct #raw_union { + #subtype id3d12devicechild: IDeviceChild, + using id3d12lifetimetracker_vtable: ^ILifetimeTracker_VTable, +} +ILifetimeTracker_VTable :: struct { + using id3d12devicechild_vtable: IDeviceChild_VTable, + DestroyOwnedObject: proc "stdcall" (this: ^ILifetimeTracker, pObject: ^IDeviceChild) -> HRESULT, +} + +META_COMMAND_PARAMETER_TYPE :: enum i32 { + FLOAT = 0, + UINT64 = 1, + GPU_VIRTUAL_ADDRESS = 2, + CPU_DESCRIPTOR_HANDLE_HEAP_TYPE_CBV_SRV_UAV = 3, + GPU_DESCRIPTOR_HANDLE_HEAP_TYPE_CBV_SRV_UAV = 4, +} + +META_COMMAND_PARAMETER_FLAGS :: enum u32 { // TODO: make bit_set + INPUT = 0x1, + OUTPUT = 0x2, +} + +META_COMMAND_PARAMETER_STAGE :: enum i32 { + CREATION = 0, + INITIALIZATION = 1, + EXECUTION = 2, +} + +META_COMMAND_PARAMETER_DESC :: struct { + Name: [^]u16, + Type: META_COMMAND_PARAMETER_TYPE, + Flags: META_COMMAND_PARAMETER_FLAGS, + RequiredResourceState: RESOURCE_STATES, + StructureOffset: u32, +} + +GRAPHICS_STATES :: enum i32 { + NONE = 0, + IA_VERTEX_BUFFERS = 1, + IA_INDEX_BUFFER = 2, + IA_PRIMITIVE_TOPOLOGY = 4, + DESCRIPTOR_HEAP = 8, + GRAPHICS_ROOT_SIGNATURE = 16, + COMPUTE_ROOT_SIGNATURE = 32, + RS_VIEWPORTS = 64, + RS_SCISSOR_RECTS = 128, + PREDICATION = 256, + OM_RENDER_TARGETS = 512, + OM_STENCIL_REF = 1024, + OM_BLEND_FACTOR = 2048, + PIPELINE_STATE = 4096, + SO_TARGETS = 8192, + OM_DEPTH_BOUNDS = 16384, + SAMPLE_POSITIONS = 32768, + VIEW_INSTANCE_MASK = 65536, +} + +META_COMMAND_DESC :: struct { + Id: GUID, + Name: [^]u16, + InitializationDirtyState: GRAPHICS_STATES, + ExecutionDirtyState: GRAPHICS_STATES, +} + + +IStateObject_UUID :: "47016943-fca8-4594-93ea-af258b55346d" +IStateObject :: struct #raw_union { + #subtype id3d12pageable: IPageable, +} + + +IStateObjectProperties_UUID :: "de5fa827-9bf9-4f26-89ff-d7f56fde3860" +IStateObjectProperties :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12stateobjectproperties_vtable: ^IStateObjectProperties_VTable, +} +IStateObjectProperties_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + GetShaderIdentifier: proc "stdcall" (this: ^IStateObjectProperties, pExportName: [^]u16) -> rawptr, + GetShaderStackSize: proc "stdcall" (this: ^IStateObjectProperties, pExportName: [^]u16) -> u64, + GetPipelineStackSize: proc "stdcall" (this: ^IStateObjectProperties) -> u64, + SetPipelineStackSize: proc "stdcall" (this: ^IStateObjectProperties, PipelineStackSizeInBytes: u64), +} + +STATE_SUBOBJECT_TYPE :: enum i32 { + STATE_OBJECT_CONFIG = 0, + GLOBAL_ROOT_SIGNATURE = 1, + LOCAL_ROOT_SIGNATURE = 2, + NODE_MASK = 3, + DXIL_LIBRARY = 5, + EXISTING_COLLECTION = 6, + SUBOBJECT_TO_EXPORTS_ASSOCIATION = 7, + DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION = 8, + RAYTRACING_SHADER_CONFIG = 9, + RAYTRACING_PIPELINE_CONFIG = 10, + HIT_GROUP = 11, + RAYTRACING_PIPELINE_CONFIG1 = 12, + MAX_VALID = 13, +} + +STATE_SUBOBJECT :: struct { + Type: STATE_SUBOBJECT_TYPE, + pDesc: rawptr, +} + +STATE_OBJECT_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + ALLOW_LOCAL_DEPENDENCIES_ON_EXTERNAL_DEFINITIONS = 0x1, + ALLOW_EXTERNAL_DEPENDENCIES_ON_LOCAL_DEFINITIONS = 0x2, + ALLOW_STATE_OBJECT_ADDITIONS = 0x4, +} + +STATE_OBJECT_CONFIG :: struct { + Flags: STATE_OBJECT_FLAGS, +} + +GLOBAL_ROOT_SIGNATURE :: struct { + pGlobalRootSignature: ^IRootSignature, +} + +LOCAL_ROOT_SIGNATURE :: struct { + pLocalRootSignature: ^IRootSignature, +} + +NODE_MASK :: struct { + NodeMask: u32, +} + +EXPORT_FLAGS :: enum u32 { // TODO: make bit_set + EXPORT_FLAG_NONE = 0x0, +} + +EXPORT_DESC :: struct { + Name: [^]u16, + ExportToRename: [^]u16, + Flags: EXPORT_FLAGS, +} + +DXIL_LIBRARY_DESC :: struct { + DXILLibrary: SHADER_BYTECODE, + NumExports: u32, + pExports: ^EXPORT_DESC, +} + +EXISTING_COLLECTION_DESC :: struct { + pExistingCollection: ^IStateObject, + NumExports: u32, + pExports: ^EXPORT_DESC, +} + +SUBOBJECT_TO_EXPORTS_ASSOCIATION :: struct { + pSubobjectToAssociate: ^STATE_SUBOBJECT, + NumExports: u32, + pExports: [^]^i16, +} + +DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION :: struct { + SubobjectToAssociate: ^i16, + NumExports: u32, + pExports: [^]^i16, +} + +HIT_GROUP_TYPE :: enum i32 { + TRIANGLES = 0, + PROCEDURAL_PRIMITIVE = 1, +} + +HIT_GROUP_DESC :: struct { + HitGroupExport: ^i16, + Type: HIT_GROUP_TYPE, + AnyHitShaderImport: ^i16, + ClosestHitShaderImport: ^i16, + IntersectionShaderImport: ^i16, +} + +RAYTRACING_SHADER_CONFIG :: struct { + MaxPayloadSizeInBytes: u32, + MaxAttributeSizeInBytes: u32, +} + +RAYTRACING_PIPELINE_CONFIG :: struct { + MaxTraceRecursionDepth: u32, +} + +RAYTRACING_PIPELINE_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + SKIP_TRIANGLES = 0x100, + SKIP_PROCEDURAL_PRIMITIVES = 0x200, +} + +RAYTRACING_PIPELINE_CONFIG1 :: struct { + MaxTraceRecursionDepth: u32, + Flags: RAYTRACING_PIPELINE_FLAGS, +} + +STATE_OBJECT_TYPE :: enum i32 { + COLLECTION = 0, + RAYTRACING_PIPELINE = 3, +} + +STATE_OBJECT_DESC :: struct { + Type: STATE_OBJECT_TYPE, + NumSubobjects: u32, + pSubobjects: ^STATE_SUBOBJECT, +} + +RAYTRACING_GEOMETRY_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + OPAQUE = 0x1, + NO_DUPLICATE_ANYHIT_INVOCATION = 0x2, +} + +RAYTRACING_GEOMETRY_TYPE :: enum i32 { + TRIANGLES = 0, + PROCEDURAL_PRIMITIVE_AABBS = 1, +} + +RAYTRACING_INSTANCE_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + TRIANGLE_CULL_DISABLE = 0x1, + TRIANGLE_FRONT_COUNTERCLOCKWISE = 0x2, + FORCE_OPAQUE = 0x4, + FORCE_NON_OPAQUE = 0x8, +} + +GPU_VIRTUAL_ADDRESS_AND_STRIDE :: struct { + StartAddress: GPU_VIRTUAL_ADDRESS, + StrideInBytes: u64, +} + +GPU_VIRTUAL_ADDRESS_RANGE :: struct { + StartAddress: GPU_VIRTUAL_ADDRESS, + SizeInBytes: u64, +} + +GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE :: struct { + StartAddress: GPU_VIRTUAL_ADDRESS, + SizeInBytes: u64, + StrideInBytes: u64, +} + +RAYTRACING_GEOMETRY_TRIANGLES_DESC :: struct { + Transform3x4: GPU_VIRTUAL_ADDRESS, + IndexFormat: dxgi.FORMAT, + VertexFormat: dxgi.FORMAT, + IndexCount: u32, + VertexCount: u32, + IndexBuffer: GPU_VIRTUAL_ADDRESS, + VertexBuffer: GPU_VIRTUAL_ADDRESS_AND_STRIDE, +} + +RAYTRACING_AABB :: struct { + MinX: f32, + MinY: f32, + MinZ: f32, + MaxX: f32, + MaxY: f32, + MaxZ: f32, +} + +RAYTRACING_GEOMETRY_AABBS_DESC :: struct { + AABBCount: u64, + AABBs: GPU_VIRTUAL_ADDRESS_AND_STRIDE, +} + +RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + ALLOW_UPDATE = 0x1, + ALLOW_COMPACTION = 0x2, + PREFER_FAST_TRACE = 0x4, + PREFER_FAST_BUILD = 0x8, + MINIMIZE_MEMORY = 0x10, + PERFORM_UPDATE = 0x20, +} + +RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE :: enum i32 { + CLONE = 0, + COMPACT = 1, + VISUALIZATION_DECODE_FOR_TOOLS = 2, + SERIALIZE = 3, + DESERIALIZE = 4, +} + +RAYTRACING_ACCELERATION_STRUCTURE_TYPE :: enum i32 { + TOP_LEVEL = 0, + BOTTOM_LEVEL = 1, +} + +ELEMENTS_LAYOUT :: enum i32 { + ARRAY = 0, + ARRAY_OF_POINTERS = 1, +} + +RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_TYPE :: enum i32 { + COMPACTED_SIZE = 0, + TOOLS_VISUALIZATION = 1, + SERIALIZATION = 2, + CURRENT_SIZE = 3, +} + +RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC :: struct { + DestBuffer: GPU_VIRTUAL_ADDRESS, + InfoType: RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_TYPE, +} + +RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE_DESC :: struct { + CompactedSizeInBytes: u64, +} + +RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_TOOLS_VISUALIZATION_DESC :: struct { + DecodedSizeInBytes: u64, +} + +BUILD_RAYTRACING_ACCELERATION_STRUCTURE_TOOLS_VISUALIZATION_HEADER :: struct { + Type: RAYTRACING_ACCELERATION_STRUCTURE_TYPE, + NumDescs: u32, +} + +RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_SERIALIZATION_DESC :: struct { + SerializedSizeInBytes: u64, + NumBottomLevelAccelerationStructurePointers: u64, +} + +SERIALIZED_DATA_DRIVER_MATCHING_IDENTIFIER :: struct { + DriverOpaqueGUID: GUID, + DriverOpaqueVersioningData: [16]u8, +} + +SERIALIZED_DATA_TYPE :: enum i32 { + SERIALIZED_DATA_RAYTRACING_ACCELERATION_STRUCTURE = 0, +} + +DRIVER_MATCHING_IDENTIFIER_STATUS :: enum i32 { + COMPATIBLE_WITH_DEVICE = 0, + UNSUPPORTED_TYPE = 1, + UNRECOGNIZED = 2, + INCOMPATIBLE_VERSION = 3, + INCOMPATIBLE_TYPE = 4, +} + +SERIALIZED_RAYTRACING_ACCELERATION_STRUCTURE_HEADER :: struct { + DriverMatchingIdentifier: SERIALIZED_DATA_DRIVER_MATCHING_IDENTIFIER, + SerializedSizeInBytesIncludingHeader: u64, + DeserializedSizeInBytes: u64, + NumBottomLevelAccelerationStructurePointersAfterHeader: u64, +} + +RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_CURRENT_SIZE_DESC :: struct { + CurrentSizeInBytes: u64, +} + +RAYTRACING_INSTANCE_DESC :: struct { + Transform: [3][4]f32, + InstanceID: u32, + InstanceContributionToHitGroupIndex: u32, + AccelerationStructure: GPU_VIRTUAL_ADDRESS, +} + +RAYTRACING_GEOMETRY_DESC :: struct { + Type: RAYTRACING_GEOMETRY_TYPE, + Flags: RAYTRACING_GEOMETRY_FLAGS, + using _: struct #raw_union { + Triangles: RAYTRACING_GEOMETRY_TRIANGLES_DESC, + AABBs: RAYTRACING_GEOMETRY_AABBS_DESC, + }, +} + +BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS :: struct { + Type: RAYTRACING_ACCELERATION_STRUCTURE_TYPE, + Flags: RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS, + NumDescs: u32, + DescsLayout: ELEMENTS_LAYOUT, + using _: struct #raw_union { + InstanceDescs: GPU_VIRTUAL_ADDRESS, + pGeometryDescs: ^RAYTRACING_GEOMETRY_DESC, + ppGeometryDescs: ^^RAYTRACING_GEOMETRY_DESC, + }, +} + +BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC :: struct { + DestAccelerationStructureData: GPU_VIRTUAL_ADDRESS, + Inputs: BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS, + SourceAccelerationStructureData: GPU_VIRTUAL_ADDRESS, + ScratchAccelerationStructureData: GPU_VIRTUAL_ADDRESS, +} + +RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO :: struct { + ResultDataMaxSizeInBytes: u64, + ScratchDataSizeInBytes: u64, + UpdateScratchDataSizeInBytes: u64, +} + +RAY_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + FORCE_OPAQUE = 0x1, + FORCE_NON_OPAQUE = 0x2, + ACCEPT_FIRST_HIT_AND_END_SEARCH = 0x4, + SKIP_CLOSEST_HIT_SHADER = 0x8, + CULL_BACK_FACING_TRIANGLES = 0x10, + CULL_FRONT_FACING_TRIANGLES = 0x20, + CULL_OPAQUE = 0x40, + CULL_NON_OPAQUE = 0x80, + SKIP_TRIANGLES = 0x100, + SKIP_PROCEDURAL_PRIMITIVES = 0x200, +} + +HIT_KIND :: enum i32 { + TRIANGLE_FRONT_FACE = 254, + TRIANGLE_BACK_FACE = 255, +} + + +IDevice5_UUID :: "8b4f173b-2fea-4b80-8f58-4307191ab95d" +IDevice5 :: struct #raw_union { + #subtype id3d12device4: IDevice4, + using id3d12device5_vtable: ^IDevice5_VTable, +} +IDevice5_VTable :: struct { + using id3d12device4_vtable: IDevice4_VTable, + CreateLifetimeTracker: proc "stdcall" (this: ^IDevice5, pOwner: ^ILifetimeOwner, riid: ^IID, ppvTracker: ^rawptr) -> HRESULT, + RemoveDevice: proc "stdcall" (this: ^IDevice5), + EnumerateMetaCommands: proc "stdcall" (this: ^IDevice5, pNumMetaCommands: ^u32, pDescs: ^META_COMMAND_DESC) -> HRESULT, + EnumerateMetaCommandParameters: proc "stdcall" (this: ^IDevice5, CommandId: ^GUID, Stage: META_COMMAND_PARAMETER_STAGE, pTotalStructureSizeInBytes: ^u32, pParameterCount: ^u32, pParameterDescs: ^META_COMMAND_PARAMETER_DESC) -> HRESULT, + CreateMetaCommand: proc "stdcall" (this: ^IDevice5, CommandId: ^GUID, NodeMask: u32, pCreationParametersData: rawptr, CreationParametersDataSizeInBytes: SIZE_T, riid: ^IID, ppMetaCommand: ^rawptr) -> HRESULT, + CreateStateObject: proc "stdcall" (this: ^IDevice5, pDesc: ^STATE_OBJECT_DESC, riid: ^IID, ppStateObject: ^rawptr) -> HRESULT, + GetRaytracingAccelerationStructurePrebuildInfo: proc "stdcall" (this: ^IDevice5, pDesc: ^BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS, pInfo: ^RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO), + CheckDriverMatchingIdentifier: proc "stdcall" (this: ^IDevice5, SerializedDataType: SERIALIZED_DATA_TYPE, pIdentifierToCheck: ^SERIALIZED_DATA_DRIVER_MATCHING_IDENTIFIER) -> DRIVER_MATCHING_IDENTIFIER_STATUS, +} + +AUTO_BREADCRUMB_OP :: enum i32 { + SETMARKER = 0, + BEGINEVENT = 1, + ENDEVENT = 2, + DRAWINSTANCED = 3, + DRAWINDEXEDINSTANCED = 4, + EXECUTEINDIRECT = 5, + DISPATCH = 6, + COPYBUFFERREGION = 7, + COPYTEXTUREREGION = 8, + COPYRESOURCE = 9, + COPYTILES = 10, + RESOLVESUBRESOURCE = 11, + CLEARRENDERTARGETVIEW = 12, + CLEARUNORDEREDACCESSVIEW = 13, + CLEARDEPTHSTENCILVIEW = 14, + RESOURCEBARRIER = 15, + EXECUTEBUNDLE = 16, + PRESENT = 17, + RESOLVEQUERYDATA = 18, + BEGINSUBMISSION = 19, + ENDSUBMISSION = 20, + DECODEFRAME = 21, + PROCESSFRAMES = 22, + ATOMICCOPYBUFFERUINT = 23, + ATOMICCOPYBUFFERUINT64 = 24, + RESOLVESUBRESOURCEREGION = 25, + WRITEBUFFERIMMEDIATE = 26, + DECODEFRAME1 = 27, + SETPROTECTEDRESOURCESESSION = 28, + DECODEFRAME2 = 29, + PROCESSFRAMES1 = 30, + BUILDRAYTRACINGACCELERATIONSTRUCTURE = 31, + EMITRAYTRACINGACCELERATIONSTRUCTUREPOSTBUILDINFO = 32, + COPYRAYTRACINGACCELERATIONSTRUCTURE = 33, + DISPATCHRAYS = 34, + INITIALIZEMETACOMMAND = 35, + EXECUTEMETACOMMAND = 36, + ESTIMATEMOTION = 37, + RESOLVEMOTIONVECTORHEAP = 38, + SETPIPELINESTATE1 = 39, + INITIALIZEEXTENSIONCOMMAND = 40, + EXECUTEEXTENSIONCOMMAND = 41, + DISPATCHMESH = 42, +} + +AUTO_BREADCRUMB_NODE :: struct { + pCommandListDebugNameA: cstring, + pCommandListDebugNameW: [^]u16, + pCommandQueueDebugNameA: cstring, + pCommandQueueDebugNameW: [^]u16, + pCommandList: ^IGraphicsCommandList, + pCommandQueue: ^ICommandQueue, + BreadcrumbCount: u32, + pLastBreadcrumbValue: ^u32, + pCommandHistory: ^AUTO_BREADCRUMB_OP, + pNext: ^AUTO_BREADCRUMB_NODE, +} + +DRED_BREADCRUMB_CONTEXT :: struct { + BreadcrumbIndex: u32, + pContextString: [^]u16, +} + +AUTO_BREADCRUMB_NODE1 :: struct { + pCommandListDebugNameA: cstring, + pCommandListDebugNameW: [^]u16, + pCommandQueueDebugNameA: cstring, + pCommandQueueDebugNameW: [^]u16, + pCommandList: ^IGraphicsCommandList, + pCommandQueue: ^ICommandQueue, + BreadcrumbCount: u32, + pLastBreadcrumbValue: ^u32, + pCommandHistory: ^AUTO_BREADCRUMB_OP, + pNext: ^AUTO_BREADCRUMB_NODE1, + BreadcrumbContextsCount: u32, + pBreadcrumbContexts: ^DRED_BREADCRUMB_CONTEXT, +} + +DRED_VERSION :: enum i32 { + _1_0 = 1, + _1_1 = 2, + _1_2 = 3, +} + +DRED_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + FORCE_ENABLE = 0x1, + DISABLE_AUTOBREADCRUMBS = 0x2, +} + +DRED_ENABLEMENT :: enum i32 { + SYSTEM_CONTROLLED = 0, + FORCED_OFF = 1, + FORCED_ON = 2, +} + +DEVICE_REMOVED_EXTENDED_DATA :: struct { + Flags: DRED_FLAGS, + pHeadAutoBreadcrumbNode: ^AUTO_BREADCRUMB_NODE, +} + +DRED_ALLOCATION_TYPE :: enum i32 { + COMMAND_QUEUE = 19, + COMMAND_ALLOCATOR = 20, + PIPELINE_STATE = 21, + COMMAND_LIST = 22, + FENCE = 23, + DESCRIPTOR_HEAP = 24, + HEAP = 25, + QUERY_HEAP = 27, + COMMAND_SIGNATURE = 28, + PIPELINE_LIBRARY = 29, + VIDEO_DECODER = 30, + VIDEO_PROCESSOR = 32, + RESOURCE = 34, + PASS = 35, + CRYPTOSESSION = 36, + CRYPTOSESSIONPOLICY = 37, + PROTECTEDRESOURCESESSION = 38, + VIDEO_DECODER_HEAP = 39, + COMMAND_POOL = 40, + COMMAND_RECORDER = 41, + STATE_OBJECT = 42, + METACOMMAND = 43, + SCHEDULINGGROUP = 44, + VIDEO_MOTION_ESTIMATOR = 45, + VIDEO_MOTION_VECTOR_HEAP = 46, + VIDEO_EXTENSION_COMMAND = 47, + INVALID = -1, +} + +DRED_ALLOCATION_NODE :: struct { + ObjectNameA: cstring, + ObjectNameW: ^i16, + AllocationType: DRED_ALLOCATION_TYPE, + pNext: ^DRED_ALLOCATION_NODE, +} + +DRED_ALLOCATION_NODE1 :: struct { + ObjectNameA: cstring, + ObjectNameW: ^i16, + AllocationType: DRED_ALLOCATION_TYPE, + pNext: ^DRED_ALLOCATION_NODE1, + pObject: ^IUnknown, +} + +DRED_AUTO_BREADCRUMBS_OUTPUT :: struct { + pHeadAutoBreadcrumbNode: ^AUTO_BREADCRUMB_NODE, +} + +DRED_AUTO_BREADCRUMBS_OUTPUT1 :: struct { + pHeadAutoBreadcrumbNode: ^AUTO_BREADCRUMB_NODE1, +} + +DRED_PAGE_FAULT_OUTPUT :: struct { + PageFaultVA: GPU_VIRTUAL_ADDRESS, + pHeadExistingAllocationNode: ^DRED_ALLOCATION_NODE, + pHeadRecentFreedAllocationNode: ^DRED_ALLOCATION_NODE, +} + +DRED_PAGE_FAULT_OUTPUT1 :: struct { + PageFaultVA: GPU_VIRTUAL_ADDRESS, + pHeadExistingAllocationNode: ^DRED_ALLOCATION_NODE1, + pHeadRecentFreedAllocationNode: ^DRED_ALLOCATION_NODE1, +} + +DEVICE_REMOVED_EXTENDED_DATA1 :: struct { + DeviceRemovedReason: HRESULT, + AutoBreadcrumbsOutput: DRED_AUTO_BREADCRUMBS_OUTPUT, + PageFaultOutput: DRED_PAGE_FAULT_OUTPUT, +} + +DEVICE_REMOVED_EXTENDED_DATA2 :: struct { + DeviceRemovedReason: HRESULT, + AutoBreadcrumbsOutput: DRED_AUTO_BREADCRUMBS_OUTPUT1, + PageFaultOutput: DRED_PAGE_FAULT_OUTPUT1, +} + +VERSIONED_DEVICE_REMOVED_EXTENDED_DATA :: struct { + Version: DRED_VERSION, + using _: struct #raw_union { + Dred_1_0: DEVICE_REMOVED_EXTENDED_DATA, + Dred_1_1: DEVICE_REMOVED_EXTENDED_DATA1, + Dred_1_2: DEVICE_REMOVED_EXTENDED_DATA2, + }, +} + + +IDeviceRemovedExtendedDataSettings_UUID :: "82BC481C-6B9B-4030-AEDB-7EE3D1DF1E63" +IDeviceRemovedExtendedDataSettings :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12deviceremovedextendeddatasettings_vtable: ^IDeviceRemovedExtendedDataSettings_VTable, +} +IDeviceRemovedExtendedDataSettings_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + SetAutoBreadcrumbsEnablement: proc "stdcall" (this: ^IDeviceRemovedExtendedDataSettings, Enablement: DRED_ENABLEMENT), + SetPageFaultEnablement: proc "stdcall" (this: ^IDeviceRemovedExtendedDataSettings, Enablement: DRED_ENABLEMENT), + SetWatsonDumpEnablement: proc "stdcall" (this: ^IDeviceRemovedExtendedDataSettings, Enablement: DRED_ENABLEMENT), +} + + +IDeviceRemovedExtendedDataSettings1_UUID :: "DBD5AE51-3317-4F0A-ADF9-1D7CEDCAAE0B" +IDeviceRemovedExtendedDataSettings1 :: struct #raw_union { + #subtype id3d12deviceremovedextendeddatasettings: IDeviceRemovedExtendedDataSettings, + using id3d12deviceremovedextendeddatasettings1_vtable: ^IDeviceRemovedExtendedDataSettings1_VTable, +} +IDeviceRemovedExtendedDataSettings1_VTable :: struct { + using id3d12deviceremovedextendeddatasettings_vtable: IDeviceRemovedExtendedDataSettings_VTable, + SetBreadcrumbContextEnablement: proc "stdcall" (this: ^IDeviceRemovedExtendedDataSettings1, Enablement: DRED_ENABLEMENT), +} + + +IDeviceRemovedExtendedData_UUID :: "98931D33-5AE8-4791-AA3C-1A73A2934E71" +IDeviceRemovedExtendedData :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12deviceremovedextendeddata_vtable: ^IDeviceRemovedExtendedData_VTable, +} +IDeviceRemovedExtendedData_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + GetAutoBreadcrumbsOutput: proc "stdcall" (this: ^IDeviceRemovedExtendedData, pOutput: ^DRED_AUTO_BREADCRUMBS_OUTPUT) -> HRESULT, + GetPageFaultAllocationOutput: proc "stdcall" (this: ^IDeviceRemovedExtendedData, pOutput: ^DRED_PAGE_FAULT_OUTPUT) -> HRESULT, +} + + +IDeviceRemovedExtendedData1_UUID :: "9727A022-CF1D-4DDA-9EBA-EFFA653FC506" +IDeviceRemovedExtendedData1 :: struct #raw_union { + #subtype id3d12deviceremovedextendeddata: IDeviceRemovedExtendedData, + using id3d12deviceremovedextendeddata1_vtable: ^IDeviceRemovedExtendedData1_VTable, +} +IDeviceRemovedExtendedData1_VTable :: struct { + using id3d12deviceremovedextendeddata_vtable: IDeviceRemovedExtendedData_VTable, + GetAutoBreadcrumbsOutput1: proc "stdcall" (this: ^IDeviceRemovedExtendedData1, pOutput: ^DRED_AUTO_BREADCRUMBS_OUTPUT1) -> HRESULT, + GetPageFaultAllocationOutput1: proc "stdcall" (this: ^IDeviceRemovedExtendedData1, pOutput: ^DRED_PAGE_FAULT_OUTPUT1) -> HRESULT, +} + +BACKGROUND_PROCESSING_MODE :: enum i32 { + ALLOWED = 0, + ALLOW_INTRUSIVE_MEASUREMENTS = 1, + DISABLE_BACKGROUND_WORK = 2, + DISABLE_PROFILING_BY_SYSTEM = 3, +} + +MEASUREMENTS_ACTION :: enum i32 { + KEEP_ALL = 0, + COMMIT_RESULTS = 1, + COMMIT_RESULTS_HIGH_PRIORITY = 2, + DISCARD_PREVIOUS = 3, +} + + +IDevice6_UUID :: "c70b221b-40e4-4a17-89af-025a0727a6dc" +IDevice6 :: struct #raw_union { + #subtype id3d12device5: IDevice5, + using id3d12device6_vtable: ^IDevice6_VTable, +} +IDevice6_VTable :: struct { + using id3d12device5_vtable: IDevice5_VTable, + SetBackgroundProcessingMode: proc "stdcall" (this: ^IDevice6, Mode: BACKGROUND_PROCESSING_MODE, MeasurementsAction: MEASUREMENTS_ACTION, hEventToSignalUponCompletion: HANDLE, pbFurtherMeasurementsDesired: ^BOOL) -> HRESULT, +} + +FEATURE_DATA_PROTECTED_RESOURCE_SESSION_TYPE_COUNT :: struct { + NodeIndex: u32, + Count: u32, +} + +FEATURE_DATA_PROTECTED_RESOURCE_SESSION_TYPES :: struct { + NodeIndex: u32, + Count: u32, + pTypes: ^GUID, +} + +PROTECTED_RESOURCE_SESSION_DESC1 :: struct { + NodeMask: u32, + Flags: PROTECTED_RESOURCE_SESSION_FLAGS, + ProtectionType: GUID, +} + + +IProtectedResourceSession1_UUID :: "D6F12DD6-76FB-406E-8961-4296EEFC0409" +IProtectedResourceSession1 :: struct #raw_union { + #subtype id3d12protectedresourcesession: IProtectedResourceSession, + using id3d12protectedresourcesession1_vtable: ^IProtectedResourceSession1_VTable, +} +IProtectedResourceSession1_VTable :: struct { + using id3d12protectedresourcesession_vtable: IProtectedResourceSession_VTable, + GetDesc1: proc "stdcall" (this: ^IProtectedResourceSession1) -> PROTECTED_RESOURCE_SESSION_DESC1, +} + + +IDevice7_UUID :: "5c014b53-68a1-4b9b-8bd1-dd6046b9358b" +IDevice7 :: struct #raw_union { + #subtype id3d12device6: IDevice6, + using id3d12device7_vtable: ^IDevice7_VTable, +} +IDevice7_VTable :: struct { + using id3d12device6_vtable: IDevice6_VTable, + AddToStateObject: proc "stdcall" (this: ^IDevice7, pAddition: ^STATE_OBJECT_DESC, pStateObjectToGrowFrom: ^IStateObject, riid: ^IID, ppNewStateObject: ^rawptr) -> HRESULT, + CreateProtectedResourceSession1: proc "stdcall" (this: ^IDevice7, pDesc: ^PROTECTED_RESOURCE_SESSION_DESC1, riid: ^IID, ppSession: ^rawptr) -> HRESULT, +} + + +IDevice8_UUID :: "9218E6BB-F944-4F7E-A75C-B1B2C7B701F3" +IDevice8 :: struct #raw_union { + #subtype id3d12device7: IDevice7, + using id3d12device8_vtable: ^IDevice8_VTable, +} +IDevice8_VTable :: struct { + using id3d12device7_vtable: IDevice7_VTable, + GetResourceAllocationInfo2: proc "stdcall" (this: ^IDevice8, visibleMask: u32, numResourceDescs: u32, pResourceDescs: ^RESOURCE_DESC1, pResourceAllocationInfo1: ^RESOURCE_ALLOCATION_INFO1) -> RESOURCE_ALLOCATION_INFO, + CreateCommittedResource2: proc "stdcall" (this: ^IDevice8, pHeapProperties: ^HEAP_PROPERTIES, HeapFlags: HEAP_FLAGS, pDesc: ^RESOURCE_DESC1, InitialResourceState: RESOURCE_STATES, pOptimizedClearValue: ^CLEAR_VALUE, pProtectedSession: ^IProtectedResourceSession, riidResource: ^IID, ppvResource: ^rawptr) -> HRESULT, + CreatePlacedResource1: proc "stdcall" (this: ^IDevice8, pHeap: ^IHeap, HeapOffset: u64, pDesc: ^RESOURCE_DESC1, InitialState: RESOURCE_STATES, pOptimizedClearValue: ^CLEAR_VALUE, riid: ^IID, ppvResource: ^rawptr) -> HRESULT, + CreateSamplerFeedbackUnorderedAccessView: proc "stdcall" (this: ^IDevice8, pTargetedResource: ^IResource, pFeedbackResource: ^IResource, DestDescriptor: CPU_DESCRIPTOR_HANDLE), + GetCopyableFootprints1: proc "stdcall" (this: ^IDevice8, pResourceDesc: ^RESOURCE_DESC1, FirstSubresource: u32, NumSubresources: u32, BaseOffset: u64, pLayouts: ^PLACED_SUBRESOURCE_FOOTPRINT, pNumRows: ^u32, pRowSizeInBytes: ^u64, pTotalBytes: ^u64), +} + + +IResource1_UUID :: "9D5E227A-4430-4161-88B3-3ECA6BB16E19" +IResource1 :: struct #raw_union { + #subtype id3d12resource: IResource, + using id3d12resource1_vtable: ^IResource1_VTable, +} +IResource1_VTable :: struct { + using id3d12resource_vtable: IResource_VTable, + GetProtectedResourceSession: proc "stdcall" (this: ^IResource1, riid: ^IID, ppProtectedSession: ^rawptr) -> HRESULT, +} + + +IResource2_UUID :: "BE36EC3B-EA85-4AEB-A45A-E9D76404A495" +IResource2 :: struct #raw_union { + #subtype id3d12resource1: IResource1, + using id3d12resource2_vtable: ^IResource2_VTable, +} +IResource2_VTable :: struct { + using id3d12resource1_vtable: IResource1_VTable, + GetDesc1: proc "stdcall" (this: ^IResource2) -> RESOURCE_DESC1, +} + + +IHeap1_UUID :: "572F7389-2168-49E3-9693-D6DF5871BF6D" +IHeap1 :: struct #raw_union { + #subtype id3d12heap: IHeap, + using id3d12heap1_vtable: ^IHeap1_VTable, +} +IHeap1_VTable :: struct { + using id3d12heap_vtable: IHeap_VTable, + GetProtectedResourceSession: proc "stdcall" (this: ^IHeap1, riid: ^IID, ppProtectedSession: ^rawptr) -> HRESULT, +} + + +IGraphicsCommandList3_UUID :: "6FDA83A7-B84C-4E38-9AC8-C7BD22016B3D" +IGraphicsCommandList3 :: struct #raw_union { + #subtype id3d12graphicscommandlist2: IGraphicsCommandList2, + using id3d12graphicscommandlist3_vtable: ^IGraphicsCommandList3_VTable, +} +IGraphicsCommandList3_VTable :: struct { + using id3d12graphicscommandlist2_vtable: IGraphicsCommandList2_VTable, + SetProtectedResourceSession: proc "stdcall" (this: ^IGraphicsCommandList3, pProtectedResourceSession: ^IProtectedResourceSession), +} + +RENDER_PASS_BEGINNING_ACCESS_TYPE :: enum i32 { + DISCARD = 0, + PRESERVE = 1, + CLEAR = 2, + NO_ACCESS = 3, +} + +RENDER_PASS_BEGINNING_ACCESS_CLEAR_PARAMETERS :: struct { + ClearValue: CLEAR_VALUE, +} + +RENDER_PASS_BEGINNING_ACCESS :: struct { + Type: RENDER_PASS_BEGINNING_ACCESS_TYPE, + using _: struct #raw_union { + Clear: RENDER_PASS_BEGINNING_ACCESS_CLEAR_PARAMETERS, + }, +} + +RENDER_PASS_ENDING_ACCESS_TYPE :: enum i32 { + DISCARD = 0, + PRESERVE = 1, + RESOLVE = 2, + NO_ACCESS = 3, +} + +RENDER_PASS_ENDING_ACCESS_RESOLVE_SUBRESOURCE_PARAMETERS :: struct { + SrcSubresource: u32, + DstSubresource: u32, + DstX: u32, + DstY: u32, + SrcRect: RECT, +} + +RENDER_PASS_ENDING_ACCESS_RESOLVE_PARAMETERS :: struct { + pSrcResource: ^IResource, + pDstResource: ^IResource, + SubresourceCount: u32, + pSubresourceParameters: ^RENDER_PASS_ENDING_ACCESS_RESOLVE_SUBRESOURCE_PARAMETERS, + Format: dxgi.FORMAT, + ResolveMode: RESOLVE_MODE, + PreserveResolveSource: BOOL, +} + +RENDER_PASS_ENDING_ACCESS :: struct { + Type: RENDER_PASS_ENDING_ACCESS_TYPE, + using _: struct #raw_union { + Resolve: RENDER_PASS_ENDING_ACCESS_RESOLVE_PARAMETERS, + }, +} + +RENDER_PASS_RENDER_TARGET_DESC :: struct { + cpuDescriptor: CPU_DESCRIPTOR_HANDLE, + BeginningAccess: RENDER_PASS_BEGINNING_ACCESS, + EndingAccess: RENDER_PASS_ENDING_ACCESS, +} + +RENDER_PASS_DEPTH_STENCIL_DESC :: struct { + cpuDescriptor: CPU_DESCRIPTOR_HANDLE, + DepthBeginningAccess: RENDER_PASS_BEGINNING_ACCESS, + StencilBeginningAccess: RENDER_PASS_BEGINNING_ACCESS, + DepthEndingAccess: RENDER_PASS_ENDING_ACCESS, + StencilEndingAccess: RENDER_PASS_ENDING_ACCESS, +} + +RENDER_PASS_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + ALLOW_UAV_WRITES = 0x1, + SUSPENDING_PASS = 0x2, + RESUMING_PASS = 0x4, +} + + +IMetaCommand_UUID :: "DBB84C27-36CE-4FC9-B801-F048C46AC570" +IMetaCommand :: struct #raw_union { + #subtype id3d12pageable: IPageable, + using id3d12metacommand_vtable: ^IMetaCommand_VTable, +} +IMetaCommand_VTable :: struct { + using id3d12devicechild_vtable: IDeviceChild_VTable, + GetRequiredParameterResourceSize: proc "stdcall" (this: ^IMetaCommand, Stage: META_COMMAND_PARAMETER_STAGE, ParameterIndex: u32) -> u64, +} + +DISPATCH_RAYS_DESC :: struct { + RayGenerationShaderRecord: GPU_VIRTUAL_ADDRESS_RANGE, + MissShaderTable: GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE, + HitGroupTable: GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE, + CallableShaderTable: GPU_VIRTUAL_ADDRESS_RANGE_AND_STRIDE, + Width: u32, + Height: u32, + Depth: u32, +} + + +IGraphicsCommandList4_UUID :: "8754318e-d3a9-4541-98cf-645b50dc4874" +IGraphicsCommandList4 :: struct #raw_union { + #subtype id3d12graphicscommandlist3: IGraphicsCommandList3, + using id3d12graphicscommandlist4_vtable: ^IGraphicsCommandList4_VTable, +} +IGraphicsCommandList4_VTable :: struct { + using id3d12graphicscommandlist3_vtable: IGraphicsCommandList3_VTable, + BeginRenderPass: proc "stdcall" (this: ^IGraphicsCommandList4, NumRenderTargets: u32, pRenderTargets: ^RENDER_PASS_RENDER_TARGET_DESC, pDepthStencil: ^RENDER_PASS_DEPTH_STENCIL_DESC, Flags: RENDER_PASS_FLAGS), + EndRenderPass: proc "stdcall" (this: ^IGraphicsCommandList4), + InitializeMetaCommand: proc "stdcall" (this: ^IGraphicsCommandList4, pMetaCommand: ^IMetaCommand, pInitializationParametersData: rawptr, InitializationParametersDataSizeInBytes: SIZE_T), + ExecuteMetaCommand: proc "stdcall" (this: ^IGraphicsCommandList4, pMetaCommand: ^IMetaCommand, pExecutionParametersData: rawptr, ExecutionParametersDataSizeInBytes: SIZE_T), + BuildRaytracingAccelerationStructure: proc "stdcall" (this: ^IGraphicsCommandList4, pDesc: ^BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC, NumPostbuildInfoDescs: u32, pPostbuildInfoDescs: ^RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC), + EmitRaytracingAccelerationStructurePostbuildInfo: proc "stdcall" (this: ^IGraphicsCommandList4, pDesc: ^RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC, NumSourceAccelerationStructures: u32, pSourceAccelerationStructureData: ^GPU_VIRTUAL_ADDRESS), + CopyRaytracingAccelerationStructure: proc "stdcall" (this: ^IGraphicsCommandList4, DestAccelerationStructureData: GPU_VIRTUAL_ADDRESS, SourceAccelerationStructureData: GPU_VIRTUAL_ADDRESS, Mode: RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE), + SetPipelineState1: proc "stdcall" (this: ^IGraphicsCommandList4, pStateObject: ^IStateObject), + DispatchRays: proc "stdcall" (this: ^IGraphicsCommandList4, pDesc: ^DISPATCH_RAYS_DESC), +} + + +ITools_UUID :: "7071e1f0-e84b-4b33-974f-12fa49de65c5" +ITools :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12tools_vtable: ^ITools_VTable, +} +ITools_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + EnableShaderInstrumentation: proc "stdcall" (this: ^ITools, bEnable: BOOL), + ShaderInstrumentationEnabled: proc "stdcall" (this: ^ITools) -> BOOL, +} + +SUBRESOURCE_DATA :: struct { + pData: rawptr, + RowPitch: i64, + SlicePitch: i64, +} + +MEMCPY_DEST :: struct { + pData: rawptr, + RowPitch: SIZE_T, + SlicePitch: SIZE_T, +} + + +IDebug_UUID :: "344488b7-6846-474b-b989-f027448245e0" +IDebug :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12debug_vtable: ^IDebug_VTable, +} +IDebug_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + EnableDebugLayer: proc "stdcall" (this: ^IDebug), +} + +GPU_BASED_VALIDATION_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + DISABLE_STATE_TRACKING = 0x1, +} + + +IDebug1_UUID :: "affaa4ca-63fe-4d8e-b8ad-159000af4304" +IDebug1 :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12debug1_vtable: ^IDebug1_VTable, +} +IDebug1_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + EnableDebugLayer: proc "stdcall" (this: ^IDebug1), + SetEnableGPUBasedValidation: proc "stdcall" (this: ^IDebug1, Enable: BOOL), + SetEnableSynchronizedCommandQueueValidation: proc "stdcall" (this: ^IDebug1, Enable: BOOL), +} + + +IDebug2_UUID :: "93a665c4-a3b2-4e5d-b692-a26ae14e3374" +IDebug2 :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12debug2_vtable: ^IDebug2_VTable, +} +IDebug2_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + SetGPUBasedValidationFlags: proc "stdcall" (this: ^IDebug2, Flags: GPU_BASED_VALIDATION_FLAGS), +} + + +IDebug3_UUID :: "5cf4e58f-f671-4ff1-a542-3686e3d153d1" +IDebug3 :: struct #raw_union { + #subtype id3d12debug: IDebug, + using id3d12debug3_vtable: ^IDebug3_VTable, +} +IDebug3_VTable :: struct { + using id3d12debug_vtable: IDebug_VTable, + SetEnableGPUBasedValidation: proc "stdcall" (this: ^IDebug3, Enable: BOOL), + SetEnableSynchronizedCommandQueueValidation: proc "stdcall" (this: ^IDebug3, Enable: BOOL), + SetGPUBasedValidationFlags: proc "stdcall" (this: ^IDebug3, Flags: GPU_BASED_VALIDATION_FLAGS), +} + +RLDO_FLAGS :: enum u32 { // TODO: make bit_set + NONE = 0x0, + SUMMARY = 0x1, + DETAIL = 0x2, + IGNORE_INTERNAL = 0x4, +} + +DEBUG_DEVICE_PARAMETER_TYPE :: enum i32 { + FEATURE_FLAGS = 0, + GPU_BASED_VALIDATION_SETTINGS = 1, + GPU_SLOWDOWN_PERFORMANCE_FACTOR = 2, +} + +DEBUG_FEATURE :: enum i32 { // TODO: make bit_set + NONE = 0, + ALLOW_BEHAVIOR_CHANGING_DEBUG_AIDS = 1, + CONSERVATIVE_RESOURCE_STATE_TRACKING = 2, + DISABLE_VIRTUALIZED_BUNDLES_VALIDATION = 4, + EMULATE_WINDOWS7 = 8, +} + +GPU_BASED_VALIDATION_SHADER_PATCH_MODE :: enum i32 { + NONE = 0, + STATE_TRACKING_ONLY = 1, + UNGUARDED_VALIDATION = 2, + GUARDED_VALIDATION = 3, + NUM_GPU_BASED_VALIDATION_SHADER_PATCH_MODES = 4, +} + +GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAGS :: enum u32 { // TODO: make bit_set + GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAG_NONE = 0x0, + GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAG_FRONT_LOAD_CREATE_TRACKING_ONLY_SHADERS = 0x1, + GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAG_FRONT_LOAD_CREATE_UNGUARDED_VALIDATION_SHADERS = 0x2, + GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAG_FRONT_LOAD_CREATE_GUARDED_VALIDATION_SHADERS = 0x4, + VALID_MASK = 0x7, +} + +DEBUG_DEVICE_GPU_BASED_VALIDATION_SETTINGS :: struct { + MaxMessagesPerCommandList: u32, + DefaultShaderPatchMode: GPU_BASED_VALIDATION_SHADER_PATCH_MODE, + PipelineStateCreateFlags: GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAGS, +} + +DEBUG_DEVICE_GPU_SLOWDOWN_PERFORMANCE_FACTOR :: struct { + SlowdownFactor: f32, +} + + +IDebugDevice1_UUID :: "a9b71770-d099-4a65-a698-3dee10020f88" +IDebugDevice1 :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12debugdevice1_vtable: ^IDebugDevice1_VTable, +} +IDebugDevice1_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + SetDebugParameter: proc "stdcall" (this: ^IDebugDevice1, Type: DEBUG_DEVICE_PARAMETER_TYPE, pData: rawptr, DataSize: u32) -> HRESULT, + GetDebugParameter: proc "stdcall" (this: ^IDebugDevice1, Type: DEBUG_DEVICE_PARAMETER_TYPE, pData: rawptr, DataSize: u32) -> HRESULT, + ReportLiveDeviceObjects: proc "stdcall" (this: ^IDebugDevice1, Flags: RLDO_FLAGS) -> HRESULT, +} + + +IDebugDevice_UUID :: "3febd6dd-4973-4787-8194-e45f9e28923e" +IDebugDevice :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12debugdevice_vtable: ^IDebugDevice_VTable, +} +IDebugDevice_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + SetFeatureMask: proc "stdcall" (this: ^IDebugDevice, Mask: DEBUG_FEATURE) -> HRESULT, + GetFeatureMask: proc "stdcall" (this: ^IDebugDevice) -> DEBUG_FEATURE, + ReportLiveDeviceObjects: proc "stdcall" (this: ^IDebugDevice, Flags: RLDO_FLAGS) -> HRESULT, +} + + +IDebugDevice2_UUID :: "60eccbc1-378d-4df1-894c-f8ac5ce4d7dd" +IDebugDevice2 :: struct #raw_union { + #subtype id3d12debugdevice: IDebugDevice, + using id3d12debugdevice2_vtable: ^IDebugDevice2_VTable, +} +IDebugDevice2_VTable :: struct { + using id3d12debugdevice_vtable: IDebugDevice_VTable, + SetDebugParameter: proc "stdcall" (this: ^IDebugDevice2, Type: DEBUG_DEVICE_PARAMETER_TYPE, pData: rawptr, DataSize: u32) -> HRESULT, + GetDebugParameter: proc "stdcall" (this: ^IDebugDevice2, Type: DEBUG_DEVICE_PARAMETER_TYPE, pData: rawptr, DataSize: u32) -> HRESULT, +} + + + +IDebugCommandQueue_UUID :: "09e0bf36-54ac-484f-8847-4baeeab6053a" +IDebugCommandQueue :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12debugcommandqueue_vtable: ^IDebugCommandQueue_VTable, +} +IDebugCommandQueue_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + AssertResourceState: proc "stdcall" (this: ^IDebugCommandQueue, pResource: ^IResource, Subresource: u32, State: u32) -> BOOL, +} + +DEBUG_COMMAND_LIST_PARAMETER_TYPE :: enum i32 { + DEBUG_COMMAND_LIST_PARAMETER_GPU_BASED_VALIDATION_SETTINGS = 0, +} + +DEBUG_COMMAND_LIST_GPU_BASED_VALIDATION_SETTINGS :: struct { + ShaderPatchMode: GPU_BASED_VALIDATION_SHADER_PATCH_MODE, +} + + +IDebugCommandList1_UUID :: "102ca951-311b-4b01-b11f-ecb83e061b37" +IDebugCommandList1 :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12debugcommandlist1_vtable: ^IDebugCommandList1_VTable, +} +IDebugCommandList1_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + AssertResourceState: proc "stdcall" (this: ^IDebugCommandList1, pResource: ^IResource, Subresource: u32, State: u32) -> BOOL, + SetDebugParameter: proc "stdcall" (this: ^IDebugCommandList1, Type: DEBUG_COMMAND_LIST_PARAMETER_TYPE, pData: rawptr, DataSize: u32) -> HRESULT, + GetDebugParameter: proc "stdcall" (this: ^IDebugCommandList1, Type: DEBUG_COMMAND_LIST_PARAMETER_TYPE, pData: rawptr, DataSize: u32) -> HRESULT, +} + + +IDebugCommandList_UUID :: "09e0bf36-54ac-484f-8847-4baeeab6053f" +IDebugCommandList :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12debugcommandlist_vtable: ^IDebugCommandList_VTable, +} +IDebugCommandList_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + AssertResourceState: proc "stdcall" (this: ^IDebugCommandList, pResource: ^IResource, Subresource: u32, State: u32) -> BOOL, + SetFeatureMask: proc "stdcall" (this: ^IDebugCommandList, Mask: DEBUG_FEATURE) -> HRESULT, + GetFeatureMask: proc "stdcall" (this: ^IDebugCommandList) -> DEBUG_FEATURE, +} + + +IDebugCommandList2_UUID :: "aeb575cf-4e06-48be-ba3b-c450fc96652e" +IDebugCommandList2 :: struct #raw_union { + #subtype id3d12debugcommandlist: IDebugCommandList, + using id3d12debugcommandlist2_vtable: ^IDebugCommandList2_VTable, +} +IDebugCommandList2_VTable :: struct { + using id3d12debugcommandlist_vtable: IDebugCommandList_VTable, + SetDebugParameter: proc "stdcall" (this: ^IDebugCommandList2, Type: DEBUG_COMMAND_LIST_PARAMETER_TYPE, pData: rawptr, DataSize: u32) -> HRESULT, + GetDebugParameter: proc "stdcall" (this: ^IDebugCommandList2, Type: DEBUG_COMMAND_LIST_PARAMETER_TYPE, pData: rawptr, DataSize: u32) -> HRESULT, +} + + +ISharingContract_UUID :: "0adf7d52-929c-4e61-addb-ffed30de66ef" +ISharingContract :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12sharingcontract_vtable: ^ISharingContract_VTable, +} +ISharingContract_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + Present: proc "stdcall" (this: ^ISharingContract, pResource: ^IResource, Subresource: u32, window: HWND), + SharedFenceSignal: proc "stdcall" (this: ^ISharingContract, pFence: ^IFence, FenceValue: u64), + BeginCapturableWork: proc "stdcall" (this: ^ISharingContract, guid: ^GUID), + EndCapturableWork: proc "stdcall" (this: ^ISharingContract, guid: ^GUID), +} + +MESSAGE_CATEGORY :: enum i32 { + APPLICATION_DEFINED = 0, + MISCELLANEOUS = 1, + INITIALIZATION = 2, + CLEANUP = 3, + COMPILATION = 4, + STATE_CREATION = 5, + STATE_SETTING = 6, + STATE_GETTING = 7, + RESOURCE_MANIPULATION = 8, + EXECUTION = 9, + SHADER = 10, +} + +MESSAGE_SEVERITY :: enum i32 { + CORRUPTION = 0, + ERROR = 1, + WARNING = 2, + INFO = 3, + MESSAGE = 4, +} + +MESSAGE_ID :: enum i32 { + UNKNOWN = 0, + STRING_FROM_APPLICATION = 1, + CORRUPTED_THIS = 2, + CORRUPTED_PARAMETER1 = 3, + CORRUPTED_PARAMETER2 = 4, + CORRUPTED_PARAMETER3 = 5, + CORRUPTED_PARAMETER4 = 6, + CORRUPTED_PARAMETER5 = 7, + CORRUPTED_PARAMETER6 = 8, + CORRUPTED_PARAMETER7 = 9, + CORRUPTED_PARAMETER8 = 10, + CORRUPTED_PARAMETER9 = 11, + CORRUPTED_PARAMETER10 = 12, + CORRUPTED_PARAMETER11 = 13, + CORRUPTED_PARAMETER12 = 14, + CORRUPTED_PARAMETER13 = 15, + CORRUPTED_PARAMETER14 = 16, + CORRUPTED_PARAMETER15 = 17, + CORRUPTED_MULTITHREADING = 18, + MESSAGE_REPORTING_OUTOFMEMORY = 19, + GETPRIVATEDATA_MOREDATA = 20, + SETPRIVATEDATA_INVALIDFREEDATA = 21, + SETPRIVATEDATA_CHANGINGPARAMS = 24, + SETPRIVATEDATA_OUTOFMEMORY = 25, + CREATESHADERRESOURCEVIEW_UNRECOGNIZEDFORMAT = 26, + CREATESHADERRESOURCEVIEW_INVALIDDESC = 27, + CREATESHADERRESOURCEVIEW_INVALIDFORMAT = 28, + CREATESHADERRESOURCEVIEW_INVALIDVIDEOPLANESLICE = 29, + CREATESHADERRESOURCEVIEW_INVALIDPLANESLICE = 30, + CREATESHADERRESOURCEVIEW_INVALIDDIMENSIONS = 31, + CREATESHADERRESOURCEVIEW_INVALIDRESOURCE = 32, + CREATERENDERTARGETVIEW_UNRECOGNIZEDFORMAT = 35, + CREATERENDERTARGETVIEW_UNSUPPORTEDFORMAT = 36, + CREATERENDERTARGETVIEW_INVALIDDESC = 37, + CREATERENDERTARGETVIEW_INVALIDFORMAT = 38, + CREATERENDERTARGETVIEW_INVALIDVIDEOPLANESLICE = 39, + CREATERENDERTARGETVIEW_INVALIDPLANESLICE = 40, + CREATERENDERTARGETVIEW_INVALIDDIMENSIONS = 41, + CREATERENDERTARGETVIEW_INVALIDRESOURCE = 42, + CREATEDEPTHSTENCILVIEW_UNRECOGNIZEDFORMAT = 45, + CREATEDEPTHSTENCILVIEW_INVALIDDESC = 46, + CREATEDEPTHSTENCILVIEW_INVALIDFORMAT = 47, + CREATEDEPTHSTENCILVIEW_INVALIDDIMENSIONS = 48, + CREATEDEPTHSTENCILVIEW_INVALIDRESOURCE = 49, + CREATEINPUTLAYOUT_OUTOFMEMORY = 52, + CREATEINPUTLAYOUT_TOOMANYELEMENTS = 53, + CREATEINPUTLAYOUT_INVALIDFORMAT = 54, + CREATEINPUTLAYOUT_INCOMPATIBLEFORMAT = 55, + CREATEINPUTLAYOUT_INVALIDSLOT = 56, + CREATEINPUTLAYOUT_INVALIDINPUTSLOTCLASS = 57, + CREATEINPUTLAYOUT_STEPRATESLOTCLASSMISMATCH = 58, + CREATEINPUTLAYOUT_INVALIDSLOTCLASSCHANGE = 59, + CREATEINPUTLAYOUT_INVALIDSTEPRATECHANGE = 60, + CREATEINPUTLAYOUT_INVALIDALIGNMENT = 61, + CREATEINPUTLAYOUT_DUPLICATESEMANTIC = 62, + CREATEINPUTLAYOUT_UNPARSEABLEINPUTSIGNATURE = 63, + CREATEINPUTLAYOUT_NULLSEMANTIC = 64, + CREATEINPUTLAYOUT_MISSINGELEMENT = 65, + CREATEVERTEXSHADER_OUTOFMEMORY = 66, + CREATEVERTEXSHADER_INVALIDSHADERBYTECODE = 67, + CREATEVERTEXSHADER_INVALIDSHADERTYPE = 68, + CREATEGEOMETRYSHADER_OUTOFMEMORY = 69, + CREATEGEOMETRYSHADER_INVALIDSHADERBYTECODE = 70, + CREATEGEOMETRYSHADER_INVALIDSHADERTYPE = 71, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTOFMEMORY = 72, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSHADERBYTECODE = 73, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSHADERTYPE = 74, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMENTRIES = 75, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTPUTSTREAMSTRIDEUNUSED = 76, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTPUTSLOT0EXPECTED = 79, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDOUTPUTSLOT = 80, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_ONLYONEELEMENTPERSLOT = 81, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDCOMPONENTCOUNT = 82, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTARTCOMPONENTANDCOMPONENTCOUNT = 83, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDGAPDEFINITION = 84, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_REPEATEDOUTPUT = 85, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDOUTPUTSTREAMSTRIDE = 86, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MISSINGSEMANTIC = 87, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MASKMISMATCH = 88, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_CANTHAVEONLYGAPS = 89, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DECLTOOCOMPLEX = 90, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MISSINGOUTPUTSIGNATURE = 91, + CREATEPIXELSHADER_OUTOFMEMORY = 92, + CREATEPIXELSHADER_INVALIDSHADERBYTECODE = 93, + CREATEPIXELSHADER_INVALIDSHADERTYPE = 94, + CREATERASTERIZERSTATE_INVALIDFILLMODE = 95, + CREATERASTERIZERSTATE_INVALIDCULLMODE = 96, + CREATERASTERIZERSTATE_INVALIDDEPTHBIASCLAMP = 97, + CREATERASTERIZERSTATE_INVALIDSLOPESCALEDDEPTHBIAS = 98, + CREATEDEPTHSTENCILSTATE_INVALIDDEPTHWRITEMASK = 100, + CREATEDEPTHSTENCILSTATE_INVALIDDEPTHFUNC = 101, + CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILFAILOP = 102, + CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILZFAILOP = 103, + CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILPASSOP = 104, + CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILFUNC = 105, + CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILFAILOP = 106, + CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILZFAILOP = 107, + CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILPASSOP = 108, + CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILFUNC = 109, + CREATEBLENDSTATE_INVALIDSRCBLEND = 111, + CREATEBLENDSTATE_INVALIDDESTBLEND = 112, + CREATEBLENDSTATE_INVALIDBLENDOP = 113, + CREATEBLENDSTATE_INVALIDSRCBLENDALPHA = 114, + CREATEBLENDSTATE_INVALIDDESTBLENDALPHA = 115, + CREATEBLENDSTATE_INVALIDBLENDOPALPHA = 116, + CREATEBLENDSTATE_INVALIDRENDERTARGETWRITEMASK = 117, + CLEARDEPTHSTENCILVIEW_INVALID = 135, + COMMAND_LIST_DRAW_ROOT_SIGNATURE_NOT_SET = 200, + COMMAND_LIST_DRAW_ROOT_SIGNATURE_MISMATCH = 201, + COMMAND_LIST_DRAW_VERTEX_BUFFER_NOT_SET = 202, + COMMAND_LIST_DRAW_VERTEX_BUFFER_STRIDE_TOO_SMALL = 209, + COMMAND_LIST_DRAW_VERTEX_BUFFER_TOO_SMALL = 210, + COMMAND_LIST_DRAW_INDEX_BUFFER_NOT_SET = 211, + COMMAND_LIST_DRAW_INDEX_BUFFER_FORMAT_INVALID = 212, + COMMAND_LIST_DRAW_INDEX_BUFFER_TOO_SMALL = 213, + COMMAND_LIST_DRAW_INVALID_PRIMITIVETOPOLOGY = 219, + COMMAND_LIST_DRAW_VERTEX_STRIDE_UNALIGNED = 221, + COMMAND_LIST_DRAW_INDEX_OFFSET_UNALIGNED = 222, + DEVICE_REMOVAL_PROCESS_AT_FAULT = 232, + DEVICE_REMOVAL_PROCESS_POSSIBLY_AT_FAULT = 233, + DEVICE_REMOVAL_PROCESS_NOT_AT_FAULT = 234, + CREATEINPUTLAYOUT_TRAILING_DIGIT_IN_SEMANTIC = 239, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_TRAILING_DIGIT_IN_SEMANTIC = 240, + CREATEINPUTLAYOUT_TYPE_MISMATCH = 245, + CREATEINPUTLAYOUT_EMPTY_LAYOUT = 253, + LIVE_OBJECT_SUMMARY = 255, + LIVE_DEVICE = 274, + LIVE_SWAPCHAIN = 275, + CREATEDEPTHSTENCILVIEW_INVALIDFLAGS = 276, + CREATEVERTEXSHADER_INVALIDCLASSLINKAGE = 277, + CREATEGEOMETRYSHADER_INVALIDCLASSLINKAGE = 278, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTREAMTORASTERIZER = 280, + CREATEPIXELSHADER_INVALIDCLASSLINKAGE = 283, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTREAM = 284, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDENTRIES = 285, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDSTRIDES = 286, + CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMSTRIDES = 287, + CREATEHULLSHADER_OUTOFMEMORY = 289, + CREATEHULLSHADER_INVALIDSHADERBYTECODE = 290, + CREATEHULLSHADER_INVALIDSHADERTYPE = 291, + CREATEHULLSHADER_INVALIDCLASSLINKAGE = 292, + CREATEDOMAINSHADER_OUTOFMEMORY = 294, + CREATEDOMAINSHADER_INVALIDSHADERBYTECODE = 295, + CREATEDOMAINSHADER_INVALIDSHADERTYPE = 296, + CREATEDOMAINSHADER_INVALIDCLASSLINKAGE = 297, + RESOURCE_UNMAP_NOTMAPPED = 310, + DEVICE_CHECKFEATURESUPPORT_MISMATCHED_DATA_SIZE = 318, + CREATECOMPUTESHADER_OUTOFMEMORY = 321, + CREATECOMPUTESHADER_INVALIDSHADERBYTECODE = 322, + CREATECOMPUTESHADER_INVALIDCLASSLINKAGE = 323, + DEVICE_CREATEVERTEXSHADER_DOUBLEFLOATOPSNOTSUPPORTED = 331, + DEVICE_CREATEHULLSHADER_DOUBLEFLOATOPSNOTSUPPORTED = 332, + DEVICE_CREATEDOMAINSHADER_DOUBLEFLOATOPSNOTSUPPORTED = 333, + DEVICE_CREATEGEOMETRYSHADER_DOUBLEFLOATOPSNOTSUPPORTED = 334, + DEVICE_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DOUBLEFLOATOPSNOTSUPPORTED = 335, + DEVICE_CREATEPIXELSHADER_DOUBLEFLOATOPSNOTSUPPORTED = 336, + DEVICE_CREATECOMPUTESHADER_DOUBLEFLOATOPSNOTSUPPORTED = 337, + CREATEUNORDEREDACCESSVIEW_INVALIDRESOURCE = 340, + CREATEUNORDEREDACCESSVIEW_INVALIDDESC = 341, + CREATEUNORDEREDACCESSVIEW_INVALIDFORMAT = 342, + CREATEUNORDEREDACCESSVIEW_INVALIDVIDEOPLANESLICE = 343, + CREATEUNORDEREDACCESSVIEW_INVALIDPLANESLICE = 344, + CREATEUNORDEREDACCESSVIEW_INVALIDDIMENSIONS = 345, + CREATEUNORDEREDACCESSVIEW_UNRECOGNIZEDFORMAT = 346, + CREATEUNORDEREDACCESSVIEW_INVALIDFLAGS = 354, + CREATERASTERIZERSTATE_INVALIDFORCEDSAMPLECOUNT = 401, + CREATEBLENDSTATE_INVALIDLOGICOPS = 403, + DEVICE_CREATEVERTEXSHADER_DOUBLEEXTENSIONSNOTSUPPORTED = 410, + DEVICE_CREATEHULLSHADER_DOUBLEEXTENSIONSNOTSUPPORTED = 412, + DEVICE_CREATEDOMAINSHADER_DOUBLEEXTENSIONSNOTSUPPORTED = 414, + DEVICE_CREATEGEOMETRYSHADER_DOUBLEEXTENSIONSNOTSUPPORTED = 416, + DEVICE_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DOUBLEEXTENSIONSNOTSUPPORTED = 418, + DEVICE_CREATEPIXELSHADER_DOUBLEEXTENSIONSNOTSUPPORTED = 420, + DEVICE_CREATECOMPUTESHADER_DOUBLEEXTENSIONSNOTSUPPORTED = 422, + DEVICE_CREATEVERTEXSHADER_UAVSNOTSUPPORTED = 425, + DEVICE_CREATEHULLSHADER_UAVSNOTSUPPORTED = 426, + DEVICE_CREATEDOMAINSHADER_UAVSNOTSUPPORTED = 427, + DEVICE_CREATEGEOMETRYSHADER_UAVSNOTSUPPORTED = 428, + DEVICE_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UAVSNOTSUPPORTED = 429, + DEVICE_CREATEPIXELSHADER_UAVSNOTSUPPORTED = 430, + DEVICE_CREATECOMPUTESHADER_UAVSNOTSUPPORTED = 431, + DEVICE_CLEARVIEW_INVALIDSOURCERECT = 447, + DEVICE_CLEARVIEW_EMPTYRECT = 448, + UPDATETILEMAPPINGS_INVALID_PARAMETER = 493, + COPYTILEMAPPINGS_INVALID_PARAMETER = 494, + CREATEDEVICE_INVALIDARGS = 506, + CREATEDEVICE_WARNING = 507, + RESOURCE_BARRIER_INVALID_TYPE = 519, + RESOURCE_BARRIER_NULL_POINTER = 520, + RESOURCE_BARRIER_INVALID_SUBRESOURCE = 521, + RESOURCE_BARRIER_RESERVED_BITS = 522, + RESOURCE_BARRIER_MISSING_BIND_FLAGS = 523, + RESOURCE_BARRIER_MISMATCHING_MISC_FLAGS = 524, + RESOURCE_BARRIER_MATCHING_STATES = 525, + RESOURCE_BARRIER_INVALID_COMBINATION = 526, + RESOURCE_BARRIER_BEFORE_AFTER_MISMATCH = 527, + RESOURCE_BARRIER_INVALID_RESOURCE = 528, + RESOURCE_BARRIER_SAMPLE_COUNT = 529, + RESOURCE_BARRIER_INVALID_FLAGS = 530, + RESOURCE_BARRIER_INVALID_COMBINED_FLAGS = 531, + RESOURCE_BARRIER_INVALID_FLAGS_FOR_FORMAT = 532, + RESOURCE_BARRIER_INVALID_SPLIT_BARRIER = 533, + RESOURCE_BARRIER_UNMATCHED_END = 534, + RESOURCE_BARRIER_UNMATCHED_BEGIN = 535, + RESOURCE_BARRIER_INVALID_FLAG = 536, + RESOURCE_BARRIER_INVALID_COMMAND_LIST_TYPE = 537, + INVALID_SUBRESOURCE_STATE = 538, + COMMAND_ALLOCATOR_CONTENTION = 540, + COMMAND_ALLOCATOR_RESET = 541, + COMMAND_ALLOCATOR_RESET_BUNDLE = 542, + COMMAND_ALLOCATOR_CANNOT_RESET = 543, + COMMAND_LIST_OPEN = 544, + INVALID_BUNDLE_API = 546, + COMMAND_LIST_CLOSED = 547, + WRONG_COMMAND_ALLOCATOR_TYPE = 549, + COMMAND_ALLOCATOR_SYNC = 552, + COMMAND_LIST_SYNC = 553, + SET_DESCRIPTOR_HEAP_INVALID = 554, + CREATE_COMMANDQUEUE = 557, + CREATE_COMMANDALLOCATOR = 558, + CREATE_PIPELINESTATE = 559, + CREATE_COMMANDLIST12 = 560, + CREATE_RESOURCE = 562, + CREATE_DESCRIPTORHEAP = 563, + CREATE_ROOTSIGNATURE = 564, + CREATE_LIBRARY = 565, + CREATE_HEAP = 566, + CREATE_MONITOREDFENCE = 567, + CREATE_QUERYHEAP = 568, + CREATE_COMMANDSIGNATURE = 569, + LIVE_COMMANDQUEUE = 570, + LIVE_COMMANDALLOCATOR = 571, + LIVE_PIPELINESTATE = 572, + LIVE_COMMANDLIST12 = 573, + LIVE_RESOURCE = 575, + LIVE_DESCRIPTORHEAP = 576, + LIVE_ROOTSIGNATURE = 577, + LIVE_LIBRARY = 578, + LIVE_HEAP = 579, + LIVE_MONITOREDFENCE = 580, + LIVE_QUERYHEAP = 581, + LIVE_COMMANDSIGNATURE = 582, + DESTROY_COMMANDQUEUE = 583, + DESTROY_COMMANDALLOCATOR = 584, + DESTROY_PIPELINESTATE = 585, + DESTROY_COMMANDLIST12 = 586, + DESTROY_RESOURCE = 588, + DESTROY_DESCRIPTORHEAP = 589, + DESTROY_ROOTSIGNATURE = 590, + DESTROY_LIBRARY = 591, + DESTROY_HEAP = 592, + DESTROY_MONITOREDFENCE = 593, + DESTROY_QUERYHEAP = 594, + DESTROY_COMMANDSIGNATURE = 595, + CREATERESOURCE_INVALIDDIMENSIONS = 597, + CREATERESOURCE_INVALIDMISCFLAGS = 599, + CREATERESOURCE_INVALIDARG_RETURN = 602, + CREATERESOURCE_OUTOFMEMORY_RETURN = 603, + CREATERESOURCE_INVALIDDESC = 604, + POSSIBLY_INVALID_SUBRESOURCE_STATE = 607, + INVALID_USE_OF_NON_RESIDENT_RESOURCE = 608, + POSSIBLE_INVALID_USE_OF_NON_RESIDENT_RESOURCE = 609, + BUNDLE_PIPELINE_STATE_MISMATCH = 610, + PRIMITIVE_TOPOLOGY_MISMATCH_PIPELINE_STATE = 611, + RENDER_TARGET_FORMAT_MISMATCH_PIPELINE_STATE = 613, + RENDER_TARGET_SAMPLE_DESC_MISMATCH_PIPELINE_STATE = 614, + DEPTH_STENCIL_FORMAT_MISMATCH_PIPELINE_STATE = 615, + DEPTH_STENCIL_SAMPLE_DESC_MISMATCH_PIPELINE_STATE = 616, + CREATESHADER_INVALIDBYTECODE = 622, + CREATEHEAP_NULLDESC = 623, + CREATEHEAP_INVALIDSIZE = 624, + CREATEHEAP_UNRECOGNIZEDHEAPTYPE = 625, + CREATEHEAP_UNRECOGNIZEDCPUPAGEPROPERTIES = 626, + CREATEHEAP_UNRECOGNIZEDMEMORYPOOL = 627, + CREATEHEAP_INVALIDPROPERTIES = 628, + CREATEHEAP_INVALIDALIGNMENT = 629, + CREATEHEAP_UNRECOGNIZEDMISCFLAGS = 630, + CREATEHEAP_INVALIDMISCFLAGS = 631, + CREATEHEAP_INVALIDARG_RETURN = 632, + CREATEHEAP_OUTOFMEMORY_RETURN = 633, + CREATERESOURCEANDHEAP_NULLHEAPPROPERTIES = 634, + CREATERESOURCEANDHEAP_UNRECOGNIZEDHEAPTYPE = 635, + CREATERESOURCEANDHEAP_UNRECOGNIZEDCPUPAGEPROPERTIES = 636, + CREATERESOURCEANDHEAP_UNRECOGNIZEDMEMORYPOOL = 637, + CREATERESOURCEANDHEAP_INVALIDHEAPPROPERTIES = 638, + CREATERESOURCEANDHEAP_UNRECOGNIZEDHEAPMISCFLAGS = 639, + CREATERESOURCEANDHEAP_INVALIDHEAPMISCFLAGS = 640, + CREATERESOURCEANDHEAP_INVALIDARG_RETURN = 641, + CREATERESOURCEANDHEAP_OUTOFMEMORY_RETURN = 642, + GETCUSTOMHEAPPROPERTIES_UNRECOGNIZEDHEAPTYPE = 643, + GETCUSTOMHEAPPROPERTIES_INVALIDHEAPTYPE = 644, + CREATE_DESCRIPTOR_HEAP_INVALID_DESC = 645, + INVALID_DESCRIPTOR_HANDLE = 646, + CREATERASTERIZERSTATE_INVALID_CONSERVATIVERASTERMODE = 647, + CREATE_CONSTANT_BUFFER_VIEW_INVALID_RESOURCE = 649, + CREATE_CONSTANT_BUFFER_VIEW_INVALID_DESC = 650, + CREATE_UNORDEREDACCESS_VIEW_INVALID_COUNTER_USAGE = 652, + COPY_DESCRIPTORS_INVALID_RANGES = 653, + COPY_DESCRIPTORS_WRITE_ONLY_DESCRIPTOR = 654, + CREATEGRAPHICSPIPELINESTATE_RTV_FORMAT_NOT_UNKNOWN = 655, + CREATEGRAPHICSPIPELINESTATE_INVALID_RENDER_TARGET_COUNT = 656, + CREATEGRAPHICSPIPELINESTATE_VERTEX_SHADER_NOT_SET = 657, + CREATEGRAPHICSPIPELINESTATE_INPUTLAYOUT_NOT_SET = 658, + CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_HS_DS_SIGNATURE_MISMATCH = 659, + CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_REGISTERINDEX = 660, + CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_COMPONENTTYPE = 661, + CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_REGISTERMASK = 662, + CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_SYSTEMVALUE = 663, + CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_NEVERWRITTEN_ALWAYSREADS = 664, + CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_MINPRECISION = 665, + CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_SEMANTICNAME_NOT_FOUND = 666, + CREATEGRAPHICSPIPELINESTATE_HS_XOR_DS_MISMATCH = 667, + CREATEGRAPHICSPIPELINESTATE_HULL_SHADER_INPUT_TOPOLOGY_MISMATCH = 668, + CREATEGRAPHICSPIPELINESTATE_HS_DS_CONTROL_POINT_COUNT_MISMATCH = 669, + CREATEGRAPHICSPIPELINESTATE_HS_DS_TESSELLATOR_DOMAIN_MISMATCH = 670, + CREATEGRAPHICSPIPELINESTATE_INVALID_USE_OF_CENTER_MULTISAMPLE_PATTERN = 671, + CREATEGRAPHICSPIPELINESTATE_INVALID_USE_OF_FORCED_SAMPLE_COUNT = 672, + CREATEGRAPHICSPIPELINESTATE_INVALID_PRIMITIVETOPOLOGY = 673, + CREATEGRAPHICSPIPELINESTATE_INVALID_SYSTEMVALUE = 674, + CREATEGRAPHICSPIPELINESTATE_OM_DUAL_SOURCE_BLENDING_CAN_ONLY_HAVE_RENDER_TARGET_0 = 675, + CREATEGRAPHICSPIPELINESTATE_OM_RENDER_TARGET_DOES_NOT_SUPPORT_BLENDING = 676, + CREATEGRAPHICSPIPELINESTATE_PS_OUTPUT_TYPE_MISMATCH = 677, + CREATEGRAPHICSPIPELINESTATE_OM_RENDER_TARGET_DOES_NOT_SUPPORT_LOGIC_OPS = 678, + CREATEGRAPHICSPIPELINESTATE_RENDERTARGETVIEW_NOT_SET = 679, + CREATEGRAPHICSPIPELINESTATE_DEPTHSTENCILVIEW_NOT_SET = 680, + CREATEGRAPHICSPIPELINESTATE_GS_INPUT_PRIMITIVE_MISMATCH = 681, + CREATEGRAPHICSPIPELINESTATE_POSITION_NOT_PRESENT = 682, + CREATEGRAPHICSPIPELINESTATE_MISSING_ROOT_SIGNATURE_FLAGS = 683, + CREATEGRAPHICSPIPELINESTATE_INVALID_INDEX_BUFFER_PROPERTIES = 684, + CREATEGRAPHICSPIPELINESTATE_INVALID_SAMPLE_DESC = 685, + CREATEGRAPHICSPIPELINESTATE_HS_ROOT_SIGNATURE_MISMATCH = 686, + CREATEGRAPHICSPIPELINESTATE_DS_ROOT_SIGNATURE_MISMATCH = 687, + CREATEGRAPHICSPIPELINESTATE_VS_ROOT_SIGNATURE_MISMATCH = 688, + CREATEGRAPHICSPIPELINESTATE_GS_ROOT_SIGNATURE_MISMATCH = 689, + CREATEGRAPHICSPIPELINESTATE_PS_ROOT_SIGNATURE_MISMATCH = 690, + CREATEGRAPHICSPIPELINESTATE_MISSING_ROOT_SIGNATURE = 691, + EXECUTE_BUNDLE_OPEN_BUNDLE = 692, + EXECUTE_BUNDLE_DESCRIPTOR_HEAP_MISMATCH = 693, + EXECUTE_BUNDLE_TYPE = 694, + DRAW_EMPTY_SCISSOR_RECTANGLE = 695, + CREATE_ROOT_SIGNATURE_BLOB_NOT_FOUND = 696, + CREATE_ROOT_SIGNATURE_DESERIALIZE_FAILED = 697, + CREATE_ROOT_SIGNATURE_INVALID_CONFIGURATION = 698, + CREATE_ROOT_SIGNATURE_NOT_SUPPORTED_ON_DEVICE = 699, + CREATERESOURCEANDHEAP_NULLRESOURCEPROPERTIES = 700, + CREATERESOURCEANDHEAP_NULLHEAP = 701, + GETRESOURCEALLOCATIONINFO_INVALIDRDESCS = 702, + MAKERESIDENT_NULLOBJECTARRAY = 703, + EVICT_NULLOBJECTARRAY = 705, + SET_DESCRIPTOR_TABLE_INVALID = 708, + SET_ROOT_CONSTANT_INVALID = 709, + SET_ROOT_CONSTANT_BUFFER_VIEW_INVALID = 710, + SET_ROOT_SHADER_RESOURCE_VIEW_INVALID = 711, + SET_ROOT_UNORDERED_ACCESS_VIEW_INVALID = 712, + SET_VERTEX_BUFFERS_INVALID_DESC = 713, + SET_INDEX_BUFFER_INVALID_DESC = 715, + SET_STREAM_OUTPUT_BUFFERS_INVALID_DESC = 717, + CREATERESOURCE_UNRECOGNIZEDDIMENSIONALITY = 718, + CREATERESOURCE_UNRECOGNIZEDLAYOUT = 719, + CREATERESOURCE_INVALIDDIMENSIONALITY = 720, + CREATERESOURCE_INVALIDALIGNMENT = 721, + CREATERESOURCE_INVALIDMIPLEVELS = 722, + CREATERESOURCE_INVALIDSAMPLEDESC = 723, + CREATERESOURCE_INVALIDLAYOUT = 724, + SET_INDEX_BUFFER_INVALID = 725, + SET_VERTEX_BUFFERS_INVALID = 726, + SET_STREAM_OUTPUT_BUFFERS_INVALID = 727, + SET_RENDER_TARGETS_INVALID = 728, + CREATEQUERY_HEAP_INVALID_PARAMETERS = 729, + BEGIN_END_QUERY_INVALID_PARAMETERS = 731, + CLOSE_COMMAND_LIST_OPEN_QUERY = 732, + RESOLVE_QUERY_DATA_INVALID_PARAMETERS = 733, + SET_PREDICATION_INVALID_PARAMETERS = 734, + TIMESTAMPS_NOT_SUPPORTED = 735, + CREATERESOURCE_UNRECOGNIZEDFORMAT = 737, + CREATERESOURCE_INVALIDFORMAT = 738, + GETCOPYABLEFOOTPRINTS_INVALIDSUBRESOURCERANGE = 739, + GETCOPYABLEFOOTPRINTS_INVALIDBASEOFFSET = 740, + GETCOPYABLELAYOUT_INVALIDSUBRESOURCERANGE = 739, + GETCOPYABLELAYOUT_INVALIDBASEOFFSET = 740, + RESOURCE_BARRIER_INVALID_HEAP = 741, + CREATE_SAMPLER_INVALID = 742, + CREATECOMMANDSIGNATURE_INVALID = 743, + EXECUTE_INDIRECT_INVALID_PARAMETERS = 744, + GETGPUVIRTUALADDRESS_INVALID_RESOURCE_DIMENSION = 745, + CREATERESOURCE_INVALIDCLEARVALUE = 815, + CREATERESOURCE_UNRECOGNIZEDCLEARVALUEFORMAT = 816, + CREATERESOURCE_INVALIDCLEARVALUEFORMAT = 817, + CREATERESOURCE_CLEARVALUEDENORMFLUSH = 818, + CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE = 820, + CLEARDEPTHSTENCILVIEW_MISMATCHINGCLEARVALUE = 821, + MAP_INVALIDHEAP = 822, + UNMAP_INVALIDHEAP = 823, + MAP_INVALIDRESOURCE = 824, + UNMAP_INVALIDRESOURCE = 825, + MAP_INVALIDSUBRESOURCE = 826, + UNMAP_INVALIDSUBRESOURCE = 827, + MAP_INVALIDRANGE = 828, + UNMAP_INVALIDRANGE = 829, + MAP_INVALIDDATAPOINTER = 832, + MAP_INVALIDARG_RETURN = 833, + MAP_OUTOFMEMORY_RETURN = 834, + EXECUTECOMMANDLISTS_BUNDLENOTSUPPORTED = 835, + EXECUTECOMMANDLISTS_COMMANDLISTMISMATCH = 836, + EXECUTECOMMANDLISTS_OPENCOMMANDLIST = 837, + EXECUTECOMMANDLISTS_FAILEDCOMMANDLIST = 838, + COPYBUFFERREGION_NULLDST = 839, + COPYBUFFERREGION_INVALIDDSTRESOURCEDIMENSION = 840, + COPYBUFFERREGION_DSTRANGEOUTOFBOUNDS = 841, + COPYBUFFERREGION_NULLSRC = 842, + COPYBUFFERREGION_INVALIDSRCRESOURCEDIMENSION = 843, + COPYBUFFERREGION_SRCRANGEOUTOFBOUNDS = 844, + COPYBUFFERREGION_INVALIDCOPYFLAGS = 845, + COPYTEXTUREREGION_NULLDST = 846, + COPYTEXTUREREGION_UNRECOGNIZEDDSTTYPE = 847, + COPYTEXTUREREGION_INVALIDDSTRESOURCEDIMENSION = 848, + COPYTEXTUREREGION_INVALIDDSTRESOURCE = 849, + COPYTEXTUREREGION_INVALIDDSTSUBRESOURCE = 850, + COPYTEXTUREREGION_INVALIDDSTOFFSET = 851, + COPYTEXTUREREGION_UNRECOGNIZEDDSTFORMAT = 852, + COPYTEXTUREREGION_INVALIDDSTFORMAT = 853, + COPYTEXTUREREGION_INVALIDDSTDIMENSIONS = 854, + COPYTEXTUREREGION_INVALIDDSTROWPITCH = 855, + COPYTEXTUREREGION_INVALIDDSTPLACEMENT = 856, + COPYTEXTUREREGION_INVALIDDSTDSPLACEDFOOTPRINTFORMAT = 857, + COPYTEXTUREREGION_DSTREGIONOUTOFBOUNDS = 858, + COPYTEXTUREREGION_NULLSRC = 859, + COPYTEXTUREREGION_UNRECOGNIZEDSRCTYPE = 860, + COPYTEXTUREREGION_INVALIDSRCRESOURCEDIMENSION = 861, + COPYTEXTUREREGION_INVALIDSRCRESOURCE = 862, + COPYTEXTUREREGION_INVALIDSRCSUBRESOURCE = 863, + COPYTEXTUREREGION_INVALIDSRCOFFSET = 864, + COPYTEXTUREREGION_UNRECOGNIZEDSRCFORMAT = 865, + COPYTEXTUREREGION_INVALIDSRCFORMAT = 866, + COPYTEXTUREREGION_INVALIDSRCDIMENSIONS = 867, + COPYTEXTUREREGION_INVALIDSRCROWPITCH = 868, + COPYTEXTUREREGION_INVALIDSRCPLACEMENT = 869, + COPYTEXTUREREGION_INVALIDSRCDSPLACEDFOOTPRINTFORMAT = 870, + COPYTEXTUREREGION_SRCREGIONOUTOFBOUNDS = 871, + COPYTEXTUREREGION_INVALIDDSTCOORDINATES = 872, + COPYTEXTUREREGION_INVALIDSRCBOX = 873, + COPYTEXTUREREGION_FORMATMISMATCH = 874, + COPYTEXTUREREGION_EMPTYBOX = 875, + COPYTEXTUREREGION_INVALIDCOPYFLAGS = 876, + RESOLVESUBRESOURCE_INVALID_SUBRESOURCE_INDEX = 877, + RESOLVESUBRESOURCE_INVALID_FORMAT = 878, + RESOLVESUBRESOURCE_RESOURCE_MISMATCH = 879, + RESOLVESUBRESOURCE_INVALID_SAMPLE_COUNT = 880, + CREATECOMPUTEPIPELINESTATE_INVALID_SHADER = 881, + CREATECOMPUTEPIPELINESTATE_CS_ROOT_SIGNATURE_MISMATCH = 882, + CREATECOMPUTEPIPELINESTATE_MISSING_ROOT_SIGNATURE = 883, + CREATEPIPELINESTATE_INVALIDCACHEDBLOB = 884, + CREATEPIPELINESTATE_CACHEDBLOBADAPTERMISMATCH = 885, + CREATEPIPELINESTATE_CACHEDBLOBDRIVERVERSIONMISMATCH = 886, + CREATEPIPELINESTATE_CACHEDBLOBDESCMISMATCH = 887, + CREATEPIPELINESTATE_CACHEDBLOBIGNORED = 888, + WRITETOSUBRESOURCE_INVALIDHEAP = 889, + WRITETOSUBRESOURCE_INVALIDRESOURCE = 890, + WRITETOSUBRESOURCE_INVALIDBOX = 891, + WRITETOSUBRESOURCE_INVALIDSUBRESOURCE = 892, + WRITETOSUBRESOURCE_EMPTYBOX = 893, + READFROMSUBRESOURCE_INVALIDHEAP = 894, + READFROMSUBRESOURCE_INVALIDRESOURCE = 895, + READFROMSUBRESOURCE_INVALIDBOX = 896, + READFROMSUBRESOURCE_INVALIDSUBRESOURCE = 897, + READFROMSUBRESOURCE_EMPTYBOX = 898, + TOO_MANY_NODES_SPECIFIED = 899, + INVALID_NODE_INDEX = 900, + GETHEAPPROPERTIES_INVALIDRESOURCE = 901, + NODE_MASK_MISMATCH = 902, + COMMAND_LIST_OUTOFMEMORY = 903, + COMMAND_LIST_MULTIPLE_SWAPCHAIN_BUFFER_REFERENCES = 904, + COMMAND_LIST_TOO_MANY_SWAPCHAIN_REFERENCES = 905, + COMMAND_QUEUE_TOO_MANY_SWAPCHAIN_REFERENCES = 906, + EXECUTECOMMANDLISTS_WRONGSWAPCHAINBUFFERREFERENCE = 907, + COMMAND_LIST_SETRENDERTARGETS_INVALIDNUMRENDERTARGETS = 908, + CREATE_QUEUE_INVALID_TYPE = 909, + CREATE_QUEUE_INVALID_FLAGS = 910, + CREATESHAREDRESOURCE_INVALIDFLAGS = 911, + CREATESHAREDRESOURCE_INVALIDFORMAT = 912, + CREATESHAREDHEAP_INVALIDFLAGS = 913, + REFLECTSHAREDPROPERTIES_UNRECOGNIZEDPROPERTIES = 914, + REFLECTSHAREDPROPERTIES_INVALIDSIZE = 915, + REFLECTSHAREDPROPERTIES_INVALIDOBJECT = 916, + KEYEDMUTEX_INVALIDOBJECT = 917, + KEYEDMUTEX_INVALIDKEY = 918, + KEYEDMUTEX_WRONGSTATE = 919, + CREATE_QUEUE_INVALID_PRIORITY = 920, + OBJECT_DELETED_WHILE_STILL_IN_USE = 921, + CREATEPIPELINESTATE_INVALID_FLAGS = 922, + HEAP_ADDRESS_RANGE_HAS_NO_RESOURCE = 923, + COMMAND_LIST_DRAW_RENDER_TARGET_DELETED = 924, + CREATEGRAPHICSPIPELINESTATE_ALL_RENDER_TARGETS_HAVE_UNKNOWN_FORMAT = 925, + HEAP_ADDRESS_RANGE_INTERSECTS_MULTIPLE_BUFFERS = 926, + EXECUTECOMMANDLISTS_GPU_WRITTEN_READBACK_RESOURCE_MAPPED = 927, + UNMAP_RANGE_NOT_EMPTY = 929, + MAP_INVALID_NULLRANGE = 930, + UNMAP_INVALID_NULLRANGE = 931, + NO_GRAPHICS_API_SUPPORT = 932, + NO_COMPUTE_API_SUPPORT = 933, + RESOLVESUBRESOURCE_RESOURCE_FLAGS_NOT_SUPPORTED = 934, + GPU_BASED_VALIDATION_ROOT_ARGUMENT_UNINITIALIZED = 935, + GPU_BASED_VALIDATION_DESCRIPTOR_HEAP_INDEX_OUT_OF_BOUNDS = 936, + GPU_BASED_VALIDATION_DESCRIPTOR_TABLE_REGISTER_INDEX_OUT_OF_BOUNDS = 937, + GPU_BASED_VALIDATION_DESCRIPTOR_UNINITIALIZED = 938, + GPU_BASED_VALIDATION_DESCRIPTOR_TYPE_MISMATCH = 939, + GPU_BASED_VALIDATION_SRV_RESOURCE_DIMENSION_MISMATCH = 940, + GPU_BASED_VALIDATION_UAV_RESOURCE_DIMENSION_MISMATCH = 941, + GPU_BASED_VALIDATION_INCOMPATIBLE_RESOURCE_STATE = 942, + COPYRESOURCE_NULLDST = 943, + COPYRESOURCE_INVALIDDSTRESOURCE = 944, + COPYRESOURCE_NULLSRC = 945, + COPYRESOURCE_INVALIDSRCRESOURCE = 946, + RESOLVESUBRESOURCE_NULLDST = 947, + RESOLVESUBRESOURCE_INVALIDDSTRESOURCE = 948, + RESOLVESUBRESOURCE_NULLSRC = 949, + RESOLVESUBRESOURCE_INVALIDSRCRESOURCE = 950, + PIPELINE_STATE_TYPE_MISMATCH = 951, + COMMAND_LIST_DISPATCH_ROOT_SIGNATURE_NOT_SET = 952, + COMMAND_LIST_DISPATCH_ROOT_SIGNATURE_MISMATCH = 953, + RESOURCE_BARRIER_ZERO_BARRIERS = 954, + BEGIN_END_EVENT_MISMATCH = 955, + RESOURCE_BARRIER_POSSIBLE_BEFORE_AFTER_MISMATCH = 956, + RESOURCE_BARRIER_MISMATCHING_BEGIN_END = 957, + GPU_BASED_VALIDATION_INVALID_RESOURCE = 958, + USE_OF_ZERO_REFCOUNT_OBJECT = 959, + OBJECT_EVICTED_WHILE_STILL_IN_USE = 960, + GPU_BASED_VALIDATION_ROOT_DESCRIPTOR_ACCESS_OUT_OF_BOUNDS = 961, + CREATEPIPELINELIBRARY_INVALIDLIBRARYBLOB = 962, + CREATEPIPELINELIBRARY_DRIVERVERSIONMISMATCH = 963, + CREATEPIPELINELIBRARY_ADAPTERVERSIONMISMATCH = 964, + CREATEPIPELINELIBRARY_UNSUPPORTED = 965, + CREATE_PIPELINELIBRARY = 966, + LIVE_PIPELINELIBRARY = 967, + DESTROY_PIPELINELIBRARY = 968, + STOREPIPELINE_NONAME = 969, + STOREPIPELINE_DUPLICATENAME = 970, + LOADPIPELINE_NAMENOTFOUND = 971, + LOADPIPELINE_INVALIDDESC = 972, + PIPELINELIBRARY_SERIALIZE_NOTENOUGHMEMORY = 973, + CREATEGRAPHICSPIPELINESTATE_PS_OUTPUT_RT_OUTPUT_MISMATCH = 974, + SETEVENTONMULTIPLEFENCECOMPLETION_INVALIDFLAGS = 975, + CREATE_QUEUE_VIDEO_NOT_SUPPORTED = 976, + CREATE_COMMAND_ALLOCATOR_VIDEO_NOT_SUPPORTED = 977, + CREATEQUERY_HEAP_VIDEO_DECODE_STATISTICS_NOT_SUPPORTED = 978, + CREATE_VIDEODECODECOMMANDLIST = 979, + CREATE_VIDEODECODER = 980, + CREATE_VIDEODECODESTREAM = 981, + LIVE_VIDEODECODECOMMANDLIST = 982, + LIVE_VIDEODECODER = 983, + LIVE_VIDEODECODESTREAM = 984, + DESTROY_VIDEODECODECOMMANDLIST = 985, + DESTROY_VIDEODECODER = 986, + DESTROY_VIDEODECODESTREAM = 987, + DECODE_FRAME_INVALID_PARAMETERS = 988, + DEPRECATED_API = 989, + RESOURCE_BARRIER_MISMATCHING_COMMAND_LIST_TYPE = 990, + COMMAND_LIST_DESCRIPTOR_TABLE_NOT_SET = 991, + COMMAND_LIST_ROOT_CONSTANT_BUFFER_VIEW_NOT_SET = 992, + COMMAND_LIST_ROOT_SHADER_RESOURCE_VIEW_NOT_SET = 993, + COMMAND_LIST_ROOT_UNORDERED_ACCESS_VIEW_NOT_SET = 994, + DISCARD_INVALID_SUBRESOURCE_RANGE = 995, + DISCARD_ONE_SUBRESOURCE_FOR_MIPS_WITH_RECTS = 996, + DISCARD_NO_RECTS_FOR_NON_TEXTURE2D = 997, + COPY_ON_SAME_SUBRESOURCE = 998, + SETRESIDENCYPRIORITY_INVALID_PAGEABLE = 999, + GPU_BASED_VALIDATION_UNSUPPORTED = 1000, + STATIC_DESCRIPTOR_INVALID_DESCRIPTOR_CHANGE = 1001, + DATA_STATIC_DESCRIPTOR_INVALID_DATA_CHANGE = 1002, + DATA_STATIC_WHILE_SET_AT_EXECUTE_DESCRIPTOR_INVALID_DATA_CHANGE = 1003, + EXECUTE_BUNDLE_STATIC_DESCRIPTOR_DATA_STATIC_NOT_SET = 1004, + GPU_BASED_VALIDATION_RESOURCE_ACCESS_OUT_OF_BOUNDS = 1005, + GPU_BASED_VALIDATION_SAMPLER_MODE_MISMATCH = 1006, + CREATE_FENCE_INVALID_FLAGS = 1007, + RESOURCE_BARRIER_DUPLICATE_SUBRESOURCE_TRANSITIONS = 1008, + SETRESIDENCYPRIORITY_INVALID_PRIORITY = 1009, + CREATE_DESCRIPTOR_HEAP_LARGE_NUM_DESCRIPTORS = 1013, + BEGIN_EVENT = 1014, + END_EVENT = 1015, + CREATEDEVICE_DEBUG_LAYER_STARTUP_OPTIONS = 1016, + CREATEDEPTHSTENCILSTATE_DEPTHBOUNDSTEST_UNSUPPORTED = 1017, + CREATEPIPELINESTATE_DUPLICATE_SUBOBJECT = 1018, + CREATEPIPELINESTATE_UNKNOWN_SUBOBJECT = 1019, + CREATEPIPELINESTATE_ZERO_SIZE_STREAM = 1020, + CREATEPIPELINESTATE_INVALID_STREAM = 1021, + CREATEPIPELINESTATE_CANNOT_DEDUCE_TYPE = 1022, + COMMAND_LIST_STATIC_DESCRIPTOR_RESOURCE_DIMENSION_MISMATCH = 1023, + CREATE_COMMAND_QUEUE_INSUFFICIENT_PRIVILEGE_FOR_GLOBAL_REALTIME = 1024, + CREATE_COMMAND_QUEUE_INSUFFICIENT_HARDWARE_SUPPORT_FOR_GLOBAL_REALTIME = 1025, + ATOMICCOPYBUFFER_INVALID_ARCHITECTURE = 1026, + ATOMICCOPYBUFFER_NULL_DST = 1027, + ATOMICCOPYBUFFER_INVALID_DST_RESOURCE_DIMENSION = 1028, + ATOMICCOPYBUFFER_DST_RANGE_OUT_OF_BOUNDS = 1029, + ATOMICCOPYBUFFER_NULL_SRC = 1030, + ATOMICCOPYBUFFER_INVALID_SRC_RESOURCE_DIMENSION = 1031, + ATOMICCOPYBUFFER_SRC_RANGE_OUT_OF_BOUNDS = 1032, + ATOMICCOPYBUFFER_INVALID_OFFSET_ALIGNMENT = 1033, + ATOMICCOPYBUFFER_NULL_DEPENDENT_RESOURCES = 1034, + ATOMICCOPYBUFFER_NULL_DEPENDENT_SUBRESOURCE_RANGES = 1035, + ATOMICCOPYBUFFER_INVALID_DEPENDENT_RESOURCE = 1036, + ATOMICCOPYBUFFER_INVALID_DEPENDENT_SUBRESOURCE_RANGE = 1037, + ATOMICCOPYBUFFER_DEPENDENT_SUBRESOURCE_OUT_OF_BOUNDS = 1038, + ATOMICCOPYBUFFER_DEPENDENT_RANGE_OUT_OF_BOUNDS = 1039, + ATOMICCOPYBUFFER_ZERO_DEPENDENCIES = 1040, + DEVICE_CREATE_SHARED_HANDLE_INVALIDARG = 1041, + DESCRIPTOR_HANDLE_WITH_INVALID_RESOURCE = 1042, + SETDEPTHBOUNDS_INVALIDARGS = 1043, + GPU_BASED_VALIDATION_RESOURCE_STATE_IMPRECISE = 1044, + COMMAND_LIST_PIPELINE_STATE_NOT_SET = 1045, + CREATEGRAPHICSPIPELINESTATE_SHADER_MODEL_MISMATCH = 1046, + OBJECT_ACCESSED_WHILE_STILL_IN_USE = 1047, + PROGRAMMABLE_MSAA_UNSUPPORTED = 1048, + SETSAMPLEPOSITIONS_INVALIDARGS = 1049, + RESOLVESUBRESOURCEREGION_INVALID_RECT = 1050, + CREATE_VIDEODECODECOMMANDQUEUE = 1051, + CREATE_VIDEOPROCESSCOMMANDLIST = 1052, + CREATE_VIDEOPROCESSCOMMANDQUEUE = 1053, + LIVE_VIDEODECODECOMMANDQUEUE = 1054, + LIVE_VIDEOPROCESSCOMMANDLIST = 1055, + LIVE_VIDEOPROCESSCOMMANDQUEUE = 1056, + DESTROY_VIDEODECODECOMMANDQUEUE = 1057, + DESTROY_VIDEOPROCESSCOMMANDLIST = 1058, + DESTROY_VIDEOPROCESSCOMMANDQUEUE = 1059, + CREATE_VIDEOPROCESSOR = 1060, + CREATE_VIDEOPROCESSSTREAM = 1061, + LIVE_VIDEOPROCESSOR = 1062, + LIVE_VIDEOPROCESSSTREAM = 1063, + DESTROY_VIDEOPROCESSOR = 1064, + DESTROY_VIDEOPROCESSSTREAM = 1065, + PROCESS_FRAME_INVALID_PARAMETERS = 1066, + COPY_INVALIDLAYOUT = 1067, + CREATE_CRYPTO_SESSION = 1068, + CREATE_CRYPTO_SESSION_POLICY = 1069, + CREATE_PROTECTED_RESOURCE_SESSION = 1070, + LIVE_CRYPTO_SESSION = 1071, + LIVE_CRYPTO_SESSION_POLICY = 1072, + LIVE_PROTECTED_RESOURCE_SESSION = 1073, + DESTROY_CRYPTO_SESSION = 1074, + DESTROY_CRYPTO_SESSION_POLICY = 1075, + DESTROY_PROTECTED_RESOURCE_SESSION = 1076, + PROTECTED_RESOURCE_SESSION_UNSUPPORTED = 1077, + FENCE_INVALIDOPERATION = 1078, + CREATEQUERY_HEAP_COPY_QUEUE_TIMESTAMPS_NOT_SUPPORTED = 1079, + SAMPLEPOSITIONS_MISMATCH_DEFERRED = 1080, + SAMPLEPOSITIONS_MISMATCH_RECORDTIME_ASSUMEDFROMFIRSTUSE = 1081, + SAMPLEPOSITIONS_MISMATCH_RECORDTIME_ASSUMEDFROMCLEAR = 1082, + CREATE_VIDEODECODERHEAP = 1083, + LIVE_VIDEODECODERHEAP = 1084, + DESTROY_VIDEODECODERHEAP = 1085, + OPENEXISTINGHEAP_INVALIDARG_RETURN = 1086, + OPENEXISTINGHEAP_OUTOFMEMORY_RETURN = 1087, + OPENEXISTINGHEAP_INVALIDADDRESS = 1088, + OPENEXISTINGHEAP_INVALIDHANDLE = 1089, + WRITEBUFFERIMMEDIATE_INVALID_DEST = 1090, + WRITEBUFFERIMMEDIATE_INVALID_MODE = 1091, + WRITEBUFFERIMMEDIATE_INVALID_ALIGNMENT = 1092, + WRITEBUFFERIMMEDIATE_NOT_SUPPORTED = 1093, + SETVIEWINSTANCEMASK_INVALIDARGS = 1094, + VIEW_INSTANCING_UNSUPPORTED = 1095, + VIEW_INSTANCING_INVALIDARGS = 1096, + COPYTEXTUREREGION_MISMATCH_DECODE_REFERENCE_ONLY_FLAG = 1097, + COPYRESOURCE_MISMATCH_DECODE_REFERENCE_ONLY_FLAG = 1098, + CREATE_VIDEO_DECODE_HEAP_CAPS_FAILURE = 1099, + CREATE_VIDEO_DECODE_HEAP_CAPS_UNSUPPORTED = 1100, + VIDEO_DECODE_SUPPORT_INVALID_INPUT = 1101, + CREATE_VIDEO_DECODER_UNSUPPORTED = 1102, + CREATEGRAPHICSPIPELINESTATE_METADATA_ERROR = 1103, + CREATEGRAPHICSPIPELINESTATE_VIEW_INSTANCING_VERTEX_SIZE_EXCEEDED = 1104, + CREATEGRAPHICSPIPELINESTATE_RUNTIME_INTERNAL_ERROR = 1105, + NO_VIDEO_API_SUPPORT = 1106, + VIDEO_PROCESS_SUPPORT_INVALID_INPUT = 1107, + CREATE_VIDEO_PROCESSOR_CAPS_FAILURE = 1108, + VIDEO_PROCESS_SUPPORT_UNSUPPORTED_FORMAT = 1109, + VIDEO_DECODE_FRAME_INVALID_ARGUMENT = 1110, + ENQUEUE_MAKE_RESIDENT_INVALID_FLAGS = 1111, + OPENEXISTINGHEAP_UNSUPPORTED = 1112, + VIDEO_PROCESS_FRAMES_INVALID_ARGUMENT = 1113, + VIDEO_DECODE_SUPPORT_UNSUPPORTED = 1114, + CREATE_COMMANDRECORDER = 1115, + LIVE_COMMANDRECORDER = 1116, + DESTROY_COMMANDRECORDER = 1117, + CREATE_COMMAND_RECORDER_VIDEO_NOT_SUPPORTED = 1118, + CREATE_COMMAND_RECORDER_INVALID_SUPPORT_FLAGS = 1119, + CREATE_COMMAND_RECORDER_INVALID_FLAGS = 1120, + CREATE_COMMAND_RECORDER_MORE_RECORDERS_THAN_LOGICAL_PROCESSORS = 1121, + CREATE_COMMANDPOOL = 1122, + LIVE_COMMANDPOOL = 1123, + DESTROY_COMMANDPOOL = 1124, + CREATE_COMMAND_POOL_INVALID_FLAGS = 1125, + CREATE_COMMAND_LIST_VIDEO_NOT_SUPPORTED = 1126, + COMMAND_RECORDER_SUPPORT_FLAGS_MISMATCH = 1127, + COMMAND_RECORDER_CONTENTION = 1128, + COMMAND_RECORDER_USAGE_WITH_CREATECOMMANDLIST_COMMAND_LIST = 1129, + COMMAND_ALLOCATOR_USAGE_WITH_CREATECOMMANDLIST1_COMMAND_LIST = 1130, + CANNOT_EXECUTE_EMPTY_COMMAND_LIST = 1131, + CANNOT_RESET_COMMAND_POOL_WITH_OPEN_COMMAND_LISTS = 1132, + CANNOT_USE_COMMAND_RECORDER_WITHOUT_CURRENT_TARGET = 1133, + CANNOT_CHANGE_COMMAND_RECORDER_TARGET_WHILE_RECORDING = 1134, + COMMAND_POOL_SYNC = 1135, + EVICT_UNDERFLOW = 1136, + CREATE_META_COMMAND = 1137, + LIVE_META_COMMAND = 1138, + DESTROY_META_COMMAND = 1139, + COPYBUFFERREGION_INVALID_DST_RESOURCE = 1140, + COPYBUFFERREGION_INVALID_SRC_RESOURCE = 1141, + ATOMICCOPYBUFFER_INVALID_DST_RESOURCE = 1142, + ATOMICCOPYBUFFER_INVALID_SRC_RESOURCE = 1143, + CREATEPLACEDRESOURCEONBUFFER_NULL_BUFFER = 1144, + CREATEPLACEDRESOURCEONBUFFER_NULL_RESOURCE_DESC = 1145, + CREATEPLACEDRESOURCEONBUFFER_UNSUPPORTED = 1146, + CREATEPLACEDRESOURCEONBUFFER_INVALID_BUFFER_DIMENSION = 1147, + CREATEPLACEDRESOURCEONBUFFER_INVALID_BUFFER_FLAGS = 1148, + CREATEPLACEDRESOURCEONBUFFER_INVALID_BUFFER_OFFSET = 1149, + CREATEPLACEDRESOURCEONBUFFER_INVALID_RESOURCE_DIMENSION = 1150, + CREATEPLACEDRESOURCEONBUFFER_INVALID_RESOURCE_FLAGS = 1151, + CREATEPLACEDRESOURCEONBUFFER_OUTOFMEMORY_RETURN = 1152, + CANNOT_CREATE_GRAPHICS_AND_VIDEO_COMMAND_RECORDER = 1153, + UPDATETILEMAPPINGS_POSSIBLY_MISMATCHING_PROPERTIES = 1154, + CREATE_COMMAND_LIST_INVALID_COMMAND_LIST_TYPE = 1155, + CLEARUNORDEREDACCESSVIEW_INCOMPATIBLE_WITH_STRUCTURED_BUFFERS = 1156, + COMPUTE_ONLY_DEVICE_OPERATION_UNSUPPORTED = 1157, + BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INVALID = 1158, + EMIT_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_INVALID = 1159, + COPY_RAYTRACING_ACCELERATION_STRUCTURE_INVALID = 1160, + DISPATCH_RAYS_INVALID = 1161, + GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_INVALID = 1162, + CREATE_LIFETIMETRACKER = 1163, + LIVE_LIFETIMETRACKER = 1164, + DESTROY_LIFETIMETRACKER = 1165, + DESTROYOWNEDOBJECT_OBJECTNOTOWNED = 1166, + CREATE_TRACKEDWORKLOAD = 1167, + LIVE_TRACKEDWORKLOAD = 1168, + DESTROY_TRACKEDWORKLOAD = 1169, + RENDER_PASS_ERROR = 1170, + META_COMMAND_ID_INVALID = 1171, + META_COMMAND_UNSUPPORTED_PARAMS = 1172, + META_COMMAND_FAILED_ENUMERATION = 1173, + META_COMMAND_PARAMETER_SIZE_MISMATCH = 1174, + UNINITIALIZED_META_COMMAND = 1175, + META_COMMAND_INVALID_GPU_VIRTUAL_ADDRESS = 1176, + CREATE_VIDEOENCODECOMMANDLIST = 1177, + LIVE_VIDEOENCODECOMMANDLIST = 1178, + DESTROY_VIDEOENCODECOMMANDLIST = 1179, + CREATE_VIDEOENCODECOMMANDQUEUE = 1180, + LIVE_VIDEOENCODECOMMANDQUEUE = 1181, + DESTROY_VIDEOENCODECOMMANDQUEUE = 1182, + CREATE_VIDEOMOTIONESTIMATOR = 1183, + LIVE_VIDEOMOTIONESTIMATOR = 1184, + DESTROY_VIDEOMOTIONESTIMATOR = 1185, + CREATE_VIDEOMOTIONVECTORHEAP = 1186, + LIVE_VIDEOMOTIONVECTORHEAP = 1187, + DESTROY_VIDEOMOTIONVECTORHEAP = 1188, + MULTIPLE_TRACKED_WORKLOADS = 1189, + MULTIPLE_TRACKED_WORKLOAD_PAIRS = 1190, + OUT_OF_ORDER_TRACKED_WORKLOAD_PAIR = 1191, + CANNOT_ADD_TRACKED_WORKLOAD = 1192, + INCOMPLETE_TRACKED_WORKLOAD_PAIR = 1193, + CREATE_STATE_OBJECT_ERROR = 1194, + GET_SHADER_IDENTIFIER_ERROR = 1195, + GET_SHADER_STACK_SIZE_ERROR = 1196, + GET_PIPELINE_STACK_SIZE_ERROR = 1197, + SET_PIPELINE_STACK_SIZE_ERROR = 1198, + GET_SHADER_IDENTIFIER_SIZE_INVALID = 1199, + CHECK_DRIVER_MATCHING_IDENTIFIER_INVALID = 1200, + CHECK_DRIVER_MATCHING_IDENTIFIER_DRIVER_REPORTED_ISSUE = 1201, + RENDER_PASS_INVALID_RESOURCE_BARRIER = 1202, + RENDER_PASS_DISALLOWED_API_CALLED = 1203, + RENDER_PASS_CANNOT_NEST_RENDER_PASSES = 1204, + RENDER_PASS_CANNOT_END_WITHOUT_BEGIN = 1205, + RENDER_PASS_CANNOT_CLOSE_COMMAND_LIST = 1206, + RENDER_PASS_GPU_WORK_WHILE_SUSPENDED = 1207, + RENDER_PASS_MISMATCHING_SUSPEND_RESUME = 1208, + RENDER_PASS_NO_PRIOR_SUSPEND_WITHIN_EXECUTECOMMANDLISTS = 1209, + RENDER_PASS_NO_SUBSEQUENT_RESUME_WITHIN_EXECUTECOMMANDLISTS = 1210, + TRACKED_WORKLOAD_COMMAND_QUEUE_MISMATCH = 1211, + TRACKED_WORKLOAD_NOT_SUPPORTED = 1212, + RENDER_PASS_MISMATCHING_NO_ACCESS = 1213, + RENDER_PASS_UNSUPPORTED_RESOLVE = 1214, + CLEARUNORDEREDACCESSVIEW_INVALID_RESOURCE_PTR = 1215, + WINDOWS7_FENCE_OUTOFORDER_SIGNAL = 1216, + WINDOWS7_FENCE_OUTOFORDER_WAIT = 1217, + VIDEO_CREATE_MOTION_ESTIMATOR_INVALID_ARGUMENT = 1218, + VIDEO_CREATE_MOTION_VECTOR_HEAP_INVALID_ARGUMENT = 1219, + ESTIMATE_MOTION_INVALID_ARGUMENT = 1220, + RESOLVE_MOTION_VECTOR_HEAP_INVALID_ARGUMENT = 1221, + GETGPUVIRTUALADDRESS_INVALID_HEAP_TYPE = 1222, + SET_BACKGROUND_PROCESSING_MODE_INVALID_ARGUMENT = 1223, + CREATE_COMMAND_LIST_INVALID_COMMAND_LIST_TYPE_FOR_FEATURE_LEVEL = 1224, + CREATE_VIDEOEXTENSIONCOMMAND = 1225, + LIVE_VIDEOEXTENSIONCOMMAND = 1226, + DESTROY_VIDEOEXTENSIONCOMMAND = 1227, + INVALID_VIDEO_EXTENSION_COMMAND_ID = 1228, + VIDEO_EXTENSION_COMMAND_INVALID_ARGUMENT = 1229, + CREATE_ROOT_SIGNATURE_NOT_UNIQUE_IN_DXIL_LIBRARY = 1230, + VARIABLE_SHADING_RATE_NOT_ALLOWED_WITH_TIR = 1231, + GEOMETRY_SHADER_OUTPUTTING_BOTH_VIEWPORT_ARRAY_INDEX_AND_SHADING_RATE_NOT_SUPPORTED_ON_DEVICE = 1232, + RSSETSHADING_RATE_INVALID_SHADING_RATE = 1233, + RSSETSHADING_RATE_SHADING_RATE_NOT_PERMITTED_BY_CAP = 1234, + RSSETSHADING_RATE_INVALID_COMBINER = 1235, + RSSETSHADINGRATEIMAGE_REQUIRES_TIER_2 = 1236, + RSSETSHADINGRATE_REQUIRES_TIER_1 = 1237, + SHADING_RATE_IMAGE_INCORRECT_FORMAT = 1238, + SHADING_RATE_IMAGE_INCORRECT_ARRAY_SIZE = 1239, + SHADING_RATE_IMAGE_INCORRECT_MIP_LEVEL = 1240, + SHADING_RATE_IMAGE_INCORRECT_SAMPLE_COUNT = 1241, + SHADING_RATE_IMAGE_INCORRECT_SAMPLE_QUALITY = 1242, + NON_RETAIL_SHADER_MODEL_WONT_VALIDATE = 1243, + CREATEGRAPHICSPIPELINESTATE_AS_ROOT_SIGNATURE_MISMATCH = 1244, + CREATEGRAPHICSPIPELINESTATE_MS_ROOT_SIGNATURE_MISMATCH = 1245, + ADD_TO_STATE_OBJECT_ERROR = 1246, + CREATE_PROTECTED_RESOURCE_SESSION_INVALID_ARGUMENT = 1247, + CREATEGRAPHICSPIPELINESTATE_MS_PSO_DESC_MISMATCH = 1248, + CREATEPIPELINESTATE_MS_INCOMPLETE_TYPE = 1249, + CREATEGRAPHICSPIPELINESTATE_AS_NOT_MS_MISMATCH = 1250, + CREATEGRAPHICSPIPELINESTATE_MS_NOT_PS_MISMATCH = 1251, + NONZERO_SAMPLER_FEEDBACK_MIP_REGION_WITH_INCOMPATIBLE_FORMAT = 1252, + CREATEGRAPHICSPIPELINESTATE_INPUTLAYOUT_SHADER_MISMATCH = 1253, + EMPTY_DISPATCH = 1254, + RESOURCE_FORMAT_REQUIRES_SAMPLER_FEEDBACK_CAPABILITY = 1255, + SAMPLER_FEEDBACK_MAP_INVALID_MIP_REGION = 1256, + SAMPLER_FEEDBACK_MAP_INVALID_DIMENSION = 1257, + SAMPLER_FEEDBACK_MAP_INVALID_SAMPLE_COUNT = 1258, + SAMPLER_FEEDBACK_MAP_INVALID_SAMPLE_QUALITY = 1259, + SAMPLER_FEEDBACK_MAP_INVALID_LAYOUT = 1260, + SAMPLER_FEEDBACK_MAP_REQUIRES_UNORDERED_ACCESS_FLAG = 1261, + SAMPLER_FEEDBACK_CREATE_UAV_NULL_ARGUMENTS = 1262, + SAMPLER_FEEDBACK_UAV_REQUIRES_SAMPLER_FEEDBACK_CAPABILITY = 1263, + SAMPLER_FEEDBACK_CREATE_UAV_REQUIRES_FEEDBACK_MAP_FORMAT = 1264, + CREATEMESHSHADER_INVALIDSHADERBYTECODE = 1265, + CREATEMESHSHADER_OUTOFMEMORY = 1266, + CREATEMESHSHADERWITHSTREAMOUTPUT_INVALIDSHADERTYPE = 1267, + RESOLVESUBRESOURCE_SAMPLER_FEEDBACK_TRANSCODE_INVALID_FORMAT = 1268, + RESOLVESUBRESOURCE_SAMPLER_FEEDBACK_INVALID_MIP_LEVEL_COUNT = 1269, + RESOLVESUBRESOURCE_SAMPLER_FEEDBACK_TRANSCODE_ARRAY_SIZE_MISMATCH = 1270, + SAMPLER_FEEDBACK_CREATE_UAV_MISMATCHING_TARGETED_RESOURCE = 1271, + CREATEMESHSHADER_OUTPUTEXCEEDSMAXSIZE = 1272, + CREATEMESHSHADER_GROUPSHAREDEXCEEDSMAXSIZE = 1273, + VERTEX_SHADER_OUTPUTTING_BOTH_VIEWPORT_ARRAY_INDEX_AND_SHADING_RATE_NOT_SUPPORTED_ON_DEVICE = 1274, + MESH_SHADER_OUTPUTTING_BOTH_VIEWPORT_ARRAY_INDEX_AND_SHADING_RATE_NOT_SUPPORTED_ON_DEVICE = 1275, + CREATEMESHSHADER_MISMATCHEDASMSPAYLOADSIZE = 1276, + CREATE_ROOT_SIGNATURE_UNBOUNDED_STATIC_DESCRIPTORS = 1277, + CREATEAMPLIFICATIONSHADER_INVALIDSHADERBYTECODE = 1278, + CREATEAMPLIFICATIONSHADER_OUTOFMEMORY = 1279, + MESSAGES_END = 1280, +} + +MESSAGE :: struct { + Category: MESSAGE_CATEGORY, + Severity: MESSAGE_SEVERITY, + ID: MESSAGE_ID, + pDescription: cstring, + DescriptionByteLength: SIZE_T, +} + +INFO_QUEUE_FILTER_DESC :: struct { + NumCategories: u32, + pCategoryList: ^MESSAGE_CATEGORY, + NumSeverities: u32, + pSeverityList: ^MESSAGE_SEVERITY, + NumIDs: u32, + pIDList: ^MESSAGE_ID, +} + +INFO_QUEUE_FILTER :: struct { + AllowList: INFO_QUEUE_FILTER_DESC, + DenyList: INFO_QUEUE_FILTER_DESC, +} + + +IInfoQueue_UUID :: "0742a90b-c387-483f-b946-30a7e4e61458" +IInfoQueue :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12infoqueue_vtable: ^IInfoQueue_VTable, +} +IInfoQueue_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + SetMessageCountLimit: proc "stdcall" (this: ^IInfoQueue, MessageCountLimit: u64) -> HRESULT, + ClearStoredMessages: proc "stdcall" (this: ^IInfoQueue), + GetMessageA: proc "stdcall" (this: ^IInfoQueue, MessageIndex: u64, pMessage: ^MESSAGE, pMessageByteLength: ^SIZE_T) -> HRESULT, + GetNumMessagesAllowedByStorageFilter: proc "stdcall" (this: ^IInfoQueue) -> u64, + GetNumMessagesDeniedByStorageFilter: proc "stdcall" (this: ^IInfoQueue) -> u64, + GetNumStoredMessages: proc "stdcall" (this: ^IInfoQueue) -> u64, + GetNumStoredMessagesAllowedByRetrievalFilter: proc "stdcall" (this: ^IInfoQueue) -> u64, + GetNumMessagesDiscardedByMessageCountLimit: proc "stdcall" (this: ^IInfoQueue) -> u64, + GetMessageCountLimit: proc "stdcall" (this: ^IInfoQueue) -> u64, + AddStorageFilterEntries: proc "stdcall" (this: ^IInfoQueue, pFilter: ^INFO_QUEUE_FILTER) -> HRESULT, + GetStorageFilter: proc "stdcall" (this: ^IInfoQueue, pFilter: ^INFO_QUEUE_FILTER, pFilterByteLength: ^SIZE_T) -> HRESULT, + ClearStorageFilter: proc "stdcall" (this: ^IInfoQueue), + PushEmptyStorageFilter: proc "stdcall" (this: ^IInfoQueue) -> HRESULT, + PushCopyOfStorageFilter: proc "stdcall" (this: ^IInfoQueue) -> HRESULT, + PushStorageFilter: proc "stdcall" (this: ^IInfoQueue, pFilter: ^INFO_QUEUE_FILTER) -> HRESULT, + PopStorageFilter: proc "stdcall" (this: ^IInfoQueue), + GetStorageFilterStackSize: proc "stdcall" (this: ^IInfoQueue) -> u32, + AddRetrievalFilterEntries: proc "stdcall" (this: ^IInfoQueue, pFilter: ^INFO_QUEUE_FILTER) -> HRESULT, + GetRetrievalFilter: proc "stdcall" (this: ^IInfoQueue, pFilter: ^INFO_QUEUE_FILTER, pFilterByteLength: ^SIZE_T) -> HRESULT, + ClearRetrievalFilter: proc "stdcall" (this: ^IInfoQueue), + PushEmptyRetrievalFilter: proc "stdcall" (this: ^IInfoQueue) -> HRESULT, + PushCopyOfRetrievalFilter: proc "stdcall" (this: ^IInfoQueue) -> HRESULT, + PushRetrievalFilter: proc "stdcall" (this: ^IInfoQueue, pFilter: ^INFO_QUEUE_FILTER) -> HRESULT, + PopRetrievalFilter: proc "stdcall" (this: ^IInfoQueue), + GetRetrievalFilterStackSize: proc "stdcall" (this: ^IInfoQueue) -> u32, + AddMessage: proc "stdcall" (this: ^IInfoQueue, Category: MESSAGE_CATEGORY, Severity: MESSAGE_SEVERITY, ID: MESSAGE_ID, pDescription: cstring) -> HRESULT, + AddApplicationMessage: proc "stdcall" (this: ^IInfoQueue, Severity: MESSAGE_SEVERITY, pDescription: cstring) -> HRESULT, + SetBreakOnCategory: proc "stdcall" (this: ^IInfoQueue, Category: MESSAGE_CATEGORY, bEnable: BOOL) -> HRESULT, + SetBreakOnSeverity: proc "stdcall" (this: ^IInfoQueue, Severity: MESSAGE_SEVERITY, bEnable: BOOL) -> HRESULT, + SetBreakOnID: proc "stdcall" (this: ^IInfoQueue, ID: MESSAGE_ID, bEnable: BOOL) -> HRESULT, + GetBreakOnCategory: proc "stdcall" (this: ^IInfoQueue, Category: MESSAGE_CATEGORY) -> BOOL, + GetBreakOnSeverity: proc "stdcall" (this: ^IInfoQueue, Severity: MESSAGE_SEVERITY) -> BOOL, + GetBreakOnID: proc "stdcall" (this: ^IInfoQueue, ID: MESSAGE_ID) -> BOOL, + SetMuteDebugOutput: proc "stdcall" (this: ^IInfoQueue, bMute: BOOL), + GetMuteDebugOutput: proc "stdcall" (this: ^IInfoQueue) -> BOOL, +} + +PFN_CREATE_DEVICE :: #type proc "c" (a0: ^IUnknown, a1: FEATURE_LEVEL, a2: ^IID, a3: ^rawptr) -> HRESULT +PFN_GET_DEBUG_INTERFACE :: #type proc "c" (a0: ^IID, a1: ^rawptr) -> HRESULT + +AXIS_SHADING_RATE :: enum i32 { + _1X = 0, + _2X = 1, + _4X = 2, +} + +SHADING_RATE :: enum i32 { + _1X1 = 0, + _1X2 = 1, + _2X1 = 4, + _2X2 = 5, + _2X4 = 6, + _4X2 = 9, + _4X4 = 10, +} + +SHADING_RATE_COMBINER :: enum i32 { + PASSTHROUGH = 0, + OVERRIDE = 1, + MIN = 2, + MAX = 3, + SUM = 4, +} + + +IGraphicsCommandList5_UUID :: "55050859-4024-474c-87f5-6472eaee44ea" +IGraphicsCommandList5 :: struct #raw_union { + #subtype id3d12graphicscommandlist4: IGraphicsCommandList4, + using id3d12graphicscommandlist5_vtable: ^IGraphicsCommandList5_VTable, +} +IGraphicsCommandList5_VTable :: struct { + using id3d12graphicscommandlist4_vtable: IGraphicsCommandList4_VTable, + RSSetShadingRate: proc "stdcall" (this: ^IGraphicsCommandList5, baseShadingRate: SHADING_RATE, combiners: ^SHADING_RATE_COMBINER), + RSSetShadingRateImage: proc "stdcall" (this: ^IGraphicsCommandList5, shadingRateImage: ^IResource), +} + +DISPATCH_MESH_ARGUMENTS :: struct { + ThreadGroupCountX: u32, + ThreadGroupCountY: u32, + ThreadGroupCountZ: u32, +} + + +IGraphicsCommandList6_UUID :: "c3827890-e548-4cfa-96cf-5689a9370f80" +IGraphicsCommandList6 :: struct #raw_union { + #subtype id3d12graphicscommandlist5: IGraphicsCommandList5, + using id3d12graphicscommandlist6_vtable: ^IGraphicsCommandList6_VTable, +} +IGraphicsCommandList6_VTable :: struct { + using id3d12graphicscommandlist5_vtable: IGraphicsCommandList5_VTable, + DispatchMesh: proc "stdcall" (this: ^IGraphicsCommandList6, ThreadGroupCountX: u32, ThreadGroupCountY: u32, ThreadGroupCountZ: u32), +} + +SHADER_VERSION_TYPE :: enum i32 { + PIXEL_SHADER = 0, + VERTEX_SHADER = 1, + GEOMETRY_SHADER = 2, + + HULL_SHADER = 3, + DOMAIN_SHADER = 4, + COMPUTE_SHADER = 5, + + RESERVED0 = 65520, +} + +SIGNATURE_PARAMETER_DESC :: struct { + SemanticName: cstring, + SemanticIndex: u32, + Register: u32, + SystemValueType: NAME, + ComponentType: REGISTER_COMPONENT_TYPE, + Mask: u8, + + ReadWriteMask: u8, + + Stream: u32, + MinPrecision: MIN_PRECISION, +} + +SHADER_BUFFER_DESC :: struct { + Name: cstring, + Type: CBUFFER_TYPE, + Variables: u32, + Size: u32, + uFlags: u32, +} + +SHADER_VARIABLE_DESC :: struct { + Name: cstring, + StartOffset: u32, + Size: u32, + uFlags: u32, + DefaultValue: rawptr, + StartTexture: u32, + TextureSize: u32, + StartSampler: u32, + SamplerSize: u32, +} + +SHADER_TYPE_DESC :: struct { + Class: SHADER_VARIABLE_CLASS, + Type: SHADER_VARIABLE_TYPE, + Rows: u32, + Columns: u32, + Elements: u32, + Members: u32, + Offset: u32, + Name: cstring, +} +SHADER_DESC :: struct { + Version: u32, + Creator: cstring, + Flags: u32, + + ConstantBuffers: u32, + BoundResources: u32, + InputParameters: u32, + OutputParameters: u32, + + InstructionCount: u32, + TempRegisterCount: u32, + TempArrayCount: u32, + DefCount: u32, + DclCount: u32, + TextureNormalInstructions: u32, + TextureLoadInstructions: u32, + TextureCompInstructions: u32, + TextureBiasInstructions: u32, + TextureGradientInstructions: u32, + FloatInstructionCount: u32, + IntInstructionCount: u32, + UintInstructionCount: u32, + StaticFlowControlCount: u32, + DynamicFlowControlCount: u32, + MacroInstructionCount: u32, + ArrayInstructionCount: u32, + CutInstructionCount: u32, + EmitInstructionCount: u32, + GSOutputTopology: PRIMITIVE_TOPOLOGY, + GSMaxOutputVertexCount: u32, + InputPrimitive: PRIMITIVE, + PatchConstantParameters: u32, + cGSInstanceCount: u32, + cControlPoints: u32, + HSOutputPrimitive: TESSELLATOR_OUTPUT_PRIMITIVE, + HSPartitioning: TESSELLATOR_PARTITIONING, + TessellatorDomain: TESSELLATOR_DOMAIN, + + cBarrierInstructions: u32, + cInterlockedInstructions: u32, + cTextureStoreInstructions: u32, +} + +SHADER_INPUT_BIND_DESC :: struct { + Name: cstring, + Type: SHADER_INPUT_TYPE, + BindPoint: u32, + BindCount: u32, + + uFlags: u32, + ReturnType: RESOURCE_RETURN_TYPE, + Dimension: SRV_DIMENSION, + NumSamples: u32, + Space: u32, + uID: u32, +} + +LIBRARY_DESC :: struct { + Creator: cstring, + Flags: u32, + FunctionCount: u32, +} + +FUNCTION_DESC :: struct { + Version: u32, + Creator: cstring, + Flags: u32, + + ConstantBuffers: u32, + BoundResources: u32, + + InstructionCount: u32, + TempRegisterCount: u32, + TempArrayCount: u32, + DefCount: u32, + DclCount: u32, + TextureNormalInstructions: u32, + TextureLoadInstructions: u32, + TextureCompInstructions: u32, + TextureBiasInstructions: u32, + TextureGradientInstructions: u32, + FloatInstructionCount: u32, + IntInstructionCount: u32, + UintInstructionCount: u32, + StaticFlowControlCount: u32, + DynamicFlowControlCount: u32, + MacroInstructionCount: u32, + ArrayInstructionCount: u32, + MovInstructionCount: u32, + MovcInstructionCount: u32, + ConversionInstructionCount: u32, + BitwiseInstructionCount: u32, + MinFeatureLevel: FEATURE_LEVEL, + RequiredFeatureFlags: u64, + + Name: cstring, + FunctionParameterCount: i32, + HasReturn: BOOL, + Has10Level9VertexShader: BOOL, + Has10Level9PixelShader: BOOL, +} + +PARAMETER_DESC :: struct { + Name: cstring, + SemanticName: cstring, + Type: SHADER_VARIABLE_TYPE, + Class: SHADER_VARIABLE_CLASS, + Rows: u32, + Columns: u32, + InterpolationMode: INTERPOLATION_MODE, + Flags: PARAMETER_FLAGS, + + FirstInRegister: u32, + FirstInComponent: u32, + FirstOutRegister: u32, + FirstOutComponent: u32, +} + +IShaderReflectionType :: struct { + vtable: ^IShaderReflectionType_VTable, +} +IShaderReflectionType_VTable :: struct { + GetDesc: proc "stdcall" (this: ^IShaderReflectionType, pDesc: ^SHADER_TYPE_DESC) -> HRESULT, + GetMemberTypeByIndex: proc "stdcall" (this: ^IShaderReflectionType, Index: u32) -> ^IShaderReflectionType, + GetMemberTypeByName: proc "stdcall" (this: ^IShaderReflectionType, Name: cstring) -> ^IShaderReflectionType, + GetMemberTypeName: proc "stdcall" (this: ^IShaderReflectionType, Index: u32) -> cstring, + IsEqual: proc "stdcall" (this: ^IShaderReflectionType, pType: ^IShaderReflectionType) -> HRESULT, + GetSubType: proc "stdcall" (this: ^IShaderReflectionType) -> ^IShaderReflectionType, + GetBaseClass: proc "stdcall" (this: ^IShaderReflectionType) -> ^IShaderReflectionType, + GetNumInterfaces: proc "stdcall" (this: ^IShaderReflectionType) -> u32, + GetInterfaceByIndex: proc "stdcall" (this: ^IShaderReflectionType, uIndex: u32) -> ^IShaderReflectionType, + IsOfType: proc "stdcall" (this: ^IShaderReflectionType, pType: ^IShaderReflectionType) -> HRESULT, + ImplementsInterface: proc "stdcall" (this: ^IShaderReflectionType, pBase: ^IShaderReflectionType) -> HRESULT, +} + +IShaderReflectionVariable :: struct { + vtable: ^IShaderReflectionVariable_VTable, +} +IShaderReflectionVariable_VTable :: struct { + GetDesc: proc "stdcall" (this: ^IShaderReflectionVariable, pDesc: ^SHADER_VARIABLE_DESC) -> HRESULT, + GetType: proc "stdcall" (this: ^IShaderReflectionVariable) -> ^IShaderReflectionType, + GetBuffer: proc "stdcall" (this: ^IShaderReflectionVariable) -> ^IShaderReflectionConstantBuffer, + GetInterfaceSlot: proc "stdcall" (this: ^IShaderReflectionVariable, uArrayIndex: u32) -> u32, +} + +IShaderReflectionConstantBuffer :: struct { + vtable: ^IShaderReflectionConstantBuffer_VTable, +} +IShaderReflectionConstantBuffer_VTable :: struct { + GetDesc: proc "stdcall" (this: ^IShaderReflectionConstantBuffer, pDesc: ^SHADER_BUFFER_DESC) -> HRESULT, + GetVariableByIndex: proc "stdcall" (this: ^IShaderReflectionConstantBuffer, Index: u32) -> ^IShaderReflectionVariable, + GetVariableByName: proc "stdcall" (this: ^IShaderReflectionConstantBuffer, Name: cstring) -> ^IShaderReflectionVariable, +} + +IShaderReflection :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12shaderreflection_vtable: ^IShaderReflection_VTable, +} +IShaderReflection_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + GetDesc: proc "stdcall" (this: ^IShaderReflection, pDesc: ^SHADER_DESC) -> HRESULT, + GetConstantBufferByIndex: proc "stdcall" (this: ^IShaderReflection, Index: u32) -> ^IShaderReflectionConstantBuffer, + GetConstantBufferByName: proc "stdcall" (this: ^IShaderReflection, Name: cstring) -> ^IShaderReflectionConstantBuffer, + GetResourceBindingDesc: proc "stdcall" (this: ^IShaderReflection, ResourceIndex: u32, pDesc: ^SHADER_INPUT_BIND_DESC) -> HRESULT, + GetInputParameterDesc: proc "stdcall" (this: ^IShaderReflection, ParameterIndex: u32, pDesc: ^SIGNATURE_PARAMETER_DESC) -> HRESULT, + GetOutputParameterDesc: proc "stdcall" (this: ^IShaderReflection, ParameterIndex: u32, pDesc: ^SIGNATURE_PARAMETER_DESC) -> HRESULT, + GetPatchConstantParameterDesc: proc "stdcall" (this: ^IShaderReflection, ParameterIndex: u32, pDesc: ^SIGNATURE_PARAMETER_DESC) -> HRESULT, + GetVariableByName: proc "stdcall" (this: ^IShaderReflection, Name: cstring) -> ^IShaderReflectionVariable, + GetResourceBindingDescByName: proc "stdcall" (this: ^IShaderReflection, Name: cstring, pDesc: ^SHADER_INPUT_BIND_DESC) -> HRESULT, + GetMovInstructionCount: proc "stdcall" (this: ^IShaderReflection) -> u32, + GetMovcInstructionCount: proc "stdcall" (this: ^IShaderReflection) -> u32, + GetConversionInstructionCount: proc "stdcall" (this: ^IShaderReflection) -> u32, + GetBitwiseInstructionCount: proc "stdcall" (this: ^IShaderReflection) -> u32, + GetGSInputPrimitive: proc "stdcall" (this: ^IShaderReflection) -> PRIMITIVE, + IsSampleFrequencyShader: proc "stdcall" (this: ^IShaderReflection) -> BOOL, + GetNumInterfaceSlots: proc "stdcall" (this: ^IShaderReflection) -> u32, + GetMinFeatureLevel: proc "stdcall" (this: ^IShaderReflection, pLevel: ^FEATURE_LEVEL) -> HRESULT, + GetThreadGroupSize: proc "stdcall" (this: ^IShaderReflection, pSizeX: ^u32, pSizeY: ^u32, pSizeZ: ^u32) -> u32, + GetRequiresFlags: proc "stdcall" (this: ^IShaderReflection) -> u64, +} + +ILibraryReflection :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12libraryreflection_vtable: ^ILibraryReflection_VTable, +} +ILibraryReflection_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + GetDesc: proc "stdcall" (this: ^ILibraryReflection, pDesc: ^LIBRARY_DESC) -> HRESULT, + GetFunctionByIndex: proc "stdcall" (this: ^ILibraryReflection, FunctionIndex: i32) -> ^IFunctionReflection, +} + +IFunctionReflection :: struct { + vtable: ^IFunctionReflection_VTable, +} +IFunctionReflection_VTable :: struct { + GetDesc: proc "stdcall" (this: ^IFunctionReflection, pDesc: ^FUNCTION_DESC) -> HRESULT, + GetConstantBufferByIndex: proc "stdcall" (this: ^IFunctionReflection, BufferIndex: u32) -> ^IShaderReflectionConstantBuffer, + GetConstantBufferByName: proc "stdcall" (this: ^IFunctionReflection, Name: cstring) -> ^IShaderReflectionConstantBuffer, + GetResourceBindingDesc: proc "stdcall" (this: ^IFunctionReflection, ResourceIndex: u32, pDesc: ^SHADER_INPUT_BIND_DESC) -> HRESULT, + GetVariableByName: proc "stdcall" (this: ^IFunctionReflection, Name: cstring) -> ^IShaderReflectionVariable, + GetResourceBindingDescByName: proc "stdcall" (this: ^IFunctionReflection, Name: cstring, pDesc: ^SHADER_INPUT_BIND_DESC) -> HRESULT, + GetFunctionParameter: proc "stdcall" (this: ^IFunctionReflection, ParameterIndex: i32) -> ^IFunctionParameterReflection, +} + +IFunctionParameterReflection :: struct { + vtable: ^IFunctionParameterReflection_VTable, +} +IFunctionParameterReflection_VTable :: struct { + GetDesc: proc "stdcall" (this: ^IFunctionParameterReflection, pDesc: ^PARAMETER_DESC) -> HRESULT, +} diff --git a/vendor/directx/d3d12/d3d12_constants.odin b/vendor/directx/d3d12/d3d12_constants.odin new file mode 100644 index 000000000..a30296cc1 --- /dev/null +++ b/vendor/directx/d3d12/d3d12_constants.odin @@ -0,0 +1,532 @@ +package directx_d3d12 + +FL9_1_REQ_TEXTURE1D_U_DIMENSION :: 2048 +FL9_3_REQ_TEXTURE1D_U_DIMENSION :: 4096 +FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION :: 2048 +FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION :: 4096 +FL9_1_REQ_TEXTURECUBE_DIMENSION :: 512 +FL9_3_REQ_TEXTURECUBE_DIMENSION :: 4096 +FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION :: 256 +FL9_1_DEFAULT_MAX_ANISOTROPY :: 2 +FL9_1_IA_PRIMITIVE_MAX_COUNT :: 65535 +FL9_2_IA_PRIMITIVE_MAX_COUNT :: 1048575 +FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT :: 1 +FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT :: 4 +FL9_1_MAX_TEXTURE_REPEAT :: 128 +FL9_2_MAX_TEXTURE_REPEAT :: 2048 +FL9_3_MAX_TEXTURE_REPEAT :: 8192 + +COMPONENT_MASK_X :: 1 +COMPONENT_MASK_Y :: 2 +COMPONENT_MASK_Z :: 4 +COMPONENT_MASK_W :: 8 + +_16BIT_INDEX_STRIP_CUT_VALUE :: 0xffff +_32BIT_INDEX_STRIP_CUT_VALUE :: 0xffffffff +_8BIT_INDEX_STRIP_CUT_VALUE :: 0xff + +APPEND_ALIGNED_ELEMENT :: 0xffffffff +ARRAY_AXIS_ADDRESS_RANGE_BIT_COUNT :: 9 + +CLIP_OR_CULL_DISTANCE_COUNT :: 8 +CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT :: 2 + +COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT :: 14 +COMMONSHADER_CONSTANT_BUFFER_COMPONENTS :: 4 +COMMONSHADER_CONSTANT_BUFFER_COMPONENT_BIT_COUNT :: 32 +COMMONSHADER_CONSTANT_BUFFER_HW_SLOT_COUNT :: 15 +COMMONSHADER_CONSTANT_BUFFER_PARTIAL_UPDATE_EXTENTS_BYTE_ALIGNMENT :: 16 +COMMONSHADER_CONSTANT_BUFFER_REGISTER_COMPONENTS :: 4 +COMMONSHADER_CONSTANT_BUFFER_REGISTER_COUNT :: 15 +COMMONSHADER_CONSTANT_BUFFER_REGISTER_READS_PER_INST :: 1 +COMMONSHADER_CONSTANT_BUFFER_REGISTER_READ_PORTS :: 1 +COMMONSHADER_FLOWCONTROL_NESTING_LIMIT :: 64 +COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_COMPONENTS :: 4 +COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_COUNT :: 1 +COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_READS_PER_INST :: 1 +COMMONSHADER_IMMEDIATE_CONSTANT_BUFFER_REGISTER_READ_PORTS :: 1 +COMMONSHADER_IMMEDIATE_VALUE_COMPONENT_BIT_COUNT :: 32 +COMMONSHADER_INPUT_RESOURCE_REGISTER_COMPONENTS :: 1 +COMMONSHADER_INPUT_RESOURCE_REGISTER_COUNT :: 128 +COMMONSHADER_INPUT_RESOURCE_REGISTER_READS_PER_INST :: 1 +COMMONSHADER_INPUT_RESOURCE_REGISTER_READ_PORTS :: 1 +COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT :: 128 +COMMONSHADER_SAMPLER_REGISTER_COMPONENTS :: 1 +COMMONSHADER_SAMPLER_REGISTER_COUNT :: 16 +COMMONSHADER_SAMPLER_REGISTER_READS_PER_INST :: 1 +COMMONSHADER_SAMPLER_REGISTER_READ_PORTS :: 1 +COMMONSHADER_SAMPLER_SLOT_COUNT :: 16 +COMMONSHADER_SUBROUTINE_NESTING_LIMIT :: 32 +COMMONSHADER_TEMP_REGISTER_COMPONENTS :: 4 +COMMONSHADER_TEMP_REGISTER_COMPONENT_BIT_COUNT :: 32 +COMMONSHADER_TEMP_REGISTER_COUNT :: 4096 +COMMONSHADER_TEMP_REGISTER_READS_PER_INST :: 3 +COMMONSHADER_TEMP_REGISTER_READ_PORTS :: 3 +COMMONSHADER_TEXCOORD_RANGE_REDUCTION_MAX :: 10 +COMMONSHADER_TEXCOORD_RANGE_REDUCTION_MIN :: -10 +COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE :: -8 +COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE :: 7 + +CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT :: 256 + +CS_4_X_BUCKET00_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 256 +CS_4_X_BUCKET00_MAX_NUM_THREADS_PER_GROUP :: 64 +CS_4_X_BUCKET01_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 240 +CS_4_X_BUCKET01_MAX_NUM_THREADS_PER_GROUP :: 68 +CS_4_X_BUCKET02_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 224 +CS_4_X_BUCKET02_MAX_NUM_THREADS_PER_GROUP :: 72 +CS_4_X_BUCKET03_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 208 +CS_4_X_BUCKET03_MAX_NUM_THREADS_PER_GROUP :: 76 +CS_4_X_BUCKET04_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 192 +CS_4_X_BUCKET04_MAX_NUM_THREADS_PER_GROUP :: 84 +CS_4_X_BUCKET05_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 176 +CS_4_X_BUCKET05_MAX_NUM_THREADS_PER_GROUP :: 92 +CS_4_X_BUCKET06_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 160 +CS_4_X_BUCKET06_MAX_NUM_THREADS_PER_GROUP :: 100 +CS_4_X_BUCKET07_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 144 +CS_4_X_BUCKET07_MAX_NUM_THREADS_PER_GROUP :: 112 +CS_4_X_BUCKET08_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 128 +CS_4_X_BUCKET08_MAX_NUM_THREADS_PER_GROUP :: 128 +CS_4_X_BUCKET09_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 112 +CS_4_X_BUCKET09_MAX_NUM_THREADS_PER_GROUP :: 144 +CS_4_X_BUCKET10_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 96 +CS_4_X_BUCKET10_MAX_NUM_THREADS_PER_GROUP :: 168 +CS_4_X_BUCKET11_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 80 +CS_4_X_BUCKET11_MAX_NUM_THREADS_PER_GROUP :: 204 +CS_4_X_BUCKET12_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 64 +CS_4_X_BUCKET12_MAX_NUM_THREADS_PER_GROUP :: 256 +CS_4_X_BUCKET13_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 48 +CS_4_X_BUCKET13_MAX_NUM_THREADS_PER_GROUP :: 340 +CS_4_X_BUCKET14_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 32 +CS_4_X_BUCKET14_MAX_NUM_THREADS_PER_GROUP :: 512 +CS_4_X_BUCKET15_MAX_BYTES_TGSM_WRITABLE_PER_THREAD :: 16 +CS_4_X_BUCKET15_MAX_NUM_THREADS_PER_GROUP :: 768 +CS_4_X_DISPATCH_MAX_THREAD_GROUPS_IN_Z_DIMENSION :: 1 +CS_4_X_RAW_UAV_BYTE_ALIGNMENT :: 256 +CS_4_X_THREAD_GROUP_MAX_THREADS_PER_GROUP :: 768 +CS_4_X_THREAD_GROUP_MAX_X :: 768 +CS_4_X_THREAD_GROUP_MAX_Y :: 768 +CS_4_X_UAV_REGISTER_COUNT :: 1 + +CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION :: 65535 +CS_TGSM_REGISTER_COUNT :: 8192 +CS_TGSM_REGISTER_READS_PER_INST :: 1 +CS_TGSM_RESOURCE_REGISTER_COMPONENTS :: 1 +CS_TGSM_RESOURCE_REGISTER_READ_PORTS :: 1 +CS_THREADGROUPID_REGISTER_COMPONENTS :: 3 +CS_THREADGROUPID_REGISTER_COUNT :: 1 +CS_THREADIDINGROUPFLATTENED_REGISTER_COMPONENTS :: 1 +CS_THREADIDINGROUPFLATTENED_REGISTER_COUNT :: 1 +CS_THREADIDINGROUP_REGISTER_COMPONENTS :: 3 +CS_THREADIDINGROUP_REGISTER_COUNT :: 1 +CS_THREADID_REGISTER_COMPONENTS :: 3 +CS_THREADID_REGISTER_COUNT :: 1 +CS_THREAD_GROUP_MAX_THREADS_PER_GROUP :: 1024 +CS_THREAD_GROUP_MAX_X :: 1024 +CS_THREAD_GROUP_MAX_Y :: 1024 +CS_THREAD_GROUP_MAX_Z :: 64 +CS_THREAD_GROUP_MIN_X :: 1 +CS_THREAD_GROUP_MIN_Y :: 1 +CS_THREAD_GROUP_MIN_Z :: 1 +CS_THREAD_LOCAL_TEMP_REGISTER_POOL :: 16384 + +DEFAULT_BLEND_FACTOR_ALPHA :: 1.0 +DEFAULT_BLEND_FACTOR_BLUE :: 1.0 +DEFAULT_BLEND_FACTOR_GREEN :: 1.0 +DEFAULT_BLEND_FACTOR_RED :: 1.0 +DEFAULT_BORDER_COLOR_COMPONENT :: 0.0 +DEFAULT_DEPTH_BIAS :: 0 +DEFAULT_DEPTH_BIAS_CLAMP :: 0.0 +DEFAULT_MAX_ANISOTROPY :: 16 +DEFAULT_MIP_LOD_BIAS :: 0.0 +DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT :: 4194304 +DEFAULT_RENDER_TARGET_ARRAY_INDEX :: 0 + +DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT :: 65536 +DEFAULT_SAMPLE_MASK :: 0xffffffff +DEFAULT_SCISSOR_ENDX :: 0 +DEFAULT_SCISSOR_ENDY :: 0 +DEFAULT_SCISSOR_STARTX :: 0 +DEFAULT_SCISSOR_STARTY :: 0 +DEFAULT_SLOPE_SCALED_DEPTH_BIAS :: 0.0 +DEFAULT_STENCIL_READ_MASK :: 0xff +DEFAULT_STENCIL_REFERENCE :: 0 +DEFAULT_STENCIL_WRITE_MASK :: 0xff +DEFAULT_VIEWPORT_AND_SCISSORRECT_INDEX :: 0 +DEFAULT_VIEWPORT_HEIGHT :: 0 +DEFAULT_VIEWPORT_MAX_DEPTH :: 0.0 +DEFAULT_VIEWPORT_MIN_DEPTH :: 0.0 +DEFAULT_VIEWPORT_TOPLEFTX :: 0 +DEFAULT_VIEWPORT_TOPLEFTY :: 0 +DEFAULT_VIEWPORT_WIDTH :: 0 + +DESCRIPTOR_RANGE_OFFSET_APPEND :: 0xffffffff + +DRIVER_RESERVED_REGISTER_SPACE_VALUES_END :: 0xfffffff7 +DRIVER_RESERVED_REGISTER_SPACE_VALUES_START :: 0xfffffff0 + +DS_INPUT_CONTROL_POINTS_MAX_TOTAL_SCALARS :: 3968 +DS_INPUT_CONTROL_POINT_REGISTER_COMPONENTS :: 4 +DS_INPUT_CONTROL_POINT_REGISTER_COMPONENT_BIT_COUNT :: 32 +DS_INPUT_CONTROL_POINT_REGISTER_COUNT :: 32 +DS_INPUT_CONTROL_POINT_REGISTER_READS_PER_INST :: 2 +DS_INPUT_CONTROL_POINT_REGISTER_READ_PORTS :: 1 +DS_INPUT_DOMAIN_POINT_REGISTER_COMPONENTS :: 3 +DS_INPUT_DOMAIN_POINT_REGISTER_COMPONENT_BIT_COUNT :: 32 +DS_INPUT_DOMAIN_POINT_REGISTER_COUNT :: 1 +DS_INPUT_DOMAIN_POINT_REGISTER_READS_PER_INST :: 2 +DS_INPUT_DOMAIN_POINT_REGISTER_READ_PORTS :: 1 +DS_INPUT_PATCH_CONSTANT_REGISTER_COMPONENTS :: 4 +DS_INPUT_PATCH_CONSTANT_REGISTER_COMPONENT_BIT_COUNT :: 32 +DS_INPUT_PATCH_CONSTANT_REGISTER_COUNT :: 32 +DS_INPUT_PATCH_CONSTANT_REGISTER_READS_PER_INST :: 2 +DS_INPUT_PATCH_CONSTANT_REGISTER_READ_PORTS :: 1 +DS_INPUT_PRIMITIVE_ID_REGISTER_COMPONENTS :: 1 +DS_INPUT_PRIMITIVE_ID_REGISTER_COMPONENT_BIT_COUNT :: 32 +DS_INPUT_PRIMITIVE_ID_REGISTER_COUNT :: 1 +DS_INPUT_PRIMITIVE_ID_REGISTER_READS_PER_INST :: 2 +DS_INPUT_PRIMITIVE_ID_REGISTER_READ_PORTS :: 1 +DS_OUTPUT_REGISTER_COMPONENTS :: 4 +DS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT :: 32 +DS_OUTPUT_REGISTER_COUNT :: 32 + +FLOAT16_FUSED_TOLERANCE_IN_ULP :: 0.6 +FLOAT32_MAX :: 3.402823466e+38 +FLOAT32_TO_INTEGER_TOLERANCE_IN_ULP :: 0.6 +FLOAT_TO_SRGB_EXPONENT_DENOMINATOR :: 2.4 +FLOAT_TO_SRGB_EXPONENT_NUMERATOR :: 1.0 +FLOAT_TO_SRGB_OFFSET :: 0.055 +FLOAT_TO_SRGB_SCALE_1 :: 12.92 +FLOAT_TO_SRGB_SCALE_2 :: 1.055 +FLOAT_TO_SRGB_THRESHOLD :: 0.0031308 +FTOI_INSTRUCTION_MAX_INPUT :: 2147483647.999 +FTOI_INSTRUCTION_MIN_INPUT :: -2147483648.999 +FTOU_INSTRUCTION_MAX_INPUT :: 4294967295.999 +FTOU_INSTRUCTION_MIN_INPUT :: 0.0 + +GS_INPUT_INSTANCE_ID_READS_PER_INST :: 2 +GS_INPUT_INSTANCE_ID_READ_PORTS :: 1 +GS_INPUT_INSTANCE_ID_REGISTER_COMPONENTS :: 1 +GS_INPUT_INSTANCE_ID_REGISTER_COMPONENT_BIT_COUNT :: 32 +GS_INPUT_INSTANCE_ID_REGISTER_COUNT :: 1 +GS_INPUT_PRIM_CONST_REGISTER_COMPONENTS :: 1 +GS_INPUT_PRIM_CONST_REGISTER_COMPONENT_BIT_COUNT :: 32 +GS_INPUT_PRIM_CONST_REGISTER_COUNT :: 1 +GS_INPUT_PRIM_CONST_REGISTER_READS_PER_INST :: 2 +GS_INPUT_PRIM_CONST_REGISTER_READ_PORTS :: 1 +GS_INPUT_REGISTER_COMPONENTS :: 4 +GS_INPUT_REGISTER_COMPONENT_BIT_COUNT :: 32 +GS_INPUT_REGISTER_COUNT :: 32 +GS_INPUT_REGISTER_READS_PER_INST :: 2 +GS_INPUT_REGISTER_READ_PORTS :: 1 +GS_INPUT_REGISTER_VERTICES :: 32 +GS_MAX_INSTANCE_COUNT :: 32 +GS_MAX_OUTPUT_VERTEX_COUNT_ACROSS_INSTANCES :: 1024 +GS_OUTPUT_ELEMENTS :: 32 +GS_OUTPUT_REGISTER_COMPONENTS :: 4 +GS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT :: 32 +GS_OUTPUT_REGISTER_COUNT :: 32 + +HS_CONTROL_POINT_PHASE_INPUT_REGISTER_COUNT :: 32 +HS_CONTROL_POINT_PHASE_OUTPUT_REGISTER_COUNT :: 32 +HS_CONTROL_POINT_REGISTER_COMPONENTS :: 4 +HS_CONTROL_POINT_REGISTER_COMPONENT_BIT_COUNT :: 32 +HS_CONTROL_POINT_REGISTER_READS_PER_INST :: 2 +HS_CONTROL_POINT_REGISTER_READ_PORTS :: 1 +HS_FORK_PHASE_INSTANCE_COUNT_UPPER_BOUND :: 0xffffffff +HS_INPUT_FORK_INSTANCE_ID_REGISTER_COMPONENTS :: 1 +HS_INPUT_FORK_INSTANCE_ID_REGISTER_COMPONENT_BIT_COUNT :: 32 +HS_INPUT_FORK_INSTANCE_ID_REGISTER_COUNT :: 1 +HS_INPUT_FORK_INSTANCE_ID_REGISTER_READS_PER_INST :: 2 +HS_INPUT_FORK_INSTANCE_ID_REGISTER_READ_PORTS :: 1 +HS_INPUT_JOIN_INSTANCE_ID_REGISTER_COMPONENTS :: 1 +HS_INPUT_JOIN_INSTANCE_ID_REGISTER_COMPONENT_BIT_COUNT :: 32 +HS_INPUT_JOIN_INSTANCE_ID_REGISTER_COUNT :: 1 +HS_INPUT_JOIN_INSTANCE_ID_REGISTER_READS_PER_INST :: 2 +HS_INPUT_JOIN_INSTANCE_ID_REGISTER_READ_PORTS :: 1 +HS_INPUT_PRIMITIVE_ID_REGISTER_COMPONENTS :: 1 +HS_INPUT_PRIMITIVE_ID_REGISTER_COMPONENT_BIT_COUNT :: 32 +HS_INPUT_PRIMITIVE_ID_REGISTER_COUNT :: 1 +HS_INPUT_PRIMITIVE_ID_REGISTER_READS_PER_INST :: 2 +HS_INPUT_PRIMITIVE_ID_REGISTER_READ_PORTS :: 1 +HS_JOIN_PHASE_INSTANCE_COUNT_UPPER_BOUND :: 0xffffffff +HS_MAXTESSFACTOR_LOWER_BOUND :: 1.0 +HS_MAXTESSFACTOR_UPPER_BOUND :: 64.0 +HS_OUTPUT_CONTROL_POINTS_MAX_TOTAL_SCALARS :: 3968 +HS_OUTPUT_CONTROL_POINT_ID_REGISTER_COMPONENTS :: 1 +HS_OUTPUT_CONTROL_POINT_ID_REGISTER_COMPONENT_BIT_COUNT :: 32 +HS_OUTPUT_CONTROL_POINT_ID_REGISTER_COUNT :: 1 +HS_OUTPUT_CONTROL_POINT_ID_REGISTER_READS_PER_INST :: 2 +HS_OUTPUT_CONTROL_POINT_ID_REGISTER_READ_PORTS :: 1 +HS_OUTPUT_PATCH_CONSTANT_REGISTER_COMPONENTS :: 4 +HS_OUTPUT_PATCH_CONSTANT_REGISTER_COMPONENT_BIT_COUNT :: 32 +HS_OUTPUT_PATCH_CONSTANT_REGISTER_COUNT :: 32 +HS_OUTPUT_PATCH_CONSTANT_REGISTER_READS_PER_INST :: 2 +HS_OUTPUT_PATCH_CONSTANT_REGISTER_READ_PORTS :: 1 +HS_OUTPUT_PATCH_CONSTANT_REGISTER_SCALAR_COMPONENTS :: 128 + +IA_DEFAULT_INDEX_BUFFER_OFFSET_IN_BYTES :: 0 +IA_DEFAULT_PRIMITIVE_TOPOLOGY :: 0 +IA_DEFAULT_VERTEX_BUFFER_OFFSET_IN_BYTES :: 0 +IA_INDEX_INPUT_RESOURCE_SLOT_COUNT :: 1 +IA_INSTANCE_ID_BIT_COUNT :: 32 +IA_INTEGER_ARITHMETIC_BIT_COUNT :: 32 +IA_PATCH_MAX_CONTROL_POINT_COUNT :: 32 +IA_PRIMITIVE_ID_BIT_COUNT :: 32 +IA_VERTEX_ID_BIT_COUNT :: 32 +IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT :: 32 +IA_VERTEX_INPUT_STRUCTURE_ELEMENTS_COMPONENTS :: 128 +IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT :: 32 + +INTEGER_DIVIDE_BY_ZERO_QUOTIENT :: 0xffffffff +INTEGER_DIVIDE_BY_ZERO_REMAINDER :: 0xffffffff + +KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL :: 0xffffffff +KEEP_UNORDERED_ACCESS_VIEWS :: 0xffffffff + +LINEAR_GAMMA :: 1.0 +MAJOR_VERSION :: 12 + +MAX_BORDER_COLOR_COMPONENT :: 1.0 +MAX_DEPTH :: 1.0 +MAX_LIVE_STATIC_SAMPLERS :: 2032 +MAX_MAXANISOTROPY :: 16 +MAX_MULTISAMPLE_SAMPLE_COUNT :: 32 +MAX_POSITION_VALUE :: 3.402823466e+34 +MAX_ROOT_COST :: 64 +MAX_SHADER_VISIBLE_DESCRIPTOR_HEAP_SIZE_TIER_1 :: 1000000 +MAX_SHADER_VISIBLE_DESCRIPTOR_HEAP_SIZE_TIER_2 :: 1000000 +MAX_SHADER_VISIBLE_SAMPLER_HEAP_SIZE :: 2048 +MAX_TEXTURE_DIMENSION_2_TO_EXP :: 17 +MAX_VIEW_INSTANCE_COUNT :: 4 + +MINOR_VERSION :: 0 + +MIN_BORDER_COLOR_COMPONENT :: 0.0 +MIN_DEPTH :: 0.0 +MIN_MAXANISOTROPY :: 0 + +MIP_LOD_BIAS_MAX :: 15.99 +MIP_LOD_BIAS_MIN :: -16.0 +MIP_LOD_FRACTIONAL_BIT_COUNT :: 8 +MIP_LOD_RANGE_BIT_COUNT :: 8 + +MULTISAMPLE_ANTIALIAS_LINE_WIDTH :: 1.4 +NONSAMPLE_FETCH_OUT_OF_RANGE_ACCESS_RESULT :: 0 + +OS_RESERVED_REGISTER_SPACE_VALUES_END :: 0xffffffff +OS_RESERVED_REGISTER_SPACE_VALUES_START :: 0xfffffff8 + +PACKED_TILE :: 0xffffffff + +PIXEL_ADDRESS_RANGE_BIT_COUNT :: 15 + +PRE_SCISSOR_PIXEL_ADDRESS_RANGE_BIT_COUNT :: 16 + +PS_CS_UAV_REGISTER_COMPONENTS :: 1 +PS_CS_UAV_REGISTER_COUNT :: 8 +PS_CS_UAV_REGISTER_READS_PER_INST :: 1 +PS_CS_UAV_REGISTER_READ_PORTS :: 1 +PS_FRONTFACING_DEFAULT_VALUE :: 0xffffffff +PS_FRONTFACING_FALSE_VALUE :: 0 +PS_FRONTFACING_TRUE_VALUE :: 0xffffffff +PS_INPUT_REGISTER_COMPONENTS :: 4 +PS_INPUT_REGISTER_COMPONENT_BIT_COUNT :: 32 +PS_INPUT_REGISTER_COUNT :: 32 +PS_INPUT_REGISTER_READS_PER_INST :: 2 +PS_INPUT_REGISTER_READ_PORTS :: 1 +PS_LEGACY_PIXEL_CENTER_FRACTIONAL_COMPONENT :: 0.0 +PS_OUTPUT_DEPTH_REGISTER_COMPONENTS :: 1 +PS_OUTPUT_DEPTH_REGISTER_COMPONENT_BIT_COUNT :: 32 +PS_OUTPUT_DEPTH_REGISTER_COUNT :: 1 +PS_OUTPUT_MASK_REGISTER_COMPONENTS :: 1 +PS_OUTPUT_MASK_REGISTER_COMPONENT_BIT_COUNT :: 32 +PS_OUTPUT_MASK_REGISTER_COUNT :: 1 +PS_OUTPUT_REGISTER_COMPONENTS :: 4 +PS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT :: 32 +PS_OUTPUT_REGISTER_COUNT :: 8 +PS_PIXEL_CENTER_FRACTIONAL_COMPONENT :: 0.5 + +RAW_UAV_SRV_BYTE_ALIGNMENT :: 16 + +RAYTRACING_AABB_BYTE_ALIGNMENT :: 8 +RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT :: 256 +RAYTRACING_INSTANCE_DESCS_BYTE_ALIGNMENT :: 16 +RAYTRACING_MAX_ATTRIBUTE_SIZE_IN_BYTES :: 32 +RAYTRACING_MAX_DECLARABLE_TRACE_RECURSION_DEPTH :: 31 +RAYTRACING_MAX_GEOMETRIES_PER_BOTTOM_LEVEL_ACCELERATION_STRUCTURE :: 16777216 +RAYTRACING_MAX_INSTANCES_PER_TOP_LEVEL_ACCELERATION_STRUCTURE :: 16777216 +RAYTRACING_MAX_PRIMITIVES_PER_BOTTOM_LEVEL_ACCELERATION_STRUCTURE :: 536870912 +RAYTRACING_MAX_RAY_GENERATION_SHADER_THREADS :: 1073741824 +RAYTRACING_MAX_SHADER_RECORD_STRIDE :: 4096 +RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT :: 32 +RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT :: 64 +RAYTRACING_TRANSFORM3X4_BYTE_ALIGNMENT :: 16 + +REQ_BLEND_OBJECT_COUNT_PER_DEVICE :: 4096 +REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP :: 27 +REQ_CONSTANT_BUFFER_ELEMENT_COUNT :: 4096 +REQ_DEPTH_STENCIL_OBJECT_COUNT_PER_DEVICE :: 4096 +REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP :: 32 +REQ_DRAW_VERTEX_COUNT_2_TO_EXP :: 32 +REQ_FILTERING_HW_ADDRESSABLE_RESOURCE_DIMENSION :: 16384 +REQ_GS_INVOCATION_32BIT_OUTPUT_COMPONENT_LIMIT :: 1024 +REQ_IMMEDIATE_CONSTANT_BUFFER_ELEMENT_COUNT :: 4096 +REQ_MAXANISOTROPY :: 16 +REQ_MIP_LEVELS :: 15 +REQ_MULTI_ELEMENT_STRUCTURE_SIZE_IN_BYTES :: 2048 +REQ_RASTERIZER_OBJECT_COUNT_PER_DEVICE :: 4096 +REQ_RENDER_TO_BUFFER_WINDOW_WIDTH :: 16384 +REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_A_TERM :: 128 +REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_B_TERM :: 0.25 +REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_C_TERM :: 2048 +REQ_RESOURCE_VIEW_COUNT_PER_DEVICE_2_TO_EXP :: 20 +REQ_SAMPLER_OBJECT_COUNT_PER_DEVICE :: 4096 +REQ_SUBRESOURCES :: 30720 +REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION :: 2048 +REQ_TEXTURE1D_U_DIMENSION :: 16384 +REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION :: 2048 +REQ_TEXTURE2D_U_OR_V_DIMENSION :: 16384 +REQ_TEXTURE3D_U_V_OR_W_DIMENSION :: 2048 +REQ_TEXTURECUBE_DIMENSION :: 16384 + +RESINFO_INSTRUCTION_MISSING_COMPONENT_RETVAL :: 0 + +RESOURCE_BARRIER_ALL_SUBRESOURCES :: 0xffffffff + +RS_SET_SHADING_RATE_COMBINER_COUNT :: 2 + +SHADER_IDENTIFIER_SIZE_IN_BYTES :: 32 +SHADER_MAJOR_VERSION :: 5 +SHADER_MAX_INSTANCES :: 65535 +SHADER_MAX_INTERFACES :: 253 +SHADER_MAX_INTERFACE_CALL_SITES :: 4096 +SHADER_MAX_TYPES :: 65535 +SHADER_MINOR_VERSION :: 1 + +SHIFT_INSTRUCTION_PAD_VALUE :: 0 +SHIFT_INSTRUCTION_SHIFT_VALUE_BIT_COUNT :: 5 + +SIMULTANEOUS_RENDER_TARGET_COUNT :: 8 + +SMALL_MSAA_RESOURCE_PLACEMENT_ALIGNMENT :: 65536 +SMALL_RESOURCE_PLACEMENT_ALIGNMENT :: 4096 + +SO_BUFFER_MAX_STRIDE_IN_BYTES :: 2048 +SO_BUFFER_MAX_WRITE_WINDOW_IN_BYTES :: 512 +SO_BUFFER_SLOT_COUNT :: 4 +SO_DDI_REGISTER_INDEX_DENOTING_GAP :: 0xffffffff +SO_NO_RASTERIZED_STREAM :: 0xffffffff +SO_OUTPUT_COMPONENT_COUNT :: 128 +SO_STREAM_COUNT :: 4 + +SPEC_DATE_DAY :: 14 +SPEC_DATE_MONTH :: 11 +SPEC_DATE_YEAR :: 2014 +SPEC_VERSION :: 1.16 + +SRGB_GAMMA :: 2.2 +SRGB_TO_FLOAT_DENOMINATOR_1 :: 12.92 +SRGB_TO_FLOAT_DENOMINATOR_2 :: 1.055 +SRGB_TO_FLOAT_EXPONENT :: 2.4 +SRGB_TO_FLOAT_OFFSET :: 0.055 +SRGB_TO_FLOAT_THRESHOLD :: 0.04045 +SRGB_TO_FLOAT_TOLERANCE_IN_ULP :: 0.5 + +STANDARD_COMPONENT_BIT_COUNT :: 32 +STANDARD_COMPONENT_BIT_COUNT_DOUBLED :: 64 +STANDARD_MAXIMUM_ELEMENT_ALIGNMENT_BYTE_MULTIPLE :: 4 +STANDARD_PIXEL_COMPONENT_COUNT :: 128 +STANDARD_PIXEL_ELEMENT_COUNT :: 32 +STANDARD_VECTOR_SIZE :: 4 +STANDARD_VERTEX_ELEMENT_COUNT :: 32 +STANDARD_VERTEX_TOTAL_COMPONENT_COUNT :: 64 + +SUBPIXEL_FRACTIONAL_BIT_COUNT :: 8 +SUBTEXEL_FRACTIONAL_BIT_COUNT :: 8 + +SYSTEM_RESERVED_REGISTER_SPACE_VALUES_END :: 0xffffffff +SYSTEM_RESERVED_REGISTER_SPACE_VALUES_START :: 0xfffffff0 + +TESSELLATOR_MAX_EVEN_TESSELLATION_FACTOR :: 64 +TESSELLATOR_MAX_ISOLINE_DENSITY_TESSELLATION_FACTOR :: 64 +TESSELLATOR_MAX_ODD_TESSELLATION_FACTOR :: 63 +TESSELLATOR_MAX_TESSELLATION_FACTOR :: 64 +TESSELLATOR_MIN_EVEN_TESSELLATION_FACTOR :: 2 +TESSELLATOR_MIN_ISOLINE_DENSITY_TESSELLATION_FACTOR :: 1 +TESSELLATOR_MIN_ODD_TESSELLATION_FACTOR :: 1 + +TEXEL_ADDRESS_RANGE_BIT_COUNT :: 16 + +TEXTURE_DATA_PITCH_ALIGNMENT :: 256 +TEXTURE_DATA_PLACEMENT_ALIGNMENT :: 512 + +TILED_RESOURCE_TILE_SIZE_IN_BYTES :: 65536 + +TRACKED_WORKLOAD_MAX_INSTANCES :: 32 + +UAV_COUNTER_PLACEMENT_ALIGNMENT :: 4096 +UAV_SLOT_COUNT :: 64 + +UNBOUND_MEMORY_ACCESS_RESULT :: 0 + +VIDEO_DECODE_MAX_ARGUMENTS :: 10 +VIDEO_DECODE_MAX_HISTOGRAM_COMPONENTS :: 4 +VIDEO_DECODE_MIN_BITSTREAM_OFFSET_ALIGNMENT :: 256 +VIDEO_DECODE_MIN_HISTOGRAM_OFFSET_ALIGNMENT :: 256 +VIDEO_DECODE_STATUS_MACROBLOCKS_AFFECTED_UNKNOWN :: 0xffffffff +VIDEO_PROCESS_MAX_FILTERS :: 32 +VIDEO_PROCESS_STEREO_VIEWS :: 2 + +VIEWPORT_AND_SCISSORRECT_MAX_INDEX :: 15 +VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE :: 16 +VIEWPORT_BOUNDS_MAX :: 32767 +VIEWPORT_BOUNDS_MIN :: -32768 + +VS_INPUT_REGISTER_COMPONENTS :: 4 +VS_INPUT_REGISTER_COMPONENT_BIT_COUNT :: 32 +VS_INPUT_REGISTER_COUNT :: 32 +VS_INPUT_REGISTER_READS_PER_INST :: 2 +VS_INPUT_REGISTER_READ_PORTS :: 1 +VS_OUTPUT_REGISTER_COMPONENTS :: 4 +VS_OUTPUT_REGISTER_COMPONENT_BIT_COUNT :: 32 +VS_OUTPUT_REGISTER_COUNT :: 32 + +WHQL_CONTEXT_COUNT_FOR_RESOURCE_LIMIT :: 10 +WHQL_DRAWINDEXED_INDEX_COUNT_2_TO_EXP :: 25 +WHQL_DRAW_VERTEX_COUNT_2_TO_EXP :: 25 + +SHADER_COMPONENT_MAPPING_MASK :: 0x7 +SHADER_COMPONENT_MAPPING_SHIFT :: 3 + +FILTER_REDUCTION_TYPE_MASK :: 0x3 +FILTER_REDUCTION_TYPE_SHIFT :: 7 +FILTER_TYPE_MASK :: 0x3 + +MIN_FILTER_SHIFT :: 4 +MAG_FILTER_SHIFT :: 2 +MIP_FILTER_SHIFT :: 0 + +ANISOTROPIC_FILTERING_BIT :: 0x40 + +INFO_QUEUE_DEFAULT_MESSAGE_COUNT_LIMIT :: 1024 + +SHADING_RATE_X_AXIS_SHIFT :: 2 +SHADING_RATE_VALID_MASK :: 3 + +RETURN_PARAMETER_INDEX :: -1 + +SHADER_REQUIRES_DOUBLES :: 0x00000001 +SHADER_REQUIRES_EARLY_DEPTH_STENCIL :: 0x00000002 +SHADER_REQUIRES_UAVS_AT_EVERY_STAGE :: 0x00000004 +SHADER_REQUIRES_64_UAVS :: 0x00000008 +SHADER_REQUIRES_MINIMUM_PRECISION :: 0x00000010 +SHADER_REQUIRES_11_1_DOUBLE_EXTENSIONS :: 0x00000020 +SHADER_REQUIRES_11_1_SHADER_EXTENSIONS :: 0x00000040 +SHADER_REQUIRES_LEVEL_9_COMPARISON_FILTERING :: 0x00000080 +SHADER_REQUIRES_TILED_RESOURCES :: 0x00000100 +SHADER_REQUIRES_STENCIL_REF :: 0x00000200 +SHADER_REQUIRES_INNER_COVERAGE :: 0x00000400 +SHADER_REQUIRES_TYPED_UAV_LOAD_ADDITIONAL_FORMATS :: 0x00000800 +SHADER_REQUIRES_ROVS :: 0x00001000 +SHADER_REQUIRES_VIEWPORT_AND_RT_ARRAY_INDEX_FROM_ANY_SHADER_FEEDING_RASTERIZER :: 0x00002000 diff --git a/vendor/directx/d3d_compiler/d3d_compiler.odin b/vendor/directx/d3d_compiler/d3d_compiler.odin new file mode 100644 index 000000000..2506f239c --- /dev/null +++ b/vendor/directx/d3d_compiler/d3d_compiler.odin @@ -0,0 +1,228 @@ +package directx_d3d_compiler + +foreign import d3dcompiler "d3dcompiler_47.lib" + +D3DCOMPILER_DLL_A :: "d3dcompiler_47.dll" +COMPILER_VERSION :: 47 + + +import "../dxgi" + +BOOL :: dxgi.BOOL +IID :: dxgi.IID +SIZE_T :: dxgi.SIZE_T +HRESULT :: dxgi.HRESULT +IUnknown :: dxgi.IUnknown +IUnknown_VTable :: dxgi.IUnknown_VTable + +@(default_calling_convention="stdcall", link_prefix="D3D") +foreign d3dcompiler { + ReadFileToBlob :: proc(pFileName: [^]u16, ppContents: ^^ID3DBlob) -> HRESULT --- + WriteBlobToFile :: proc(pBlob: ^ID3DBlob, pFileName: [^]u16, bOverwrite: BOOL) -> HRESULT --- + Compile :: proc(pSrcData: rawptr, SrcDataSize: SIZE_T, pSourceName: cstring, pDefines: ^SHADER_MACRO, pInclude: ^ID3DInclude, pEntrypoint: cstring, pTarget: cstring, Flags1: u32, Flags2: u32, ppCode: ^^ID3DBlob, ppErrorMsgs: ^^ID3DBlob) -> HRESULT --- + Compile2 :: proc(pSrcData: rawptr, SrcDataSize: SIZE_T, pSourceName: cstring, pDefines: ^SHADER_MACRO, pInclude: ^ID3DInclude, pEntrypoint: cstring, pTarget: cstring, Flags1: u32, Flags2: u32, SecondaryDataFlags: u32, pSecondaryData: rawptr, SecondaryDataSize: SIZE_T, ppCode: ^^ID3DBlob, ppErrorMsgs: ^^ID3DBlob) -> HRESULT --- + CompileFromFile :: proc(pFileName: [^]u16, pDefines: ^SHADER_MACRO, pInclude: ^ID3DInclude, pEntrypoint: cstring, pTarget: cstring, Flags1: u32, Flags2: u32, ppCode: ^^ID3DBlob, ppErrorMsgs: ^^ID3DBlob) -> HRESULT --- + Preprocess :: proc(pSrcData: rawptr, SrcDataSize: SIZE_T, pSourceName: cstring, pDefines: ^SHADER_MACRO, pInclude: ^ID3DInclude, ppCodeText: ^^ID3DBlob, ppErrorMsgs: ^^ID3DBlob) -> HRESULT --- + GetDebugInfo :: proc(pSrcData: rawptr, SrcDataSize: SIZE_T, ppDebugInfo: ^^ID3DBlob) -> HRESULT --- + Reflect :: proc(pSrcData: rawptr, SrcDataSize: SIZE_T, pInterface: ^IID, ppReflector: ^rawptr) -> HRESULT --- + ReflectLibrary :: proc(pSrcData: rawptr, SrcDataSize: SIZE_T, riid: ^IID, ppReflector: ^rawptr) -> HRESULT --- + Disassemble :: proc(pSrcData: rawptr, SrcDataSize: SIZE_T, Flags: u32, szComments: cstring, ppDisassembly: ^^ID3DBlob) -> HRESULT --- + DisassembleRegion :: proc(pSrcData: rawptr, SrcDataSize: SIZE_T, Flags: u32, szComments: cstring, StartByteOffset: SIZE_T, NumInsts: SIZE_T, pFinishByteOffset: ^SIZE_T, ppDisassembly: ^^ID3DBlob) -> HRESULT --- + CreateLinker :: proc(ppLinker: ^^ID3D11Linker) -> HRESULT --- + LoadModule :: proc(pSrcData: rawptr, cbSrcDataSize: SIZE_T, ppModule: ^^ID3D11Module) -> HRESULT --- + GetTraceInstructionOffsets :: proc(pSrcData: rawptr, SrcDataSize: SIZE_T, Flags: u32, StartInstIndex: SIZE_T, NumInsts: SIZE_T, pOffsets: ^SIZE_T, pTotalInsts: ^SIZE_T) -> HRESULT --- + GetInputSignatureBlob :: proc(pSrcData: rawptr, SrcDataSize: SIZE_T, ppSignatureBlob: ^^ID3DBlob) -> HRESULT --- + GetOutputSignatureBlob :: proc(pSrcData: rawptr, SrcDataSize: SIZE_T, ppSignatureBlob: ^^ID3DBlob) -> HRESULT --- + GetInputAndOutputSignatureBlob :: proc(pSrcData: rawptr, SrcDataSize: SIZE_T, ppSignatureBlob: ^^ID3DBlob) -> HRESULT --- + StripShader :: proc(pShaderBytecode: rawptr, BytecodeLength: SIZE_T, uStripFlags: u32, ppStrippedBlob: ^^ID3DBlob) -> HRESULT --- + GetBlobPart :: proc(pSrcData: rawptr, SrcDataSize: SIZE_T, Part: BLOB_PART, Flags: u32, ppPart: ^^ID3DBlob) -> HRESULT --- + SetBlobPart :: proc(pSrcData: rawptr, SrcDataSize: SIZE_T, Part: BLOB_PART, Flags: u32, pPart: rawptr, PartSize: SIZE_T, ppNewShader: ^^ID3DBlob) -> HRESULT --- + CreateBlob :: proc(Size: SIZE_T, ppBlob: ^^ID3DBlob) -> HRESULT --- + CompressShaders :: proc(uNumShaders: u32, pShaderData: ^SHADER_DATA, uFlags: u32, ppCompressedData: ^^ID3DBlob) -> HRESULT --- + DecompressShaders :: proc(pSrcData: rawptr, SrcDataSize: SIZE_T, uNumShaders: u32, uStartIndex: u32, pIndices: ^u32, uFlags: u32, ppShaders: ^^ID3DBlob, pTotalShaders: ^u32) -> HRESULT --- + Disassemble10Effect :: proc(pEffect: ^ID3D10Effect, Flags: u32, ppDisassembly: ^^ID3DBlob) -> HRESULT --- +} + + + +D3DCOMPILE :: enum u32 { // TODO: make bit_field + DEBUG = 1 << 0, + SKIP_VALIDATION = 1 << 1, + SKIP_OPTIMIZATION = 1 << 2, + PACK_MATRIX_ROW_MAJOR = 1 << 3, + PACK_MATRIX_COLUMN_MAJOR = 1 << 4, + PARTIAL_PRECISION = 1 << 5, + FORCE_VS_SOFTWARE_NO_OPT = 1 << 6, + FORCE_PS_SOFTWARE_NO_OPT = 1 << 7, + NO_PRESHADER = 1 << 8, + AVOID_FLOW_CONTROL = 1 << 9, + PREFER_FLOW_CONTROL = 1 << 10, + ENABLE_STRICTNESS = 1 << 11, + ENABLE_BACKWARDS_COMPATIBILITY = 1 << 12, + IEEE_STRICTNESS = 1 << 13, + OPTIMIZATION_LEVEL0 = 1 << 14, + OPTIMIZATION_LEVEL1 = 0, + OPTIMIZATION_LEVEL2 = (1 << 14)|(1 << 15), // Added manually + OPTIMIZATION_LEVEL3 = 1 << 15, + RESERVED16 = 1 << 16, + RESERVED17 = 1 << 17, + WARNINGS_ARE_ERRORS = 1 << 18, + RESOURCES_MAY_ALIAS = 1 << 19, + ENABLE_UNBOUNDED_DESCRIPTOR_TABLES = 1 << 20, + ALL_RESOURCES_BOUND = 1 << 21, + DEBUG_NAME_FOR_SOURCE = 1 << 22, + DEBUG_NAME_FOR_BINARY = 1 << 23, +} + +EFFECT :: enum u32 { // TODO: make bit_field + CHILD_EFFECT = 1 << 0, + ALLOW_SLOW_OPS = 1 << 1, +} + +FLAGS2 :: enum u32 { // TODO: make bit_field + FORCE_ROOT_SIGNATURE_LATEST = 0, + FORCE_ROOT_SIGNATURE_1_0 = 1 << 4, + FORCE_ROOT_SIGNATURE_1_1 = 1 << 5, +} + +SECDATA :: enum u32 { // TODO: make bit_field + MERGE_UAV_SLOTS = 0x00000001, + PRESERVE_TEMPLATE_SLOTS = 0x00000002, + REQUIRE_TEMPLATE_MATCH = 0x00000004, +} + +DISASM_ENABLE_COLOR_CODE :: 0x00000001 +DISASM_ENABLE_DEFAULT_VALUE_PRINTS :: 0x00000002 +DISASM_ENABLE_INSTRUCTION_NUMBERING :: 0x00000004 +DISASM_ENABLE_INSTRUCTION_CYCLE :: 0x00000008 +DISASM_DISABLE_DEBUG_INFO :: 0x00000010 +DISASM_ENABLE_INSTRUCTION_OFFSET :: 0x00000020 +DISASM_INSTRUCTION_ONLY :: 0x00000040 +DISASM_PRINT_HEX_LITERALS :: 0x00000080 + +GET_INST_OFFSETS_INCLUDE_NON_EXECUTABLE :: 0x00000001 + +COMPRESS_SHADER_KEEP_ALL_PARTS :: 0x00000001 + +SHADER_MACRO :: struct { + Name: cstring, + Definition: cstring, +} + +ID3D10Blob_UUID_STRING :: "8BA5FB08-5195-40E2-AC58-0D989C3A0102" +ID3D10Blob_UUID := &IID{0x8BA5FB08, 0x5195, 0x40E2, {0xAC, 0x58, 0x0D, 0x98, 0x9C, 0x3A, 0x01, 0x02}} +ID3D10Blob :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d10blob_vtable: ^ID3D10Blob_VTable, +} +ID3D10Blob_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + GetBufferPointer: proc "stdcall" (this: ^ID3D10Blob) -> rawptr, + GetBufferSize: proc "stdcall" (this: ^ID3D10Blob) -> SIZE_T, +} + + +ID3DBlob :: ID3D10Blob +ID3DBlob_VTable :: ID3D10Blob_VTable + + +INCLUDE_TYPE :: enum i32 { + INCLUDE_LOCAL = 0, + INCLUDE_SYSTEM = 1, + _10_INCLUDE_LOCAL = 0, + _10_INCLUDE_SYSTEM = 1, + INCLUDE_FORCE_DWORD = 2147483647, +} + +ID3DInclude :: struct { + vtable: ^ID3DInclude_VTable, +} +ID3DInclude_VTable :: struct { + Open: proc "stdcall" (this: ^ID3DInclude, IncludeType: INCLUDE_TYPE, pFileName: cstring, pParentData: rawptr, ppData: ^rawptr, pBytes: ^u32) -> HRESULT, + Close: proc "stdcall" (this: ^ID3DInclude, pData: rawptr) -> HRESULT, +} + + +ID3D11Module :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d11module_vtable: ^ID3D11Module_VTable, +} +ID3D11Module_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + CreateInstance: proc "stdcall" (this: ^ID3D11Module, pNamespace: cstring, ppModuleInstance: ^^ID3D11ModuleInstance) -> HRESULT, +} + + +ID3D11ModuleInstance :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d11moduleinstance_vtable: ^ID3D11ModuleInstance_VTable, +} +ID3D11ModuleInstance_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + BindConstantBuffer: proc "stdcall" (this: ^ID3D11ModuleInstance, uSrcSlot: u32, uDstSlot: u32, cbDstOffset: u32) -> HRESULT, + BindConstantBufferByName: proc "stdcall" (this: ^ID3D11ModuleInstance, pName: cstring, uDstSlot: u32, cbDstOffset: u32) -> HRESULT, + BindResource: proc "stdcall" (this: ^ID3D11ModuleInstance, uSrcSlot: u32, uDstSlot: u32, uCount: u32) -> HRESULT, + BindResourceByName: proc "stdcall" (this: ^ID3D11ModuleInstance, pName: cstring, uDstSlot: u32, uCount: u32) -> HRESULT, + BindSampler: proc "stdcall" (this: ^ID3D11ModuleInstance, uSrcSlot: u32, uDstSlot: u32, uCount: u32) -> HRESULT, + BindSamplerByName: proc "stdcall" (this: ^ID3D11ModuleInstance, pName: cstring, uDstSlot: u32, uCount: u32) -> HRESULT, + BindUnorderedAccessView: proc "stdcall" (this: ^ID3D11ModuleInstance, uSrcSlot: u32, uDstSlot: u32, uCount: u32) -> HRESULT, + BindUnorderedAccessViewByName: proc "stdcall" (this: ^ID3D11ModuleInstance, pName: cstring, uDstSlot: u32, uCount: u32) -> HRESULT, + BindResourceAsUnorderedAccessView: proc "stdcall" (this: ^ID3D11ModuleInstance, uSrcSrvSlot: u32, uDstUavSlot: u32, uCount: u32) -> HRESULT, + BindResourceAsUnorderedAccessViewByName: proc "stdcall" (this: ^ID3D11ModuleInstance, pSrvName: cstring, uDstUavSlot: u32, uCount: u32) -> HRESULT, +} + + +ID3D11Linker :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d11linker_vtable: ^ID3D11Linker_VTable, +} +ID3D11Linker_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + Link: proc "stdcall" (this: ^ID3D11Linker, pEntry: ^ID3D11ModuleInstance, pEntryName: cstring, pTargetName: cstring, uFlags: u32, ppShaderBlob: ^^ID3DBlob, ppErrorBuffer: ^^ID3DBlob) -> HRESULT, + UseLibrary: proc "stdcall" (this: ^ID3D11Linker, pLibraryMI: ^ID3D11ModuleInstance) -> HRESULT, + AddClipPlaneFromCBuffer: proc "stdcall" (this: ^ID3D11Linker, uCBufferSlot: u32, uCBufferEntry: u32) -> HRESULT, +} + + +pD3DCompile :: #type proc "c" (a0: rawptr, a1: SIZE_T, a2: cstring, a3: ^SHADER_MACRO, a4: ^ID3DInclude, a5: cstring, a6: cstring, a7: u32, a8: u32, a9: ^^ID3DBlob, a10: ^^ID3DBlob) -> HRESULT +pD3DPreprocess :: #type proc "c" (a0: rawptr, a1: SIZE_T, a2: cstring, a3: ^SHADER_MACRO, a4: ^ID3DInclude, a5: ^^ID3DBlob, a6: ^^ID3DBlob) -> HRESULT +pD3DDisassemble :: #type proc "c" (a0: rawptr, a1: SIZE_T, a2: u32, a3: cstring, a4: ^^ID3DBlob) -> HRESULT + +D3DCOMPILER_STRIP_FLAGS :: enum u32 { // TODO: make bit_field + REFLECTION_DATA = 0x1, + DEBUG_INFO = 0x2, + TEST_BLOBS = 0x4, + PRIVATE_DATA = 0x8, + ROOT_SIGNATURE = 0x10, + FORCE_DWORD = 0x7fffffff, +} + +BLOB_PART :: enum i32 { + INPUT_SIGNATURE_BLOB = 0, + OUTPUT_SIGNATURE_BLOB = 1, + INPUT_AND_OUTPUT_SIGNATURE_BLOB = 2, + PATCH_CONSTANT_SIGNATURE_BLOB = 3, + ALL_SIGNATURE_BLOB = 4, + DEBUG_INFO = 5, + LEGACY_SHADER = 6, + XNA_PREPASS_SHADER = 7, + XNA_SHADER = 8, + PDB = 9, + PRIVATE_DATA = 10, + ROOT_SIGNATURE = 11, + DEBUG_NAME = 12, + + TEST_ALTERNATE_SHADER = 32768, + TEST_COMPILE_DETAILS = 32769, + TEST_COMPILE_PERF = 32770, + TEST_COMPILE_REPORT = 32771, +} + +SHADER_DATA :: struct { + pBytecode: rawptr, + BytecodeLength: SIZE_T, +} + +ID3D10Effect :: struct { + // ???? +} diff --git a/vendor/directx/d3d_compiler/d3dcompiler_47.dll b/vendor/directx/d3d_compiler/d3dcompiler_47.dll new file mode 100644 index 000000000..d30a17652 Binary files /dev/null and b/vendor/directx/d3d_compiler/d3dcompiler_47.dll differ diff --git a/vendor/directx/d3d_compiler/d3dcompiler_47.lib b/vendor/directx/d3d_compiler/d3dcompiler_47.lib new file mode 100644 index 000000000..022890ad9 Binary files /dev/null and b/vendor/directx/d3d_compiler/d3dcompiler_47.lib differ diff --git a/vendor/directx/dxgi/dxgi.odin b/vendor/directx/dxgi/dxgi.odin new file mode 100644 index 000000000..70c5a9e71 --- /dev/null +++ b/vendor/directx/dxgi/dxgi.odin @@ -0,0 +1,1141 @@ +package directx_dxgi + +foreign import dxgi { + "system:dxgi.lib", + "system:user32.lib", + "system:gdi32.lib", +} + +import win32 "core:sys/windows" + +LUID :: win32.LUID +IID :: win32.GUID +UUID :: win32.GUID +GUID :: win32.GUID +HANDLE :: win32.HANDLE +HRESULT :: win32.HRESULT +HMONITOR :: win32.HMONITOR +HWND :: win32.HWND +HMODULE :: win32.HMODULE +HDC :: win32.HANDLE +BOOL :: win32.BOOL +LARGE_INTEGER :: win32.LARGE_INTEGER +SIZE_T :: win32.SIZE_T +ULONG :: win32.ULONG +LONG :: win32.LONG +RECT :: win32.RECT +POINT :: win32.POINT +SIZE :: win32.SIZE + +IUnknown :: struct { + using _iunknown_vtable: ^IUnknown_VTable, +} +IUnknown_VTable :: struct { + QueryInterface: proc "stdcall" (this: ^IUnknown, riid: ^IID, ppvObject: ^rawptr) -> HRESULT, + AddRef: proc "stdcall" (this: ^IUnknown) -> ULONG, + Release: proc "stdcall" (this: ^IUnknown) -> ULONG, +} + +@(default_calling_convention="stdcall") +foreign dxgi { + CreateDXGIFactory :: proc(riid: ^IID, ppFactory: rawptr) -> HRESULT --- + CreateDXGIFactory1 :: proc(riid: ^IID, ppFactory: rawptr) -> HRESULT --- + CreateDXGIFactory2 :: proc(Flags: u32, riid: ^IID, ppFactory: rawptr) -> HRESULT --- + DXGIGetDebugInterface1 :: proc(Flags: u32, riid: ^IID, pDebug: rawptr) -> HRESULT --- +} + +STANDARD_MULTISAMPLE_QUALITY_PATTERN :: 0xffffffff +CENTER_MULTISAMPLE_QUALITY_PATTERN :: 0xfffffffe +FORMAT_DEFINED :: 1 +_FACDXGI :: 0x87a + +CPU_ACCESS :: enum u32 { + NONE = 0, + DYNAMIC = 1, + READ_WRITE = 2, + SCRATCH = 3, + FIELD = 15, +} + +USAGE :: enum u32 { // TODO: convert to bit_set + SHADER_INPUT = 0x00000010, + RENDER_TARGET_OUTPUT = 0x00000020, + BACK_BUFFER = 0x00000040, + SHARED = 0x00000080, + READ_ONLY = 0x00000100, + DISCARD_ON_PRESENT = 0x00000200, + UNORDERED_ACCESS = 0x00000400, +} + +RESOURCE_PRIORITY :: enum u32 { + MINIMUM = 0x28000000, + LOW = 0x50000000, + NORMAL = 0x78000000, + HIGH = 0xa0000000, + MAXIMUM = 0xc8000000, +} + +MAP :: enum u32 { // TODO: convert to bit_set + READ = 1, + WRITE = 2, + DISCARD = 4, +} + +ENUM_MODES :: enum u32 { // TODO: convert to bit_set + INTERLACED = 1, + SCALING = 2, + STEREO = 4, + DISABLED_STEREO = 8, +} + +MAX_SWAP_CHAIN_BUFFERS :: 16 +PRESENT :: enum u32 { // TODO: convert to bit_set + TEST = 0x00000001, + DO_NOT_SEQUENCE = 0x00000002, + RESTART = 0x00000004, + DO_NOT_WAIT = 0x00000008, + STEREO_PREFER_RIGHT = 0x00000010, + STEREO_TEMPORARY_MONO = 0x00000020, + RESTRICT_TO_OUTPUT = 0x00000040, + USE_DURATION = 0x00000100, + ALLOW_TEARING = 0x00000200, +} + +MWA :: enum u32 { // TODO: convert to bit_set + NO_WINDOW_CHANGES = 1 << 0, + NO_ALT_ENTER = 1 << 1, + NO_PRINT_SCREEN = 1 << 2, + VALID = 0x7, +} + +SHARED_RESOURCE_READ :: 0x80000000 +SHARED_RESOURCE_WRITE :: 1 +CREATE_FACTORY_DEBUG :: 0x1 + +RATIONAL :: struct { + Numerator: u32, + Denominator: u32, +} + +SAMPLE_DESC :: struct { + Count: u32, + Quality: u32, +} + +COLOR_SPACE_TYPE :: enum i32 { + RGB_FULL_G22_NONE_P709 = 0, + RGB_FULL_G10_NONE_P709 = 1, + RGB_STUDIO_G22_NONE_P709 = 2, + RGB_STUDIO_G22_NONE_P2020 = 3, + RESERVED = 4, + YCBCR_FULL_G22_NONE_P709_X601 = 5, + YCBCR_STUDIO_G22_LEFT_P601 = 6, + YCBCR_FULL_G22_LEFT_P601 = 7, + YCBCR_STUDIO_G22_LEFT_P709 = 8, + YCBCR_FULL_G22_LEFT_P709 = 9, + YCBCR_STUDIO_G22_LEFT_P2020 = 10, + YCBCR_FULL_G22_LEFT_P2020 = 11, + RGB_FULL_G2084_NONE_P2020 = 12, + YCBCR_STUDIO_G2084_LEFT_P2020 = 13, + RGB_STUDIO_G2084_NONE_P2020 = 14, + YCBCR_STUDIO_G22_TOPLEFT_P2020 = 15, + YCBCR_STUDIO_G2084_TOPLEFT_P2020 = 16, + RGB_FULL_G22_NONE_P2020 = 17, + YCBCR_STUDIO_GHLG_TOPLEFT_P2020 = 18, + YCBCR_FULL_GHLG_TOPLEFT_P2020 = 19, + RGB_STUDIO_G24_NONE_P709 = 20, + RGB_STUDIO_G24_NONE_P2020 = 21, + YCBCR_STUDIO_G24_LEFT_P709 = 22, + YCBCR_STUDIO_G24_LEFT_P2020 = 23, + YCBCR_STUDIO_G24_TOPLEFT_P2020 = 24, + CUSTOM = -1, +} + +FORMAT :: enum i32 { + UNKNOWN = 0, + R32G32B32A32_TYPELESS = 1, + R32G32B32A32_FLOAT = 2, + R32G32B32A32_UINT = 3, + R32G32B32A32_SINT = 4, + R32G32B32_TYPELESS = 5, + R32G32B32_FLOAT = 6, + R32G32B32_UINT = 7, + R32G32B32_SINT = 8, + R16G16B16A16_TYPELESS = 9, + R16G16B16A16_FLOAT = 10, + R16G16B16A16_UNORM = 11, + R16G16B16A16_UINT = 12, + R16G16B16A16_SNORM = 13, + R16G16B16A16_SINT = 14, + R32G32_TYPELESS = 15, + R32G32_FLOAT = 16, + R32G32_UINT = 17, + R32G32_SINT = 18, + R32G8X24_TYPELESS = 19, + D32_FLOAT_S8X24_UINT = 20, + R32_FLOAT_X8X24_TYPELESS = 21, + X32_TYPELESS_G8X24_UINT = 22, + R10G10B10A2_TYPELESS = 23, + R10G10B10A2_UNORM = 24, + R10G10B10A2_UINT = 25, + R11G11B10_FLOAT = 26, + R8G8B8A8_TYPELESS = 27, + R8G8B8A8_UNORM = 28, + R8G8B8A8_UNORM_SRGB = 29, + R8G8B8A8_UINT = 30, + R8G8B8A8_SNORM = 31, + R8G8B8A8_SINT = 32, + R16G16_TYPELESS = 33, + R16G16_FLOAT = 34, + R16G16_UNORM = 35, + R16G16_UINT = 36, + R16G16_SNORM = 37, + R16G16_SINT = 38, + R32_TYPELESS = 39, + D32_FLOAT = 40, + R32_FLOAT = 41, + R32_UINT = 42, + R32_SINT = 43, + R24G8_TYPELESS = 44, + D24_UNORM_S8_UINT = 45, + R24_UNORM_X8_TYPELESS = 46, + X24_TYPELESS_G8_UINT = 47, + R8G8_TYPELESS = 48, + R8G8_UNORM = 49, + R8G8_UINT = 50, + R8G8_SNORM = 51, + R8G8_SINT = 52, + R16_TYPELESS = 53, + R16_FLOAT = 54, + D16_UNORM = 55, + R16_UNORM = 56, + R16_UINT = 57, + R16_SNORM = 58, + R16_SINT = 59, + R8_TYPELESS = 60, + R8_UNORM = 61, + R8_UINT = 62, + R8_SNORM = 63, + R8_SINT = 64, + A8_UNORM = 65, + R1_UNORM = 66, + R9G9B9E5_SHAREDEXP = 67, + R8G8_B8G8_UNORM = 68, + G8R8_G8B8_UNORM = 69, + BC1_TYPELESS = 70, + BC1_UNORM = 71, + BC1_UNORM_SRGB = 72, + BC2_TYPELESS = 73, + BC2_UNORM = 74, + BC2_UNORM_SRGB = 75, + BC3_TYPELESS = 76, + BC3_UNORM = 77, + BC3_UNORM_SRGB = 78, + BC4_TYPELESS = 79, + BC4_UNORM = 80, + BC4_SNORM = 81, + BC5_TYPELESS = 82, + BC5_UNORM = 83, + BC5_SNORM = 84, + B5G6R5_UNORM = 85, + B5G5R5A1_UNORM = 86, + B8G8R8A8_UNORM = 87, + B8G8R8X8_UNORM = 88, + R10G10B10_XR_BIAS_A2_UNORM = 89, + B8G8R8A8_TYPELESS = 90, + B8G8R8A8_UNORM_SRGB = 91, + B8G8R8X8_TYPELESS = 92, + B8G8R8X8_UNORM_SRGB = 93, + BC6H_TYPELESS = 94, + BC6H_UF16 = 95, + BC6H_SF16 = 96, + BC7_TYPELESS = 97, + BC7_UNORM = 98, + BC7_UNORM_SRGB = 99, + AYUV = 100, + Y410 = 101, + Y416 = 102, + NV12 = 103, + P010 = 104, + P016 = 105, + _420_OPAQUE = 106, + YUY2 = 107, + Y210 = 108, + Y216 = 109, + NV11 = 110, + AI44 = 111, + IA44 = 112, + P8 = 113, + A8P8 = 114, + B4G4R4A4_UNORM = 115, + + P208 = 130, + V208 = 131, + V408 = 132, + + SAMPLER_FEEDBACK_MIN_MIP_OPAQUE = 189, + SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE = 190, + + FORCE_UINT = -1, +} + +RGB :: struct { + Red: f32, + Green: f32, + Blue: f32, +} + +D3DCOLORVALUE :: struct { + r: f32, + g: f32, + b: f32, + a: f32, +} + +RGBA :: D3DCOLORVALUE + +GAMMA_CONTROL :: struct { + Scale: RGB, + Offset: RGB, + GammaCurve: [1025]RGB, +} + +GAMMA_CONTROL_CAPABILITIES :: struct { + ScaleAndOffsetSupported: BOOL, + MaxConvertedValue: f32, + MinConvertedValue: f32, + NumGammaControlPoints: u32, + ControlPointPositions: [1025]f32, +} + +MODE_SCANLINE_ORDER :: enum i32 { + UNSPECIFIED = 0, + PROGRESSIVE = 1, + UPPER_FIELD_FIRST = 2, + LOWER_FIELD_FIRST = 3, +} + +MODE_SCALING :: enum i32 { + UNSPECIFIED = 0, + CENTERED = 1, + STRETCHED = 2, +} + +MODE_ROTATION :: enum i32 { + UNSPECIFIED = 0, + IDENTITY = 1, + ROTATE90 = 2, + ROTATE180 = 3, + ROTATE270 = 4, +} + +MODE_DESC :: struct { + Width: u32, + Height: u32, + RefreshRate: RATIONAL, + Format: FORMAT, + ScanlineOrdering: MODE_SCANLINE_ORDER, + Scaling: MODE_SCALING, +} + +JPEG_DC_HUFFMAN_TABLE :: struct { + CodeCounts: [12]u8, + CodeValues: [12]u8, +} + +JPEG_AC_HUFFMAN_TABLE :: struct { + CodeCounts: [16]u8, + CodeValues: [162]u8, +} + +JPEG_QUANTIZATION_TABLE :: struct { + Elements: [64]u8, +} + +FRAME_STATISTICS :: struct { + PresentCount: u32, + PresentRefreshCount: u32, + SyncRefreshCount: u32, + SyncQPCTime: LARGE_INTEGER, + SyncGPUTime: LARGE_INTEGER, +} + +MAPPED_RECT :: struct { + Pitch: i32, + pBits: [^]u8, +} + +ADAPTER_DESC :: struct { + Description: [128]i16, + VendorId: u32, + DeviceId: u32, + SubSysId: u32, + Revision: u32, + DedicatedVideoMemory: SIZE_T, + DedicatedSystemMemory: SIZE_T, + SharedSystemMemory: SIZE_T, + AdapterLuid: LUID, +} + +OUTPUT_DESC :: struct { + DeviceName: [32]i16, + DesktopCoordinates: RECT, + AttachedToDesktop: BOOL, + Rotation: MODE_ROTATION, + Monitor: HMONITOR, +} + +SHARED_RESOURCE :: struct { + Handle: HANDLE, +} + +RESIDENCY :: enum i32 { + FULLY_RESIDENT = 1, + RESIDENT_IN_SHARED_MEMORY = 2, + EVICTED_TO_DISK = 3, +} + +SURFACE_DESC :: struct { + Width: u32, + Height: u32, + Format: FORMAT, + SampleDesc: SAMPLE_DESC, +} + +SWAP_EFFECT :: enum i32 { + DISCARD = 0, + SEQUENTIAL = 1, + FLIP_SEQUENTIAL = 3, + FLIP_DISCARD = 4, +} + +SWAP_CHAIN_FLAG :: enum u32 { // TODO: convert to bit_set + NONPREROTATED = 0x1, + ALLOW_MODE_SWITCH = 0x2, + GDI_COMPATIBLE = 0x4, + RESTRICTED_CONTENT = 0x8, + RESTRICT_SHARED_RESOURCE_DRIVER = 0x10, + DISPLAY_ONLY = 0x20, + FRAME_LATENCY_WAITABLE_OBJECT = 0x40, + FOREGROUND_LAYER = 0x80, + FULLSCREEN_VIDEO = 0x100, + YUV_VIDEO = 0x200, + HW_PROTECTED = 0x400, + ALLOW_TEARING = 0x800, + RESTRICTED_TO_ALL_HOLOGRAPHIC_DISPLAYS = 0x1000, +} + +SWAP_CHAIN_DESC :: struct { + BufferDesc: MODE_DESC, + SampleDesc: SAMPLE_DESC, + BufferUsage: USAGE, + BufferCount: u32, + OutputWindow: HWND, + Windowed: BOOL, + SwapEffect: SWAP_EFFECT, + Flags: u32, +} + + +IObject_UUID_STRING :: "AEC22FB8-76F3-4639-9BE0-28EB43A67A2E" +IObject_UUID := &IID{0xAEC22FB8, 0x76F3, 0x4639, {0x9B, 0xE0, 0x28, 0xEB, 0x43, 0xA6, 0x7A, 0x2E}} +IObject :: struct #raw_union { + #subtype iunknown: IUnknown, + using vtable: ^IObject_VTable, +} +IObject_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + SetPrivateData: proc "stdcall" (this: ^IObject, Name: ^GUID, DataSize: u32, pData: rawptr) -> HRESULT, + SetPrivateDataInterface: proc "stdcall" (this: ^IObject, Name: ^GUID, pUnknown: ^IUnknown) -> HRESULT, + GetPrivateData: proc "stdcall" (this: ^IObject, Name: ^GUID, pDataSize: ^u32, pData: rawptr) -> HRESULT, + GetParent: proc "stdcall" (this: ^IObject, riid: ^IID, ppParent: ^rawptr) -> HRESULT, +} + +IDeviceSubObject_UUID_STRING :: "3D3E0379-F9DE-4D58-BB6C-18D62992F1A6" +IDeviceSubObject_UUID := &IID{0x3D3E0379, 0xF9DE, 0x4D58, {0xBB, 0x6C, 0x18, 0xD6, 0x29, 0x92, 0xF1, 0xA6}} +IDeviceSubObject :: struct #raw_union { + #subtype idxgiobject: IObject, + using idxgidevicesubobject_vtable: ^IDeviceSubObject_VTable, +} +IDeviceSubObject_VTable :: struct { + using idxgiobject_vtable: IObject_VTable, + GetDevice: proc "stdcall" (this: ^IDeviceSubObject, riid: ^IID, ppDevice: ^rawptr) -> HRESULT, +} + +IResource_UUID_STRING :: "035F3AB4-482E-4E50-B41F-8A7F8BD8960B" +IResource_UUID := &IID{0x035F3AB4, 0x482E, 0x4E50, {0xB4, 0x1F, 0x8A, 0x7F, 0x8B, 0xD8, 0x96, 0x0B}} +IResource :: struct #raw_union { + #subtype idxgidevicesubobject: IDeviceSubObject, + using idxgiresource_vtable: ^IResource_VTable, +} +IResource_VTable :: struct { + using idxgidevicesubobject_vtable: IDeviceSubObject_VTable, + GetSharedHandle: proc "stdcall" (this: ^IResource, pSharedHandle: ^HANDLE) -> HRESULT, + GetUsage: proc "stdcall" (this: ^IResource, pUsage: ^USAGE) -> HRESULT, + SetEvictionPriority: proc "stdcall" (this: ^IResource, EvictionPriority: u32) -> HRESULT, + GetEvictionPriority: proc "stdcall" (this: ^IResource, pEvictionPriority: ^u32) -> HRESULT, +} + +IKeyedMutex_UUID_STRING :: "9D8E1289-D7B3-465F-8126-250E349AF85D" +IKeyedMutex_UUID := &IID{0x9D8E1289, 0xD7B3, 0x465F, {0x81, 0x26, 0x25, 0x0E, 0x34, 0x9A, 0xF8, 0x5D}} +IKeyedMutex :: struct #raw_union { + #subtype idxgidevicesubobject: IDeviceSubObject, + using idxgikeyedmutex_vtable: ^IKeyedMutex_VTable, +} +IKeyedMutex_VTable :: struct { + using idxgidevicesubobject_vtable: IDeviceSubObject_VTable, + AcquireSync: proc "stdcall" (this: ^IKeyedMutex, Key: u64, dwMilliseconds: u32) -> HRESULT, + ReleaseSync: proc "stdcall" (this: ^IKeyedMutex, Key: u64) -> HRESULT, +} + +ISurface_UUID_STRING :: "CAFCB56C-6AC3-4889-BF47-9E23BBD260EC" +ISurface_UUID := &IID{0xCAFCB56C, 0x6AC3, 0x4889, {0xBF, 0x47, 0x9E, 0x23, 0xBB, 0xD2, 0x60, 0xEC}} +ISurface :: struct #raw_union { + #subtype idxgidevicesubobject: IDeviceSubObject, + using idxgisurface_vtable: ^ISurface_VTable, +} +ISurface_VTable :: struct { + using idxgidevicesubobject_vtable: IDeviceSubObject_VTable, + GetDesc: proc "stdcall" (this: ^ISurface, pDesc: ^SURFACE_DESC) -> HRESULT, + Map: proc "stdcall" (this: ^ISurface, pLockedRect: ^MAPPED_RECT, MapFlags: u32) -> HRESULT, + Unmap: proc "stdcall" (this: ^ISurface) -> HRESULT, +} + +ISurface1_UUID_STRING :: "4AE63092-6327-4C1B-80AE-BFE12EA32B86" +ISurface1_UUID := &IID{0x4AE63092, 0x6327, 0x4C1B, {0x80, 0xAE, 0xBF, 0xE1, 0x2E, 0xA3, 0x2B, 0x86}} +ISurface1 :: struct #raw_union { + #subtype idxgisurface: ISurface, + using idxgisurface1_vtable: ^ISurface1_VTable, +} +ISurface1_VTable :: struct { + using idxgisurface_vtable: ISurface_VTable, + GetDC: proc "stdcall" (this: ^ISurface1, Discard: BOOL, phdc: ^HDC) -> HRESULT, + ReleaseDC: proc "stdcall" (this: ^ISurface1, pDirtyRect: ^RECT) -> HRESULT, +} + +IAdapter_UUID_STRING :: "2411E7E1-12AC-4CCF-BD14-9798E8534DC0" +IAdapter_UUID := &IID{0x2411E7E1, 0x12AC, 0x4CCF, {0xBD, 0x14, 0x97, 0x98, 0xE8, 0x53, 0x4D, 0xC0}} +IAdapter :: struct #raw_union { + #subtype idxgiobject: IObject, + using idxgiadapter_vtable: ^IAdapter_VTable, +} +IAdapter_VTable :: struct { + using idxgiobject_vtable: IObject_VTable, + EnumOutputs: proc "stdcall" (this: ^IAdapter, Output: u32, ppOutput: ^^IOutput) -> HRESULT, + GetDesc: proc "stdcall" (this: ^IAdapter, pDesc: ^ADAPTER_DESC) -> HRESULT, + CheckInterfaceSupport: proc "stdcall" (this: ^IAdapter, InterfaceName: ^GUID, pUMDVersion: ^LARGE_INTEGER) -> HRESULT, +} + +IOutput_UUID_STRING :: "AE02EEDB-C735-4690-8D52-5A8DC20213AA" +IOutput_UUID := &IID{0xAE02EEDB, 0xC735, 0x4690, {0x8D, 0x52, 0x5A, 0x8D, 0xC2, 0x02, 0x13, 0xAA}} +IOutput :: struct #raw_union { + #subtype idxgiobject: IObject, + using idxgioutput_vtable: ^IOutput_VTable, +} +IOutput_VTable :: struct { + using idxgiobject_vtable: IObject_VTable, + GetDesc: proc "stdcall" (this: ^IOutput, pDesc: ^OUTPUT_DESC) -> HRESULT, + GetDisplayModeList: proc "stdcall" (this: ^IOutput, EnumFormat: FORMAT, Flags: u32, pNumModes: ^u32, pDesc: ^MODE_DESC) -> HRESULT, + FindClosestMatchingMode: proc "stdcall" (this: ^IOutput, pModeToMatch: ^MODE_DESC, pClosestMatch: ^MODE_DESC, pConcernedDevice: ^IUnknown) -> HRESULT, + WaitForVBlank: proc "stdcall" (this: ^IOutput) -> HRESULT, + TakeOwnership: proc "stdcall" (this: ^IOutput, pDevice: ^IUnknown, Exclusive: BOOL) -> HRESULT, + ReleaseOwnership: proc "stdcall" (this: ^IOutput), + GetGammaControlCapabilities: proc "stdcall" (this: ^IOutput, pGammaCaps: ^GAMMA_CONTROL_CAPABILITIES) -> HRESULT, + SetGammaControl: proc "stdcall" (this: ^IOutput, pArray: ^GAMMA_CONTROL) -> HRESULT, + GetGammaControl: proc "stdcall" (this: ^IOutput, pArray: ^GAMMA_CONTROL) -> HRESULT, + SetDisplaySurface: proc "stdcall" (this: ^IOutput, pScanoutSurface: ^ISurface) -> HRESULT, + GetDisplaySurfaceData: proc "stdcall" (this: ^IOutput, pDestination: ^ISurface) -> HRESULT, + GetFrameStatistics: proc "stdcall" (this: ^IOutput, pStats: ^FRAME_STATISTICS) -> HRESULT, +} + +ISwapChain_UUID_STRING :: "310D36A0-D2E7-4C0A-AA04-6A9D23B8886A" +ISwapChain_UUID := &IID{0x310D36A0, 0xD2E7, 0x4C0A, {0xAA, 0x04, 0x6A, 0x9D, 0x23, 0xB8, 0x88, 0x6A}} +ISwapChain :: struct #raw_union { + #subtype idxgidevicesubobject: IDeviceSubObject, + using idxgiswapchain_vtable: ^ISwapChain_VTable, +} +ISwapChain_VTable :: struct { + using idxgidevicesubobject_vtable: IDeviceSubObject_VTable, + Present: proc "stdcall" (this: ^ISwapChain, SyncInterval: u32, Flags: u32) -> HRESULT, + GetBuffer: proc "stdcall" (this: ^ISwapChain, Buffer: u32, riid: ^IID, ppSurface: ^rawptr) -> HRESULT, + SetFullscreenState: proc "stdcall" (this: ^ISwapChain, Fullscreen: BOOL, pTarget: ^IOutput) -> HRESULT, + GetFullscreenState: proc "stdcall" (this: ^ISwapChain, pFullscreen: ^BOOL, ppTarget: ^^IOutput) -> HRESULT, + GetDesc: proc "stdcall" (this: ^ISwapChain, pDesc: ^SWAP_CHAIN_DESC) -> HRESULT, + ResizeBuffers: proc "stdcall" (this: ^ISwapChain, BufferCount: u32, Width: u32, Height: u32, NewFormat: FORMAT, SwapChainFlags: u32) -> HRESULT, + ResizeTarget: proc "stdcall" (this: ^ISwapChain, pNewTargetParameters: ^MODE_DESC) -> HRESULT, + GetContainingOutput: proc "stdcall" (this: ^ISwapChain, ppOutput: ^^IOutput) -> HRESULT, + GetFrameStatistics: proc "stdcall" (this: ^ISwapChain, pStats: ^FRAME_STATISTICS) -> HRESULT, + GetLastPresentCount: proc "stdcall" (this: ^ISwapChain, pLastPresentCount: ^u32) -> HRESULT, +} + +IFactory_UUID_STRING :: "7B7166EC-21C7-44AE-B21A-C9AE321AE369" +IFactory_UUID := &IID{0x7B7166EC, 0x21C7, 0x44AE, {0xB2, 0x1A, 0xC9, 0xAE, 0x32, 0x1A, 0xE3, 0x69}} +IFactory :: struct #raw_union { + #subtype idxgiobject: IObject, + using idxgifactory_vtable: ^IFactory_VTable, +} +IFactory_VTable :: struct { + using idxgiobject_vtable: IObject_VTable, + EnumAdapters: proc "stdcall" (this: ^IFactory, Adapter: u32, ppAdapter: ^^IAdapter) -> HRESULT, + MakeWindowAssociation: proc "stdcall" (this: ^IFactory, WindowHandle: HWND, Flags: u32) -> HRESULT, + GetWindowAssociation: proc "stdcall" (this: ^IFactory, pWindowHandle: ^HWND) -> HRESULT, + CreateSwapChain: proc "stdcall" (this: ^IFactory, pDevice: ^IUnknown, pDesc: ^SWAP_CHAIN_DESC, ppSwapChain: ^^ISwapChain) -> HRESULT, + CreateSoftwareAdapter: proc "stdcall" (this: ^IFactory, Module: HMODULE, ppAdapter: ^^IAdapter) -> HRESULT, +} +IDevice_UUID_STRING :: "54EC77FA-1377-44E6-8C32-88FD5F44C84C" +IDevice_UUID := &IID{0x54EC77FA, 0x1377, 0x44E6, {0x8C, 0x32, 0x88, 0xFD, 0x5F, 0x44, 0xC8, 0x4C}} +IDevice :: struct #raw_union { + #subtype idxgiobject: IObject, + using idxgidevice_vtable: ^IDevice_VTable, +} +IDevice_VTable :: struct { + using idxgiobject_vtable: IObject_VTable, + GetAdapter: proc "stdcall" (this: ^IDevice, pAdapter: ^^IAdapter) -> HRESULT, + CreateSurface: proc "stdcall" (this: ^IDevice, pDesc: ^SURFACE_DESC, NumSurfaces: u32, Usage: USAGE, pSharedResource: ^SHARED_RESOURCE, ppSurface: ^^ISurface) -> HRESULT, + QueryResourceResidency: proc "stdcall" (this: ^IDevice, ppResources: ^^IUnknown, pResidencyStatus: ^RESIDENCY, NumResources: u32) -> HRESULT, + SetGPUThreadPriority: proc "stdcall" (this: ^IDevice, Priority: i32) -> HRESULT, + GetGPUThreadPriority: proc "stdcall" (this: ^IDevice, pPriority: ^i32) -> HRESULT, +} +ADAPTER_FLAG :: enum u32 { // TODO: convert to bit_set + NONE = 0x0, + REMOTE = 0x1, + SOFTWARE = 0x2, + FORCE_DWORD = 0xffffffff, +} + +ADAPTER_DESC1 :: struct { + Description: [128]i16, + VendorId: u32, + DeviceId: u32, + SubSysId: u32, + Revision: u32, + DedicatedVideoMemory: SIZE_T, + DedicatedSystemMemory: SIZE_T, + SharedSystemMemory: SIZE_T, + AdapterLuid: LUID, + Flags: u32, +} + +DISPLAY_COLOR_SPACE :: struct { + PrimaryCoordinates: [8][2]f32, + WhitePoints: [16][2]f32, +} + + +IFactory1_UUID_STRING :: "770AAE78-F26F-4DBA-A829-253C83D1B387" +IFactory1_UUID := &IID{0x770AAE78, 0xF26F, 0x4DBA, {0xA8, 0x29, 0x25, 0x3C, 0x83, 0xD1, 0xB3, 0x87}} +IFactory1 :: struct #raw_union { + #subtype idxgifactory: IFactory, + using idxgifactory1_vtable: ^IFactory1_VTable, +} +IFactory1_VTable :: struct { + using idxgifactory_vtable: IFactory_VTable, + EnumAdapters1: proc "stdcall" (this: ^IFactory1, Adapter: u32, ppAdapter: ^^IAdapter1) -> HRESULT, + IsCurrent: proc "stdcall" (this: ^IFactory1) -> BOOL, +} + +IAdapter1_UUID_STRING :: "29038F61-3839-4626-91FD-086879011A05" +IAdapter1_UUID := &IID{0x29038F61, 0x3839, 0x4626, {0x91, 0xFD, 0x08, 0x68, 0x79, 0x01, 0x1A, 0x05}} +IAdapter1 :: struct #raw_union { + #subtype idxgiadapter: IAdapter, + using idxgiadapter1_vtable: ^IAdapter1_VTable, +} +IAdapter1_VTable :: struct { + using idxgiadapter_vtable: IAdapter_VTable, + GetDesc1: proc "stdcall" (this: ^IAdapter1, pDesc: ^ADAPTER_DESC1) -> HRESULT, +} + +IDevice1_UUID_STRING :: "77DB970F-6276-48BA-BA28-070143B4392C" +IDevice1_UUID := &IID{0x77DB970F, 0x6276, 0x48BA, {0xBA, 0x28, 0x07, 0x01, 0x43, 0xB4, 0x39, 0x2C}} +IDevice1 :: struct #raw_union { + #subtype idxgidevice: IDevice, + using idxgidevice1_vtable: ^IDevice1_VTable, +} +IDevice1_VTable :: struct { + using idxgidevice_vtable: IDevice_VTable, + SetMaximumFrameLatency: proc "stdcall" (this: ^IDevice1, MaxLatency: u32) -> HRESULT, + GetMaximumFrameLatency: proc "stdcall" (this: ^IDevice1, pMaxLatency: ^u32) -> HRESULT, +} + +IDisplayControl_UUID_STRING :: "EA9DBF1A-C88E-4486-854A-98AA0138F30C" +IDisplayControl_UUID := &IID{0xEA9DBF1A, 0xC88E, 0x4486, {0x85, 0x4A, 0x98, 0xAA, 0x01, 0x38, 0xF3, 0x0C}} +IDisplayControl :: struct #raw_union { + #subtype iunknown: IUnknown, + using idxgidisplaycontrol_vtable: ^IDisplayControl_VTable, +} +IDisplayControl_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + IsStereoEnabled: proc "stdcall" (this: ^IDisplayControl) -> BOOL, + SetStereoEnabled: proc "stdcall" (this: ^IDisplayControl, enabled: BOOL), +} +OUTDUPL_MOVE_RECT :: struct { + SourcePoint: POINT, + DestinationRect: RECT, +} + +OUTDUPL_DESC :: struct { + ModeDesc: MODE_DESC, + Rotation: MODE_ROTATION, + DesktopImageInSystemMemory: BOOL, +} + +OUTDUPL_POINTER_POSITION :: struct { + Position: POINT, + Visible: BOOL, +} + +OUTDUPL_POINTER_SHAPE_TYPE :: enum i32 { + MONOCHROME = 1, + COLOR = 2, + MASKED_COLOR = 4, +} + +OUTDUPL_POINTER_SHAPE_INFO :: struct { + Type: u32, + Width: u32, + Height: u32, + Pitch: u32, + HotSpot: POINT, +} + +OUTDUPL_FRAME_INFO :: struct { + LastPresentTime: LARGE_INTEGER, + LastMouseUpdateTime: LARGE_INTEGER, + AccumulatedFrames: u32, + RectsCoalesced: BOOL, + ProtectedContentMaskedOut: BOOL, + PointerPosition: OUTDUPL_POINTER_POSITION, + TotalMetadataBufferSize: u32, + PointerShapeBufferSize: u32, +} + + +IOutputDuplication_UUID_STRING :: "191CFAC3-A341-470D-B26E-A864F428319C" +IOutputDuplication_UUID := &IID{0x191CFAC3, 0xA341, 0x470D, {0xB2, 0x6E, 0xA8, 0x64, 0xF4, 0x28, 0x31, 0x9C}} +IOutputDuplication :: struct #raw_union { + #subtype idxgiobject: IObject, + using idxgioutputduplication_vtable: ^IOutputDuplication_VTable, +} +IOutputDuplication_VTable :: struct { + using idxgiobject_vtable: IObject_VTable, + GetDesc: proc "stdcall" (this: ^IOutputDuplication, pDesc: ^OUTDUPL_DESC), + AcquireNextFrame: proc "stdcall" (this: ^IOutputDuplication, TimeoutInMilliseconds: u32, pFrameInfo: ^OUTDUPL_FRAME_INFO, ppDesktopResource: ^^IResource) -> HRESULT, + GetFrameDirtyRects: proc "stdcall" (this: ^IOutputDuplication, DirtyRectsBufferSize: u32, pDirtyRectsBuffer: ^RECT, pDirtyRectsBufferSizeRequired: ^u32) -> HRESULT, + GetFrameMoveRects: proc "stdcall" (this: ^IOutputDuplication, MoveRectsBufferSize: u32, pMoveRectBuffer: ^OUTDUPL_MOVE_RECT, pMoveRectsBufferSizeRequired: ^u32) -> HRESULT, + GetFramePointerShape: proc "stdcall" (this: ^IOutputDuplication, PointerShapeBufferSize: u32, pPointerShapeBuffer: rawptr, pPointerShapeBufferSizeRequired: ^u32, pPointerShapeInfo: ^OUTDUPL_POINTER_SHAPE_INFO) -> HRESULT, + MapDesktopSurface: proc "stdcall" (this: ^IOutputDuplication, pLockedRect: ^MAPPED_RECT) -> HRESULT, + UnMapDesktopSurface: proc "stdcall" (this: ^IOutputDuplication) -> HRESULT, + ReleaseFrame: proc "stdcall" (this: ^IOutputDuplication) -> HRESULT, +} +ALPHA_MODE :: enum i32 { + UNSPECIFIED = 0, + PREMULTIPLIED = 1, + STRAIGHT = 2, + IGNORE = 3, + FORCE_DWORD = -1, +} + + +ISurface2_UUID_STRING :: "ABA496DD-B617-4CB8-A866-BC44D7EB1FA2" +ISurface2_UUID := &IID{0xABA496DD, 0xB617, 0x4CB8, {0xA8, 0x66, 0xBC, 0x44, 0xD7, 0xEB, 0x1F, 0xA2}} +ISurface2 :: struct #raw_union { + #subtype idxgisurface1: ISurface1, + using idxgisurface2_vtable: ^ISurface2_VTable, +} +ISurface2_VTable :: struct { + using idxgisurface1_vtable: ISurface1_VTable, + GetResource: proc "stdcall" (this: ^ISurface2, riid: ^IID, ppParentResource: ^rawptr, pSubresourceIndex: ^u32) -> HRESULT, +} + +IResource1_UUID_STRING :: "30961379-4609-4A41-998E-54FE567EE0C1" +IResource1_UUID := &IID{0x30961379, 0x4609, 0x4A41, {0x99, 0x8E, 0x54, 0xFE, 0x56, 0x7E, 0xE0, 0xC1}} +IResource1 :: struct #raw_union { + #subtype idxgiresource: IResource, + using idxgiresource1_vtable: ^IResource1_VTable, +} +IResource1_VTable :: struct { + using idxgiresource_vtable: IResource_VTable, + CreateSubresourceSurface: proc "stdcall" (this: ^IResource1, index: u32, ppSurface: ^^ISurface2) -> HRESULT, + CreateSharedHandle: proc "stdcall" (this: ^IResource1, pAttributes: ^win32.SECURITY_ATTRIBUTES, dwAccess: u32, lpName: ^i16, pHandle: ^HANDLE) -> HRESULT, +} +OFFER_RESOURCE_PRIORITY :: enum i32 { + LOW = 1, + NORMAL = 2, + HIGH = 3, +} + + +IDevice2_UUID_STRING :: "05008617-FBFD-4051-A790-144884B4F6A9" +IDevice2_UUID := &IID{0x05008617, 0xFBFD, 0x4051, {0xA7, 0x90, 0x14, 0x48, 0x84, 0xB4, 0xF6, 0xA9}} +IDevice2 :: struct #raw_union { + #subtype idxgidevice1: IDevice1, + using idxgidevice2_vtable: ^IDevice2_VTable, +} +IDevice2_VTable :: struct { + using idxgidevice1_vtable: IDevice1_VTable, + OfferResources: proc "stdcall" (this: ^IDevice2, NumResources: u32, ppResources: ^^IResource, Priority: OFFER_RESOURCE_PRIORITY) -> HRESULT, + ReclaimResources: proc "stdcall" (this: ^IDevice2, NumResources: u32, ppResources: ^^IResource, pDiscarded: ^BOOL) -> HRESULT, + EnqueueSetEvent: proc "stdcall" (this: ^IDevice2, hEvent: HANDLE) -> HRESULT, +} +MODE_DESC1 :: struct { + Width: u32, + Height: u32, + RefreshRate: RATIONAL, + Format: FORMAT, + ScanlineOrdering: MODE_SCANLINE_ORDER, + Scaling: MODE_SCALING, + Stereo: BOOL, +} + +SCALING :: enum i32 { + STRETCH = 0, + NONE = 1, + ASPECT_RATIO_STRETCH = 2, +} + +SWAP_CHAIN_DESC1 :: struct { + Width: u32, + Height: u32, + Format: FORMAT, + Stereo: BOOL, + SampleDesc: SAMPLE_DESC, + BufferUsage: USAGE, + BufferCount: u32, + Scaling: SCALING, + SwapEffect: SWAP_EFFECT, + AlphaMode: ALPHA_MODE, + Flags: u32, +} + +SWAP_CHAIN_FULLSCREEN_DESC :: struct { + RefreshRate: RATIONAL, + ScanlineOrdering: MODE_SCANLINE_ORDER, + Scaling: MODE_SCALING, + Windowed: BOOL, +} + +PRESENT_PARAMETERS :: struct { + DirtyRectsCount: u32, + + pDirtyRects: [^]RECT, + pScrollRect: ^RECT, + pScrollOffset: ^POINT, +} + + +ISwapChain1_UUID_STRING :: "790A45F7-0D42-4876-983A-0A55CFE6F4AA" +ISwapChain1_UUID := &IID{0x790A45F7, 0x0D42, 0x4876, {0x98, 0x3A, 0x0A, 0x55, 0xCF, 0xE6, 0xF4, 0xAA}} +ISwapChain1 :: struct #raw_union { + #subtype idxgiswapchain: ISwapChain, + using idxgiswapchain1_vtable: ^ISwapChain1_VTable, +} +ISwapChain1_VTable :: struct { + using idxgiswapchain_vtable: ISwapChain_VTable, + GetDesc1: proc "stdcall" (this: ^ISwapChain1, pDesc: ^SWAP_CHAIN_DESC1) -> HRESULT, + GetFullscreenDesc: proc "stdcall" (this: ^ISwapChain1, pDesc: ^SWAP_CHAIN_FULLSCREEN_DESC) -> HRESULT, + GetHwnd: proc "stdcall" (this: ^ISwapChain1, pHwnd: ^HWND) -> HRESULT, + GetCoreWindow: proc "stdcall" (this: ^ISwapChain1, refiid: ^IID, ppUnk: ^rawptr) -> HRESULT, + Present1: proc "stdcall" (this: ^ISwapChain1, SyncInterval: u32, PresentFlags: u32, pPresentParameters: ^PRESENT_PARAMETERS) -> HRESULT, + IsTemporaryMonoSupported: proc "stdcall" (this: ^ISwapChain1) -> BOOL, + GetRestrictToOutput: proc "stdcall" (this: ^ISwapChain1, ppRestrictToOutput: ^^IOutput) -> HRESULT, + SetBackgroundColor: proc "stdcall" (this: ^ISwapChain1, pColor: ^RGBA) -> HRESULT, + GetBackgroundColor: proc "stdcall" (this: ^ISwapChain1, pColor: ^RGBA) -> HRESULT, + SetRotation: proc "stdcall" (this: ^ISwapChain1, Rotation: MODE_ROTATION) -> HRESULT, + GetRotation: proc "stdcall" (this: ^ISwapChain1, pRotation: ^MODE_ROTATION) -> HRESULT, +} + +IFactory2_UUID_STRING :: "50C83A1C-E072-4C48-87B0-3630FA36A6D0" +IFactory2_UUID := &IID{0x50C83A1C, 0xE072, 0x4C48, {0x87, 0xB0, 0x36, 0x30, 0xFA, 0x36, 0xA6, 0xD0}} +IFactory2 :: struct #raw_union { + #subtype idxgifactory1: IFactory1, + using idxgifactory2_vtable: ^IFactory2_VTable, +} +IFactory2_VTable :: struct { + using idxgifactory1_vtable: IFactory1_VTable, + IsWindowedStereoEnabled: proc "stdcall" (this: ^IFactory2) -> BOOL, + CreateSwapChainForHwnd: proc "stdcall" (this: ^IFactory2, pDevice: ^IUnknown, hWnd: HWND, pDesc: ^SWAP_CHAIN_DESC1, pFullscreenDesc: ^SWAP_CHAIN_FULLSCREEN_DESC, pRestrictToOutput: ^IOutput, ppSwapChain: ^^ISwapChain1) -> HRESULT, + CreateSwapChainForCoreWindow: proc "stdcall" (this: ^IFactory2, pDevice: ^IUnknown, pWindow: ^IUnknown, pDesc: ^SWAP_CHAIN_DESC1, pRestrictToOutput: ^IOutput, ppSwapChain: ^^ISwapChain1) -> HRESULT, + GetSharedResourceAdapterLuid: proc "stdcall" (this: ^IFactory2, hResource: HANDLE, pLuid: ^LUID) -> HRESULT, + RegisterStereoStatusWindow: proc "stdcall" (this: ^IFactory2, WindowHandle: HWND, wMsg: u32, pdwCookie: ^u32) -> HRESULT, + RegisterStereoStatusEvent: proc "stdcall" (this: ^IFactory2, hEvent: HANDLE, pdwCookie: ^u32) -> HRESULT, + UnregisterStereoStatus: proc "stdcall" (this: ^IFactory2, dwCookie: u32), + RegisterOcclusionStatusWindow: proc "stdcall" (this: ^IFactory2, WindowHandle: HWND, wMsg: u32, pdwCookie: ^u32) -> HRESULT, + RegisterOcclusionStatusEvent: proc "stdcall" (this: ^IFactory2, hEvent: HANDLE, pdwCookie: ^u32) -> HRESULT, + UnregisterOcclusionStatus: proc "stdcall" (this: ^IFactory2, dwCookie: u32), + CreateSwapChainForComposition: proc "stdcall" (this: ^IFactory2, pDevice: ^IUnknown, pDesc: ^SWAP_CHAIN_DESC1, pRestrictToOutput: ^IOutput, ppSwapChain: ^^ISwapChain1) -> HRESULT, +} +GRAPHICS_PREEMPTION_GRANULARITY :: enum i32 { + DMA_BUFFER_BOUNDARY = 0, + PRIMITIVE_BOUNDARY = 1, + TRIANGLE_BOUNDARY = 2, + PIXEL_BOUNDARY = 3, + INSTRUCTION_BOUNDARY = 4, +} + +COMPUTE_PREEMPTION_GRANULARITY :: enum i32 { + DMA_BUFFER_BOUNDARY = 0, + DISPATCH_BOUNDARY = 1, + THREAD_GROUP_BOUNDARY = 2, + THREAD_BOUNDARY = 3, + INSTRUCTION_BOUNDARY = 4, +} + +ADAPTER_DESC2 :: struct { + Description: [128]i16, + VendorId: u32, + DeviceId: u32, + SubSysId: u32, + Revision: u32, + DedicatedVideoMemory: SIZE_T, + DedicatedSystemMemory: SIZE_T, + SharedSystemMemory: SIZE_T, + AdapterLuid: LUID, + Flags: u32, + GraphicsPreemptionGranularity: GRAPHICS_PREEMPTION_GRANULARITY, + ComputePreemptionGranularity: COMPUTE_PREEMPTION_GRANULARITY, +} + + +IAdapter2_UUID_STRING :: "0AA1AE0A-FA0E-4B84-8644-E05FF8E5ACB5" +IAdapter2_UUID := &IID{0x0AA1AE0A, 0xFA0E, 0x4B84, {0x86, 0x44, 0xE0, 0x5F, 0xF8, 0xE5, 0xAC, 0xB5}} +IAdapter2 :: struct #raw_union { + #subtype idxgiadapter1: IAdapter1, + using idxgiadapter2_vtable: ^IAdapter2_VTable, +} +IAdapter2_VTable :: struct { + using idxgiadapter1_vtable: IAdapter1_VTable, + GetDesc2: proc "stdcall" (this: ^IAdapter2, pDesc: ^ADAPTER_DESC2) -> HRESULT, +} + +IOutput1_UUID_STRING :: "00CDDEA8-939B-4B83-A340-A685226666CC" +IOutput1_UUID := &IID{0x00CDDEA8, 0x939B, 0x4B83, {0xA3, 0x40, 0xA6, 0x85, 0x22, 0x66, 0x66, 0xCC}} +IOutput1 :: struct #raw_union { + #subtype idxgioutput: IOutput, + using idxgioutput1_vtable: ^IOutput1_VTable, +} +IOutput1_VTable :: struct { + using idxgioutput_vtable: IOutput_VTable, + GetDisplayModeList1: proc "stdcall" (this: ^IOutput1, EnumFormat: FORMAT, Flags: u32, pNumModes: ^u32, pDesc: ^MODE_DESC1) -> HRESULT, + FindClosestMatchingMode1: proc "stdcall" (this: ^IOutput1, pModeToMatch: ^MODE_DESC1, pClosestMatch: ^MODE_DESC1, pConcernedDevice: ^IUnknown) -> HRESULT, + GetDisplaySurfaceData1: proc "stdcall" (this: ^IOutput1, pDestination: ^IResource) -> HRESULT, + DuplicateOutput: proc "stdcall" (this: ^IOutput1, pDevice: ^IUnknown, ppOutputDuplication: ^^IOutputDuplication) -> HRESULT, +} +IDevice3_UUID_STRING :: "6007896C-3244-4AFD-BF18-A6D3BEDA5023" +IDevice3_UUID := &IID{0x6007896C, 0x3244, 0x4AFD, {0xBF, 0x18, 0xA6, 0xD3, 0xBE, 0xDA, 0x50, 0x23}} +IDevice3 :: struct #raw_union { + #subtype idxgidevice2: IDevice2, + using idxgidevice3_vtable: ^IDevice3_VTable, +} +IDevice3_VTable :: struct { + using idxgidevice2_vtable: IDevice2_VTable, + Trim: proc "stdcall" (this: ^IDevice3), +} +MATRIX_3X2_F :: struct { + _11: f32, + _12: f32, + _21: f32, + _22: f32, + _31: f32, + _32: f32, +} + + +ISwapChain2_UUID_STRING :: "A8BE2AC4-199F-4946-B331-79599FB98DE7" +ISwapChain2_UUID := &IID{0xA8BE2AC4, 0x199F, 0x4946, {0xB3, 0x31, 0x79, 0x59, 0x9F, 0xB9, 0x8D, 0xE7}} +ISwapChain2 :: struct #raw_union { + #subtype idxgiswapchain1: ISwapChain1, + using idxgiswapchain2_vtable: ^ISwapChain2_VTable, +} +ISwapChain2_VTable :: struct { + using idxgiswapchain1_vtable: ISwapChain1_VTable, + SetSourceSize: proc "stdcall" (this: ^ISwapChain2, Width: u32, Height: u32) -> HRESULT, + GetSourceSize: proc "stdcall" (this: ^ISwapChain2, pWidth: ^u32, pHeight: ^u32) -> HRESULT, + SetMaximumFrameLatency: proc "stdcall" (this: ^ISwapChain2, MaxLatency: u32) -> HRESULT, + GetMaximumFrameLatency: proc "stdcall" (this: ^ISwapChain2, pMaxLatency: ^u32) -> HRESULT, + GetFrameLatencyWaitableObject: proc "stdcall" (this: ^ISwapChain2) -> HANDLE, + SetMatrixTransform: proc "stdcall" (this: ^ISwapChain2, pMatrix: ^MATRIX_3X2_F) -> HRESULT, + GetMatrixTransform: proc "stdcall" (this: ^ISwapChain2, pMatrix: ^MATRIX_3X2_F) -> HRESULT, +} + +IOutput2_UUID_STRING :: "595E39D1-2724-4663-99B1-DA969DE28364" +IOutput2_UUID := &IID{0x595E39D1, 0x2724, 0x4663, {0x99, 0xB1, 0xDA, 0x96, 0x9D, 0xE2, 0x83, 0x64}} +IOutput2 :: struct #raw_union { + #subtype idxgioutput1: IOutput1, + using idxgioutput2_vtable: ^IOutput2_VTable, +} +IOutput2_VTable :: struct { + using idxgioutput1_vtable: IOutput1_VTable, + SupportsOverlays: proc "stdcall" (this: ^IOutput2) -> BOOL, +} + +IFactory3_UUID_STRING :: "25483823-CD46-4C7D-86CA-47AA95B837BD" +IFactory3_UUID := &IID{0x25483823, 0xCD46, 0x4C7D, {0x86, 0xCA, 0x47, 0xAA, 0x95, 0xB8, 0x37, 0xBD}} +IFactory3 :: struct #raw_union { + #subtype idxgifactory2: IFactory2, + using idxgifactory3_vtable: ^IFactory3_VTable, +} +IFactory3_VTable :: struct { + using idxgifactory2_vtable: IFactory2_VTable, + GetCreationFlags: proc "stdcall" (this: ^IFactory3) -> u32, +} +DECODE_SWAP_CHAIN_DESC :: struct { + Flags: u32, +} + +MULTIPLANE_OVERLAY_YCbCr_FLAGS :: enum u32 { // TODO: convert to bit_set + NOMINAL_RANGE = 0x1, + BT709 = 0x2, + xvYCC = 0x4, +} + + +IDecodeSwapChain_UUID_STRING :: "2633066B-4514-4C7A-8FD8-12EA98059D18" +IDecodeSwapChain_UUID := &IID{0x2633066B, 0x4514, 0x4C7A, {0x8F, 0xD8, 0x12, 0xEA, 0x98, 0x05, 0x9D, 0x18}} +IDecodeSwapChain :: struct #raw_union { + #subtype iunknown: IUnknown, + using idxgidecodeswapchain_vtable: ^IDecodeSwapChain_VTable, +} +IDecodeSwapChain_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + PresentBuffer: proc "stdcall" (this: ^IDecodeSwapChain, BufferToPresent: u32, SyncInterval: u32, Flags: u32) -> HRESULT, + SetSourceRect: proc "stdcall" (this: ^IDecodeSwapChain, pRect: ^RECT) -> HRESULT, + SetTargetRect: proc "stdcall" (this: ^IDecodeSwapChain, pRect: ^RECT) -> HRESULT, + SetDestSize: proc "stdcall" (this: ^IDecodeSwapChain, Width: u32, Height: u32) -> HRESULT, + GetSourceRect: proc "stdcall" (this: ^IDecodeSwapChain, pRect: ^RECT) -> HRESULT, + GetTargetRect: proc "stdcall" (this: ^IDecodeSwapChain, pRect: ^RECT) -> HRESULT, + GetDestSize: proc "stdcall" (this: ^IDecodeSwapChain, pWidth: ^u32, pHeight: ^u32) -> HRESULT, + SetColorSpace: proc "stdcall" (this: ^IDecodeSwapChain, ColorSpace: MULTIPLANE_OVERLAY_YCbCr_FLAGS) -> HRESULT, + GetColorSpace: proc "stdcall" (this: ^IDecodeSwapChain) -> MULTIPLANE_OVERLAY_YCbCr_FLAGS, +} + +IFactoryMedia_UUID_STRING :: "41E7D1F2-A591-4F7B-A2E5-FA9C843E1C12" +IFactoryMedia_UUID := &IID{0x41E7D1F2, 0xA591, 0x4F7B, {0xA2, 0xE5, 0xFA, 0x9C, 0x84, 0x3E, 0x1C, 0x12}} +IFactoryMedia :: struct #raw_union { + #subtype iunknown: IUnknown, + using idxgifactorymedia_vtable: ^IFactoryMedia_VTable, +} +IFactoryMedia_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + CreateSwapChainForCompositionSurfaceHandle: proc "stdcall" (this: ^IFactoryMedia, pDevice: ^IUnknown, hSurface: HANDLE, pDesc: ^SWAP_CHAIN_DESC1, pRestrictToOutput: ^IOutput, ppSwapChain: ^^ISwapChain1) -> HRESULT, + CreateDecodeSwapChainForCompositionSurfaceHandle: proc "stdcall" (this: ^IFactoryMedia, pDevice: ^IUnknown, hSurface: HANDLE, pDesc: ^DECODE_SWAP_CHAIN_DESC, pYuvDecodeBuffers: ^IResource, pRestrictToOutput: ^IOutput, ppSwapChain: ^^IDecodeSwapChain) -> HRESULT, +} +FRAME_PRESENTATION_MODE :: enum i32 { + COMPOSED = 0, + OVERLAY = 1, + NONE = 2, + COMPOSITION_FAILURE = 3, +} + +FRAME_STATISTICS_MEDIA :: struct { + PresentCount: u32, + PresentRefreshCount: u32, + SyncRefreshCount: u32, + SyncQPCTime: LARGE_INTEGER, + SyncGPUTime: LARGE_INTEGER, + CompositionMode: FRAME_PRESENTATION_MODE, + ApprovedPresentDuration: u32, +} + + +ISwapChainMedia_UUID_STRING :: "DD95B90B-F05F-4F6A-BD65-25BFB264BD84" +ISwapChainMedia_UUID := &IID{0xDD95B90B, 0xF05F, 0x4F6A, {0xBD, 0x65, 0x25, 0xBF, 0xB2, 0x64, 0xBD, 0x84}} +ISwapChainMedia :: struct #raw_union { + #subtype iunknown: IUnknown, + using idxgiswapchainmedia_vtable: ^ISwapChainMedia_VTable, +} +ISwapChainMedia_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + GetFrameStatisticsMedia: proc "stdcall" (this: ^ISwapChainMedia, pStats: ^FRAME_STATISTICS_MEDIA) -> HRESULT, + SetPresentDuration: proc "stdcall" (this: ^ISwapChainMedia, Duration: u32) -> HRESULT, + CheckPresentDurationSupport: proc "stdcall" (this: ^ISwapChainMedia, DesiredPresentDuration: u32, pClosestSmallerPresentDuration: ^u32, pClosestLargerPresentDuration: ^u32) -> HRESULT, +} +OVERLAY_SUPPORT_FLAG :: enum u32 { // TODO: convert to bit_set + DIRECT = 0x1, + SCALING = 0x2, +} + + +IOutput3_UUID_STRING :: "8A6BB301-7E7E-41F4-A8E0-5B32F7F99B18" +IOutput3_UUID := &IID{0x8A6BB301, 0x7E7E, 0x41F4, {0xA8, 0xE0, 0x5B, 0x32, 0xF7, 0xF9, 0x9B, 0x18}} +IOutput3 :: struct #raw_union { + #subtype idxgioutput2: IOutput2, + using idxgioutput3_vtable: ^IOutput3_VTable, +} +IOutput3_VTable :: struct { + using idxgioutput2_vtable: IOutput2_VTable, + CheckOverlaySupport: proc "stdcall" (this: ^IOutput3, EnumFormat: FORMAT, pConcernedDevice: ^IUnknown, pFlags: ^u32) -> HRESULT, +} +SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG :: enum u32 { // TODO: convert to bit_set + PRESENT = 0x1, + OVERLAY_PRESENT = 0x2, +} + + +ISwapChain3_UUID_STRING :: "94D99BDB-F1F8-4AB0-B236-7DA0170EDAB1" +ISwapChain3_UUID := &IID{0x94D99BDB, 0xF1F8, 0x4AB0, {0xB2, 0x36, 0x7D, 0xA0, 0x17, 0x0E, 0xDA, 0xB1}} +ISwapChain3 :: struct #raw_union { + #subtype idxgiswapchain2: ISwapChain2, + using idxgiswapchain3_vtable: ^ISwapChain3_VTable, +} +ISwapChain3_VTable :: struct { + using idxgiswapchain2_vtable: ISwapChain2_VTable, + GetCurrentBackBufferIndex: proc "stdcall" (this: ^ISwapChain3) -> u32, + CheckColorSpaceSupport: proc "stdcall" (this: ^ISwapChain3, ColorSpace: COLOR_SPACE_TYPE, pColorSpaceSupport: ^u32) -> HRESULT, + SetColorSpace1: proc "stdcall" (this: ^ISwapChain3, ColorSpace: COLOR_SPACE_TYPE) -> HRESULT, + ResizeBuffers1: proc "stdcall" (this: ^ISwapChain3, BufferCount: u32, Width: u32, Height: u32, Format: FORMAT, SwapChainFlags: u32, pCreationNodeMask: ^u32, ppPresentQueue: ^^IUnknown) -> HRESULT, +} +OVERLAY_COLOR_SPACE_SUPPORT_FLAG :: enum u32 { // TODO: convert to bit_set + PRESENT = 0x1, +} + + +IOutput4_UUID_STRING :: "DC7DCA35-2196-414D-9F53-617884032A60" +IOutput4_UUID := &IID{0xDC7DCA35, 0x2196, 0x414D, {0x9F, 0x53, 0x61, 0x78, 0x84, 0x03, 0x2A, 0x60}} +IOutput4 :: struct #raw_union { + #subtype idxgioutput3: IOutput3, + using idxgioutput4_vtable: ^IOutput4_VTable, +} +IOutput4_VTable :: struct { + using idxgioutput3_vtable: IOutput3_VTable, + CheckOverlayColorSpaceSupport: proc "stdcall" (this: ^IOutput4, Format: FORMAT, ColorSpace: COLOR_SPACE_TYPE, pConcernedDevice: ^IUnknown, pFlags: ^u32) -> HRESULT, +} + +IFactory4_UUID_STRING :: "1BC6EA02-EF36-464F-BF0C-21CA39E5168A" +IFactory4_UUID := &IID{0x1BC6EA02, 0xEF36, 0x464F, {0xBF, 0x0C, 0x21, 0xCA, 0x39, 0xE5, 0x16, 0x8A}} +IFactory4 :: struct #raw_union { + #subtype idxgifactory3: IFactory3, + using idxgifactory4_vtable: ^IFactory4_VTable, +} +IFactory4_VTable :: struct { + using idxgifactory3_vtable: IFactory3_VTable, + EnumAdapterByLuid: proc "stdcall" (this: ^IFactory4, AdapterLuid: LUID, riid: ^IID, ppvAdapter: ^rawptr) -> HRESULT, + EnumWarpAdapter: proc "stdcall" (this: ^IFactory4, riid: ^IID, ppvAdapter: ^rawptr) -> HRESULT, +} +MEMORY_SEGMENT_GROUP :: enum i32 { + LOCAL = 0, + NON_LOCAL = 1, +} + +QUERY_VIDEO_MEMORY_INFO :: struct { + Budget: u64, + CurrentUsage: u64, + AvailableForReservation: u64, + CurrentReservation: u64, +} + + +IAdapter3_UUID_STRING :: "645967A4-1392-4310-A798-8053CE3E93FD" +IAdapter3_UUID := &IID{0x645967A4, 0x1392, 0x4310, {0xA7, 0x98, 0x80, 0x53, 0xCE, 0x3E, 0x93, 0xFD}} +IAdapter3 :: struct #raw_union { + #subtype idxgiadapter2: IAdapter2, + using idxgiadapter3_vtable: ^IAdapter3_VTable, +} +IAdapter3_VTable :: struct { + using idxgiadapter2_vtable: IAdapter2_VTable, + RegisterHardwareContentProtectionTeardownStatusEvent: proc "stdcall" (this: ^IAdapter3, hEvent: HANDLE, pdwCookie: ^u32) -> HRESULT, + UnregisterHardwareContentProtectionTeardownStatus: proc "stdcall" (this: ^IAdapter3, dwCookie: u32), + QueryVideoMemoryInfo: proc "stdcall" (this: ^IAdapter3, NodeIndex: u32, MemorySegmentGroup: MEMORY_SEGMENT_GROUP, pVideoMemoryInfo: ^QUERY_VIDEO_MEMORY_INFO) -> HRESULT, + SetVideoMemoryReservation: proc "stdcall" (this: ^IAdapter3, NodeIndex: u32, MemorySegmentGroup: MEMORY_SEGMENT_GROUP, Reservation: u64) -> HRESULT, + RegisterVideoMemoryBudgetChangeNotificationEvent: proc "stdcall" (this: ^IAdapter3, hEvent: HANDLE, pdwCookie: ^u32) -> HRESULT, + UnregisterVideoMemoryBudgetChangeNotification: proc "stdcall" (this: ^IAdapter3, dwCookie: u32), +} \ No newline at end of file diff --git a/vendor/glfw/bindings/bindings.odin b/vendor/glfw/bindings/bindings.odin index 84905f603..aa1578153 100644 --- a/vendor/glfw/bindings/bindings.odin +++ b/vendor/glfw/bindings/bindings.odin @@ -3,15 +3,18 @@ package glfw_bindings import "core:c" import vk "vendor:vulkan" -when ODIN_OS == "linux" { foreign import glfw "system:glfw" } // TODO: Add the billion-or-so static libs to link to in linux -when ODIN_OS == "darwin" { foreign import glfw "system:glfw" } -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import glfw { "../lib/glfw3_mt.lib", "system:user32.lib", "system:gdi32.lib", "system:shell32.lib", } +} else when ODIN_OS == .Linux { + // TODO: Add the billion-or-so static libs to link to in linux + foreign import glfw "system:glfw" +} else { + foreign import glfw "system:glfw" } #assert(size_of(c.int) == size_of(b32)) diff --git a/vendor/glfw/native.odin b/vendor/glfw/native.odin index 871c42af9..902b30656 100644 --- a/vendor/glfw/native.odin +++ b/vendor/glfw/native.odin @@ -1,6 +1,6 @@ package glfw -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { import win32 "core:sys/windows" foreign import glfw { "lib/glfw3.lib", "system:user32.lib", "system:gdi32.lib", "system:shell32.lib" } @@ -12,7 +12,7 @@ when ODIN_OS == "windows" { GetWin32Window :: proc(window: WindowHandle) -> win32.HWND --- GetWGLContext :: proc(window: WindowHandle) -> rawptr --- } -} else when ODIN_OS == "linux" { +} else when ODIN_OS == .Linux { // TODO: Native Linux // Display* glfwGetX11Display(void); // RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor); @@ -24,7 +24,7 @@ when ODIN_OS == "windows" { // struct wl_display* glfwGetWaylandDisplay(void); // struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor); // struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window); -} else when ODIN_OS == "darwin" { +} else when ODIN_OS == .Darwin { // TODO: Native Darwin // CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor); // id glfwGetCocoaWindow(GLFWwindow* window); diff --git a/vendor/microui/microui.odin b/vendor/microui/microui.odin index 9d3e01fa0..947f59f40 100644 --- a/vendor/microui/microui.odin +++ b/vendor/microui/microui.odin @@ -1030,9 +1030,7 @@ number_textbox :: proc(ctx: ^Context, value: ^Real, r: Rect, id: Id, fmt_string: if ctx.number_edit_id == id { res := textbox_raw(ctx, ctx.number_edit_buf[:], &ctx.number_edit_len, id, r, {}) if .SUBMIT in res || ctx.focus_id != id { - ok: bool - value^, ok = parse_real(string(ctx.number_edit_buf[:ctx.number_edit_len])) - assert(ok == true) + value^, _ = parse_real(string(ctx.number_edit_buf[:ctx.number_edit_len])) ctx.number_edit_id = 0 } else { return true diff --git a/vendor/miniaudio/common.odin b/vendor/miniaudio/common.odin index 62e32e8b1..89e3d6bd2 100644 --- a/vendor/miniaudio/common.odin +++ b/vendor/miniaudio/common.odin @@ -2,8 +2,13 @@ package miniaudio import "core:c" -when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" } -when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" } +when ODIN_OS == .Windows { + foreign import lib "lib/miniaudio.lib" +} else when ODIN_OS == .Linux { + foreign import lib "lib/miniaudio.a" +} else { + foreign import lib "system:miniaudio" +} handle :: distinct rawptr @@ -270,7 +275,7 @@ thread_priority :: enum c.int { /* Spinlocks are 32-bit for compatibility reasons. */ spinlock :: distinct u32 -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { thread :: distinct rawptr mutex :: distinct rawptr event :: distinct rawptr diff --git a/vendor/miniaudio/data_conversion.odin b/vendor/miniaudio/data_conversion.odin index 1a5c9d265..7167270a1 100644 --- a/vendor/miniaudio/data_conversion.odin +++ b/vendor/miniaudio/data_conversion.odin @@ -2,9 +2,13 @@ package miniaudio import "core:c" -when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" } -when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" } - +when ODIN_OS == .Windows { + foreign import lib "lib/miniaudio.lib" +} else when ODIN_OS == .Linux { + foreign import lib "lib/miniaudio.a" +} else { + foreign import lib "system:miniaudio" +} /************************************************************************************************************************************************************ ************************************************************************************************************************************************************* diff --git a/vendor/miniaudio/decoding.odin b/vendor/miniaudio/decoding.odin index cdddd06fe..dcf3b7a1a 100644 --- a/vendor/miniaudio/decoding.odin +++ b/vendor/miniaudio/decoding.odin @@ -2,10 +2,13 @@ package miniaudio import "core:c" -when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" } -when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" } - - +when ODIN_OS == .Windows { + foreign import lib "lib/miniaudio.lib" +} else when ODIN_OS == .Linux { + foreign import lib "lib/miniaudio.a" +} else { + foreign import lib "system:miniaudio" +} /************************************************************************************************************************************************************ @@ -164,4 +167,4 @@ foreign lib { decode_from_vfs :: proc(pVFS: ^vfs, pFilePath: cstring, pConfig: ^decoder_config, pFrameCountOut: ^u64, ppPCMFramesOut: ^rawptr) -> result --- decode_file :: proc(pFilePath: cstring, pConfig: ^decoder_config, pFrameCountOut: ^u64, ppPCMFramesOut: ^rawptr) -> result --- decode_memory :: proc(pData: rawptr, dataSize: c.size_t, pConfig: ^decoder_config, pFrameCountOut: ^u64, ppPCMFramesOut: ^rawptr) -> result --- -} \ No newline at end of file +} diff --git a/vendor/miniaudio/device_io_procs.odin b/vendor/miniaudio/device_io_procs.odin index c9cfb7c04..7cff3f621 100644 --- a/vendor/miniaudio/device_io_procs.odin +++ b/vendor/miniaudio/device_io_procs.odin @@ -1,7 +1,12 @@ package miniaudio -when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" } -when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" } +when ODIN_OS == .Windows { + foreign import lib "lib/miniaudio.lib" +} else when ODIN_OS == .Linux { + foreign import lib "lib/miniaudio.a" +} else { + foreign import lib "system:miniaudio" +} import "core:c" diff --git a/vendor/miniaudio/device_io_types.odin b/vendor/miniaudio/device_io_types.odin index 8f43b8640..e05f94665 100644 --- a/vendor/miniaudio/device_io_types.odin +++ b/vendor/miniaudio/device_io_types.odin @@ -2,21 +2,21 @@ package miniaudio import "core:c" -SUPPORT_WASAPI :: ODIN_OS == "windows" -SUPPORT_DSOUND :: ODIN_OS == "windows" -SUPPORT_WINMM :: ODIN_OS == "windows" -SUPPORT_COREAUDIO :: ODIN_OS == "darwin" -SUPPORT_SNDIO :: ODIN_OS == "openbsd" -SUPPORT_AUDIO4 :: ODIN_OS == "openbsd" || ODIN_OS == "netbsd" -SUPPORT_OSS :: ODIN_OS == "freebsd" -SUPPORT_PULSEAUDIO :: ODIN_OS == "linux" -SUPPORT_ALSA :: ODIN_OS == "linux" -SUPPORT_JACK :: ODIN_OS == "windows" -SUPPORT_AAUDIO :: ODIN_OS == "android" -SUPPORT_OPENSL :: ODIN_OS == "android" -SUPPORT_WEBAUDIO :: ODIN_OS == "emscripten" +SUPPORT_WASAPI :: ODIN_OS == .Windows +SUPPORT_DSOUND :: ODIN_OS == .Windows +SUPPORT_WINMM :: ODIN_OS == .Windows +SUPPORT_COREAUDIO :: ODIN_OS == .Darwin +SUPPORT_SNDIO :: ODIN_OS == .OpenBSD +SUPPORT_AUDIO4 :: false // ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD +SUPPORT_OSS :: ODIN_OS == .FreeBSD +SUPPORT_PULSEAUDIO :: ODIN_OS == .Linux +SUPPORT_ALSA :: ODIN_OS == .Linux +SUPPORT_JACK :: ODIN_OS == .Windows +SUPPORT_AAUDIO :: false // ODIN_OS == .Android +SUPPORT_OPENSL :: false // ODIN_OS == .Android +SUPPORT_WEBAUDIO :: false // ODIN_OS == .Emscripten SUPPORT_CUSTOM :: true -SUPPORT_NULL :: ODIN_OS != "emscripten" +SUPPORT_NULL :: true // ODIN_OS != .Emscripten STATE_UNINITIALIZED :: 0 STATE_STOPPED :: 1 /* The device's default state after initialization. */ @@ -739,8 +739,8 @@ context_type :: struct { pa_stream_writable_size: proc "system" (), pa_stream_readable_size: proc "system" (), - /*pa_mainloop**/ pMainLoop: ptr, - /*pa_context**/ pPulseContext: ptr, + /*pa_mainloop**/ pMainLoop: rawptr, + /*pa_context**/ pPulseContext: rawptr, } when SUPPORT_PULSEAUDIO else struct {}), jack: (struct { @@ -791,7 +791,7 @@ context_type :: struct { AudioUnitInitialize: proc "system" (), AudioUnitRender: proc "system" (), - /*AudioComponent*/ component: ptr, + /*AudioComponent*/ component: rawptr, noAudioSessionDeactivate: b32, /* For tracking whether or not the iOS audio session should be explicitly deactivated. Set from the config in ma_context_init__coreaudio(). */ } when SUPPORT_COREAUDIO else struct {}), @@ -895,7 +895,7 @@ context_type :: struct { RegOpenKeyExA: proc "system" (), RegCloseKey: proc "system" (), RegQueryValueExA: proc "system" (), - } when ODIN_OS == "windows" else struct {}), + } when ODIN_OS == .Windows else struct {}), posix: (struct { pthreadSO: handle, @@ -914,7 +914,7 @@ context_type :: struct { pthread_attr_setschedpolicy: proc "system" (), pthread_attr_getschedparam: proc "system" (), pthread_attr_setschedparam: proc "system" (), - } when ODIN_OS != "windows" else struct {}), + } when ODIN_OS != .Windows else struct {}), _unused: c.int, }, diff --git a/vendor/miniaudio/encoding.odin b/vendor/miniaudio/encoding.odin index 866c19010..9b84108dc 100644 --- a/vendor/miniaudio/encoding.odin +++ b/vendor/miniaudio/encoding.odin @@ -2,8 +2,13 @@ package miniaudio import "core:c" -when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" } -when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" } +when ODIN_OS == .Windows { + foreign import lib "lib/miniaudio.lib" +} else when ODIN_OS == .Linux { + foreign import lib "lib/miniaudio.a" +} else { + foreign import lib "system:miniaudio" +} /************************************************************************************************************************************************************ @@ -49,4 +54,4 @@ foreign lib { encoder_init_file_w :: proc(pFilePath: [^]c.wchar_t, pConfig: ^encoder_config, pEncoder: ^encoder) -> result --- encoder_uninit :: proc(pEncoder: ^encoder) --- encoder_write_pcm_frames :: proc(pEncoder: ^encoder, FramesIn: rawptr, frameCount: u64) -> u64 --- -} \ No newline at end of file +} diff --git a/vendor/miniaudio/filtering.odin b/vendor/miniaudio/filtering.odin index fec21f33d..9949f6338 100644 --- a/vendor/miniaudio/filtering.odin +++ b/vendor/miniaudio/filtering.odin @@ -1,7 +1,12 @@ package miniaudio -when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" } -when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" } +when ODIN_OS == .Windows { + foreign import lib "lib/miniaudio.lib" +} else when ODIN_OS == .Linux { + foreign import lib "lib/miniaudio.a" +} else { + foreign import lib "system:miniaudio" +} /************************************************************************************************************************************************************** diff --git a/vendor/miniaudio/generation.odin b/vendor/miniaudio/generation.odin index c2009967c..97b7d453c 100644 --- a/vendor/miniaudio/generation.odin +++ b/vendor/miniaudio/generation.odin @@ -2,8 +2,13 @@ package miniaudio import "core:c" -when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" } -when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" } +when ODIN_OS == .Windows { + foreign import lib "lib/miniaudio.lib" +} else when ODIN_OS == .Linux { + foreign import lib "lib/miniaudio.a" +} else { + foreign import lib "system:miniaudio" +} waveform_type :: enum c.int { sine, @@ -82,4 +87,4 @@ foreign lib { noise_set_amplitude :: proc(pNoise: ^noise, amplitude: f64) -> result --- noise_set_seed :: proc(pNoise: ^noise, seed: i32) -> result --- noise_set_type :: proc(pNoise: ^noise, type: noise_type) -> result --- -} \ No newline at end of file +} diff --git a/vendor/miniaudio/logging.odin b/vendor/miniaudio/logging.odin index 54792bff9..0c14a10c2 100644 --- a/vendor/miniaudio/logging.odin +++ b/vendor/miniaudio/logging.odin @@ -2,8 +2,13 @@ package miniaudio import c "core:c/libc" -when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" } -when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" } +when ODIN_OS == .Windows { + foreign import lib "lib/miniaudio.lib" +} else when ODIN_OS == .Linux { + foreign import lib "lib/miniaudio.a" +} else { + foreign import lib "system:miniaudio" +} MAX_LOG_CALLBACKS :: 4 @@ -32,4 +37,4 @@ foreign lib { log_post :: proc(pLog: ^log, level: u32, pMessage: cstring) -> result --- log_postv :: proc(pLog: ^log, level: u32, pFormat: cstring, args: c.va_list) -> result --- log_postf :: proc(pLog: ^log, level: u32, pFormat: cstring, #c_vararg args: ..any) -> result --- -} \ No newline at end of file +} diff --git a/vendor/miniaudio/src/Makefile b/vendor/miniaudio/src/Makefile index 7ff72ebdc..3c61b5e2f 100644 --- a/vendor/miniaudio/src/Makefile +++ b/vendor/miniaudio/src/Makefile @@ -1,6 +1,6 @@ all: mkdir -p ../lib - gcc -c -O2 -Os -fPIC miniaudio.c - ar rcs ../lib/miniaudio.a miniaudio.o - #gcc -fPIC -shared -Wl,-soname=miniaudio.so -o ../lib/miniaudio.so miniaudio.o + $(CC) -c -O2 -Os -fPIC miniaudio.c + $(AR) rcs ../lib/miniaudio.a miniaudio.o + #$(CC) -fPIC -shared -Wl,-soname=miniaudio.so -o ../lib/miniaudio.so miniaudio.o rm *.o diff --git a/vendor/miniaudio/utilities.odin b/vendor/miniaudio/utilities.odin index 1a94550e4..9ced019f5 100644 --- a/vendor/miniaudio/utilities.odin +++ b/vendor/miniaudio/utilities.odin @@ -1,7 +1,12 @@ package miniaudio -when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" } -when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" } +when ODIN_OS == .Windows { + foreign import lib "lib/miniaudio.lib" +} else when ODIN_OS == .Linux { + foreign import lib "lib/miniaudio.a" +} else { + foreign import lib "system:miniaudio" +} @(default_calling_convention="c", link_prefix="ma_") foreign lib { @@ -228,4 +233,4 @@ foreign lib { audio_buffer_get_cursor_in_pcm_frames :: proc(pAudioBuffer: ^audio_buffer, pCursor: ^u64) -> result --- audio_buffer_get_length_in_pcm_frames :: proc(pAudioBuffer: ^audio_buffer, pLength: ^u64) -> result --- audio_buffer_get_available_frames :: proc(pAudioBuffer: ^audio_buffer, pAvailableFrames: ^u64) -> result --- -} \ No newline at end of file +} diff --git a/vendor/miniaudio/vfs.odin b/vendor/miniaudio/vfs.odin index fa18afb6b..85571341e 100644 --- a/vendor/miniaudio/vfs.odin +++ b/vendor/miniaudio/vfs.odin @@ -2,8 +2,13 @@ package miniaudio import "core:c" -when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" } -when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" } +when ODIN_OS == .Windows { + foreign import lib "lib/miniaudio.lib" +} else when ODIN_OS == .Linux { + foreign import lib "lib/miniaudio.a" +} else { + foreign import lib "system:miniaudio" +} /************************************************************************************************************************************************************ diff --git a/vendor/portmidi/portmidi.odin b/vendor/portmidi/portmidi.odin index 08f78150c..a3db4191c 100644 --- a/vendor/portmidi/portmidi.odin +++ b/vendor/portmidi/portmidi.odin @@ -3,12 +3,14 @@ package portmidi import "core:c" import "core:strings" -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import lib { "portmidi_s.lib", "system:Winmm.lib", "system:Advapi32.lib", } +} else { + foreign import lib "system:portmidi" } #assert(size_of(b32) == size_of(c.int)) @@ -519,4 +521,4 @@ foreign lib { WriteSysEx() writes a timestamped system-exclusive midi message. */ WriteSysEx :: proc(stream: Stream, whence: Timestamp, msg: cstring) -> Error --- -} \ No newline at end of file +} diff --git a/vendor/portmidi/util.odin b/vendor/portmidi/util.odin index d02142bd0..caf73f8ad 100644 --- a/vendor/portmidi/util.odin +++ b/vendor/portmidi/util.odin @@ -7,7 +7,11 @@ package portmidi import "core:c" -when ODIN_OS == "windows" { foreign import lib "portmidi_s.lib" } +when ODIN_OS == .Windows { + foreign import lib "portmidi_s.lib" +} else { + foreign import lib "system:portmidi" +} Queue :: distinct rawptr @@ -118,4 +122,4 @@ foreign lib { state, returns .NoError if successfully set overflow state. */ SetOverflow :: proc(queue: Queue) -> Error --- -} \ No newline at end of file +} diff --git a/vendor/raylib/raylib.odin b/vendor/raylib/raylib.odin index fb4d7dd92..ec057cd78 100644 --- a/vendor/raylib/raylib.odin +++ b/vendor/raylib/raylib.odin @@ -91,7 +91,7 @@ MAX_TEXT_BUFFER_LENGTH :: #config(RAYLIB_MAX_TEXT_BUFFER_LENGTH, 1024) #assert(size_of(rune) == size_of(c.int)) -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import lib { "raylib.lib", "system:Winmm.lib", @@ -99,15 +99,17 @@ when ODIN_OS == "windows" { "system:User32.lib", "system:Shell32.lib", } -} -when ODIN_OS == "linux" { +} else when ODIN_OS == .Linux { foreign import lib { "linux/libraylib.a", "system:dl", "system:pthread", } +} else when ODIN_OS == .Darwin { + foreign import lib "macos/libraylib.a" +} else { + foreign import lib "system:raylib" } -when ODIN_OS == "darwin" { foreign import lib "macos/libraylib.a" } VERSION :: "4.0" @@ -1150,9 +1152,9 @@ foreign lib { DrawRectangleGradientH :: proc(posX, posY, width, height: c.int, color1: Color, color2: Color) --- // Draw a horizontal-gradient-filled rectangle DrawRectangleGradientEx :: proc(rec: Rectangle, col1, col2, col3, col4: Color) --- // Draw a gradient-filled rectangle with custom vertex colors DrawRectangleLines :: proc(posX, posY, width, height: c.int, color: Color) --- // Draw rectangle outline - DrawRectangleLinesEx :: proc(rec: Rectangle, lineThick: c.int, color: Color) --- // Draw rectangle outline with extended parameters + DrawRectangleLinesEx :: proc(rec: Rectangle, lineThick: f32, color: Color) --- // Draw rectangle outline with extended parameters DrawRectangleRounded :: proc(rec: Rectangle, roundness: f32, segments: c.int, color: Color) --- // Draw rectangle with rounded edges - DrawRectangleRoundedLines :: proc(rec: Rectangle, roundness: f32, segments: c.int, lineThick: c.int, color: Color) --- // Draw rectangle with rounded edges outline + DrawRectangleRoundedLines :: proc(rec: Rectangle, roundness: f32, segments: c.int, lineThick: f32, color: Color) --- // Draw rectangle with rounded edges outline DrawTriangle :: proc(v1, v2, v3: Vector2, color: Color) --- // Draw a color-filled triangle (vertex in counter-clockwise order!) DrawTriangleLines :: proc(v1, v2, v3: Vector2, color: Color) --- // Draw triangle outline (vertex in counter-clockwise order!) DrawTriangleFan :: proc(points: [^]Vector2, pointsCount: c.int, color: Color) --- // Draw a triangle fan defined by points (first vertex is the center) diff --git a/vendor/raylib/rlgl.odin b/vendor/raylib/rlgl.odin index 8f91486c1..7e7f2feea 100644 --- a/vendor/raylib/rlgl.odin +++ b/vendor/raylib/rlgl.odin @@ -2,7 +2,7 @@ package raylib import "core:c" -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { foreign import lib { "raylib.lib", "system:Winmm.lib", @@ -10,9 +10,13 @@ when ODIN_OS == "windows" { "system:User32.lib", "system:Shell32.lib", } +} else when ODIN_OS == .Linux { + foreign import lib "linux/libraylib.a" +} else when ODIN_OS == .Darwin { + foreign import lib "macos/libraylib.a" +} else { + foreign import lib "system:raylib" } -when ODIN_OS == "linux" { foreign import lib "linux/libraylib.a" } -when ODIN_OS == "darwin" { foreign import lib "macos/libraylib.a" } GRAPHICS_API_OPENGL_11 :: false GRAPHICS_API_OPENGL_21 :: true @@ -378,4 +382,4 @@ foreign lib { // Quick and dirty cube/quad buffers load->draw->unload rlLoadDrawCube :: proc() --- // Load and draw a cube rlLoadDrawQuad :: proc() --- // Load and draw a quad -} \ No newline at end of file +} diff --git a/vendor/sdl2/image/sdl_image.odin b/vendor/sdl2/image/sdl_image.odin index 1dbe048ed..204ec9a0d 100644 --- a/vendor/sdl2/image/sdl_image.odin +++ b/vendor/sdl2/image/sdl_image.odin @@ -3,10 +3,11 @@ package sdl2_image import "core:c" import SDL ".." -when ODIN_OS == "windows" { foreign import lib "SDL2_image.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2_image" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2_image" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2_image" } +when ODIN_OS == .Windows { + foreign import lib "SDL2_image.lib" +} else { + foreign import lib "system:SDL2_image" +} bool :: SDL.bool @@ -119,4 +120,4 @@ foreign lib { /* Individual loading functions */ LoadGIFAnimation_RW :: proc(src: ^SDL.RWops) -> ^Animation --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/mixer/sdl_mixer.odin b/vendor/sdl2/mixer/sdl_mixer.odin index 90334d91a..b0c16871d 100644 --- a/vendor/sdl2/mixer/sdl_mixer.odin +++ b/vendor/sdl2/mixer/sdl_mixer.odin @@ -3,11 +3,11 @@ package sdl2_mixer import "core:c" import SDL ".." -when ODIN_OS == "windows" { foreign import lib "SDL2_mixer.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2_mixer" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2_mixer" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2_mixer" } - +when ODIN_OS == .Windows { + foreign import lib "SDL2_mixer.lib" +} else { + foreign import lib "system:SDL2_mixer" +} MAJOR_VERSION :: 2 MINOR_VERSION :: 0 diff --git a/vendor/sdl2/net/sdl_net.odin b/vendor/sdl2/net/sdl_net.odin index 49671764a..579f245e5 100644 --- a/vendor/sdl2/net/sdl_net.odin +++ b/vendor/sdl2/net/sdl_net.odin @@ -3,10 +3,11 @@ package sdl2_net import "core:c" import SDL ".." -when ODIN_OS == "windows" { foreign import lib "SDL2_net.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2_net" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2_net" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2_net" } +when ODIN_OS == .Windows { + foreign import lib "SDL2_net.lib" +} else { + foreign import lib "system:SDL2_net" +} bool :: SDL.bool @@ -188,4 +189,4 @@ Read16 :: #force_inline proc "c" (areap: rawptr) -> u16 { Read32 :: #force_inline proc "c" (areap: rawptr) -> u32 { area := (^[4]u8)(areap) return u32(area[0])<<24 | u32(area[1])<<16 | u32(area[2])<<8 | u32(area[3]) -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl2.odin b/vendor/sdl2/sdl2.odin index 4781483f7..24ecc38e6 100644 --- a/vendor/sdl2/sdl2.odin +++ b/vendor/sdl2/sdl2.odin @@ -25,10 +25,11 @@ package sdl2 import "core:c" import "core:intrinsics" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} version :: struct { major: u8, /**< major version */ @@ -314,4 +315,4 @@ foreign lib { IsShapedWindow :: proc(window: ^Window) -> bool --- SetWindowShape :: proc(window: ^Window, shape: ^Surface, shape_mode: ^WindowShapeMode) -> c.int --- GetShapedWindowMode :: proc(window: ^Window, shape_mode: ^WindowShapeMode) -> c.int --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_audio.odin b/vendor/sdl2/sdl_audio.odin index e108e31c6..28a59d947 100644 --- a/vendor/sdl2/sdl_audio.odin +++ b/vendor/sdl2/sdl_audio.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} /** * \brief Audio format flags. @@ -59,7 +60,7 @@ AUDIO_F32LSB :: 0x8120 /**< 32-bit floating point samples */ AUDIO_F32MSB :: 0x9120 /**< As above, but big-endian byte order */ AUDIO_F32 :: AUDIO_F32LSB -when ODIN_ENDIAN == "little" { +when ODIN_ENDIAN == .Little { AUDIO_U16SYS :: AUDIO_U16LSB AUDIO_S16SYS :: AUDIO_S16LSB AUDIO_S32SYS :: AUDIO_S32LSB diff --git a/vendor/sdl2/sdl_blendmode.odin b/vendor/sdl2/sdl_blendmode.odin index 3fb7c2e83..4fde5111b 100644 --- a/vendor/sdl2/sdl_blendmode.odin +++ b/vendor/sdl2/sdl_blendmode.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} /** * \brief The blend mode used in SDL_RenderCopy() and drawing operations. @@ -62,4 +63,4 @@ BlendFactor :: enum c.int { foreign lib { ComposeCustomBlendMode :: proc(srcColorFactor, dstColorFactor: BlendFactor, colorOperation: BlendOperation, srcAlphaFactor, dstAlphaFactor: BlendFactor, alphaOperation: BlendOperation) -> BlendMode --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_cpuinfo.odin b/vendor/sdl2/sdl_cpuinfo.odin index 5fe5cf16c..c5175e4d5 100644 --- a/vendor/sdl2/sdl_cpuinfo.odin +++ b/vendor/sdl2/sdl_cpuinfo.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} /* This is a guess for the cacheline size used for padding. * Most x86 processors have a 64 byte cache line. @@ -41,4 +42,4 @@ foreign lib { SIMDAlloc :: proc(len: c.size_t) -> rawptr --- SIMDRealloc :: proc(mem: rawptr, len: c.size_t) -> rawptr --- SIMDFree :: proc(ptr: rawptr) --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_events.odin b/vendor/sdl2/sdl_events.odin index 535269656..29f6e8a43 100644 --- a/vendor/sdl2/sdl_events.odin +++ b/vendor/sdl2/sdl_events.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} RELEASED :: 0 PRESSED :: 1 @@ -498,4 +499,4 @@ foreign lib { FilterEvents :: proc(filter: EventFilter, userdata: rawptr) --- EventState :: proc(type: EventType, state: c.int) -> u8 --- RegisterEvents :: proc(numevents: c.int) -> u32 --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_gamecontroller.odin b/vendor/sdl2/sdl_gamecontroller.odin index 747cd1af6..76e0b8966 100644 --- a/vendor/sdl2/sdl_gamecontroller.odin +++ b/vendor/sdl2/sdl_gamecontroller.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} GameController :: struct {} diff --git a/vendor/sdl2/sdl_gesture_haptic.odin b/vendor/sdl2/sdl_gesture_haptic.odin index 0d257a525..a21e0df06 100644 --- a/vendor/sdl2/sdl_gesture_haptic.odin +++ b/vendor/sdl2/sdl_gesture_haptic.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} // Gesture @@ -259,4 +260,4 @@ foreign lib { HapticRumbleInit :: proc(haptic: ^Haptic) -> c.int --- HapticRumblePlay :: proc(haptic: ^Haptic, strength: f32, length: u32) -> c.int --- HapticRumbleStop :: proc(haptic: ^Haptic) -> c.int --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_hints.odin b/vendor/sdl2/sdl_hints.odin index b5793bb02..913d4ea12 100644 --- a/vendor/sdl2/sdl_hints.odin +++ b/vendor/sdl2/sdl_hints.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} HINT_ACCELEROMETER_AS_JOYSTICK :: "SDL_ACCELEROMETER_AS_JOYSTICK" HINT_ALLOW_ALT_TAB_WHILE_GRABBED :: "SDL_ALLOW_ALT_TAB_WHILE_GRABBED" @@ -146,4 +147,4 @@ foreign lib { AddHintCallback :: proc(name: cstring, callback: HintCallback, userdata: rawptr) --- DelHintCallback :: proc(name: cstring, callback: HintCallback, userdata: rawptr) --- ClearHints :: proc() --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_joystick.odin b/vendor/sdl2/sdl_joystick.odin index d2bb624b7..35ca5cdcc 100644 --- a/vendor/sdl2/sdl_joystick.odin +++ b/vendor/sdl2/sdl_joystick.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} Joystick :: struct {} @@ -106,4 +107,4 @@ foreign lib { JoystickSendEffect :: proc(joystick: ^Joystick, data: rawptr, size: c.int) -> c.int --- JoystickClose :: proc(joystick: ^Joystick) --- JoystickCurrentPowerLevel :: proc(joystick: ^Joystick) -> JoystickPowerLevel --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_keyboard.odin b/vendor/sdl2/sdl_keyboard.odin index 86112863a..f880286aa 100644 --- a/vendor/sdl2/sdl_keyboard.odin +++ b/vendor/sdl2/sdl_keyboard.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} Keysym :: struct { scancode: Scancode, /**< SDL physical key code - see ::SDL_Scancode for details */ diff --git a/vendor/sdl2/sdl_keycode.odin b/vendor/sdl2/sdl_keycode.odin index 73637f072..c03fdc2a9 100644 --- a/vendor/sdl2/sdl_keycode.odin +++ b/vendor/sdl2/sdl_keycode.odin @@ -327,4 +327,4 @@ KMOD_RESERVED :: Keymod{.RESERVED} KMOD_CTRL :: Keymod{.LCTRL, .RCTRL} KMOD_SHIFT :: Keymod{.LSHIFT, .RSHIFT} KMOD_ALT :: Keymod{.LALT, .RALT} -KMOD_GUI :: Keymod{.LGUI, .RGUI}; \ No newline at end of file +KMOD_GUI :: Keymod{.LGUI, .RGUI} diff --git a/vendor/sdl2/sdl_log.odin b/vendor/sdl2/sdl_log.odin index b9f8a8d7d..09b7eaef0 100644 --- a/vendor/sdl2/sdl_log.odin +++ b/vendor/sdl2/sdl_log.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} MAX_LOG_MESSAGE :: 4096 @@ -74,4 +75,4 @@ foreign lib { // LogMessageV :: proc(category: c.int, priority: LogPriority, fmt: cstring, ap: va_list) --- LogGetOutputFunction :: proc(callback: ^LogOutputFunction, userdata: ^rawptr) --- LogSetOutputFunction :: proc(callback: LogOutputFunction, userdata: rawptr) --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_messagebox.odin b/vendor/sdl2/sdl_messagebox.odin index d8a07c1e2..6228704ac 100644 --- a/vendor/sdl2/sdl_messagebox.odin +++ b/vendor/sdl2/sdl_messagebox.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} MessageBoxFlag :: enum u32 { _ = 0, diff --git a/vendor/sdl2/sdl_metal.odin b/vendor/sdl2/sdl_metal.odin index 87a0313ef..1eccf7f5a 100644 --- a/vendor/sdl2/sdl_metal.odin +++ b/vendor/sdl2/sdl_metal.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} MetalView :: distinct rawptr @@ -15,4 +16,4 @@ foreign lib { Metal_DestroyView :: proc(view: MetalView) --- Metal_GetLayer :: proc(view: MetalView) -> rawptr --- Metal_GetDrawableSize :: proc(window: ^Window, w, h: ^c.int) --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_mouse.odin b/vendor/sdl2/sdl_mouse.odin index d667addc8..13220c94b 100644 --- a/vendor/sdl2/sdl_mouse.odin +++ b/vendor/sdl2/sdl_mouse.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} Cursor :: struct {} @@ -61,4 +62,4 @@ foreign lib { GetDefaultCursor :: proc() -> ^Cursor --- FreeCursor :: proc(cursor: ^Cursor) --- ShowCursor :: proc(toggle: c.int) -> c.int --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_mutex.odin b/vendor/sdl2/sdl_mutex.odin index 80d62f7c8..1fd5849e0 100644 --- a/vendor/sdl2/sdl_mutex.odin +++ b/vendor/sdl2/sdl_mutex.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} MUTEX_TIMEDOUT :: 1 MUTEX_MAXWAIT :: ~u32(0) @@ -41,4 +42,4 @@ foreign lib { CondBroadcast :: proc(cv: ^cond) -> c.int --- CondWait :: proc(cv: ^cond, m: ^mutex) -> c.int --- CondWaitTimeout :: proc(cv: ^cond, m: ^mutex, ms: u32) -> c.int --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_pixels.odin b/vendor/sdl2/sdl_pixels.odin index a8503c621..8ee06aa1a 100644 --- a/vendor/sdl2/sdl_pixels.odin +++ b/vendor/sdl2/sdl_pixels.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} ALPHA_OPAQUE :: 255 ALPHA_TRANSPARENT :: 0 @@ -156,10 +157,10 @@ PixelFormatEnum :: enum u32 { ARGB2101010 = 1<<28 | PIXELTYPE_PACKED32<<24 | PACKEDORDER_ARGB<<20 | PACKEDLAYOUT_2101010<<16 | 32<<8 | 4<<0, /* Aliases for RGBA byte arrays of color data, for the current platform */ - RGBA32 = RGBA8888 when ODIN_ENDIAN == "big" else ABGR8888, - ARGB32 = ARGB8888 when ODIN_ENDIAN == "big" else BGRA8888, - BGRA32 = BGRA8888 when ODIN_ENDIAN == "big" else ARGB8888, - ABGR32 = ABGR8888 when ODIN_ENDIAN == "big" else RGBA8888, + RGBA32 = RGBA8888 when ODIN_ENDIAN == .Big else ABGR8888, + ARGB32 = ARGB8888 when ODIN_ENDIAN == .Big else BGRA8888, + BGRA32 = BGRA8888 when ODIN_ENDIAN == .Big else ARGB8888, + ABGR32 = ABGR8888 when ODIN_ENDIAN == .Big else RGBA8888, YV12 = /**< Planar mode: Y + V + U (3 planes) */ 'Y'<<24 | 'V'<<16 | '1'<<8 | '2'<<0, @@ -234,4 +235,4 @@ foreign lib { GetRGB :: proc(pixel: u32, format: ^PixelFormat, r, g, b: ^u8) --- GetRGBA :: proc(pixel: u32, format: ^PixelFormat, r, g, b, a: ^u8) --- CalculateGammaRamp :: proc(gamma: f32, ramp: ^[256]u16) --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_rect.odin b/vendor/sdl2/sdl_rect.odin index 929897c26..852309cd2 100644 --- a/vendor/sdl2/sdl_rect.odin +++ b/vendor/sdl2/sdl_rect.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} Point :: struct { x: c.int, @@ -47,4 +48,4 @@ foreign lib { UnionRect :: proc(A, B: ^Rect, result: ^Rect) --- EnclosePoints :: proc(points: [^]Point, count: c.int, clip: ^Rect, result: ^Rect) -> bool --- IntersectRectAndLine :: proc(rect: ^Rect, X1, Y1, X2, Y2: ^c.int) -> bool --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_render.odin b/vendor/sdl2/sdl_render.odin index c92fd3eda..57845235b 100644 --- a/vendor/sdl2/sdl_render.odin +++ b/vendor/sdl2/sdl_render.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} RendererFlag :: enum u32 { SOFTWARE = 0, /**< The renderer is a software fallback */ @@ -140,4 +141,4 @@ foreign lib { GL_UnbindTexture :: proc(texture: ^Texture) -> c.int --- RenderGetMetalLayer :: proc(renderer: ^Renderer) -> rawptr --- RenderGetMetalCommandEncoder :: proc(renderer: ^Renderer) -> rawptr --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_rwops.odin b/vendor/sdl2/sdl_rwops.odin index 590815c90..86fb23c75 100644 --- a/vendor/sdl2/sdl_rwops.odin +++ b/vendor/sdl2/sdl_rwops.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} /* RWops Types */ RWOPS_UNKNOWN :: 0 /**< Unknown stream type */ @@ -105,4 +106,4 @@ foreign lib { WriteBE32 :: proc(dst: ^RWops, value: ^u32) -> c.size_t --- WriteLE64 :: proc(dst: ^RWops, value: ^u64) -> c.size_t --- WriteBE64 :: proc(dst: ^RWops, value: ^u64) -> c.size_t --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_scancode.odin b/vendor/sdl2/sdl_scancode.odin index d27bba7f7..ca2169778 100644 --- a/vendor/sdl2/sdl_scancode.odin +++ b/vendor/sdl2/sdl_scancode.odin @@ -539,4 +539,4 @@ SCANCODE_APP1 :: Scancode.APP1 SCANCODE_APP2 :: Scancode.APP2 SCANCODE_AUDIOREWIND :: Scancode.AUDIOREWIND -SCANCODE_AUDIOFASTFORWARD :: Scancode.AUDIOFASTFORWARD; \ No newline at end of file +SCANCODE_AUDIOFASTFORWARD :: Scancode.AUDIOFASTFORWARD diff --git a/vendor/sdl2/sdl_stdinc.odin b/vendor/sdl2/sdl_stdinc.odin index bf098a591..97722f4fe 100644 --- a/vendor/sdl2/sdl_stdinc.odin +++ b/vendor/sdl2/sdl_stdinc.odin @@ -5,10 +5,11 @@ import "core:intrinsics" import "core:runtime" _, _ :: intrinsics, runtime -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} bool :: distinct b32 #assert(size_of(bool) == size_of(c.int)) @@ -160,4 +161,4 @@ iconv_utf8_ucs2 :: proc "c" (s: string) -> [^]u16 { iconv_utf8_utf32 :: iconv_utf8_ucs4 iconv_utf8_ucs4 :: proc "c" (s: string) -> [^]rune { return cast([^]rune)iconv_string("UCS-4-INTERNAL", "UTF-8", cstring(raw_data(s)), len(s)+1) -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_surface.odin b/vendor/sdl2/sdl_surface.odin index c0b20be63..f50de35f7 100644 --- a/vendor/sdl2/sdl_surface.odin +++ b/vendor/sdl2/sdl_surface.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} SWSURFACE :: 0 /**< Just here for compatibility */ PREALLOC :: 0x00000001 /**< Surface uses preallocated memory */ @@ -108,4 +109,4 @@ foreign lib { SetYUVConversionMode :: proc(mode: YUV_CONVERSION_MODE) --- GetYUVConversionMode :: proc() -> YUV_CONVERSION_MODE --- GetYUVConversionModeForResolution :: proc(width, height: c.int) -> YUV_CONVERSION_MODE --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_system.odin b/vendor/sdl2/sdl_system.odin index 31f1b590b..d9b6b98df 100644 --- a/vendor/sdl2/sdl_system.odin +++ b/vendor/sdl2/sdl_system.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} // General @(default_calling_convention="c", link_prefix="SDL_") @@ -122,4 +123,4 @@ foreign lib { AndroidGetExternalStoragePath :: proc() -> cstring --- AndroidRequestPermission :: proc(permission: cstring) -> bool --- AndroidShowToast :: proc(message: cstring, duration, gravity, xoffset, yoffset: c.int) -> c.int --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_syswm.odin b/vendor/sdl2/sdl_syswm.odin index e374e72b7..62ca9d628 100644 --- a/vendor/sdl2/sdl_syswm.odin +++ b/vendor/sdl2/sdl_syswm.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} SYSWM_TYPE :: enum c.int { UNKNOWN, @@ -105,4 +106,4 @@ SysWMinfo :: struct { @(default_calling_convention="c", link_prefix="SDL_") foreign lib { GetWindowWMInfo :: proc(window: ^Window, info: ^SysWMinfo) -> bool --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_thread.odin b/vendor/sdl2/sdl_thread.odin index cbaf3ac00..5d1c0bd37 100644 --- a/vendor/sdl2/sdl_thread.odin +++ b/vendor/sdl2/sdl_thread.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} Thread :: struct {} diff --git a/vendor/sdl2/sdl_timer.odin b/vendor/sdl2/sdl_timer.odin index 5b26c7346..d71ed2da5 100644 --- a/vendor/sdl2/sdl_timer.odin +++ b/vendor/sdl2/sdl_timer.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} TimerCallback :: proc "c" (interval: u32, param: rawptr) -> u32 TimerID :: distinct c.int @@ -22,4 +23,4 @@ foreign lib { Delay :: proc(ms: u32) --- AddTimer :: proc(interval: u32, callback: TimerCallback, param: rawptr) -> TimerID --- RemoveTimer :: proc(id: TimerID) -> bool --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_touch.odin b/vendor/sdl2/sdl_touch.odin index c393b74ef..f2a8cc695 100644 --- a/vendor/sdl2/sdl_touch.odin +++ b/vendor/sdl2/sdl_touch.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} TouchID :: distinct i64 FingerID :: distinct i64 @@ -34,4 +35,4 @@ foreign lib { GetTouchDeviceType :: proc(touchID: TouchID) -> TouchDeviceType --- GetNumTouchFingers :: proc(touchID: TouchID) -> c.int --- GetTouchFinger :: proc(touchID: TouchID, index: c.int) -> ^Finger --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_video.odin b/vendor/sdl2/sdl_video.odin index 97a134739..86b564541 100644 --- a/vendor/sdl2/sdl_video.odin +++ b/vendor/sdl2/sdl_video.odin @@ -2,10 +2,11 @@ package sdl2 import "core:c" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} DisplayMode :: struct { format: u32, /**< pixel format */ @@ -310,4 +311,4 @@ foreign lib { // Used by vendor:OpenGL gl_set_proc_address :: proc(p: rawptr, name: cstring) { (^rawptr)(p)^ = GL_GetProcAddress(name) -} \ No newline at end of file +} diff --git a/vendor/sdl2/sdl_vulkan.odin b/vendor/sdl2/sdl_vulkan.odin index 97a41bacf..33bb8e51c 100644 --- a/vendor/sdl2/sdl_vulkan.odin +++ b/vendor/sdl2/sdl_vulkan.odin @@ -3,10 +3,11 @@ package sdl2 import "core:c" import vk "vendor:vulkan" -when ODIN_OS == "windows" { foreign import lib "SDL2.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2" } +when ODIN_OS == .Windows { + foreign import lib "SDL2.lib" +} else { + foreign import lib "system:SDL2" +} VkInstance :: vk.Instance VkSurfaceKHR :: vk.SurfaceKHR @@ -22,4 +23,4 @@ foreign lib { Vulkan_GetInstanceExtensions :: proc(window: ^Window, pCount: ^c.uint, pNames: [^]cstring) -> bool --- Vulkan_CreateSurface :: proc(window: ^Window, instance: VkInstance, surface: ^VkSurfaceKHR) -> bool --- Vulkan_GetDrawableSize :: proc(window: ^Window, w, h: ^c.int) --- -} \ No newline at end of file +} diff --git a/vendor/sdl2/ttf/SDL2_ttf.dll b/vendor/sdl2/ttf/SDL2_ttf.dll index 575636a91..2acc0e5bc 100644 Binary files a/vendor/sdl2/ttf/SDL2_ttf.dll and b/vendor/sdl2/ttf/SDL2_ttf.dll differ diff --git a/vendor/sdl2/ttf/SDL2_ttf.lib b/vendor/sdl2/ttf/SDL2_ttf.lib index 28810a7bc..bd53219e9 100644 Binary files a/vendor/sdl2/ttf/SDL2_ttf.lib and b/vendor/sdl2/ttf/SDL2_ttf.lib differ diff --git a/vendor/sdl2/ttf/sdl_ttf.odin b/vendor/sdl2/ttf/sdl_ttf.odin index 6b41f07c2..ca9beded0 100644 --- a/vendor/sdl2/ttf/sdl_ttf.odin +++ b/vendor/sdl2/ttf/sdl_ttf.odin @@ -3,10 +3,11 @@ package sdl2_ttf import "core:c" import SDL ".." -when ODIN_OS == "windows" { foreign import lib "SDL2_ttf.lib" } -when ODIN_OS == "linux" { foreign import lib "system:SDL2_ttf" } -when ODIN_OS == "darwin" { foreign import lib "system:SDL2_ttf" } -when ODIN_OS == "freebsd" { foreign import lib "system:SDL2_ttf" } +when ODIN_OS == .Windows { + foreign import lib "SDL2_ttf.lib" +} else { + foreign import lib "system:SDL2_ttf" +} bool :: SDL.bool @@ -14,7 +15,7 @@ bool :: SDL.bool MAJOR_VERSION :: 2 MINOR_VERSION :: 0 -PATCHLEVEL :: 15 +PATCHLEVEL :: 18 UNICODE_BOM_NATIVE :: 0xFEFF UNICODE_BOM_SWAPPED :: 0xFFFE @@ -163,4 +164,4 @@ foreign lib { SetFontSDF :: proc(font: ^Font, on_off: bool) -> c.int --- GetFontSDF :: proc(font: ^Font) -> bool --- -} \ No newline at end of file +} diff --git a/vendor/stb/easy_font/stb_easy_font.odin b/vendor/stb/easy_font/stb_easy_font.odin index 3a60301e5..0208ca316 100644 --- a/vendor/stb/easy_font/stb_easy_font.odin +++ b/vendor/stb/easy_font/stb_easy_font.odin @@ -1,32 +1,105 @@ package stb_easy_font -// Source port of stb_easy_font.h +/* + Source port of stb_easy_font.h + + Original port: gingerBill + Bugfixes: Florian Behr & Jeroen van Rijn + Additions: Jeroen van Rijn + + Changelog: + 2022-04-03 + Bug fixes + Add `print(x, y, text, color, quad_buffer)` version that takes `[]quad`. + (Same internal memory layout as []u8 API, but more convenient for the caller.) + Add optional `scale := f32(1.0)` param to `print` to embiggen the glyph quads. + + 2021-09-14 + Original Odin version +*/ + +/* + // Example for use with vendor:raylib + + quads: [999]easy_font.Quad = --- + + color := rl.GREEN + c := transmute(easy_font.Color)color + num_quads := easy_font.print(10, 60, TEXT, c, quads[:]) + + for q in quads[:num_quads] { + tl := q.tl.v + br := q.br.v + color = transmute(rl.Color)q.tl.c + + r := rl.Rectangle{x = tl.x, y = tl.y, width = br.x - tl.x, height = br.y - tl.y} + + // Yes, we could just use the `color` from above, but this shows how to get it back from the vertex. + // And in practice this code will likely not live as close to the `easy_font` call. + rl.DrawRectangleRec(r, color) + } +*/ import "core:math" +import "core:mem" -color :: struct { - c: [4]u8, +Color :: [4]u8 + +Vertex :: struct { + v: [3]f32, + c: Color, } +#assert(size_of(Vertex) == 16) -draw_segs :: proc(x, y: f32, segs: []u8, vertical: bool, c: color, vbuf: []byte, offset: int) -> int { - x, y, offset := x, y, offset - for i in 0..>31) & 1) - if n != 0 && offset+64 <= len(vbuf) { - y0 := y + f32(segs[i]>>4) - for j in 0..<4 { - (^f32)(&vbuf[offset+0])^ = x + ((vertical ? 1 : len) if j==1 || j==2 else 0) - (^f32)(&vbuf[offset+4])^ = y0 + ((vertical ? len : 1) if j >= 2 else 0) - (^f32)(&vbuf[offset+8])^ = 0 - (^color)(&vbuf[offset+12])^ = c - offset += 16 - } +Quad :: struct #packed { + tl: Vertex, + tr: Vertex, + br: Vertex, + bl: Vertex, +} +#assert(size_of(Quad) == 64) + +// Same memory layout, but takes a []quad instead of []byte +draw_segs_quad_buffer :: proc(x, y: f32, segs: []u8, vertical: bool, c: Color, buf: []Quad, start_offset: int, scale := f32(1.0)) -> (quads: int) { + x, y := x, y + quads = start_offset + + for seg in segs { + stroke_length := f32(seg & 7) * scale + x += f32((seg >> 3) & 1) * scale + if stroke_length != 0 && quads + 1 <= len(buf) { + y0 := y + (f32(seg >> 4) * scale) + + horz := scale if vertical else stroke_length + vert := stroke_length if vertical else scale + + buf[quads].tl.c = c + buf[quads].tl.v = { x, y0, 0 } + + buf[quads].tr.c = c + buf[quads].tr.v = { x + horz, y0, 0 } + + buf[quads].br.c = c + buf[quads].br.v = { x + horz, y0 + vert, 0 } + + buf[quads].bl.c = c + buf[quads].bl.v = { x, y0 + vert, 0 } + + quads += 1 } } + return quads +} + +// Compatible with original C API +draw_segs_vertex_buffer :: proc(x, y: f32, segs: []u8, vertical: bool, c: Color, vbuf: []byte, start_offset: int, scale := f32(1.0)) -> (offset: int) { + buf := mem.slice_data_cast([]Quad, vbuf) + offset = draw_segs_quad_buffer(x, y, segs, vertical, c, buf, start_offset / size_of(Quad), scale) * size_of(Quad) return offset } +draw_segs :: proc{ draw_segs_quad_buffer, draw_segs_vertex_buffer } + @(private) _spacing_val := f32(0) @@ -34,13 +107,17 @@ font_spacing :: proc(spacing: f32) { _spacing_val = spacing } -print :: proc(x, y: f32, text: string, color: color, vertex_buffer: []byte) -> int { - x, y := x, y +// Same memory layout, but takes a []quad instead of []byte +print_quad_buffer :: proc(x, y: f32, text: string, color: Color, quad_buffer: []Quad, scale := f32(1.0)) -> (quads: int) { + x, y, color := x, y, color text := text start_x := x - offset := 0 - - for len(text) != 0 && offset < len(vertex_buffer) { + + if color == {} { + color = {255, 255, 255, 255} + } + + for len(text) != 0 && quads < len(quad_buffer) { c := text[0] if c == '\n' { y += 12 @@ -52,17 +129,27 @@ print :: proc(x, y: f32, text: string, color: color, vertex_buffer: []byte) -> i v_seg := charinfo[c-32].v_seg num_h := charinfo[c-32 + 1].h_seg - h_seg num_v := charinfo[c-32 + 1].v_seg - v_seg - offset = draw_segs(x, y_ch, hseg[h_seg:][:num_h], false, color, vertex_buffer, offset) - offset = draw_segs(x, y_ch, hseg[v_seg:][:num_v], true, color, vertex_buffer, offset) - x += f32(advance & 15) - x += _spacing_val + + quads = draw_segs(x, y_ch, hseg[h_seg:][:num_h], false, color, quad_buffer, quads, scale) + quads = draw_segs(x, y_ch, vseg[v_seg:][:num_v], true, color, quad_buffer, quads, scale) + + x += f32(advance & 15) * scale + x += _spacing_val * scale } text = text[1:] } - return offset/64 + return } +// Compatible with original C API +print_vertex_buffer :: proc(x, y: f32, text: string, color: Color, vertex_buffer: []byte, scale := f32(1.0)) -> int { + buf := mem.slice_data_cast([]Quad, vertex_buffer) + return print_quad_buffer(x, y, text, color, buf, scale) +} + +print :: proc{ print_quad_buffer, print_vertex_buffer } + width :: proc(text: string) -> int { length := f32(0) max_length := f32(0) diff --git a/vendor/stb/image/stb_image.odin b/vendor/stb/image/stb_image.odin index 9e72760ab..eedce5f04 100644 --- a/vendor/stb/image/stb_image.odin +++ b/vendor/stb/image/stb_image.odin @@ -4,8 +4,9 @@ import c "core:c/libc" #assert(size_of(c.int) == size_of(b32)) -when ODIN_OS == "windows" { foreign import stbi "../lib/stb_image.lib" } -when ODIN_OS == "linux" { foreign import stbi "../lib/stb_image.a" } +when ODIN_OS == .Windows { foreign import stbi "../lib/stb_image.lib" } +when ODIN_OS == .Linux { foreign import stbi "../lib/stb_image.a" } +when ODIN_OS == .Darwin { foreign import stbi "../lib/stb_image.a" } #assert(size_of(b32) == size_of(c.int)) @@ -74,8 +75,9 @@ foreign stbi { info_from_memory :: proc(buffer: [^]byte, len: c.int, x, y, comp: ^c.int) -> c.int --- info_from_callbacks :: proc(clbk: ^Io_Callbacks, user: rawptr, x, y, comp: ^c.int) -> c.int --- - is_16_bit :: proc(filename: cstring) -> b32 --- - is_16_bit_from_file :: proc(f: ^c.FILE) -> b32 --- + is_16_bit :: proc(filename: cstring) -> b32 --- + is_16_bit_from_file :: proc(f: ^c.FILE) -> b32 --- + is_16_bit_from_memory :: proc(buffer: [^]byte, len: c.int) -> c.int --- // for image formats that explicitly notate that they have premultiplied alpha, // we just return the colors as stored in the file. set this flag to force diff --git a/vendor/stb/image/stb_image_resize.odin b/vendor/stb/image/stb_image_resize.odin index bee29a15e..362ec9315 100644 --- a/vendor/stb/image/stb_image_resize.odin +++ b/vendor/stb/image/stb_image_resize.odin @@ -2,8 +2,9 @@ package stb_image import c "core:c/libc" -when ODIN_OS == "windows" { foreign import lib "../lib/stb_image_resize.lib" } -when ODIN_OS == "linux" { foreign import lib "../lib/stb_image_resize.a" } +when ODIN_OS == .Windows { foreign import lib "../lib/stb_image_resize.lib" } +when ODIN_OS == .Linux { foreign import lib "../lib/stb_image_resize.a" } +when ODIN_OS == .Darwin { foreign import lib "../lib/stb_image_resize.a" } ////////////////////////////////////////////////////////////////////////////// // diff --git a/vendor/stb/image/stb_image_write.odin b/vendor/stb/image/stb_image_write.odin index 1f0cfce85..b9433e821 100644 --- a/vendor/stb/image/stb_image_write.odin +++ b/vendor/stb/image/stb_image_write.odin @@ -2,8 +2,9 @@ package stb_image import c "core:c/libc" -when ODIN_OS == "windows" { foreign import stbiw "../lib/stb_image_write.lib" } -when ODIN_OS == "linux" { foreign import stbiw "../lib/stb_image_write.a" } +when ODIN_OS == .Windows { foreign import stbiw "../lib/stb_image_write.lib" } +when ODIN_OS == .Linux { foreign import stbiw "../lib/stb_image_write.a" } +when ODIN_OS == .Darwin { foreign import stbiw "../lib/stb_image_write.a" } write_func :: proc "c" (ctx: rawptr, data: rawptr, size: c.int) diff --git a/vendor/stb/rect_pack/stb_rect_pack.odin b/vendor/stb/rect_pack/stb_rect_pack.odin index 4142a73ec..c9f999bf7 100644 --- a/vendor/stb/rect_pack/stb_rect_pack.odin +++ b/vendor/stb/rect_pack/stb_rect_pack.odin @@ -4,8 +4,9 @@ import c "core:c/libc" #assert(size_of(b32) == size_of(c.int)) -when ODIN_OS == "windows" { foreign import lib "../lib/stb_rect_pack.lib" } -when ODIN_OS == "linux" { foreign import lib "../lib/stb_rect_pack.a" } +when ODIN_OS == .Windows { foreign import lib "../lib/stb_rect_pack.lib" } +when ODIN_OS == .Linux { foreign import lib "../lib/stb_rect_pack.a" } +when ODIN_OS == .Darwin { foreign import lib "../lib/stb_rect_pack.a" } Coord :: distinct c.int _MAXVAL :: max(Coord) diff --git a/vendor/stb/src/Makefile b/vendor/stb/src/Makefile index c65aa7263..5504fede9 100644 --- a/vendor/stb/src/Makefile +++ b/vendor/stb/src/Makefile @@ -1,16 +1,16 @@ all: mkdir -p ../lib - gcc -c -O2 -Os -fPIC stb_image.c stb_image_write.c stb_image_resize.c stb_truetype.c stb_rect_pack.c stb_vorbis.c - ar rcs ../lib/stb_image.a stb_image.o - ar rcs ../lib/stb_image_write.a stb_image_write.o - ar rcs ../lib/stb_image_resize.a stb_image_resize.o - ar rcs ../lib/stb_truetype.a stb_truetype.o - ar rcs ../lib/stb_rect_pack.a stb_rect_pack.o - #ar rcs ../lib/stb_vorbis_pack.a stb_vorbis_pack.o - #gcc -fPIC -shared -Wl,-soname=stb_image.so -o ../lib/stb_image.so stb_image.o - #gcc -fPIC -shared -Wl,-soname=stb_image_write.so -o ../lib/stb_image_write.so stb_image_write.o - #gcc -fPIC -shared -Wl,-soname=stb_image_resize.so -o ../lib/stb_image_resize.so stb_image_resize.o - #gcc -fPIC -shared -Wl,-soname=stb_truetype.so -o ../lib/stb_truetype.so stb_image_truetype.o - #gcc -fPIC -shared -Wl,-soname=stb_rect_pack.so -o ../lib/stb_rect_pack.so stb_rect_packl.o - #gcc -fPIC -shared -Wl,-soname=stb_vorbis.so -o ../lib/stb_vorbis.so stb_vorbisl.o + $(CC) -c -O2 -Os -fPIC stb_image.c stb_image_write.c stb_image_resize.c stb_truetype.c stb_rect_pack.c stb_vorbis.c + $(AR) rcs ../lib/stb_image.a stb_image.o + $(AR) rcs ../lib/stb_image_write.a stb_image_write.o + $(AR) rcs ../lib/stb_image_resize.a stb_image_resize.o + $(AR) rcs ../lib/stb_truetype.a stb_truetype.o + $(AR) rcs ../lib/stb_rect_pack.a stb_rect_pack.o + #$(AR) rcs ../lib/stb_vorbis_pack.a stb_vorbis_pack.o + #$(CC) -fPIC -shared -Wl,-soname=stb_image.so -o ../lib/stb_image.so stb_image.o + #$(CC) -fPIC -shared -Wl,-soname=stb_image_write.so -o ../lib/stb_image_write.so stb_image_write.o + #$(CC) -fPIC -shared -Wl,-soname=stb_image_resize.so -o ../lib/stb_image_resize.so stb_image_resize.o + #$(CC) -fPIC -shared -Wl,-soname=stb_truetype.so -o ../lib/stb_truetype.so stb_image_truetype.o + #$(CC) -fPIC -shared -Wl,-soname=stb_rect_pack.so -o ../lib/stb_rect_pack.so stb_rect_packl.o + #$(CC) -fPIC -shared -Wl,-soname=stb_vorbis.so -o ../lib/stb_vorbis.so stb_vorbisl.o rm *.o diff --git a/vendor/stb/truetype/stb_truetype.odin b/vendor/stb/truetype/stb_truetype.odin index 3abb187c2..b51cb037f 100644 --- a/vendor/stb/truetype/stb_truetype.odin +++ b/vendor/stb/truetype/stb_truetype.odin @@ -3,8 +3,9 @@ package stb_truetype import c "core:c" import stbrp "vendor:stb/rect_pack" -when ODIN_OS == "windows" { foreign import stbtt "../lib/stb_truetype.lib" } -when ODIN_OS == "linux" { foreign import stbtt "../lib/stb_truetype.a" } +when ODIN_OS == .Windows { foreign import stbtt "../lib/stb_truetype.lib" } +when ODIN_OS == .Linux { foreign import stbtt "../lib/stb_truetype.a" } +when ODIN_OS == .Darwin { foreign import stbtt "../lib/stb_truetype.a" } /////////////////////////////////////////////////////////////////////////////// diff --git a/vendor/stb/vorbis/stb_vorbis.odin b/vendor/stb/vorbis/stb_vorbis.odin index 7ec248df5..43b9bc715 100644 --- a/vendor/stb/vorbis/stb_vorbis.odin +++ b/vendor/stb/vorbis/stb_vorbis.odin @@ -3,8 +3,9 @@ package stb_vorbis import c "core:c/libc" -when ODIN_OS == "windows" { foreign import lib "../lib/stb_vorbis.lib" } -when ODIN_OS == "linux" { foreign import lib "../lib/stb_vorbis.a" } +when ODIN_OS == .Windows { foreign import lib "../lib/stb_vorbis.lib" } +when ODIN_OS == .Linux { foreign import lib "../lib/stb_vorbis.a" } +when ODIN_OS == .Darwin { foreign import lib "../lib/stb_vorbis.a" } diff --git a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py index 1525f4e15..9a32f5796 100644 --- a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py +++ b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py @@ -7,14 +7,14 @@ import os.path import math file_and_urls = [ - ("vk_platform.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vk_platform.h', True), - ("vulkan_core.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vulkan_core.h', False), - ("vk_layer.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vk_layer.h', True), - ("vk_icd.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vk_icd.h', True), - ("vulkan_win32.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vulkan_win32.h', False), - ("vulkan_metal.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vulkan_metal.h', False), - ("vulkan_macos.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vulkan_macos.h', False), - ("vulkan_ios.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/master/include/vulkan/vulkan_ios.h', False), + ("vk_platform.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/main/include/vulkan/vk_platform.h', True), + ("vulkan_core.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/main/include/vulkan/vulkan_core.h', False), + ("vk_layer.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/main/include/vulkan/vk_layer.h', True), + ("vk_icd.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/main/include/vulkan/vk_icd.h', True), + ("vulkan_win32.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/main/include/vulkan/vulkan_win32.h', False), + ("vulkan_metal.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/main/include/vulkan/vulkan_metal.h', False), + ("vulkan_macos.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/main/include/vulkan/vulkan_macos.h', False), + ("vulkan_ios.h", 'https://raw.githubusercontent.com/KhronosGroup/Vulkan-Headers/main/include/vulkan/vulkan_ios.h', False), ] for file, url, _ in file_and_urls: @@ -125,7 +125,7 @@ def to_snake_case(name): s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name) return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower() -ext_suffixes = ["KHR", "EXT", "AMD", "NV", "NVX", "GOOGLE"] +ext_suffixes = ["KHR", "EXT", "AMD", "NV", "NVX", "GOOGLE", "KHX"] ext_suffixes_title = [ext.title() for ext in ext_suffixes] @@ -254,9 +254,19 @@ def parse_constants(f): f.write("{}{} :: {}\n".format(name, "".rjust(max_len-len(name)), value)) f.write("\n// Vendor Constants\n") - data = re.findall(r"#define VK_((?:"+'|'.join(ext_suffixes)+r")\w+)\s*(.*?)\n", src, re.S) + fixes = '|'.join(ext_suffixes) + inner = r"((?:(?:" + fixes + r")\w+)|(?:\w+" + fixes + r"))" + pattern = r"#define\s+VK_" + inner + r"\s*(.*?)\n" + data = re.findall(pattern, src, re.S) + + number_suffix_re = re.compile(r"(\d+)[UuLlFf]") + max_len = max(len(name) for name, value in data) for name, value in data: + value = remove_prefix(value, 'VK_') + v = number_suffix_re.findall(value) + if v: + value = v[0] f.write("{}{} :: {}\n".format(name, "".rjust(max_len-len(name)), value)) f.write("\n") @@ -444,7 +454,7 @@ procedure_map = {} def parse_procedures(f): data = re.findall(r"typedef (\w+\*?) \(\w+ \*(\w+)\)\((.+?)\);", src, re.S) - ff = [] + group_ff = {"Loader":[], "Misc":[], "Instance":[], "Device":[]} for rt, name, fields in data: proc_name = no_vk(name) @@ -464,18 +474,32 @@ def parse_procedures(f): ts += " -> {}".format(rt_str) procedure_map[proc_name] = ts - ff.append( (proc_name, ts) ) - max_len = max(len(n) for n, t in ff) + fields_types_name = [do_type(t) for t in re.findall(r"(?:\s*|)(.+?)\s*\w+(?:,|$)", fields)] + table_name = fields_types_name[0] + nn = (proc_name, ts) + if table_name in ('Device', 'Queue', 'CommandBuffer') and proc_name != 'GetDeviceProcAddr': + group_ff["Device"].append(nn) + elif table_name in ('Instance', 'PhysicalDevice') or proc_name == 'GetDeviceProcAddr': + group_ff["Instance"].append(nn) + elif table_name in ('rawptr', '', 'DebugReportFlagsEXT') or proc_name == 'GetInstanceProcAddr': + group_ff["Misc"].append(nn) + else: + group_ff["Loader"].append(nn) + f.write("import \"core:c\"\n\n") - f.write("// Procedure Types\n\n"); - for n, t in ff: - f.write("{} :: #type {}\n".format(n.ljust(max_len), t.replace('"c"', '"system"'))) + for group_name, ff in group_ff.items(): + ff.sort() + f.write("// {} Procedure Types\n".format(group_name)) + max_len = max(len(n) for n, t in ff) + for n, t in ff: + f.write("{} :: #type {}\n".format(n.ljust(max_len), t.replace('"c"', '"system"'))) + f.write("\n") def group_functions(f): data = re.findall(r"typedef (\w+\*?) \(\w+ \*(\w+)\)\((.+?)\);", src, re.S) - group_map = {"Instance":[], "Device":[], "Loader":[]} + group_map = {"Loader":[], "Instance":[], "Device":[]} for rt, vkname, fields in data: fields_types_name = [do_type(t) for t in re.findall(r"(?:\s*|)(.+?)\s*\w+(?:,|$)", fields)] @@ -493,6 +517,8 @@ def group_functions(f): pass else: group_map["Loader"].append(nn) + for _, group in group_map.items(): + group.sort() for group_name, group_lines in group_map.items(): f.write("// {} Procedures\n".format(group_name)) @@ -502,7 +528,7 @@ def group_functions(f): f.write('{}: {}\n'.format(remove_prefix(name, "Proc"), name.rjust(max_len))) f.write("\n") - f.write("load_proc_addresses :: proc(set_proc_address: SetProcAddressType) {\n") + f.write("load_proc_addresses_custom :: proc(set_proc_address: SetProcAddressType) {\n") for group_name, group_lines in group_map.items(): f.write("\t// {} Procedures\n".format(group_name)) max_len = max(len(name) for name, _ in group_lines) @@ -514,7 +540,77 @@ def group_functions(f): remove_prefix(vk_name, 'Proc'), )) f.write("\n") - f.write("}\n") + f.write("}\n\n") + + f.write("// Device Procedure VTable\n") + f.write("Device_VTable :: struct {\n") + max_len = max(len(name) for name, _ in group_map["Device"]) + for name, vk_name in group_map["Device"]: + f.write('\t{}: {},\n'.format(remove_prefix(name, "Proc"), name.rjust(max_len))) + f.write("}\n\n") + + f.write("load_proc_addresses_device_vtable :: proc(device: Device, vtable: ^Device_VTable) {\n") + for name, vk_name in group_map["Device"]: + k = max_len - len(name) + f.write('\tvtable.{}{} = auto_cast GetDeviceProcAddr(device, "vk{}")\n'.format( + remove_prefix(name, 'Proc'), + "".ljust(k), + remove_prefix(vk_name, 'Proc'), + )) + f.write("}\n\n") + + f.write("load_proc_addresses_device :: proc(device: Device) {\n") + max_len = max(len(name) for name, _ in group_map["Device"]) + for name, vk_name in group_map["Device"]: + k = max_len - len(name) + f.write('\t{}{} = auto_cast GetDeviceProcAddr(device, "vk{}")\n'.format( + remove_prefix(name, 'Proc'), + "".ljust(k), + remove_prefix(vk_name, 'Proc'), + )) + f.write("}\n\n") + + f.write("load_proc_addresses_instance :: proc(instance: Instance) {\n") + max_len = max(len(name) for name, _ in group_map["Instance"]) + for name, vk_name in group_map["Instance"]: + k = max_len - len(name) + f.write('\t{}{} = auto_cast GetInstanceProcAddr(instance, "vk{}")\n'.format( + remove_prefix(name, 'Proc'), + "".ljust(k), + remove_prefix(vk_name, 'Proc'), + )) + f.write("\n\t// Device Procedures (may call into dispatch)\n") + max_len = max(len(name) for name, _ in group_map["Device"]) + for name, vk_name in group_map["Device"]: + k = max_len - len(name) + f.write('\t{}{} = auto_cast GetInstanceProcAddr(instance, "vk{}")\n'.format( + remove_prefix(name, 'Proc'), + "".ljust(k), + remove_prefix(vk_name, 'Proc'), + )) + f.write("}\n\n") + + f.write("load_proc_addresses_global :: proc(vk_get_instance_proc_addr: rawptr) {\n") + f.write("\tGetInstanceProcAddr = auto_cast vk_get_instance_proc_addr\n\n") + max_len = max(len(name) for name, _ in group_map["Loader"]) + for name, vk_name in group_map["Loader"]: + k = max_len - len(name) + f.write('\t{}{} = auto_cast GetInstanceProcAddr(nil, "vk{}")\n'.format( + remove_prefix(name, 'Proc'), + "".ljust(k), + remove_prefix(vk_name, 'Proc'), + )) + f.write("}\n\n") + + f.write(""" +load_proc_addresses :: proc{ +\tload_proc_addresses_global, +\tload_proc_addresses_instance, +\tload_proc_addresses_device, +\tload_proc_addresses_device_vtable, +\tload_proc_addresses_custom, +}\n +"""[1::]) @@ -530,6 +626,9 @@ with open("../core.odin", 'w', encoding='utf-8') as f: f.write(BASE) f.write(""" API_VERSION_1_0 :: (1<<22) | (0<<12) | (0) +API_VERSION_1_1 :: (1<<22) | (1<<12) | (0) +API_VERSION_1_2 :: (1<<22) | (2<<12) | (0) +API_VERSION_1_3 :: (1<<22) | (3<<12) | (0) MAKE_VERSION :: proc(major, minor, patch: u32) -> u32 { return (major<<22) | (minor<<12) | (patch) @@ -566,32 +665,29 @@ MAX_MEMORY_TYPES :: 32 MAX_MEMORY_HEAPS :: 16 MAX_EXTENSION_NAME_SIZE :: 256 MAX_DESCRIPTION_SIZE :: 256 -MAX_DEVICE_GROUP_SIZE_KHX :: 32 MAX_DEVICE_GROUP_SIZE :: 32 LUID_SIZE_KHX :: 8 -LUID_SIZE_KHR :: 8 LUID_SIZE :: 8 -MAX_DRIVER_NAME_SIZE_KHR :: 256 -MAX_DRIVER_INFO_SIZE_KHR :: 256 -MAX_QUEUE_FAMILY_EXTERNAL :: ~u32(0)-1 +MAX_QUEUE_FAMILY_EXTERNAL :: ~u32(1) MAX_GLOBAL_PRIORITY_SIZE_EXT :: 16 +QUEUE_FAMILY_EXTERNAL :: MAX_QUEUE_FAMILY_EXTERNAL """[1::]) parse_constants(f) parse_handles_def(f) f.write("\n\n") parse_flags_def(f) - with open("../enums.odin", 'w', encoding='utf-8') as f: - f.write(BASE) - f.write("\n") - parse_enums(f) - f.write("\n\n") - with open("../structs.odin", 'w', encoding='utf-8') as f: - f.write(BASE) - f.write(""" +with open("../enums.odin", 'w', encoding='utf-8') as f: + f.write(BASE) + f.write("\n") + parse_enums(f) + f.write("\n\n") +with open("../structs.odin", 'w', encoding='utf-8') as f: + f.write(BASE) + f.write(""" import "core:c" -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { \timport win32 "core:sys/windows" \tHINSTANCE :: win32.HINSTANCE @@ -622,13 +718,12 @@ CAMetalLayer :: struct {} /********************************/ """) - f.write("\n") - parse_structs(f) - f.write("\n\n") - with open("../procedures.odin", 'w', encoding='utf-8') as f: - f.write(BASE) - f.write("\n") - parse_procedures(f) - f.write("\n") - group_functions(f) - f.write("\n\n") \ No newline at end of file + f.write("\n") + parse_structs(f) + f.write("\n\n") +with open("../procedures.odin", 'w', encoding='utf-8') as f: + f.write(BASE) + f.write("\n") + parse_procedures(f) + f.write("\n") + group_functions(f) diff --git a/vendor/vulkan/_gen/vk_icd.h b/vendor/vulkan/_gen/vk_icd.h index ae006d06d..41989ee35 100644 --- a/vendor/vulkan/_gen/vk_icd.h +++ b/vendor/vulkan/_gen/vk_icd.h @@ -33,7 +33,7 @@ // Version 2 - Add Loader/ICD Interface version negotiation // via vk_icdNegotiateLoaderICDInterfaceVersion. // Version 3 - Add ICD creation/destruction of KHR_surface objects. -// Version 4 - Add unknown physical device extension qyering via +// Version 4 - Add unknown physical device extension querying via // vk_icdGetPhysicalDeviceProcAddr. // Version 5 - Tells ICDs that the loader is now paying attention to the // application version of Vulkan passed into the ApplicationInfo diff --git a/vendor/vulkan/_gen/vk_platform.h b/vendor/vulkan/_gen/vk_platform.h index 18b913abc..3ff8c5d14 100644 --- a/vendor/vulkan/_gen/vk_platform.h +++ b/vendor/vulkan/_gen/vk_platform.h @@ -2,7 +2,7 @@ // File: vk_platform.h // /* -** Copyright 2014-2021 The Khronos Group Inc. +** Copyright 2014-2022 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -42,7 +42,7 @@ extern "C" #define VKAPI_CALL __stdcall #define VKAPI_PTR VKAPI_CALL #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7 - #error "Vulkan isn't supported for the 'armeabi' NDK ABI" + #error "Vulkan is not supported for the 'armeabi' NDK ABI" #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE) // On Android 32-bit ARM targets, Vulkan functions use the "hardfloat" // calling convention, i.e. float parameters are passed in registers. This diff --git a/vendor/vulkan/_gen/vulkan_core.h b/vendor/vulkan/_gen/vulkan_core.h index 18b302fa0..5c8b8461f 100644 --- a/vendor/vulkan/_gen/vulkan_core.h +++ b/vendor/vulkan/_gen/vulkan_core.h @@ -2,7 +2,7 @@ #define VULKAN_CORE_H_ 1 /* -** Copyright 2015-2021 The Khronos Group Inc. +** Copyright 2015-2022 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -72,10 +72,10 @@ extern "C" { #define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)// Patch version should always be set to 0 // Version of this file -#define VK_HEADER_VERSION 191 +#define VK_HEADER_VERSION 211 // Complete version of this file -#define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 2, VK_HEADER_VERSION) +#define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 3, VK_HEADER_VERSION) // DEPRECATED: This define is deprecated. VK_API_VERSION_MAJOR should be used instead. #define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22) @@ -160,6 +160,7 @@ typedef enum VkResult { VK_ERROR_INVALID_EXTERNAL_HANDLE = -1000072003, VK_ERROR_FRAGMENTATION = -1000161000, VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = -1000257000, + VK_PIPELINE_COMPILE_REQUIRED = 1000297000, VK_ERROR_SURFACE_LOST_KHR = -1000000000, VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001, VK_SUBOPTIMAL_KHR = 1000001003, @@ -168,19 +169,20 @@ typedef enum VkResult { VK_ERROR_VALIDATION_FAILED_EXT = -1000011001, VK_ERROR_INVALID_SHADER_NV = -1000012000, VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT = -1000158000, - VK_ERROR_NOT_PERMITTED_EXT = -1000174001, + VK_ERROR_NOT_PERMITTED_KHR = -1000174001, VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT = -1000255000, VK_THREAD_IDLE_KHR = 1000268000, VK_THREAD_DONE_KHR = 1000268001, VK_OPERATION_DEFERRED_KHR = 1000268002, VK_OPERATION_NOT_DEFERRED_KHR = 1000268003, - VK_PIPELINE_COMPILE_REQUIRED_EXT = 1000297000, VK_ERROR_OUT_OF_POOL_MEMORY_KHR = VK_ERROR_OUT_OF_POOL_MEMORY, VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = VK_ERROR_INVALID_EXTERNAL_HANDLE, VK_ERROR_FRAGMENTATION_EXT = VK_ERROR_FRAGMENTATION, + VK_ERROR_NOT_PERMITTED_EXT = VK_ERROR_NOT_PERMITTED_KHR, VK_ERROR_INVALID_DEVICE_ADDRESS_EXT = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, - VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED_EXT, + VK_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED, + VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED, VK_RESULT_MAX_ENUM = 0x7FFFFFFF } VkResult; @@ -349,6 +351,58 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO = 1000257002, VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO = 1000257003, VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO = 1000257004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES = 53, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES = 54, + VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO = 1000192000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES = 1000215000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES = 1000245000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES = 1000276000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES = 1000295000, + VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO = 1000295001, + VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO = 1000295002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES = 1000297000, + VK_STRUCTURE_TYPE_MEMORY_BARRIER_2 = 1000314000, + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2 = 1000314001, + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 = 1000314002, + VK_STRUCTURE_TYPE_DEPENDENCY_INFO = 1000314003, + VK_STRUCTURE_TYPE_SUBMIT_INFO_2 = 1000314004, + VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO = 1000314005, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO = 1000314006, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES = 1000314007, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES = 1000325000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES = 1000335000, + VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2 = 1000337000, + VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2 = 1000337001, + VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2 = 1000337002, + VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2 = 1000337003, + VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2 = 1000337004, + VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2 = 1000337005, + VK_STRUCTURE_TYPE_BUFFER_COPY_2 = 1000337006, + VK_STRUCTURE_TYPE_IMAGE_COPY_2 = 1000337007, + VK_STRUCTURE_TYPE_IMAGE_BLIT_2 = 1000337008, + VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2 = 1000337009, + VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2 = 1000337010, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES = 1000225000, + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO = 1000225001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES = 1000225002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES = 1000138000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES = 1000138001, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK = 1000138002, + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO = 1000138003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES = 1000066000, + VK_STRUCTURE_TYPE_RENDERING_INFO = 1000044000, + VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO = 1000044001, + VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO = 1000044002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES = 1000044003, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO = 1000044004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES = 1000280000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES = 1000280001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES = 1000281001, + VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3 = 1000360000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES = 1000413000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES = 1000413001, + VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS = 1000413002, + VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS = 1000413003, VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000, VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001, VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007, @@ -418,8 +472,14 @@ typedef enum VkStructureType { #ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR = 1000023015, #endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_QUEUE_FAMILY_QUERY_RESULT_STATUS_PROPERTIES_2_KHR = 1000023016, +#endif #ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_VIDEO_DECODE_INFO_KHR = 1000024000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_DECODE_CAPABILITIES_KHR = 1000024001, #endif VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000, VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001, @@ -436,54 +496,94 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_CAPABILITIES_EXT = 1000038000, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_CREATE_INFO_EXT = 1000038001, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000038001, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000038002, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000038002, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000038003, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_VCL_FRAME_INFO_EXT = 1000038003, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_VCL_FRAME_INFO_EXT = 1000038004, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_DPB_SLOT_INFO_EXT = 1000038004, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_DPB_SLOT_INFO_EXT = 1000038005, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_NALU_SLICE_EXT = 1000038005, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_NALU_SLICE_EXT = 1000038006, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_EMIT_PICTURE_PARAMETERS_EXT = 1000038006, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_EMIT_PICTURE_PARAMETERS_EXT = 1000038007, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_EXT = 1000038007, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_EXT = 1000038008, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_RATE_CONTROL_INFO_EXT = 1000038008, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_RATE_CONTROL_LAYER_INFO_EXT = 1000038009, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_REFERENCE_LISTS_EXT = 1000038010, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_CAPABILITIES_EXT = 1000039000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000039001, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT = 1000039002, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_VCL_FRAME_INFO_EXT = 1000039003, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_DPB_SLOT_INFO_EXT = 1000039004, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_NALU_SLICE_SEGMENT_EXT = 1000039005, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_EMIT_PICTURE_PARAMETERS_EXT = 1000039006, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_EXT = 1000039007, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_REFERENCE_LISTS_EXT = 1000039008, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_RATE_CONTROL_INFO_EXT = 1000039009, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_RATE_CONTROL_LAYER_INFO_EXT = 1000039010, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_CAPABILITIES_EXT = 1000040000, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_CREATE_INFO_EXT = 1000040001, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PICTURE_INFO_EXT = 1000040001, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PICTURE_INFO_EXT = 1000040002, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_MVC_EXT = 1000040002, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_MVC_EXT = 1000040003, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_EXT = 1000040003, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_EXT = 1000040004, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000040004, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000040005, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000040005, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000040006, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_DPB_SLOT_INFO_EXT = 1000040007, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_DPB_SLOT_INFO_EXT = 1000040006, #endif VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000, + VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000044006, + VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_INFO_EXT = 1000044007, + VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_AMD = 1000044008, + VK_STRUCTURE_TYPE_MULTIVIEW_PER_VIEW_ATTRIBUTES_INFO_NVX = 1000044009, VK_STRUCTURE_TYPE_STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP = 1000049000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV = 1000050000, VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV = 1000056000, @@ -493,7 +593,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV = 1000058000, VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT = 1000061000, VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN = 1000062000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT = 1000066000, VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT = 1000067000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT = 1000067001, VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073000, @@ -565,10 +664,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129003, VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129004, VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID = 1000129005, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = 1000138000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = 1000138001, - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = 1000138002, - VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT = 1000138003, + VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID = 1000129006, VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT = 1000143000, VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT = 1000143001, VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002, @@ -607,6 +703,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT = 1000158003, VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT = 1000158004, VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT = 1000158005, + VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT = 1000158006, VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000, VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001, #ifdef VK_ENABLE_BETA_EXTENSIONS @@ -634,7 +731,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV = 1000166001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT = 1000170000, VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT = 1000170001, - VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = 1000174000, VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000, VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002, @@ -646,29 +742,28 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_CAPABILITIES_EXT = 1000187000, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_CREATE_INFO_EXT = 1000187001, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000187001, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000187002, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT = 1000187002, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT = 1000187003, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_EXT = 1000187003, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_EXT = 1000187004, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PICTURE_INFO_EXT = 1000187004, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PICTURE_INFO_EXT = 1000187005, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_DPB_SLOT_INFO_EXT = 1000187006, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_DPB_SLOT_INFO_EXT = 1000187005, #endif + VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR = 1000174000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR = 1000388000, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR = 1000388001, VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD = 1000189000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000, VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = 1000190001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = 1000190002, VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP = 1000191000, - VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT = 1000192000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001, @@ -689,14 +784,10 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_DISPLAY_NATIVE_HDR_SURFACE_CAPABILITIES_AMD = 1000213000, VK_STRUCTURE_TYPE_SWAPCHAIN_DISPLAY_NATIVE_HDR_CREATE_INFO_AMD = 1000213001, VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR = 1000215000, VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001, VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT = 1000225000, - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = 1000225001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT = 1000225002, VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000226000, VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR = 1000226001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR = 1000226002, @@ -712,7 +803,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV = 1000240000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT = 1000244000, VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = 1000245000, VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT = 1000247000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR = 1000248000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV = 1000249000, @@ -743,7 +833,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR = 1000269004, VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR = 1000269005, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT = 1000273000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = 1000276000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV = 1000277000, VK_STRUCTURE_TYPE_GRAPHICS_SHADER_GROUP_CREATE_INFO_NV = 1000277001, VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_SHADER_GROUPS_CREATE_INFO_NV = 1000277002, @@ -754,10 +843,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV = 1000277007, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV = 1000278000, VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV = 1000278001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR = 1000280000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR = 1000280001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT = 1000281000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = 1000281001, VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDER_PASS_TRANSFORM_INFO_QCOM = 1000282000, VK_STRUCTURE_TYPE_RENDER_PASS_TRANSFORM_BEGIN_INFO_QCOM = 1000282001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT = 1000284000, @@ -771,30 +857,26 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR = 1000290000, VK_STRUCTURE_TYPE_PRESENT_ID_KHR = 1000294000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR = 1000294001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT = 1000295000, - VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT = 1000295001, - VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT = 1000295002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT = 1000297000, #ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_VIDEO_ENCODE_INFO_KHR = 1000299000, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_VIDEO_ENCODE_RATE_CONTROL_INFO_KHR = 1000299001, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_RATE_CONTROL_LAYER_INFO_KHR = 1000299002, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_CAPABILITIES_KHR = 1000299003, #endif VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV = 1000300000, VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV = 1000300001, - VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR = 1000314000, - VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2_KHR = 1000314001, - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2_KHR = 1000314002, - VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR = 1000314003, - VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR = 1000314004, - VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR = 1000314005, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO_KHR = 1000314006, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR = 1000314007, VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_2_NV = 1000314008, VK_STRUCTURE_TYPE_CHECKPOINT_DATA_2_NV = 1000314009, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT = 1000320000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT = 1000320001, + VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT = 1000320002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR = 1000323000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES_KHR = 1000325000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_PROPERTIES_NV = 1000326000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_FEATURES_NV = 1000326001, VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_ENUM_STATE_CREATE_INFO_NV = 1000326002, @@ -805,20 +887,10 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT = 1000332000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_PROPERTIES_EXT = 1000332001, VK_STRUCTURE_TYPE_COPY_COMMAND_TRANSFORM_INFO_QCOM = 1000333000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT = 1000335000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR = 1000336000, - VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR = 1000337000, - VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR = 1000337001, - VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR = 1000337002, - VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR = 1000337003, - VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR = 1000337004, - VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR = 1000337005, - VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR = 1000337006, - VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR = 1000337007, - VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR = 1000337008, - VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR = 1000337009, - VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR = 1000337010, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT = 1000340000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_ARM = 1000342000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT = 1000344000, VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT = 1000346000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_VALVE = 1000351000, VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE = 1000351002, @@ -826,12 +898,24 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT = 1000352001, VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT = 1000352002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT = 1000353000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT = 1000355000, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT = 1000355001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT = 1000356000, VK_STRUCTURE_TYPE_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364000, VK_STRUCTURE_TYPE_MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA = 1000364001, VK_STRUCTURE_TYPE_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364002, VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365000, VK_STRUCTURE_TYPE_SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365001, + VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CREATE_INFO_FUCHSIA = 1000366000, + VK_STRUCTURE_TYPE_IMPORT_MEMORY_BUFFER_COLLECTION_FUCHSIA = 1000366001, + VK_STRUCTURE_TYPE_BUFFER_COLLECTION_IMAGE_CREATE_INFO_FUCHSIA = 1000366002, + VK_STRUCTURE_TYPE_BUFFER_COLLECTION_PROPERTIES_FUCHSIA = 1000366003, + VK_STRUCTURE_TYPE_BUFFER_CONSTRAINTS_INFO_FUCHSIA = 1000366004, + VK_STRUCTURE_TYPE_BUFFER_COLLECTION_BUFFER_CREATE_INFO_FUCHSIA = 1000366005, + VK_STRUCTURE_TYPE_IMAGE_CONSTRAINTS_INFO_FUCHSIA = 1000366006, + VK_STRUCTURE_TYPE_IMAGE_FORMAT_CONSTRAINTS_INFO_FUCHSIA = 1000366007, + VK_STRUCTURE_TYPE_SYSMEM_COLOR_SPACE_FUCHSIA = 1000366008, + VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CONSTRAINTS_INFO_FUCHSIA = 1000366009, VK_STRUCTURE_TYPE_SUBPASS_SHADING_PIPELINE_CREATE_INFO_HUAWEI = 1000369000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_FEATURES_HUAWEI = 1000369001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_PROPERTIES_HUAWEI = 1000369002, @@ -842,14 +926,31 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX = 1000378000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT = 1000381000, VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT = 1000381001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT = 1000388000, - VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT = 1000388001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT = 1000382000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT = 1000391000, + VK_STRUCTURE_TYPE_IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT = 1000391001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT = 1000392000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT = 1000392001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT = 1000393000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BORDER_COLOR_SWIZZLE_FEATURES_EXT = 1000411000, + VK_STRUCTURE_TYPE_SAMPLER_BORDER_COLOR_COMPONENT_MAPPING_CREATE_INFO_EXT = 1000411001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT = 1000412000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_SET_HOST_MAPPING_FEATURES_VALVE = 1000420000, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_BINDING_REFERENCE_VALVE = 1000420001, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_HOST_MAPPING_INFO_VALVE = 1000420002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_QCOM = 1000425000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_PROPERTIES_QCOM = 1000425001, + VK_STRUCTURE_TYPE_SUBPASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_QCOM = 1000425002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINEAR_COLOR_ATTACHMENT_FEATURES_NV = 1000430000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, + VK_STRUCTURE_TYPE_RENDERING_INFO_KHR = VK_STRUCTURE_TYPE_RENDERING_INFO, + VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, + VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO, + VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_NV = VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_AMD, VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES, @@ -869,6 +970,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO, VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO_KHR = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO, VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES, VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, @@ -911,6 +1013,10 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES, VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK, + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO, VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2, @@ -932,9 +1038,11 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT, + VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, + VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES, @@ -947,12 +1055,17 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO, VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO_INTEL = VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES, + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT, VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT, VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES, VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES, @@ -961,6 +1074,42 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO, VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES, + VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO, + VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES, + VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2_KHR = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2, + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2_KHR = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, + VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, + VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR = VK_STRUCTURE_TYPE_SUBMIT_INFO_2, + VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES, + VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2, + VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2, + VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2, + VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2, + VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2, + VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2, + VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR = VK_STRUCTURE_TYPE_BUFFER_COPY_2, + VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR = VK_STRUCTURE_TYPE_IMAGE_COPY_2, + VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR = VK_STRUCTURE_TYPE_IMAGE_BLIT_2, + VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR = VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2, + VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2, + VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT = VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES, + VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS, + VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS, VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF } VkStructureType; @@ -980,6 +1129,8 @@ typedef enum VkImageLayout { VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL = 1000241001, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL = 1000241002, VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL = 1000241003, + VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL = 1000314000, + VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL = 1000314001, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002, #ifdef VK_ENABLE_BETA_EXTENSIONS VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR = 1000024000, @@ -1002,8 +1153,6 @@ typedef enum VkImageLayout { #ifdef VK_ENABLE_BETA_EXTENSIONS VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR = 1000299002, #endif - VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR = 1000314000, - VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR = 1000314001, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR, @@ -1011,6 +1160,8 @@ typedef enum VkImageLayout { VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_MAX_ENUM = 0x7FFFFFFF } VkImageLayout; @@ -1043,6 +1194,7 @@ typedef enum VkObjectType { VK_OBJECT_TYPE_COMMAND_POOL = 25, VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION = 1000156000, VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE = 1000085000, + VK_OBJECT_TYPE_PRIVATE_DATA_SLOT = 1000295000, VK_OBJECT_TYPE_SURFACE_KHR = 1000000000, VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000, VK_OBJECT_TYPE_DISPLAY_KHR = 1000002000, @@ -1063,9 +1215,10 @@ typedef enum VkObjectType { VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL = 1000210000, VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR = 1000268000, VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV = 1000277000, - VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT = 1000295000, + VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA = 1000366000, VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE, VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR = VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION, + VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT = VK_OBJECT_TYPE_PRIVATE_DATA_SLOT, VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF } VkObjectType; @@ -1318,6 +1471,26 @@ typedef enum VkFormat { VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM = 1000156031, VK_FORMAT_G16_B16R16_2PLANE_422_UNORM = 1000156032, VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM = 1000156033, + VK_FORMAT_G8_B8R8_2PLANE_444_UNORM = 1000330000, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16 = 1000330001, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16 = 1000330002, + VK_FORMAT_G16_B16R16_2PLANE_444_UNORM = 1000330003, + VK_FORMAT_A4R4G4B4_UNORM_PACK16 = 1000340000, + VK_FORMAT_A4B4G4R4_UNORM_PACK16 = 1000340001, + VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK = 1000066000, + VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK = 1000066001, + VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK = 1000066002, + VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK = 1000066003, + VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK = 1000066004, + VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK = 1000066005, + VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK = 1000066006, + VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK = 1000066007, + VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK = 1000066008, + VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK = 1000066009, + VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK = 1000066010, + VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK = 1000066011, + VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK = 1000066012, + VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK = 1000066013, VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG = 1000054000, VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG = 1000054001, VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG = 1000054002, @@ -1326,26 +1499,20 @@ typedef enum VkFormat { VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG = 1000054005, VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG = 1000054006, VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG = 1000054007, - VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT = 1000066000, - VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT = 1000066001, - VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT = 1000066002, - VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT = 1000066003, - VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT = 1000066004, - VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT = 1000066005, - VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT = 1000066006, - VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT = 1000066007, - VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT = 1000066008, - VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT = 1000066009, - VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT = 1000066010, - VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT = 1000066011, - VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT = 1000066012, - VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT = 1000066013, - VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT = 1000330000, - VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT = 1000330001, - VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT = 1000330002, - VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT = 1000330003, - VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT = 1000340000, - VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT = 1000340001, + VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK, + VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK, + VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK, + VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK, + VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK, + VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK, + VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK, + VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK, + VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK, + VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK, + VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK, + VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK, + VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK, + VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK, VK_FORMAT_G8B8G8R8_422_UNORM_KHR = VK_FORMAT_G8B8G8R8_422_UNORM, VK_FORMAT_B8G8R8G8_422_UNORM_KHR = VK_FORMAT_B8G8R8G8_422_UNORM, VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, @@ -1380,6 +1547,12 @@ typedef enum VkFormat { VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM, VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16R16_2PLANE_422_UNORM, VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, + VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT = VK_FORMAT_G8_B8R8_2PLANE_444_UNORM, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16, + VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT = VK_FORMAT_G16_B16R16_2PLANE_444_UNORM, + VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT = VK_FORMAT_A4R4G4B4_UNORM_PACK16, + VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT = VK_FORMAT_A4B4G4R4_UNORM_PACK16, VK_FORMAT_MAX_ENUM = 0x7FFFFFFF } VkFormat; @@ -1422,6 +1595,7 @@ typedef enum VkQueryType { #ifdef VK_ENABLE_BETA_EXTENSIONS VK_QUERY_TYPE_VIDEO_ENCODE_BITSTREAM_BUFFER_RANGE_KHR = 1000299000, #endif + VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT = 1000382000, VK_QUERY_TYPE_MAX_ENUM = 0x7FFFFFFF } VkQueryType; @@ -1553,6 +1727,21 @@ typedef enum VkDynamicState { VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6, VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7, VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8, + VK_DYNAMIC_STATE_CULL_MODE = 1000267000, + VK_DYNAMIC_STATE_FRONT_FACE = 1000267001, + VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY = 1000267002, + VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT = 1000267003, + VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT = 1000267004, + VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE = 1000267005, + VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE = 1000267006, + VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE = 1000267007, + VK_DYNAMIC_STATE_DEPTH_COMPARE_OP = 1000267008, + VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE = 1000267009, + VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE = 1000267010, + VK_DYNAMIC_STATE_STENCIL_OP = 1000267011, + VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE = 1000377001, + VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE = 1000377002, + VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE = 1000377004, VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV = 1000087000, VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT = 1000099000, VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT = 1000143000, @@ -1562,25 +1751,25 @@ typedef enum VkDynamicState { VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV = 1000205001, VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR = 1000226000, VK_DYNAMIC_STATE_LINE_STIPPLE_EXT = 1000259000, - VK_DYNAMIC_STATE_CULL_MODE_EXT = 1000267000, - VK_DYNAMIC_STATE_FRONT_FACE_EXT = 1000267001, - VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT = 1000267002, - VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT = 1000267003, - VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT = 1000267004, - VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT = 1000267005, - VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT = 1000267006, - VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT = 1000267007, - VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT = 1000267008, - VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT = 1000267009, - VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT = 1000267010, - VK_DYNAMIC_STATE_STENCIL_OP_EXT = 1000267011, VK_DYNAMIC_STATE_VERTEX_INPUT_EXT = 1000352000, VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT = 1000377000, - VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT = 1000377001, - VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT = 1000377002, VK_DYNAMIC_STATE_LOGIC_OP_EXT = 1000377003, - VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT = 1000377004, VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT = 1000381000, + VK_DYNAMIC_STATE_CULL_MODE_EXT = VK_DYNAMIC_STATE_CULL_MODE, + VK_DYNAMIC_STATE_FRONT_FACE_EXT = VK_DYNAMIC_STATE_FRONT_FACE, + VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT = VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY, + VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT, + VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT, + VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE, + VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE, + VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE, + VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP, + VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE, + VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE, + VK_DYNAMIC_STATE_STENCIL_OP_EXT = VK_DYNAMIC_STATE_STENCIL_OP, + VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT = VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE, + VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE, + VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE, VK_DYNAMIC_STATE_MAX_ENUM = 0x7FFFFFFF } VkDynamicState; @@ -1699,10 +1888,11 @@ typedef enum VkDescriptorType { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, - VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = 1000138000, + VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK = 1000138000, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, VK_DESCRIPTOR_TYPE_MUTABLE_VALVE = 1000351000, + VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK, VK_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF } VkDescriptorType; @@ -1717,8 +1907,10 @@ typedef enum VkAttachmentLoadOp { typedef enum VkAttachmentStoreOp { VK_ATTACHMENT_STORE_OP_STORE = 0, VK_ATTACHMENT_STORE_OP_DONT_CARE = 1, - VK_ATTACHMENT_STORE_OP_NONE_EXT = 1000301000, - VK_ATTACHMENT_STORE_OP_NONE_QCOM = VK_ATTACHMENT_STORE_OP_NONE_EXT, + VK_ATTACHMENT_STORE_OP_NONE = 1000301000, + VK_ATTACHMENT_STORE_OP_NONE_KHR = VK_ATTACHMENT_STORE_OP_NONE, + VK_ATTACHMENT_STORE_OP_NONE_QCOM = VK_ATTACHMENT_STORE_OP_NONE, + VK_ATTACHMENT_STORE_OP_NONE_EXT = VK_ATTACHMENT_STORE_OP_NONE, VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF } VkAttachmentStoreOp; @@ -1770,6 +1962,7 @@ typedef enum VkAccessFlagBits { VK_ACCESS_HOST_WRITE_BIT = 0x00004000, VK_ACCESS_MEMORY_READ_BIT = 0x00008000, VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000, + VK_ACCESS_NONE = 0, VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000, VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000, VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000, @@ -1781,10 +1974,10 @@ typedef enum VkAccessFlagBits { VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000, VK_ACCESS_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000, VK_ACCESS_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000, - VK_ACCESS_NONE_KHR = 0, VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV = VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, + VK_ACCESS_NONE_KHR = VK_ACCESS_NONE, VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkAccessFlagBits; typedef VkFlags VkAccessFlags; @@ -1797,6 +1990,7 @@ typedef enum VkImageAspectFlagBits { VK_IMAGE_ASPECT_PLANE_0_BIT = 0x00000010, VK_IMAGE_ASPECT_PLANE_1_BIT = 0x00000020, VK_IMAGE_ASPECT_PLANE_2_BIT = 0x00000040, + VK_IMAGE_ASPECT_NONE = 0, VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT = 0x00000080, VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT = 0x00000100, VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT = 0x00000200, @@ -1804,6 +1998,7 @@ typedef enum VkImageAspectFlagBits { VK_IMAGE_ASPECT_PLANE_0_BIT_KHR = VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT_KHR = VK_IMAGE_ASPECT_PLANE_1_BIT, VK_IMAGE_ASPECT_PLANE_2_BIT_KHR = VK_IMAGE_ASPECT_PLANE_2_BIT, + VK_IMAGE_ASPECT_NONE_KHR = VK_IMAGE_ASPECT_NONE, VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkImageAspectFlagBits; typedef VkFlags VkImageAspectFlags; @@ -1879,6 +2074,8 @@ typedef enum VkImageCreateFlagBits { VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV = 0x00002000, VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT = 0x00001000, VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT = 0x00004000, + VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT = 0x00020000, + VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_QCOM = 0x00008000, VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT, VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT, @@ -1935,6 +2132,11 @@ typedef enum VkImageUsageFlagBits { VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkImageUsageFlagBits; typedef VkFlags VkImageUsageFlags; + +typedef enum VkInstanceCreateFlagBits { + VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR = 0x00000001, + VK_INSTANCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkInstanceCreateFlagBits; typedef VkFlags VkInstanceCreateFlags; typedef enum VkMemoryHeapFlagBits { @@ -2000,6 +2202,7 @@ typedef enum VkPipelineStageFlagBits { VK_PIPELINE_STAGE_HOST_BIT = 0x00004000, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 0x00008000, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000, + VK_PIPELINE_STAGE_NONE = 0, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000, VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000, @@ -2009,10 +2212,10 @@ typedef enum VkPipelineStageFlagBits { VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000, VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000, VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV = 0x00020000, - VK_PIPELINE_STAGE_NONE_KHR = 0, VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV = VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_NV = VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV = VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, + VK_PIPELINE_STAGE_NONE_KHR = VK_PIPELINE_STAGE_NONE, VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineStageFlagBits; typedef VkFlags VkPipelineStageFlags; @@ -2040,7 +2243,8 @@ typedef VkFlags VkFenceCreateFlags; typedef VkFlags VkSemaphoreCreateFlags; typedef enum VkEventCreateFlagBits { - VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR = 0x00000001, + VK_EVENT_CREATE_DEVICE_ONLY_BIT = 0x00000001, + VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR = VK_EVENT_CREATE_DEVICE_ONLY_BIT, VK_EVENT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkEventCreateFlagBits; typedef VkFlags VkEventCreateFlags; @@ -2132,7 +2336,8 @@ typedef VkFlags VkImageViewCreateFlags; typedef VkFlags VkShaderModuleCreateFlags; typedef enum VkPipelineCacheCreateFlagBits { - VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT_EXT = 0x00000001, + VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT = 0x00000001, + VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT_EXT = VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT, VK_PIPELINE_CACHE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineCacheCreateFlagBits; typedef VkFlags VkPipelineCacheCreateFlags; @@ -2152,6 +2357,10 @@ typedef enum VkPipelineCreateFlagBits { VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004, VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT = 0x00000008, VK_PIPELINE_CREATE_DISPATCH_BASE_BIT = 0x00000010, + VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT = 0x00000100, + VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT = 0x00000200, + VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00200000, + VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = 0x00400000, VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_ANY_HIT_SHADERS_BIT_KHR = 0x00004000, VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_CLOSEST_HIT_SHADERS_BIT_KHR = 0x00008000, VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_MISS_SHADERS_BIT_KHR = 0x00010000, @@ -2164,19 +2373,25 @@ typedef enum VkPipelineCreateFlagBits { VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR = 0x00000080, VK_PIPELINE_CREATE_INDIRECT_BINDABLE_BIT_NV = 0x00040000, VK_PIPELINE_CREATE_LIBRARY_BIT_KHR = 0x00000800, - VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT = 0x00000100, - VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT_EXT = 0x00000200, + VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT = 0x00800000, + VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT = 0x00000400, VK_PIPELINE_CREATE_RAY_TRACING_ALLOW_MOTION_BIT_NV = 0x00100000, VK_PIPELINE_CREATE_DISPATCH_BASE = VK_PIPELINE_CREATE_DISPATCH_BASE_BIT, + VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, + VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT, VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR = VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT, VK_PIPELINE_CREATE_DISPATCH_BASE_KHR = VK_PIPELINE_CREATE_DISPATCH_BASE, + VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT = VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT, + VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT_EXT = VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT, VK_PIPELINE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineCreateFlagBits; typedef VkFlags VkPipelineCreateFlags; typedef enum VkPipelineShaderStageCreateFlagBits { - VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT = 0x00000001, - VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT = 0x00000002, + VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT = 0x00000001, + VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT = 0x00000002, + VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT = VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT, + VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT = VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT, VK_PIPELINE_SHADER_STAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineShaderStageCreateFlagBits; typedef VkFlags VkPipelineShaderStageCreateFlags; @@ -2222,9 +2437,25 @@ typedef VkFlags VkPipelineTessellationStateCreateFlags; typedef VkFlags VkPipelineViewportStateCreateFlags; typedef VkFlags VkPipelineRasterizationStateCreateFlags; typedef VkFlags VkPipelineMultisampleStateCreateFlags; + +typedef enum VkPipelineDepthStencilStateCreateFlagBits { + VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM = 0x00000001, + VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM = 0x00000002, + VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineDepthStencilStateCreateFlagBits; typedef VkFlags VkPipelineDepthStencilStateCreateFlags; + +typedef enum VkPipelineColorBlendStateCreateFlagBits { + VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_ARM = 0x00000001, + VK_PIPELINE_COLOR_BLEND_STATE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineColorBlendStateCreateFlagBits; typedef VkFlags VkPipelineColorBlendStateCreateFlags; typedef VkFlags VkPipelineDynamicStateCreateFlags; + +typedef enum VkPipelineLayoutCreateFlagBits { + VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT = 0x00000002, + VK_PIPELINE_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineLayoutCreateFlagBits; typedef VkFlags VkPipelineLayoutCreateFlags; typedef VkFlags VkShaderStageFlags; @@ -2288,6 +2519,9 @@ typedef enum VkSubpassDescriptionFlagBits { VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX = 0x00000002, VK_SUBPASS_DESCRIPTION_FRAGMENT_REGION_BIT_QCOM = 0x00000004, VK_SUBPASS_DESCRIPTION_SHADER_RESOLVE_BIT_QCOM = 0x00000008, + VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_ARM = 0x00000010, + VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM = 0x00000020, + VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM = 0x00000040, VK_SUBPASS_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkSubpassDescriptionFlagBits; typedef VkFlags VkSubpassDescriptionFlags; @@ -5285,6 +5519,11 @@ typedef enum VkDriverId { VK_DRIVER_ID_COREAVI_PROPRIETARY = 15, VK_DRIVER_ID_JUICE_PROPRIETARY = 16, VK_DRIVER_ID_VERISILICON_PROPRIETARY = 17, + VK_DRIVER_ID_MESA_TURNIP = 18, + VK_DRIVER_ID_MESA_V3DV = 19, + VK_DRIVER_ID_MESA_PANVK = 20, + VK_DRIVER_ID_SAMSUNG_PROPRIETARY = 21, + VK_DRIVER_ID_MESA_VENUS = 22, VK_DRIVER_ID_AMD_PROPRIETARY_KHR = VK_DRIVER_ID_AMD_PROPRIETARY, VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = VK_DRIVER_ID_AMD_OPEN_SOURCE, VK_DRIVER_ID_MESA_RADV_KHR = VK_DRIVER_ID_MESA_RADV, @@ -6006,6 +6245,1037 @@ VKAPI_ATTR uint64_t VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddress( #endif +#define VK_VERSION_1_3 1 +// Vulkan 1.3 version number +#define VK_API_VERSION_1_3 VK_MAKE_API_VERSION(0, 1, 3, 0)// Patch version should always be set to 0 + +typedef uint64_t VkFlags64; +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPrivateDataSlot) + +typedef enum VkPipelineCreationFeedbackFlagBits { + VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT = 0x00000001, + VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT = 0x00000002, + VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT = 0x00000004, + VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT, + VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT, + VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT, + VK_PIPELINE_CREATION_FEEDBACK_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineCreationFeedbackFlagBits; +typedef VkFlags VkPipelineCreationFeedbackFlags; + +typedef enum VkToolPurposeFlagBits { + VK_TOOL_PURPOSE_VALIDATION_BIT = 0x00000001, + VK_TOOL_PURPOSE_PROFILING_BIT = 0x00000002, + VK_TOOL_PURPOSE_TRACING_BIT = 0x00000004, + VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT = 0x00000008, + VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT = 0x00000010, + VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT = 0x00000020, + VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT = 0x00000040, + VK_TOOL_PURPOSE_VALIDATION_BIT_EXT = VK_TOOL_PURPOSE_VALIDATION_BIT, + VK_TOOL_PURPOSE_PROFILING_BIT_EXT = VK_TOOL_PURPOSE_PROFILING_BIT, + VK_TOOL_PURPOSE_TRACING_BIT_EXT = VK_TOOL_PURPOSE_TRACING_BIT, + VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT = VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT, + VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT = VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT, + VK_TOOL_PURPOSE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkToolPurposeFlagBits; +typedef VkFlags VkToolPurposeFlags; +typedef VkFlags VkPrivateDataSlotCreateFlags; +typedef VkFlags64 VkPipelineStageFlags2; + +// Flag bits for VkPipelineStageFlagBits2 +typedef VkFlags64 VkPipelineStageFlagBits2; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_NONE = 0ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_NONE_KHR = 0ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT = 0x00000001ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR = 0x00000001ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT = 0x00000002ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR = 0x00000002ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT = 0x00000004ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT_KHR = 0x00000004ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT = 0x00000008ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR = 0x00000008ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT = 0x00000010ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR = 0x00000010ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT = 0x00000020ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR = 0x00000020ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT = 0x00000040ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR = 0x00000040ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT = 0x00000080ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR = 0x00000080ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT = 0x00000100ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR = 0x00000100ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT = 0x00000200ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR = 0x00000200ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT = 0x00000400ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR = 0x00000400ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT = 0x00000800ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR = 0x00000800ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT = 0x00001000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR = 0x00001000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFER_BIT = 0x00001000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR = 0x00001000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT = 0x00002000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR = 0x00002000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_HOST_BIT = 0x00004000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_HOST_BIT_KHR = 0x00004000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT = 0x00008000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR = 0x00008000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT = 0x00010000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR = 0x00010000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COPY_BIT = 0x100000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COPY_BIT_KHR = 0x100000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RESOLVE_BIT = 0x200000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR = 0x200000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BLIT_BIT = 0x400000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BLIT_BIT_KHR = 0x400000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLEAR_BIT = 0x800000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR = 0x800000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT = 0x1000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR = 0x1000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT = 0x2000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR = 0x2000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT = 0x4000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT_KHR = 0x4000000000ULL; +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR = 0x04000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR = 0x08000000ULL; +#endif +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_NV = 0x00020000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_SHADING_RATE_IMAGE_BIT_NV = 0x00400000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR = 0x00200000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_NV = 0x00200000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_NV = 0x00080000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV = 0x00100000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI = 0x8000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI = 0x10000000000ULL; + +typedef VkFlags64 VkAccessFlags2; + +// Flag bits for VkAccessFlagBits2 +typedef VkFlags64 VkAccessFlagBits2; +static const VkAccessFlagBits2 VK_ACCESS_2_NONE = 0ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_NONE_KHR = 0ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT = 0x00000001ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT_KHR = 0x00000001ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INDEX_READ_BIT = 0x00000002ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INDEX_READ_BIT_KHR = 0x00000002ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT = 0x00000004ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT_KHR = 0x00000004ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_UNIFORM_READ_BIT = 0x00000008ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_UNIFORM_READ_BIT_KHR = 0x00000008ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT = 0x00000010ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR = 0x00000010ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_READ_BIT = 0x00000020ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_READ_BIT_KHR = 0x00000020ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_WRITE_BIT = 0x00000040ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_WRITE_BIT_KHR = 0x00000040ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT = 0x00000080ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT_KHR = 0x00000080ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR = 0x00000100ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 0x00000200ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT_KHR = 0x00000200ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 0x00000400ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR = 0x00000400ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_READ_BIT = 0x00000800ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_READ_BIT_KHR = 0x00000800ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_WRITE_BIT = 0x00001000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR = 0x00001000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_READ_BIT = 0x00002000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_READ_BIT_KHR = 0x00002000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_WRITE_BIT = 0x00004000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_WRITE_BIT_KHR = 0x00004000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_READ_BIT = 0x00008000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_READ_BIT_KHR = 0x00008000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_WRITE_BIT = 0x00010000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_WRITE_BIT_KHR = 0x00010000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT = 0x100000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR = 0x100000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_READ_BIT = 0x200000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR = 0x200000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT = 0x400000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR = 0x400000000ULL; +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR = 0x800000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR = 0x1000000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR = 0x2000000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_ENCODE_WRITE_BIT_KHR = 0x4000000000ULL; +#endif +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_NV = 0x00200000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_NV = 0x00400000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INVOCATION_MASK_READ_BIT_HUAWEI = 0x8000000000ULL; + + +typedef enum VkSubmitFlagBits { + VK_SUBMIT_PROTECTED_BIT = 0x00000001, + VK_SUBMIT_PROTECTED_BIT_KHR = VK_SUBMIT_PROTECTED_BIT, + VK_SUBMIT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSubmitFlagBits; +typedef VkFlags VkSubmitFlags; + +typedef enum VkRenderingFlagBits { + VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT = 0x00000001, + VK_RENDERING_SUSPENDING_BIT = 0x00000002, + VK_RENDERING_RESUMING_BIT = 0x00000004, + VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT, + VK_RENDERING_SUSPENDING_BIT_KHR = VK_RENDERING_SUSPENDING_BIT, + VK_RENDERING_RESUMING_BIT_KHR = VK_RENDERING_RESUMING_BIT, + VK_RENDERING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkRenderingFlagBits; +typedef VkFlags VkRenderingFlags; +typedef VkFlags64 VkFormatFeatureFlags2; + +// Flag bits for VkFormatFeatureFlagBits2 +typedef VkFlags64 VkFormatFeatureFlagBits2; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT = 0x00000001ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR = 0x00000001ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT = 0x00000002ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR = 0x00000002ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT = 0x00000004ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT_KHR = 0x00000004ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT = 0x00000008ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT_KHR = 0x00000008ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT = 0x00000010ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT_KHR = 0x00000010ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT = 0x00000020ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT_KHR = 0x00000020ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT = 0x00000040ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT_KHR = 0x00000040ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT = 0x00000080ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR = 0x00000080ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT = 0x00000100ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT_KHR = 0x00000100ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000200ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR = 0x00000200ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT = 0x00000400ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT_KHR = 0x00000400ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_DST_BIT = 0x00000800ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_DST_BIT_KHR = 0x00000800ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT_KHR = 0x00001000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_CUBIC_BIT = 0x00002000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT = 0x00002000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT = 0x00004000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT_KHR = 0x00004000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT = 0x00008000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT_KHR = 0x00008000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT = 0x00010000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT_KHR = 0x00010000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT = 0x00020000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = 0x00020000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT = 0x00040000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR = 0x00040000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT = 0x00080000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR = 0x00080000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT = 0x00100000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT_KHR = 0x00100000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT = 0x00200000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR = 0x00200000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DISJOINT_BIT = 0x00400000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DISJOINT_BIT_KHR = 0x00400000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT = 0x00800000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT_KHR = 0x00800000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT = 0x80000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR = 0x80000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT = 0x100000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR = 0x100000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT = 0x200000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR = 0x200000000ULL; +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_DECODE_OUTPUT_BIT_KHR = 0x02000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_DECODE_DPB_BIT_KHR = 0x04000000ULL; +#endif +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR = 0x20000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x01000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x40000000ULL; +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_ENCODE_INPUT_BIT_KHR = 0x08000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_ENCODE_DPB_BIT_KHR = 0x10000000ULL; +#endif +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_LINEAR_COLOR_ATTACHMENT_BIT_NV = 0x4000000000ULL; + +typedef struct VkPhysicalDeviceVulkan13Features { + VkStructureType sType; + void* pNext; + VkBool32 robustImageAccess; + VkBool32 inlineUniformBlock; + VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind; + VkBool32 pipelineCreationCacheControl; + VkBool32 privateData; + VkBool32 shaderDemoteToHelperInvocation; + VkBool32 shaderTerminateInvocation; + VkBool32 subgroupSizeControl; + VkBool32 computeFullSubgroups; + VkBool32 synchronization2; + VkBool32 textureCompressionASTC_HDR; + VkBool32 shaderZeroInitializeWorkgroupMemory; + VkBool32 dynamicRendering; + VkBool32 shaderIntegerDotProduct; + VkBool32 maintenance4; +} VkPhysicalDeviceVulkan13Features; + +typedef struct VkPhysicalDeviceVulkan13Properties { + VkStructureType sType; + void* pNext; + uint32_t minSubgroupSize; + uint32_t maxSubgroupSize; + uint32_t maxComputeWorkgroupSubgroups; + VkShaderStageFlags requiredSubgroupSizeStages; + uint32_t maxInlineUniformBlockSize; + uint32_t maxPerStageDescriptorInlineUniformBlocks; + uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks; + uint32_t maxDescriptorSetInlineUniformBlocks; + uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks; + uint32_t maxInlineUniformTotalSize; + VkBool32 integerDotProduct8BitUnsignedAccelerated; + VkBool32 integerDotProduct8BitSignedAccelerated; + VkBool32 integerDotProduct8BitMixedSignednessAccelerated; + VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedSignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProduct16BitUnsignedAccelerated; + VkBool32 integerDotProduct16BitSignedAccelerated; + VkBool32 integerDotProduct16BitMixedSignednessAccelerated; + VkBool32 integerDotProduct32BitUnsignedAccelerated; + VkBool32 integerDotProduct32BitSignedAccelerated; + VkBool32 integerDotProduct32BitMixedSignednessAccelerated; + VkBool32 integerDotProduct64BitUnsignedAccelerated; + VkBool32 integerDotProduct64BitSignedAccelerated; + VkBool32 integerDotProduct64BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated; + VkDeviceSize storageTexelBufferOffsetAlignmentBytes; + VkBool32 storageTexelBufferOffsetSingleTexelAlignment; + VkDeviceSize uniformTexelBufferOffsetAlignmentBytes; + VkBool32 uniformTexelBufferOffsetSingleTexelAlignment; + VkDeviceSize maxBufferSize; +} VkPhysicalDeviceVulkan13Properties; + +typedef struct VkPipelineCreationFeedback { + VkPipelineCreationFeedbackFlags flags; + uint64_t duration; +} VkPipelineCreationFeedback; + +typedef struct VkPipelineCreationFeedbackCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineCreationFeedback* pPipelineCreationFeedback; + uint32_t pipelineStageCreationFeedbackCount; + VkPipelineCreationFeedback* pPipelineStageCreationFeedbacks; +} VkPipelineCreationFeedbackCreateInfo; + +typedef struct VkPhysicalDeviceShaderTerminateInvocationFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderTerminateInvocation; +} VkPhysicalDeviceShaderTerminateInvocationFeatures; + +typedef struct VkPhysicalDeviceToolProperties { + VkStructureType sType; + void* pNext; + char name[VK_MAX_EXTENSION_NAME_SIZE]; + char version[VK_MAX_EXTENSION_NAME_SIZE]; + VkToolPurposeFlags purposes; + char description[VK_MAX_DESCRIPTION_SIZE]; + char layer[VK_MAX_EXTENSION_NAME_SIZE]; +} VkPhysicalDeviceToolProperties; + +typedef struct VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderDemoteToHelperInvocation; +} VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures; + +typedef struct VkPhysicalDevicePrivateDataFeatures { + VkStructureType sType; + void* pNext; + VkBool32 privateData; +} VkPhysicalDevicePrivateDataFeatures; + +typedef struct VkDevicePrivateDataCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t privateDataSlotRequestCount; +} VkDevicePrivateDataCreateInfo; + +typedef struct VkPrivateDataSlotCreateInfo { + VkStructureType sType; + const void* pNext; + VkPrivateDataSlotCreateFlags flags; +} VkPrivateDataSlotCreateInfo; + +typedef struct VkPhysicalDevicePipelineCreationCacheControlFeatures { + VkStructureType sType; + void* pNext; + VkBool32 pipelineCreationCacheControl; +} VkPhysicalDevicePipelineCreationCacheControlFeatures; + +typedef struct VkMemoryBarrier2 { + VkStructureType sType; + const void* pNext; + VkPipelineStageFlags2 srcStageMask; + VkAccessFlags2 srcAccessMask; + VkPipelineStageFlags2 dstStageMask; + VkAccessFlags2 dstAccessMask; +} VkMemoryBarrier2; + +typedef struct VkBufferMemoryBarrier2 { + VkStructureType sType; + const void* pNext; + VkPipelineStageFlags2 srcStageMask; + VkAccessFlags2 srcAccessMask; + VkPipelineStageFlags2 dstStageMask; + VkAccessFlags2 dstAccessMask; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize size; +} VkBufferMemoryBarrier2; + +typedef struct VkImageMemoryBarrier2 { + VkStructureType sType; + const void* pNext; + VkPipelineStageFlags2 srcStageMask; + VkAccessFlags2 srcAccessMask; + VkPipelineStageFlags2 dstStageMask; + VkAccessFlags2 dstAccessMask; + VkImageLayout oldLayout; + VkImageLayout newLayout; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkImage image; + VkImageSubresourceRange subresourceRange; +} VkImageMemoryBarrier2; + +typedef struct VkDependencyInfo { + VkStructureType sType; + const void* pNext; + VkDependencyFlags dependencyFlags; + uint32_t memoryBarrierCount; + const VkMemoryBarrier2* pMemoryBarriers; + uint32_t bufferMemoryBarrierCount; + const VkBufferMemoryBarrier2* pBufferMemoryBarriers; + uint32_t imageMemoryBarrierCount; + const VkImageMemoryBarrier2* pImageMemoryBarriers; +} VkDependencyInfo; + +typedef struct VkSemaphoreSubmitInfo { + VkStructureType sType; + const void* pNext; + VkSemaphore semaphore; + uint64_t value; + VkPipelineStageFlags2 stageMask; + uint32_t deviceIndex; +} VkSemaphoreSubmitInfo; + +typedef struct VkCommandBufferSubmitInfo { + VkStructureType sType; + const void* pNext; + VkCommandBuffer commandBuffer; + uint32_t deviceMask; +} VkCommandBufferSubmitInfo; + +typedef struct VkSubmitInfo2 { + VkStructureType sType; + const void* pNext; + VkSubmitFlags flags; + uint32_t waitSemaphoreInfoCount; + const VkSemaphoreSubmitInfo* pWaitSemaphoreInfos; + uint32_t commandBufferInfoCount; + const VkCommandBufferSubmitInfo* pCommandBufferInfos; + uint32_t signalSemaphoreInfoCount; + const VkSemaphoreSubmitInfo* pSignalSemaphoreInfos; +} VkSubmitInfo2; + +typedef struct VkPhysicalDeviceSynchronization2Features { + VkStructureType sType; + void* pNext; + VkBool32 synchronization2; +} VkPhysicalDeviceSynchronization2Features; + +typedef struct VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderZeroInitializeWorkgroupMemory; +} VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures; + +typedef struct VkPhysicalDeviceImageRobustnessFeatures { + VkStructureType sType; + void* pNext; + VkBool32 robustImageAccess; +} VkPhysicalDeviceImageRobustnessFeatures; + +typedef struct VkBufferCopy2 { + VkStructureType sType; + const void* pNext; + VkDeviceSize srcOffset; + VkDeviceSize dstOffset; + VkDeviceSize size; +} VkBufferCopy2; + +typedef struct VkCopyBufferInfo2 { + VkStructureType sType; + const void* pNext; + VkBuffer srcBuffer; + VkBuffer dstBuffer; + uint32_t regionCount; + const VkBufferCopy2* pRegions; +} VkCopyBufferInfo2; + +typedef struct VkImageCopy2 { + VkStructureType sType; + const void* pNext; + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageCopy2; + +typedef struct VkCopyImageInfo2 { + VkStructureType sType; + const void* pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkImageCopy2* pRegions; +} VkCopyImageInfo2; + +typedef struct VkBufferImageCopy2 { + VkStructureType sType; + const void* pNext; + VkDeviceSize bufferOffset; + uint32_t bufferRowLength; + uint32_t bufferImageHeight; + VkImageSubresourceLayers imageSubresource; + VkOffset3D imageOffset; + VkExtent3D imageExtent; +} VkBufferImageCopy2; + +typedef struct VkCopyBufferToImageInfo2 { + VkStructureType sType; + const void* pNext; + VkBuffer srcBuffer; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkBufferImageCopy2* pRegions; +} VkCopyBufferToImageInfo2; + +typedef struct VkCopyImageToBufferInfo2 { + VkStructureType sType; + const void* pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkBuffer dstBuffer; + uint32_t regionCount; + const VkBufferImageCopy2* pRegions; +} VkCopyImageToBufferInfo2; + +typedef struct VkImageBlit2 { + VkStructureType sType; + const void* pNext; + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffsets[2]; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffsets[2]; +} VkImageBlit2; + +typedef struct VkBlitImageInfo2 { + VkStructureType sType; + const void* pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkImageBlit2* pRegions; + VkFilter filter; +} VkBlitImageInfo2; + +typedef struct VkImageResolve2 { + VkStructureType sType; + const void* pNext; + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageResolve2; + +typedef struct VkResolveImageInfo2 { + VkStructureType sType; + const void* pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkImageResolve2* pRegions; +} VkResolveImageInfo2; + +typedef struct VkPhysicalDeviceSubgroupSizeControlFeatures { + VkStructureType sType; + void* pNext; + VkBool32 subgroupSizeControl; + VkBool32 computeFullSubgroups; +} VkPhysicalDeviceSubgroupSizeControlFeatures; + +typedef struct VkPhysicalDeviceSubgroupSizeControlProperties { + VkStructureType sType; + void* pNext; + uint32_t minSubgroupSize; + uint32_t maxSubgroupSize; + uint32_t maxComputeWorkgroupSubgroups; + VkShaderStageFlags requiredSubgroupSizeStages; +} VkPhysicalDeviceSubgroupSizeControlProperties; + +typedef struct VkPipelineShaderStageRequiredSubgroupSizeCreateInfo { + VkStructureType sType; + void* pNext; + uint32_t requiredSubgroupSize; +} VkPipelineShaderStageRequiredSubgroupSizeCreateInfo; + +typedef struct VkPhysicalDeviceInlineUniformBlockFeatures { + VkStructureType sType; + void* pNext; + VkBool32 inlineUniformBlock; + VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind; +} VkPhysicalDeviceInlineUniformBlockFeatures; + +typedef struct VkPhysicalDeviceInlineUniformBlockProperties { + VkStructureType sType; + void* pNext; + uint32_t maxInlineUniformBlockSize; + uint32_t maxPerStageDescriptorInlineUniformBlocks; + uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks; + uint32_t maxDescriptorSetInlineUniformBlocks; + uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks; +} VkPhysicalDeviceInlineUniformBlockProperties; + +typedef struct VkWriteDescriptorSetInlineUniformBlock { + VkStructureType sType; + const void* pNext; + uint32_t dataSize; + const void* pData; +} VkWriteDescriptorSetInlineUniformBlock; + +typedef struct VkDescriptorPoolInlineUniformBlockCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t maxInlineUniformBlockBindings; +} VkDescriptorPoolInlineUniformBlockCreateInfo; + +typedef struct VkPhysicalDeviceTextureCompressionASTCHDRFeatures { + VkStructureType sType; + void* pNext; + VkBool32 textureCompressionASTC_HDR; +} VkPhysicalDeviceTextureCompressionASTCHDRFeatures; + +typedef struct VkRenderingAttachmentInfo { + VkStructureType sType; + const void* pNext; + VkImageView imageView; + VkImageLayout imageLayout; + VkResolveModeFlagBits resolveMode; + VkImageView resolveImageView; + VkImageLayout resolveImageLayout; + VkAttachmentLoadOp loadOp; + VkAttachmentStoreOp storeOp; + VkClearValue clearValue; +} VkRenderingAttachmentInfo; + +typedef struct VkRenderingInfo { + VkStructureType sType; + const void* pNext; + VkRenderingFlags flags; + VkRect2D renderArea; + uint32_t layerCount; + uint32_t viewMask; + uint32_t colorAttachmentCount; + const VkRenderingAttachmentInfo* pColorAttachments; + const VkRenderingAttachmentInfo* pDepthAttachment; + const VkRenderingAttachmentInfo* pStencilAttachment; +} VkRenderingInfo; + +typedef struct VkPipelineRenderingCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t viewMask; + uint32_t colorAttachmentCount; + const VkFormat* pColorAttachmentFormats; + VkFormat depthAttachmentFormat; + VkFormat stencilAttachmentFormat; +} VkPipelineRenderingCreateInfo; + +typedef struct VkPhysicalDeviceDynamicRenderingFeatures { + VkStructureType sType; + void* pNext; + VkBool32 dynamicRendering; +} VkPhysicalDeviceDynamicRenderingFeatures; + +typedef struct VkCommandBufferInheritanceRenderingInfo { + VkStructureType sType; + const void* pNext; + VkRenderingFlags flags; + uint32_t viewMask; + uint32_t colorAttachmentCount; + const VkFormat* pColorAttachmentFormats; + VkFormat depthAttachmentFormat; + VkFormat stencilAttachmentFormat; + VkSampleCountFlagBits rasterizationSamples; +} VkCommandBufferInheritanceRenderingInfo; + +typedef struct VkPhysicalDeviceShaderIntegerDotProductFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderIntegerDotProduct; +} VkPhysicalDeviceShaderIntegerDotProductFeatures; + +typedef struct VkPhysicalDeviceShaderIntegerDotProductProperties { + VkStructureType sType; + void* pNext; + VkBool32 integerDotProduct8BitUnsignedAccelerated; + VkBool32 integerDotProduct8BitSignedAccelerated; + VkBool32 integerDotProduct8BitMixedSignednessAccelerated; + VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedSignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProduct16BitUnsignedAccelerated; + VkBool32 integerDotProduct16BitSignedAccelerated; + VkBool32 integerDotProduct16BitMixedSignednessAccelerated; + VkBool32 integerDotProduct32BitUnsignedAccelerated; + VkBool32 integerDotProduct32BitSignedAccelerated; + VkBool32 integerDotProduct32BitMixedSignednessAccelerated; + VkBool32 integerDotProduct64BitUnsignedAccelerated; + VkBool32 integerDotProduct64BitSignedAccelerated; + VkBool32 integerDotProduct64BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated; +} VkPhysicalDeviceShaderIntegerDotProductProperties; + +typedef struct VkPhysicalDeviceTexelBufferAlignmentProperties { + VkStructureType sType; + void* pNext; + VkDeviceSize storageTexelBufferOffsetAlignmentBytes; + VkBool32 storageTexelBufferOffsetSingleTexelAlignment; + VkDeviceSize uniformTexelBufferOffsetAlignmentBytes; + VkBool32 uniformTexelBufferOffsetSingleTexelAlignment; +} VkPhysicalDeviceTexelBufferAlignmentProperties; + +typedef struct VkFormatProperties3 { + VkStructureType sType; + void* pNext; + VkFormatFeatureFlags2 linearTilingFeatures; + VkFormatFeatureFlags2 optimalTilingFeatures; + VkFormatFeatureFlags2 bufferFeatures; +} VkFormatProperties3; + +typedef struct VkPhysicalDeviceMaintenance4Features { + VkStructureType sType; + void* pNext; + VkBool32 maintenance4; +} VkPhysicalDeviceMaintenance4Features; + +typedef struct VkPhysicalDeviceMaintenance4Properties { + VkStructureType sType; + void* pNext; + VkDeviceSize maxBufferSize; +} VkPhysicalDeviceMaintenance4Properties; + +typedef struct VkDeviceBufferMemoryRequirements { + VkStructureType sType; + const void* pNext; + const VkBufferCreateInfo* pCreateInfo; +} VkDeviceBufferMemoryRequirements; + +typedef struct VkDeviceImageMemoryRequirements { + VkStructureType sType; + const void* pNext; + const VkImageCreateInfo* pCreateInfo; + VkImageAspectFlagBits planeAspect; +} VkDeviceImageMemoryRequirements; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceToolProperties)(VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolProperties* pToolProperties); +typedef VkResult (VKAPI_PTR *PFN_vkCreatePrivateDataSlot)(VkDevice device, const VkPrivateDataSlotCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPrivateDataSlot* pPrivateDataSlot); +typedef void (VKAPI_PTR *PFN_vkDestroyPrivateDataSlot)(VkDevice device, VkPrivateDataSlot privateDataSlot, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkSetPrivateData)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t data); +typedef void (VKAPI_PTR *PFN_vkGetPrivateData)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t* pData); +typedef void (VKAPI_PTR *PFN_vkCmdSetEvent2)(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo* pDependencyInfo); +typedef void (VKAPI_PTR *PFN_vkCmdResetEvent2)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask); +typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents2)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, const VkDependencyInfo* pDependencyInfos); +typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier2)(VkCommandBuffer commandBuffer, const VkDependencyInfo* pDependencyInfo); +typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp2)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query); +typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit2)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, VkFence fence); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer2)(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2* pCopyBufferInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImage2)(VkCommandBuffer commandBuffer, const VkCopyImageInfo2* pCopyImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage2)(VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer2)(VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBlitImage2)(VkCommandBuffer commandBuffer, const VkBlitImageInfo2* pBlitImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdResolveImage2)(VkCommandBuffer commandBuffer, const VkResolveImageInfo2* pResolveImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBeginRendering)(VkCommandBuffer commandBuffer, const VkRenderingInfo* pRenderingInfo); +typedef void (VKAPI_PTR *PFN_vkCmdEndRendering)(VkCommandBuffer commandBuffer); +typedef void (VKAPI_PTR *PFN_vkCmdSetCullMode)(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode); +typedef void (VKAPI_PTR *PFN_vkCmdSetFrontFace)(VkCommandBuffer commandBuffer, VkFrontFace frontFace); +typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveTopology)(VkCommandBuffer commandBuffer, VkPrimitiveTopology primitiveTopology); +typedef void (VKAPI_PTR *PFN_vkCmdSetViewportWithCount)(VkCommandBuffer commandBuffer, uint32_t viewportCount, const VkViewport* pViewports); +typedef void (VKAPI_PTR *PFN_vkCmdSetScissorWithCount)(VkCommandBuffer commandBuffer, uint32_t scissorCount, const VkRect2D* pScissors); +typedef void (VKAPI_PTR *PFN_vkCmdBindVertexBuffers2)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes, const VkDeviceSize* pStrides); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthTestEnable)(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthWriteEnable)(VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthCompareOp)(VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBoundsTestEnable)(VkCommandBuffer commandBuffer, VkBool32 depthBoundsTestEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilTestEnable)(VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilOp)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp); +typedef void (VKAPI_PTR *PFN_vkCmdSetRasterizerDiscardEnable)(VkCommandBuffer commandBuffer, VkBool32 rasterizerDiscardEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBiasEnable)(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveRestartEnable)(VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable); +typedef void (VKAPI_PTR *PFN_vkGetDeviceBufferMemoryRequirements)(VkDevice device, const VkDeviceBufferMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetDeviceImageMemoryRequirements)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetDeviceImageSparseMemoryRequirements)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceToolProperties( + VkPhysicalDevice physicalDevice, + uint32_t* pToolCount, + VkPhysicalDeviceToolProperties* pToolProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreatePrivateDataSlot( + VkDevice device, + const VkPrivateDataSlotCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkPrivateDataSlot* pPrivateDataSlot); + +VKAPI_ATTR void VKAPI_CALL vkDestroyPrivateDataSlot( + VkDevice device, + VkPrivateDataSlot privateDataSlot, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkSetPrivateData( + VkDevice device, + VkObjectType objectType, + uint64_t objectHandle, + VkPrivateDataSlot privateDataSlot, + uint64_t data); + +VKAPI_ATTR void VKAPI_CALL vkGetPrivateData( + VkDevice device, + VkObjectType objectType, + uint64_t objectHandle, + VkPrivateDataSlot privateDataSlot, + uint64_t* pData); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent2( + VkCommandBuffer commandBuffer, + VkEvent event, + const VkDependencyInfo* pDependencyInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent2( + VkCommandBuffer commandBuffer, + VkEvent event, + VkPipelineStageFlags2 stageMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents2( + VkCommandBuffer commandBuffer, + uint32_t eventCount, + const VkEvent* pEvents, + const VkDependencyInfo* pDependencyInfos); + +VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier2( + VkCommandBuffer commandBuffer, + const VkDependencyInfo* pDependencyInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp2( + VkCommandBuffer commandBuffer, + VkPipelineStageFlags2 stage, + VkQueryPool queryPool, + uint32_t query); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit2( + VkQueue queue, + uint32_t submitCount, + const VkSubmitInfo2* pSubmits, + VkFence fence); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer2( + VkCommandBuffer commandBuffer, + const VkCopyBufferInfo2* pCopyBufferInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage2( + VkCommandBuffer commandBuffer, + const VkCopyImageInfo2* pCopyImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage2( + VkCommandBuffer commandBuffer, + const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer2( + VkCommandBuffer commandBuffer, + const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage2( + VkCommandBuffer commandBuffer, + const VkBlitImageInfo2* pBlitImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage2( + VkCommandBuffer commandBuffer, + const VkResolveImageInfo2* pResolveImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginRendering( + VkCommandBuffer commandBuffer, + const VkRenderingInfo* pRenderingInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndRendering( + VkCommandBuffer commandBuffer); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetCullMode( + VkCommandBuffer commandBuffer, + VkCullModeFlags cullMode); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetFrontFace( + VkCommandBuffer commandBuffer, + VkFrontFace frontFace); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveTopology( + VkCommandBuffer commandBuffer, + VkPrimitiveTopology primitiveTopology); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWithCount( + VkCommandBuffer commandBuffer, + uint32_t viewportCount, + const VkViewport* pViewports); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetScissorWithCount( + VkCommandBuffer commandBuffer, + uint32_t scissorCount, + const VkRect2D* pScissors); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers2( + VkCommandBuffer commandBuffer, + uint32_t firstBinding, + uint32_t bindingCount, + const VkBuffer* pBuffers, + const VkDeviceSize* pOffsets, + const VkDeviceSize* pSizes, + const VkDeviceSize* pStrides); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthTestEnable( + VkCommandBuffer commandBuffer, + VkBool32 depthTestEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthWriteEnable( + VkCommandBuffer commandBuffer, + VkBool32 depthWriteEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthCompareOp( + VkCommandBuffer commandBuffer, + VkCompareOp depthCompareOp); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBoundsTestEnable( + VkCommandBuffer commandBuffer, + VkBool32 depthBoundsTestEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilTestEnable( + VkCommandBuffer commandBuffer, + VkBool32 stencilTestEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilOp( + VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, + VkStencilOp failOp, + VkStencilOp passOp, + VkStencilOp depthFailOp, + VkCompareOp compareOp); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetRasterizerDiscardEnable( + VkCommandBuffer commandBuffer, + VkBool32 rasterizerDiscardEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBiasEnable( + VkCommandBuffer commandBuffer, + VkBool32 depthBiasEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveRestartEnable( + VkCommandBuffer commandBuffer, + VkBool32 primitiveRestartEnable); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceBufferMemoryRequirements( + VkDevice device, + const VkDeviceBufferMemoryRequirements* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageMemoryRequirements( + VkDevice device, + const VkDeviceImageMemoryRequirements* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageSparseMemoryRequirements( + VkDevice device, + const VkDeviceImageMemoryRequirements* pInfo, + uint32_t* pSparseMemoryRequirementCount, + VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); +#endif + + #define VK_KHR_surface 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) #define VK_KHR_SURFACE_SPEC_VERSION 25 @@ -6432,6 +7702,68 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR( #define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME "VK_KHR_sampler_mirror_clamp_to_edge" +#define VK_KHR_dynamic_rendering 1 +#define VK_KHR_DYNAMIC_RENDERING_SPEC_VERSION 1 +#define VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME "VK_KHR_dynamic_rendering" +typedef VkRenderingFlags VkRenderingFlagsKHR; + +typedef VkRenderingFlagBits VkRenderingFlagBitsKHR; + +typedef VkRenderingInfo VkRenderingInfoKHR; + +typedef VkRenderingAttachmentInfo VkRenderingAttachmentInfoKHR; + +typedef VkPipelineRenderingCreateInfo VkPipelineRenderingCreateInfoKHR; + +typedef VkPhysicalDeviceDynamicRenderingFeatures VkPhysicalDeviceDynamicRenderingFeaturesKHR; + +typedef VkCommandBufferInheritanceRenderingInfo VkCommandBufferInheritanceRenderingInfoKHR; + +typedef struct VkRenderingFragmentShadingRateAttachmentInfoKHR { + VkStructureType sType; + const void* pNext; + VkImageView imageView; + VkImageLayout imageLayout; + VkExtent2D shadingRateAttachmentTexelSize; +} VkRenderingFragmentShadingRateAttachmentInfoKHR; + +typedef struct VkRenderingFragmentDensityMapAttachmentInfoEXT { + VkStructureType sType; + const void* pNext; + VkImageView imageView; + VkImageLayout imageLayout; +} VkRenderingFragmentDensityMapAttachmentInfoEXT; + +typedef struct VkAttachmentSampleCountInfoAMD { + VkStructureType sType; + const void* pNext; + uint32_t colorAttachmentCount; + const VkSampleCountFlagBits* pColorAttachmentSamples; + VkSampleCountFlagBits depthStencilAttachmentSamples; +} VkAttachmentSampleCountInfoAMD; + +typedef VkAttachmentSampleCountInfoAMD VkAttachmentSampleCountInfoNV; + +typedef struct VkMultiviewPerViewAttributesInfoNVX { + VkStructureType sType; + const void* pNext; + VkBool32 perViewAttributes; + VkBool32 perViewAttributesPositionXOnly; +} VkMultiviewPerViewAttributesInfoNVX; + +typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderingKHR)(VkCommandBuffer commandBuffer, const VkRenderingInfo* pRenderingInfo); +typedef void (VKAPI_PTR *PFN_vkCmdEndRenderingKHR)(VkCommandBuffer commandBuffer); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderingKHR( + VkCommandBuffer commandBuffer, + const VkRenderingInfo* pRenderingInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderingKHR( + VkCommandBuffer commandBuffer); +#endif + + #define VK_KHR_multiview 1 #define VK_KHR_MULTIVIEW_SPEC_VERSION 1 #define VK_KHR_MULTIVIEW_EXTENSION_NAME "VK_KHR_multiview" @@ -6566,8 +7898,10 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBaseKHR( #define VK_KHR_maintenance1 1 -#define VK_KHR_MAINTENANCE1_SPEC_VERSION 2 -#define VK_KHR_MAINTENANCE1_EXTENSION_NAME "VK_KHR_maintenance1" +#define VK_KHR_MAINTENANCE_1_SPEC_VERSION 2 +#define VK_KHR_MAINTENANCE_1_EXTENSION_NAME "VK_KHR_maintenance1" +#define VK_KHR_MAINTENANCE1_SPEC_VERSION VK_KHR_MAINTENANCE_1_SPEC_VERSION +#define VK_KHR_MAINTENANCE1_EXTENSION_NAME VK_KHR_MAINTENANCE_1_EXTENSION_NAME typedef VkCommandPoolTrimFlags VkCommandPoolTrimFlagsKHR; typedef void (VKAPI_PTR *PFN_vkTrimCommandPoolKHR)(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags); @@ -7147,8 +8481,10 @@ VKAPI_ATTR void VKAPI_CALL vkReleaseProfilingLockKHR( #define VK_KHR_maintenance2 1 -#define VK_KHR_MAINTENANCE2_SPEC_VERSION 1 -#define VK_KHR_MAINTENANCE2_EXTENSION_NAME "VK_KHR_maintenance2" +#define VK_KHR_MAINTENANCE_2_SPEC_VERSION 1 +#define VK_KHR_MAINTENANCE_2_EXTENSION_NAME "VK_KHR_maintenance2" +#define VK_KHR_MAINTENANCE2_SPEC_VERSION VK_KHR_MAINTENANCE_2_SPEC_VERSION +#define VK_KHR_MAINTENANCE2_EXTENSION_NAME VK_KHR_MAINTENANCE_2_EXTENSION_NAME typedef VkPointClippingBehavior VkPointClippingBehaviorKHR; typedef VkTessellationDomainOrigin VkTessellationDomainOriginKHR; @@ -7401,8 +8737,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory2KHR( #define VK_KHR_maintenance3 1 -#define VK_KHR_MAINTENANCE3_SPEC_VERSION 1 -#define VK_KHR_MAINTENANCE3_EXTENSION_NAME "VK_KHR_maintenance3" +#define VK_KHR_MAINTENANCE_3_SPEC_VERSION 1 +#define VK_KHR_MAINTENANCE_3_EXTENSION_NAME "VK_KHR_maintenance3" +#define VK_KHR_MAINTENANCE3_SPEC_VERSION VK_KHR_MAINTENANCE_3_SPEC_VERSION +#define VK_KHR_MAINTENANCE3_EXTENSION_NAME VK_KHR_MAINTENANCE_3_EXTENSION_NAME typedef VkPhysicalDeviceMaintenance3Properties VkPhysicalDeviceMaintenance3PropertiesKHR; typedef VkDescriptorSetLayoutSupport VkDescriptorSetLayoutSupportKHR; @@ -7477,6 +8815,43 @@ typedef struct VkPhysicalDeviceShaderClockFeaturesKHR { +#define VK_KHR_global_priority 1 +#define VK_MAX_GLOBAL_PRIORITY_SIZE_KHR 16U +#define VK_KHR_GLOBAL_PRIORITY_SPEC_VERSION 1 +#define VK_KHR_GLOBAL_PRIORITY_EXTENSION_NAME "VK_KHR_global_priority" + +typedef enum VkQueueGlobalPriorityKHR { + VK_QUEUE_GLOBAL_PRIORITY_LOW_KHR = 128, + VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR = 256, + VK_QUEUE_GLOBAL_PRIORITY_HIGH_KHR = 512, + VK_QUEUE_GLOBAL_PRIORITY_REALTIME_KHR = 1024, + VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT = VK_QUEUE_GLOBAL_PRIORITY_LOW_KHR, + VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT = VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR, + VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT = VK_QUEUE_GLOBAL_PRIORITY_HIGH_KHR, + VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT = VK_QUEUE_GLOBAL_PRIORITY_REALTIME_KHR, + VK_QUEUE_GLOBAL_PRIORITY_MAX_ENUM_KHR = 0x7FFFFFFF +} VkQueueGlobalPriorityKHR; +typedef struct VkDeviceQueueGlobalPriorityCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkQueueGlobalPriorityKHR globalPriority; +} VkDeviceQueueGlobalPriorityCreateInfoKHR; + +typedef struct VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 globalPriorityQuery; +} VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR; + +typedef struct VkQueueFamilyGlobalPriorityPropertiesKHR { + VkStructureType sType; + void* pNext; + uint32_t priorityCount; + VkQueueGlobalPriorityKHR priorities[VK_MAX_GLOBAL_PRIORITY_SIZE_KHR]; +} VkQueueFamilyGlobalPriorityPropertiesKHR; + + + #define VK_KHR_driver_properties 1 #define VK_KHR_DRIVER_PROPERTIES_SPEC_VERSION 1 #define VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME "VK_KHR_driver_properties" @@ -7569,16 +8944,12 @@ typedef VkPhysicalDeviceVulkanMemoryModelFeatures VkPhysicalDeviceVulkanMemoryMo #define VK_KHR_shader_terminate_invocation 1 #define VK_KHR_SHADER_TERMINATE_INVOCATION_SPEC_VERSION 1 #define VK_KHR_SHADER_TERMINATE_INVOCATION_EXTENSION_NAME "VK_KHR_shader_terminate_invocation" -typedef struct VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 shaderTerminateInvocation; -} VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR; +typedef VkPhysicalDeviceShaderTerminateInvocationFeatures VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR; #define VK_KHR_fragment_shading_rate 1 -#define VK_KHR_FRAGMENT_SHADING_RATE_SPEC_VERSION 1 +#define VK_KHR_FRAGMENT_SHADING_RATE_SPEC_VERSION 2 #define VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME "VK_KHR_fragment_shading_rate" typedef enum VkFragmentShadingRateCombinerOpKHR { @@ -7870,46 +9241,9 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutableInternalRepresentationsKHR #define VK_KHR_shader_integer_dot_product 1 #define VK_KHR_SHADER_INTEGER_DOT_PRODUCT_SPEC_VERSION 1 #define VK_KHR_SHADER_INTEGER_DOT_PRODUCT_EXTENSION_NAME "VK_KHR_shader_integer_dot_product" -typedef struct VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 shaderIntegerDotProduct; -} VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR; +typedef VkPhysicalDeviceShaderIntegerDotProductFeatures VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR; -typedef struct VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR { - VkStructureType sType; - void* pNext; - VkBool32 integerDotProduct8BitUnsignedAccelerated; - VkBool32 integerDotProduct8BitSignedAccelerated; - VkBool32 integerDotProduct8BitMixedSignednessAccelerated; - VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated; - VkBool32 integerDotProduct4x8BitPackedSignedAccelerated; - VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated; - VkBool32 integerDotProduct16BitUnsignedAccelerated; - VkBool32 integerDotProduct16BitSignedAccelerated; - VkBool32 integerDotProduct16BitMixedSignednessAccelerated; - VkBool32 integerDotProduct32BitUnsignedAccelerated; - VkBool32 integerDotProduct32BitSignedAccelerated; - VkBool32 integerDotProduct32BitMixedSignednessAccelerated; - VkBool32 integerDotProduct64BitUnsignedAccelerated; - VkBool32 integerDotProduct64BitSignedAccelerated; - VkBool32 integerDotProduct64BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated; -} VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR; +typedef VkPhysicalDeviceShaderIntegerDotProductProperties VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR; @@ -7949,261 +9283,94 @@ typedef struct VkPhysicalDevicePresentIdFeaturesKHR { #define VK_KHR_synchronization2 1 -typedef uint64_t VkFlags64; #define VK_KHR_SYNCHRONIZATION_2_SPEC_VERSION 1 #define VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME "VK_KHR_synchronization2" -typedef VkFlags64 VkPipelineStageFlags2KHR; +typedef VkPipelineStageFlags2 VkPipelineStageFlags2KHR; -// Flag bits for VkPipelineStageFlagBits2KHR -typedef VkFlags64 VkPipelineStageFlagBits2KHR; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_NONE_KHR = 0ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR = 0x00000001ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR = 0x00000002ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT_KHR = 0x00000004ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR = 0x00000008ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR = 0x00000010ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR = 0x00000020ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR = 0x00000040ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR = 0x00000080ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR = 0x00000100ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR = 0x00000200ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR = 0x00000400ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR = 0x00000800ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR = 0x00001000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR = 0x00001000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR = 0x00002000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_HOST_BIT_KHR = 0x00004000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR = 0x00008000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR = 0x00010000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COPY_BIT_KHR = 0x100000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR = 0x200000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_BLIT_BIT_KHR = 0x400000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR = 0x800000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR = 0x1000000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR = 0x2000000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT_KHR = 0x4000000000ULL; -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR = 0x04000000ULL; -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR = 0x08000000ULL; -#endif -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_NV = 0x00020000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_SHADING_RATE_IMAGE_BIT_NV = 0x00400000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR = 0x00200000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_NV = 0x00200000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_NV = 0x00080000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV = 0x00100000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI = 0x8000000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI = 0x10000000000ULL; +typedef VkPipelineStageFlagBits2 VkPipelineStageFlagBits2KHR; -typedef VkFlags64 VkAccessFlags2KHR; +typedef VkAccessFlags2 VkAccessFlags2KHR; -// Flag bits for VkAccessFlagBits2KHR -typedef VkFlags64 VkAccessFlagBits2KHR; -static const VkAccessFlagBits2KHR VK_ACCESS_2_NONE_KHR = 0ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT_KHR = 0x00000001ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_INDEX_READ_BIT_KHR = 0x00000002ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT_KHR = 0x00000004ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_UNIFORM_READ_BIT_KHR = 0x00000008ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR = 0x00000010ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADER_READ_BIT_KHR = 0x00000020ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADER_WRITE_BIT_KHR = 0x00000040ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT_KHR = 0x00000080ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR = 0x00000100ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT_KHR = 0x00000200ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR = 0x00000400ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_TRANSFER_READ_BIT_KHR = 0x00000800ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR = 0x00001000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_HOST_READ_BIT_KHR = 0x00002000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_HOST_WRITE_BIT_KHR = 0x00004000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_MEMORY_READ_BIT_KHR = 0x00008000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_MEMORY_WRITE_BIT_KHR = 0x00010000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR = 0x100000000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR = 0x200000000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR = 0x400000000ULL; -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkAccessFlagBits2KHR VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR = 0x800000000ULL; -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkAccessFlagBits2KHR VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR = 0x1000000000ULL; -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkAccessFlagBits2KHR VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR = 0x2000000000ULL; -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkAccessFlagBits2KHR VK_ACCESS_2_VIDEO_ENCODE_WRITE_BIT_KHR = 0x4000000000ULL; -#endif -static const VkAccessFlagBits2KHR VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_NV = 0x00200000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_NV = 0x00400000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_INVOCATION_MASK_READ_BIT_HUAWEI = 0x8000000000ULL; +typedef VkAccessFlagBits2 VkAccessFlagBits2KHR; +typedef VkSubmitFlagBits VkSubmitFlagBitsKHR; -typedef enum VkSubmitFlagBitsKHR { - VK_SUBMIT_PROTECTED_BIT_KHR = 0x00000001, - VK_SUBMIT_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkSubmitFlagBitsKHR; -typedef VkFlags VkSubmitFlagsKHR; -typedef struct VkMemoryBarrier2KHR { - VkStructureType sType; - const void* pNext; - VkPipelineStageFlags2KHR srcStageMask; - VkAccessFlags2KHR srcAccessMask; - VkPipelineStageFlags2KHR dstStageMask; - VkAccessFlags2KHR dstAccessMask; -} VkMemoryBarrier2KHR; +typedef VkSubmitFlags VkSubmitFlagsKHR; -typedef struct VkBufferMemoryBarrier2KHR { - VkStructureType sType; - const void* pNext; - VkPipelineStageFlags2KHR srcStageMask; - VkAccessFlags2KHR srcAccessMask; - VkPipelineStageFlags2KHR dstStageMask; - VkAccessFlags2KHR dstAccessMask; - uint32_t srcQueueFamilyIndex; - uint32_t dstQueueFamilyIndex; - VkBuffer buffer; - VkDeviceSize offset; - VkDeviceSize size; -} VkBufferMemoryBarrier2KHR; +typedef VkMemoryBarrier2 VkMemoryBarrier2KHR; -typedef struct VkImageMemoryBarrier2KHR { - VkStructureType sType; - const void* pNext; - VkPipelineStageFlags2KHR srcStageMask; - VkAccessFlags2KHR srcAccessMask; - VkPipelineStageFlags2KHR dstStageMask; - VkAccessFlags2KHR dstAccessMask; - VkImageLayout oldLayout; - VkImageLayout newLayout; - uint32_t srcQueueFamilyIndex; - uint32_t dstQueueFamilyIndex; - VkImage image; - VkImageSubresourceRange subresourceRange; -} VkImageMemoryBarrier2KHR; +typedef VkBufferMemoryBarrier2 VkBufferMemoryBarrier2KHR; -typedef struct VkDependencyInfoKHR { - VkStructureType sType; - const void* pNext; - VkDependencyFlags dependencyFlags; - uint32_t memoryBarrierCount; - const VkMemoryBarrier2KHR* pMemoryBarriers; - uint32_t bufferMemoryBarrierCount; - const VkBufferMemoryBarrier2KHR* pBufferMemoryBarriers; - uint32_t imageMemoryBarrierCount; - const VkImageMemoryBarrier2KHR* pImageMemoryBarriers; -} VkDependencyInfoKHR; +typedef VkImageMemoryBarrier2 VkImageMemoryBarrier2KHR; -typedef struct VkSemaphoreSubmitInfoKHR { - VkStructureType sType; - const void* pNext; - VkSemaphore semaphore; - uint64_t value; - VkPipelineStageFlags2KHR stageMask; - uint32_t deviceIndex; -} VkSemaphoreSubmitInfoKHR; +typedef VkDependencyInfo VkDependencyInfoKHR; -typedef struct VkCommandBufferSubmitInfoKHR { - VkStructureType sType; - const void* pNext; - VkCommandBuffer commandBuffer; - uint32_t deviceMask; -} VkCommandBufferSubmitInfoKHR; +typedef VkSubmitInfo2 VkSubmitInfo2KHR; -typedef struct VkSubmitInfo2KHR { - VkStructureType sType; - const void* pNext; - VkSubmitFlagsKHR flags; - uint32_t waitSemaphoreInfoCount; - const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos; - uint32_t commandBufferInfoCount; - const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos; - uint32_t signalSemaphoreInfoCount; - const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos; -} VkSubmitInfo2KHR; +typedef VkSemaphoreSubmitInfo VkSemaphoreSubmitInfoKHR; -typedef struct VkPhysicalDeviceSynchronization2FeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 synchronization2; -} VkPhysicalDeviceSynchronization2FeaturesKHR; +typedef VkCommandBufferSubmitInfo VkCommandBufferSubmitInfoKHR; + +typedef VkPhysicalDeviceSynchronization2Features VkPhysicalDeviceSynchronization2FeaturesKHR; typedef struct VkQueueFamilyCheckpointProperties2NV { - VkStructureType sType; - void* pNext; - VkPipelineStageFlags2KHR checkpointExecutionStageMask; + VkStructureType sType; + void* pNext; + VkPipelineStageFlags2 checkpointExecutionStageMask; } VkQueueFamilyCheckpointProperties2NV; typedef struct VkCheckpointData2NV { - VkStructureType sType; - void* pNext; - VkPipelineStageFlags2KHR stage; - void* pCheckpointMarker; + VkStructureType sType; + void* pNext; + VkPipelineStageFlags2 stage; + void* pCheckpointMarker; } VkCheckpointData2NV; -typedef void (VKAPI_PTR *PFN_vkCmdSetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfoKHR* pDependencyInfo); -typedef void (VKAPI_PTR *PFN_vkCmdResetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2KHR stageMask); -typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents2KHR)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, const VkDependencyInfoKHR* pDependencyInfos); -typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier2KHR)(VkCommandBuffer commandBuffer, const VkDependencyInfoKHR* pDependencyInfo); -typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp2KHR)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2KHR stage, VkQueryPool queryPool, uint32_t query); -typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit2KHR)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR* pSubmits, VkFence fence); -typedef void (VKAPI_PTR *PFN_vkCmdWriteBufferMarker2AMD)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2KHR stage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker); +typedef void (VKAPI_PTR *PFN_vkCmdSetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo* pDependencyInfo); +typedef void (VKAPI_PTR *PFN_vkCmdResetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask); +typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents2KHR)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, const VkDependencyInfo* pDependencyInfos); +typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier2KHR)(VkCommandBuffer commandBuffer, const VkDependencyInfo* pDependencyInfo); +typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp2KHR)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query); +typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit2KHR)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, VkFence fence); +typedef void (VKAPI_PTR *PFN_vkCmdWriteBufferMarker2AMD)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker); typedef void (VKAPI_PTR *PFN_vkGetQueueCheckpointData2NV)(VkQueue queue, uint32_t* pCheckpointDataCount, VkCheckpointData2NV* pCheckpointData); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent2KHR( VkCommandBuffer commandBuffer, VkEvent event, - const VkDependencyInfoKHR* pDependencyInfo); + const VkDependencyInfo* pDependencyInfo); VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent2KHR( VkCommandBuffer commandBuffer, VkEvent event, - VkPipelineStageFlags2KHR stageMask); + VkPipelineStageFlags2 stageMask); VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents2KHR( VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, - const VkDependencyInfoKHR* pDependencyInfos); + const VkDependencyInfo* pDependencyInfos); VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier2KHR( VkCommandBuffer commandBuffer, - const VkDependencyInfoKHR* pDependencyInfo); + const VkDependencyInfo* pDependencyInfo); VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp2KHR( VkCommandBuffer commandBuffer, - VkPipelineStageFlags2KHR stage, + VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query); VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit2KHR( VkQueue queue, uint32_t submitCount, - const VkSubmitInfo2KHR* pSubmits, + const VkSubmitInfo2* pSubmits, VkFence fence); VKAPI_ATTR void VKAPI_CALL vkCmdWriteBufferMarker2AMD( VkCommandBuffer commandBuffer, - VkPipelineStageFlags2KHR stage, + VkPipelineStageFlags2 stage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker); @@ -8229,11 +9396,7 @@ typedef struct VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR { #define VK_KHR_zero_initialize_workgroup_memory 1 #define VK_KHR_ZERO_INITIALIZE_WORKGROUP_MEMORY_SPEC_VERSION 1 #define VK_KHR_ZERO_INITIALIZE_WORKGROUP_MEMORY_EXTENSION_NAME "VK_KHR_zero_initialize_workgroup_memory" -typedef struct VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 shaderZeroInitializeWorkgroupMemory; -} VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR; +typedef VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR; @@ -8254,148 +9417,109 @@ typedef struct VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR { #define VK_KHR_copy_commands2 1 #define VK_KHR_COPY_COMMANDS_2_SPEC_VERSION 1 #define VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME "VK_KHR_copy_commands2" -typedef struct VkBufferCopy2KHR { - VkStructureType sType; - const void* pNext; - VkDeviceSize srcOffset; - VkDeviceSize dstOffset; - VkDeviceSize size; -} VkBufferCopy2KHR; +typedef VkCopyBufferInfo2 VkCopyBufferInfo2KHR; -typedef struct VkCopyBufferInfo2KHR { - VkStructureType sType; - const void* pNext; - VkBuffer srcBuffer; - VkBuffer dstBuffer; - uint32_t regionCount; - const VkBufferCopy2KHR* pRegions; -} VkCopyBufferInfo2KHR; +typedef VkCopyImageInfo2 VkCopyImageInfo2KHR; -typedef struct VkImageCopy2KHR { - VkStructureType sType; - const void* pNext; - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffset; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffset; - VkExtent3D extent; -} VkImageCopy2KHR; +typedef VkCopyBufferToImageInfo2 VkCopyBufferToImageInfo2KHR; -typedef struct VkCopyImageInfo2KHR { - VkStructureType sType; - const void* pNext; - VkImage srcImage; - VkImageLayout srcImageLayout; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkImageCopy2KHR* pRegions; -} VkCopyImageInfo2KHR; +typedef VkCopyImageToBufferInfo2 VkCopyImageToBufferInfo2KHR; -typedef struct VkBufferImageCopy2KHR { - VkStructureType sType; - const void* pNext; - VkDeviceSize bufferOffset; - uint32_t bufferRowLength; - uint32_t bufferImageHeight; - VkImageSubresourceLayers imageSubresource; - VkOffset3D imageOffset; - VkExtent3D imageExtent; -} VkBufferImageCopy2KHR; +typedef VkBlitImageInfo2 VkBlitImageInfo2KHR; -typedef struct VkCopyBufferToImageInfo2KHR { - VkStructureType sType; - const void* pNext; - VkBuffer srcBuffer; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkBufferImageCopy2KHR* pRegions; -} VkCopyBufferToImageInfo2KHR; +typedef VkResolveImageInfo2 VkResolveImageInfo2KHR; -typedef struct VkCopyImageToBufferInfo2KHR { - VkStructureType sType; - const void* pNext; - VkImage srcImage; - VkImageLayout srcImageLayout; - VkBuffer dstBuffer; - uint32_t regionCount; - const VkBufferImageCopy2KHR* pRegions; -} VkCopyImageToBufferInfo2KHR; +typedef VkBufferCopy2 VkBufferCopy2KHR; -typedef struct VkImageBlit2KHR { - VkStructureType sType; - const void* pNext; - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffsets[2]; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffsets[2]; -} VkImageBlit2KHR; +typedef VkImageCopy2 VkImageCopy2KHR; -typedef struct VkBlitImageInfo2KHR { - VkStructureType sType; - const void* pNext; - VkImage srcImage; - VkImageLayout srcImageLayout; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkImageBlit2KHR* pRegions; - VkFilter filter; -} VkBlitImageInfo2KHR; +typedef VkImageBlit2 VkImageBlit2KHR; -typedef struct VkImageResolve2KHR { - VkStructureType sType; - const void* pNext; - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffset; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffset; - VkExtent3D extent; -} VkImageResolve2KHR; +typedef VkBufferImageCopy2 VkBufferImageCopy2KHR; -typedef struct VkResolveImageInfo2KHR { - VkStructureType sType; - const void* pNext; - VkImage srcImage; - VkImageLayout srcImageLayout; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkImageResolve2KHR* pRegions; -} VkResolveImageInfo2KHR; +typedef VkImageResolve2 VkImageResolve2KHR; -typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer2KHR)(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2KHR* pCopyBufferInfo); -typedef void (VKAPI_PTR *PFN_vkCmdCopyImage2KHR)(VkCommandBuffer commandBuffer, const VkCopyImageInfo2KHR* pCopyImageInfo); -typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage2KHR)(VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2KHR* pCopyBufferToImageInfo); -typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer2KHR)(VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2KHR* pCopyImageToBufferInfo); -typedef void (VKAPI_PTR *PFN_vkCmdBlitImage2KHR)(VkCommandBuffer commandBuffer, const VkBlitImageInfo2KHR* pBlitImageInfo); -typedef void (VKAPI_PTR *PFN_vkCmdResolveImage2KHR)(VkCommandBuffer commandBuffer, const VkResolveImageInfo2KHR* pResolveImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer2KHR)(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2* pCopyBufferInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImage2KHR)(VkCommandBuffer commandBuffer, const VkCopyImageInfo2* pCopyImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage2KHR)(VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer2KHR)(VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBlitImage2KHR)(VkCommandBuffer commandBuffer, const VkBlitImageInfo2* pBlitImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdResolveImage2KHR)(VkCommandBuffer commandBuffer, const VkResolveImageInfo2* pResolveImageInfo); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer2KHR( VkCommandBuffer commandBuffer, - const VkCopyBufferInfo2KHR* pCopyBufferInfo); + const VkCopyBufferInfo2* pCopyBufferInfo); VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage2KHR( VkCommandBuffer commandBuffer, - const VkCopyImageInfo2KHR* pCopyImageInfo); + const VkCopyImageInfo2* pCopyImageInfo); VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage2KHR( VkCommandBuffer commandBuffer, - const VkCopyBufferToImageInfo2KHR* pCopyBufferToImageInfo); + const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer2KHR( VkCommandBuffer commandBuffer, - const VkCopyImageToBufferInfo2KHR* pCopyImageToBufferInfo); + const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage2KHR( VkCommandBuffer commandBuffer, - const VkBlitImageInfo2KHR* pBlitImageInfo); + const VkBlitImageInfo2* pBlitImageInfo); VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage2KHR( VkCommandBuffer commandBuffer, - const VkResolveImageInfo2KHR* pResolveImageInfo); + const VkResolveImageInfo2* pResolveImageInfo); +#endif + + +#define VK_KHR_format_feature_flags2 1 +#define VK_KHR_FORMAT_FEATURE_FLAGS_2_SPEC_VERSION 1 +#define VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME "VK_KHR_format_feature_flags2" +typedef VkFormatFeatureFlags2 VkFormatFeatureFlags2KHR; + +typedef VkFormatFeatureFlagBits2 VkFormatFeatureFlagBits2KHR; + +typedef VkFormatProperties3 VkFormatProperties3KHR; + + + +#define VK_KHR_portability_enumeration 1 +#define VK_KHR_PORTABILITY_ENUMERATION_SPEC_VERSION 1 +#define VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME "VK_KHR_portability_enumeration" + + +#define VK_KHR_maintenance4 1 +#define VK_KHR_MAINTENANCE_4_SPEC_VERSION 2 +#define VK_KHR_MAINTENANCE_4_EXTENSION_NAME "VK_KHR_maintenance4" +typedef VkPhysicalDeviceMaintenance4Features VkPhysicalDeviceMaintenance4FeaturesKHR; + +typedef VkPhysicalDeviceMaintenance4Properties VkPhysicalDeviceMaintenance4PropertiesKHR; + +typedef VkDeviceBufferMemoryRequirements VkDeviceBufferMemoryRequirementsKHR; + +typedef VkDeviceImageMemoryRequirements VkDeviceImageMemoryRequirementsKHR; + +typedef void (VKAPI_PTR *PFN_vkGetDeviceBufferMemoryRequirementsKHR)(VkDevice device, const VkDeviceBufferMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetDeviceImageMemoryRequirementsKHR)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetDeviceImageSparseMemoryRequirementsKHR)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetDeviceBufferMemoryRequirementsKHR( + VkDevice device, + const VkDeviceBufferMemoryRequirements* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageMemoryRequirementsKHR( + VkDevice device, + const VkDeviceImageMemoryRequirements* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageSparseMemoryRequirementsKHR( + VkDevice device, + const VkDeviceImageMemoryRequirements* pInfo, + uint32_t* pSparseMemoryRequirementCount, + VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); #endif @@ -8443,6 +9567,7 @@ typedef enum VkDebugReportObjectTypeEXT { VK_DEBUG_REPORT_OBJECT_TYPE_CU_FUNCTION_NVX_EXT = 1000029001, VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR_EXT = 1000150000, VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT = 1000165000, + VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA_EXT = 1000366000, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT, @@ -9028,11 +10153,7 @@ typedef struct VkValidationFlagsEXT { #define VK_EXT_texture_compression_astc_hdr 1 #define VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_SPEC_VERSION 1 #define VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME "VK_EXT_texture_compression_astc_hdr" -typedef struct VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 textureCompressionASTC_HDR; -} VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT; +typedef VkPhysicalDeviceTextureCompressionASTCHDRFeatures VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT; @@ -9302,8 +10423,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPastPresentationTimingGOOGLE( #define VK_NV_viewport_array2 1 -#define VK_NV_VIEWPORT_ARRAY2_SPEC_VERSION 1 -#define VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME "VK_NV_viewport_array2" +#define VK_NV_VIEWPORT_ARRAY_2_SPEC_VERSION 1 +#define VK_NV_VIEWPORT_ARRAY_2_EXTENSION_NAME "VK_NV_viewport_array2" +#define VK_NV_VIEWPORT_ARRAY2_SPEC_VERSION VK_NV_VIEWPORT_ARRAY_2_SPEC_VERSION +#define VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME VK_NV_VIEWPORT_ARRAY_2_EXTENSION_NAME #define VK_NVX_multiview_per_view_attributes 1 @@ -9658,35 +10781,13 @@ typedef VkPhysicalDeviceSamplerFilterMinmaxProperties VkPhysicalDeviceSamplerFil #define VK_EXT_inline_uniform_block 1 #define VK_EXT_INLINE_UNIFORM_BLOCK_SPEC_VERSION 1 #define VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME "VK_EXT_inline_uniform_block" -typedef struct VkPhysicalDeviceInlineUniformBlockFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 inlineUniformBlock; - VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind; -} VkPhysicalDeviceInlineUniformBlockFeaturesEXT; +typedef VkPhysicalDeviceInlineUniformBlockFeatures VkPhysicalDeviceInlineUniformBlockFeaturesEXT; -typedef struct VkPhysicalDeviceInlineUniformBlockPropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t maxInlineUniformBlockSize; - uint32_t maxPerStageDescriptorInlineUniformBlocks; - uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks; - uint32_t maxDescriptorSetInlineUniformBlocks; - uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks; -} VkPhysicalDeviceInlineUniformBlockPropertiesEXT; +typedef VkPhysicalDeviceInlineUniformBlockProperties VkPhysicalDeviceInlineUniformBlockPropertiesEXT; -typedef struct VkWriteDescriptorSetInlineUniformBlockEXT { - VkStructureType sType; - const void* pNext; - uint32_t dataSize; - const void* pData; -} VkWriteDescriptorSetInlineUniformBlockEXT; +typedef VkWriteDescriptorSetInlineUniformBlock VkWriteDescriptorSetInlineUniformBlockEXT; -typedef struct VkDescriptorPoolInlineUniformBlockCreateInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t maxInlineUniformBlockBindings; -} VkDescriptorPoolInlineUniformBlockCreateInfoEXT; +typedef VkDescriptorPoolInlineUniformBlockCreateInfo VkDescriptorPoolInlineUniformBlockCreateInfoEXT; @@ -9873,7 +10974,7 @@ typedef struct VkPhysicalDeviceShaderSMBuiltinsFeaturesNV { #define VK_EXT_image_drm_format_modifier 1 -#define VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_SPEC_VERSION 1 +#define VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_SPEC_VERSION 2 #define VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME "VK_EXT_image_drm_format_modifier" typedef struct VkDrmFormatModifierPropertiesEXT { uint64_t drmFormatModifier; @@ -9918,6 +11019,19 @@ typedef struct VkImageDrmFormatModifierPropertiesEXT { uint64_t drmFormatModifier; } VkImageDrmFormatModifierPropertiesEXT; +typedef struct VkDrmFormatModifierProperties2EXT { + uint64_t drmFormatModifier; + uint32_t drmFormatModifierPlaneCount; + VkFormatFeatureFlags2 drmFormatModifierTilingFeatures; +} VkDrmFormatModifierProperties2EXT; + +typedef struct VkDrmFormatModifierPropertiesList2EXT { + VkStructureType sType; + void* pNext; + uint32_t drmFormatModifierCount; + VkDrmFormatModifierProperties2EXT* pDrmFormatModifierProperties; +} VkDrmFormatModifierPropertiesList2EXT; + typedef VkResult (VKAPI_PTR *PFN_vkGetImageDrmFormatModifierPropertiesEXT)(VkDevice device, VkImage image, VkImageDrmFormatModifierPropertiesEXT* pProperties); #ifndef VK_NO_PROTOTYPES @@ -10519,19 +11633,9 @@ typedef struct VkFilterCubicImageViewImageFormatPropertiesEXT { #define VK_EXT_global_priority 1 #define VK_EXT_GLOBAL_PRIORITY_SPEC_VERSION 2 #define VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME "VK_EXT_global_priority" +typedef VkQueueGlobalPriorityKHR VkQueueGlobalPriorityEXT; -typedef enum VkQueueGlobalPriorityEXT { - VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT = 128, - VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT = 256, - VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT = 512, - VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT = 1024, - VK_QUEUE_GLOBAL_PRIORITY_MAX_ENUM_EXT = 0x7FFFFFFF -} VkQueueGlobalPriorityEXT; -typedef struct VkDeviceQueueGlobalPriorityCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkQueueGlobalPriorityEXT globalPriority; -} VkDeviceQueueGlobalPriorityCreateInfoEXT; +typedef VkDeviceQueueGlobalPriorityCreateInfoKHR VkDeviceQueueGlobalPriorityCreateInfoEXT; @@ -10709,26 +11813,13 @@ typedef struct VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT { #define VK_EXT_pipeline_creation_feedback 1 #define VK_EXT_PIPELINE_CREATION_FEEDBACK_SPEC_VERSION 1 #define VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME "VK_EXT_pipeline_creation_feedback" +typedef VkPipelineCreationFeedbackFlagBits VkPipelineCreationFeedbackFlagBitsEXT; -typedef enum VkPipelineCreationFeedbackFlagBitsEXT { - VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT = 0x00000001, - VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT = 0x00000002, - VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT_EXT = 0x00000004, - VK_PIPELINE_CREATION_FEEDBACK_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkPipelineCreationFeedbackFlagBitsEXT; -typedef VkFlags VkPipelineCreationFeedbackFlagsEXT; -typedef struct VkPipelineCreationFeedbackEXT { - VkPipelineCreationFeedbackFlagsEXT flags; - uint64_t duration; -} VkPipelineCreationFeedbackEXT; +typedef VkPipelineCreationFeedbackFlags VkPipelineCreationFeedbackFlagsEXT; -typedef struct VkPipelineCreationFeedbackCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkPipelineCreationFeedbackEXT* pPipelineCreationFeedback; - uint32_t pipelineStageCreationFeedbackCount; - VkPipelineCreationFeedbackEXT* pPipelineStageCreationFeedbacks; -} VkPipelineCreationFeedbackCreateInfoEXT; +typedef VkPipelineCreationFeedbackCreateInfo VkPipelineCreationFeedbackCreateInfoEXT; + +typedef VkPipelineCreationFeedback VkPipelineCreationFeedbackEXT; @@ -11079,7 +12170,7 @@ VKAPI_ATTR void VKAPI_CALL vkSetLocalDimmingAMD( #define VK_EXT_fragment_density_map 1 -#define VK_EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION 1 +#define VK_EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION 2 #define VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME "VK_EXT_fragment_density_map" typedef struct VkPhysicalDeviceFragmentDensityMapFeaturesEXT { VkStructureType sType; @@ -11113,8 +12204,10 @@ typedef VkPhysicalDeviceScalarBlockLayoutFeatures VkPhysicalDeviceScalarBlockLay #define VK_GOOGLE_hlsl_functionality1 1 -#define VK_GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION 1 -#define VK_GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME "VK_GOOGLE_hlsl_functionality1" +#define VK_GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION 1 +#define VK_GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME "VK_GOOGLE_hlsl_functionality1" +#define VK_GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION VK_GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION +#define VK_GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME VK_GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME #define VK_GOOGLE_decorate_string 1 @@ -11125,27 +12218,11 @@ typedef VkPhysicalDeviceScalarBlockLayoutFeatures VkPhysicalDeviceScalarBlockLay #define VK_EXT_subgroup_size_control 1 #define VK_EXT_SUBGROUP_SIZE_CONTROL_SPEC_VERSION 2 #define VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME "VK_EXT_subgroup_size_control" -typedef struct VkPhysicalDeviceSubgroupSizeControlFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 subgroupSizeControl; - VkBool32 computeFullSubgroups; -} VkPhysicalDeviceSubgroupSizeControlFeaturesEXT; +typedef VkPhysicalDeviceSubgroupSizeControlFeatures VkPhysicalDeviceSubgroupSizeControlFeaturesEXT; -typedef struct VkPhysicalDeviceSubgroupSizeControlPropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t minSubgroupSize; - uint32_t maxSubgroupSize; - uint32_t maxComputeWorkgroupSubgroups; - VkShaderStageFlags requiredSubgroupSizeStages; -} VkPhysicalDeviceSubgroupSizeControlPropertiesEXT; +typedef VkPhysicalDeviceSubgroupSizeControlProperties VkPhysicalDeviceSubgroupSizeControlPropertiesEXT; -typedef struct VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT { - VkStructureType sType; - void* pNext; - uint32_t requiredSubgroupSize; -} VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT; +typedef VkPipelineShaderStageRequiredSubgroupSizeCreateInfo VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT; @@ -11262,35 +12339,19 @@ VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddressEXT( #define VK_EXT_tooling_info 1 #define VK_EXT_TOOLING_INFO_SPEC_VERSION 1 #define VK_EXT_TOOLING_INFO_EXTENSION_NAME "VK_EXT_tooling_info" +typedef VkToolPurposeFlagBits VkToolPurposeFlagBitsEXT; -typedef enum VkToolPurposeFlagBitsEXT { - VK_TOOL_PURPOSE_VALIDATION_BIT_EXT = 0x00000001, - VK_TOOL_PURPOSE_PROFILING_BIT_EXT = 0x00000002, - VK_TOOL_PURPOSE_TRACING_BIT_EXT = 0x00000004, - VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT = 0x00000008, - VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT = 0x00000010, - VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT = 0x00000020, - VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT = 0x00000040, - VK_TOOL_PURPOSE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkToolPurposeFlagBitsEXT; -typedef VkFlags VkToolPurposeFlagsEXT; -typedef struct VkPhysicalDeviceToolPropertiesEXT { - VkStructureType sType; - void* pNext; - char name[VK_MAX_EXTENSION_NAME_SIZE]; - char version[VK_MAX_EXTENSION_NAME_SIZE]; - VkToolPurposeFlagsEXT purposes; - char description[VK_MAX_DESCRIPTION_SIZE]; - char layer[VK_MAX_EXTENSION_NAME_SIZE]; -} VkPhysicalDeviceToolPropertiesEXT; +typedef VkToolPurposeFlags VkToolPurposeFlagsEXT; -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceToolPropertiesEXT)(VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolPropertiesEXT* pToolProperties); +typedef VkPhysicalDeviceToolProperties VkPhysicalDeviceToolPropertiesEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceToolPropertiesEXT)(VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolProperties* pToolProperties); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceToolPropertiesEXT( VkPhysicalDevice physicalDevice, uint32_t* pToolCount, - VkPhysicalDeviceToolPropertiesEXT* pToolProperties); + VkPhysicalDeviceToolProperties* pToolProperties); #endif @@ -11721,11 +12782,7 @@ typedef struct VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT { #define VK_EXT_shader_demote_to_helper_invocation 1 #define VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_SPEC_VERSION 1 #define VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME "VK_EXT_shader_demote_to_helper_invocation" -typedef struct VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 shaderDemoteToHelperInvocation; -} VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT; +typedef VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT; @@ -11947,14 +13004,7 @@ typedef struct VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT { VkBool32 texelBufferAlignment; } VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT; -typedef struct VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT { - VkStructureType sType; - void* pNext; - VkDeviceSize storageTexelBufferOffsetAlignmentBytes; - VkBool32 storageTexelBufferOffsetSingleTexelAlignment; - VkDeviceSize uniformTexelBufferOffsetAlignmentBytes; - VkBool32 uniformTexelBufferOffsetSingleTexelAlignment; -} VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT; +typedef VkPhysicalDeviceTexelBufferAlignmentProperties VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT; @@ -12092,61 +13142,47 @@ typedef struct VkPhysicalDeviceCustomBorderColorFeaturesEXT { #define VK_EXT_private_data 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPrivateDataSlotEXT) +typedef VkPrivateDataSlot VkPrivateDataSlotEXT; + #define VK_EXT_PRIVATE_DATA_SPEC_VERSION 1 #define VK_EXT_PRIVATE_DATA_EXTENSION_NAME "VK_EXT_private_data" +typedef VkPrivateDataSlotCreateFlags VkPrivateDataSlotCreateFlagsEXT; -typedef enum VkPrivateDataSlotCreateFlagBitsEXT { - VK_PRIVATE_DATA_SLOT_CREATE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkPrivateDataSlotCreateFlagBitsEXT; -typedef VkFlags VkPrivateDataSlotCreateFlagsEXT; -typedef struct VkPhysicalDevicePrivateDataFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 privateData; -} VkPhysicalDevicePrivateDataFeaturesEXT; +typedef VkPhysicalDevicePrivateDataFeatures VkPhysicalDevicePrivateDataFeaturesEXT; -typedef struct VkDevicePrivateDataCreateInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t privateDataSlotRequestCount; -} VkDevicePrivateDataCreateInfoEXT; +typedef VkDevicePrivateDataCreateInfo VkDevicePrivateDataCreateInfoEXT; -typedef struct VkPrivateDataSlotCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkPrivateDataSlotCreateFlagsEXT flags; -} VkPrivateDataSlotCreateInfoEXT; +typedef VkPrivateDataSlotCreateInfo VkPrivateDataSlotCreateInfoEXT; -typedef VkResult (VKAPI_PTR *PFN_vkCreatePrivateDataSlotEXT)(VkDevice device, const VkPrivateDataSlotCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPrivateDataSlotEXT* pPrivateDataSlot); -typedef void (VKAPI_PTR *PFN_vkDestroyPrivateDataSlotEXT)(VkDevice device, VkPrivateDataSlotEXT privateDataSlot, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkSetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlotEXT privateDataSlot, uint64_t data); -typedef void (VKAPI_PTR *PFN_vkGetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlotEXT privateDataSlot, uint64_t* pData); +typedef VkResult (VKAPI_PTR *PFN_vkCreatePrivateDataSlotEXT)(VkDevice device, const VkPrivateDataSlotCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPrivateDataSlot* pPrivateDataSlot); +typedef void (VKAPI_PTR *PFN_vkDestroyPrivateDataSlotEXT)(VkDevice device, VkPrivateDataSlot privateDataSlot, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkSetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t data); +typedef void (VKAPI_PTR *PFN_vkGetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t* pData); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreatePrivateDataSlotEXT( VkDevice device, - const VkPrivateDataSlotCreateInfoEXT* pCreateInfo, + const VkPrivateDataSlotCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, - VkPrivateDataSlotEXT* pPrivateDataSlot); + VkPrivateDataSlot* pPrivateDataSlot); VKAPI_ATTR void VKAPI_CALL vkDestroyPrivateDataSlotEXT( VkDevice device, - VkPrivateDataSlotEXT privateDataSlot, + VkPrivateDataSlot privateDataSlot, const VkAllocationCallbacks* pAllocator); VKAPI_ATTR VkResult VKAPI_CALL vkSetPrivateDataEXT( VkDevice device, VkObjectType objectType, uint64_t objectHandle, - VkPrivateDataSlotEXT privateDataSlot, + VkPrivateDataSlot privateDataSlot, uint64_t data); VKAPI_ATTR void VKAPI_CALL vkGetPrivateDataEXT( VkDevice device, VkObjectType objectType, uint64_t objectHandle, - VkPrivateDataSlotEXT privateDataSlot, + VkPrivateDataSlot privateDataSlot, uint64_t* pData); #endif @@ -12154,11 +13190,7 @@ VKAPI_ATTR void VKAPI_CALL vkGetPrivateDataEXT( #define VK_EXT_pipeline_creation_cache_control 1 #define VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_SPEC_VERSION 3 #define VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME "VK_EXT_pipeline_creation_cache_control" -typedef struct VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 pipelineCreationCacheControl; -} VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT; +typedef VkPhysicalDevicePipelineCreationCacheControlFeatures VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT; @@ -12192,6 +13224,39 @@ typedef struct VkDeviceDiagnosticsConfigCreateInfoNV { #define VK_QCOM_RENDER_PASS_STORE_OPS_EXTENSION_NAME "VK_QCOM_render_pass_store_ops" +#define VK_EXT_graphics_pipeline_library 1 +#define VK_EXT_GRAPHICS_PIPELINE_LIBRARY_SPEC_VERSION 1 +#define VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME "VK_EXT_graphics_pipeline_library" + +typedef enum VkGraphicsPipelineLibraryFlagBitsEXT { + VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT = 0x00000001, + VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT = 0x00000002, + VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT = 0x00000004, + VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT = 0x00000008, + VK_GRAPHICS_PIPELINE_LIBRARY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkGraphicsPipelineLibraryFlagBitsEXT; +typedef VkFlags VkGraphicsPipelineLibraryFlagsEXT; +typedef struct VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 graphicsPipelineLibrary; +} VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT; + +typedef struct VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT { + VkStructureType sType; + void* pNext; + VkBool32 graphicsPipelineLibraryFastLinking; + VkBool32 graphicsPipelineLibraryIndependentInterpolationDecoration; +} VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT; + +typedef struct VkGraphicsPipelineLibraryCreateInfoEXT { + VkStructureType sType; + void* pNext; + VkGraphicsPipelineLibraryFlagsEXT flags; +} VkGraphicsPipelineLibraryCreateInfoEXT; + + + #define VK_NV_fragment_shading_rate_enums 1 #define VK_NV_FRAGMENT_SHADING_RATE_ENUMS_SPEC_VERSION 1 #define VK_NV_FRAGMENT_SHADING_RATE_ENUMS_EXTENSION_NAME "VK_NV_fragment_shading_rate_enums" @@ -12384,11 +13449,7 @@ typedef struct VkCopyCommandTransformInfoQCOM { #define VK_EXT_image_robustness 1 #define VK_EXT_IMAGE_ROBUSTNESS_SPEC_VERSION 1 #define VK_EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME "VK_EXT_image_robustness" -typedef struct VkPhysicalDeviceImageRobustnessFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 robustImageAccess; -} VkPhysicalDeviceImageRobustnessFeaturesEXT; +typedef VkPhysicalDeviceImageRobustnessFeatures VkPhysicalDeviceImageRobustnessFeaturesEXT; @@ -12404,6 +13465,30 @@ typedef struct VkPhysicalDevice4444FormatsFeaturesEXT { +#define VK_ARM_rasterization_order_attachment_access 1 +#define VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_SPEC_VERSION 1 +#define VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME "VK_ARM_rasterization_order_attachment_access" +typedef struct VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM { + VkStructureType sType; + void* pNext; + VkBool32 rasterizationOrderColorAttachmentAccess; + VkBool32 rasterizationOrderDepthAttachmentAccess; + VkBool32 rasterizationOrderStencilAttachmentAccess; +} VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM; + + + +#define VK_EXT_rgba10x6_formats 1 +#define VK_EXT_RGBA10X6_FORMATS_SPEC_VERSION 1 +#define VK_EXT_RGBA10X6_FORMATS_EXTENSION_NAME "VK_EXT_rgba10x6_formats" +typedef struct VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 formatRgba10x6WithoutYCbCrSampler; +} VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT; + + + #define VK_NV_acquire_winrt_display 1 #define VK_NV_ACQUIRE_WINRT_DISPLAY_SPEC_VERSION 1 #define VK_NV_ACQUIRE_WINRT_DISPLAY_EXTENSION_NAME "VK_NV_acquire_winrt_display" @@ -12500,6 +13585,23 @@ typedef struct VkPhysicalDeviceDrmPropertiesEXT { +#define VK_EXT_depth_clip_control 1 +#define VK_EXT_DEPTH_CLIP_CONTROL_SPEC_VERSION 1 +#define VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME "VK_EXT_depth_clip_control" +typedef struct VkPhysicalDeviceDepthClipControlFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 depthClipControl; +} VkPhysicalDeviceDepthClipControlFeaturesEXT; + +typedef struct VkPipelineViewportDepthClipControlCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkBool32 negativeOneToOne; +} VkPipelineViewportDepthClipControlCreateInfoEXT; + + + #define VK_EXT_primitive_topology_list_restart 1 #define VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_SPEC_VERSION 1 #define VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME "VK_EXT_primitive_topology_list_restart" @@ -12660,22 +13762,43 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSetColorWrite #endif -#define VK_EXT_global_priority_query 1 -#define VK_MAX_GLOBAL_PRIORITY_SIZE_EXT 16U -#define VK_EXT_GLOBAL_PRIORITY_QUERY_SPEC_VERSION 1 -#define VK_EXT_GLOBAL_PRIORITY_QUERY_EXTENSION_NAME "VK_EXT_global_priority_query" -typedef struct VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT { +#define VK_EXT_primitives_generated_query 1 +#define VK_EXT_PRIMITIVES_GENERATED_QUERY_SPEC_VERSION 1 +#define VK_EXT_PRIMITIVES_GENERATED_QUERY_EXTENSION_NAME "VK_EXT_primitives_generated_query" +typedef struct VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT { VkStructureType sType; void* pNext; - VkBool32 globalPriorityQuery; -} VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT; + VkBool32 primitivesGeneratedQuery; + VkBool32 primitivesGeneratedQueryWithRasterizerDiscard; + VkBool32 primitivesGeneratedQueryWithNonZeroStreams; +} VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT; -typedef struct VkQueueFamilyGlobalPriorityPropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t priorityCount; - VkQueueGlobalPriorityEXT priorities[VK_MAX_GLOBAL_PRIORITY_SIZE_EXT]; -} VkQueueFamilyGlobalPriorityPropertiesEXT; + + +#define VK_EXT_global_priority_query 1 +#define VK_EXT_GLOBAL_PRIORITY_QUERY_SPEC_VERSION 1 +#define VK_EXT_GLOBAL_PRIORITY_QUERY_EXTENSION_NAME "VK_EXT_global_priority_query" +#define VK_MAX_GLOBAL_PRIORITY_SIZE_EXT VK_MAX_GLOBAL_PRIORITY_SIZE_KHR +typedef VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT; + +typedef VkQueueFamilyGlobalPriorityPropertiesKHR VkQueueFamilyGlobalPriorityPropertiesEXT; + + + +#define VK_EXT_image_view_min_lod 1 +#define VK_EXT_IMAGE_VIEW_MIN_LOD_SPEC_VERSION 1 +#define VK_EXT_IMAGE_VIEW_MIN_LOD_EXTENSION_NAME "VK_EXT_image_view_min_lod" +typedef struct VkPhysicalDeviceImageViewMinLodFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 minLod; +} VkPhysicalDeviceImageViewMinLodFeaturesEXT; + +typedef struct VkImageViewMinLodCreateInfoEXT { + VkStructureType sType; + const void* pNext; + float minLod; +} VkImageViewMinLodCreateInfoEXT; @@ -12728,11 +13851,42 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawMultiIndexedEXT( #endif +#define VK_EXT_image_2d_view_of_3d 1 +#define VK_EXT_IMAGE_2D_VIEW_OF_3D_SPEC_VERSION 1 +#define VK_EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME "VK_EXT_image_2d_view_of_3d" +typedef struct VkPhysicalDeviceImage2DViewOf3DFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 image2DViewOf3D; + VkBool32 sampler2DViewOf3D; +} VkPhysicalDeviceImage2DViewOf3DFeaturesEXT; + + + #define VK_EXT_load_store_op_none 1 #define VK_EXT_LOAD_STORE_OP_NONE_SPEC_VERSION 1 #define VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME "VK_EXT_load_store_op_none" +#define VK_EXT_border_color_swizzle 1 +#define VK_EXT_BORDER_COLOR_SWIZZLE_SPEC_VERSION 1 +#define VK_EXT_BORDER_COLOR_SWIZZLE_EXTENSION_NAME "VK_EXT_border_color_swizzle" +typedef struct VkPhysicalDeviceBorderColorSwizzleFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 borderColorSwizzle; + VkBool32 borderColorSwizzleFromImage; +} VkPhysicalDeviceBorderColorSwizzleFeaturesEXT; + +typedef struct VkSamplerBorderColorComponentMappingCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkComponentMapping components; + VkBool32 srgb; +} VkSamplerBorderColorComponentMappingCreateInfoEXT; + + + #define VK_EXT_pageable_device_local_memory 1 #define VK_EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_SPEC_VERSION 1 #define VK_EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_EXTENSION_NAME "VK_EXT_pageable_device_local_memory" @@ -12752,9 +13906,88 @@ VKAPI_ATTR void VKAPI_CALL vkSetDeviceMemoryPriorityEXT( #endif +#define VK_VALVE_descriptor_set_host_mapping 1 +#define VK_VALVE_DESCRIPTOR_SET_HOST_MAPPING_SPEC_VERSION 1 +#define VK_VALVE_DESCRIPTOR_SET_HOST_MAPPING_EXTENSION_NAME "VK_VALVE_descriptor_set_host_mapping" +typedef struct VkPhysicalDeviceDescriptorSetHostMappingFeaturesVALVE { + VkStructureType sType; + void* pNext; + VkBool32 descriptorSetHostMapping; +} VkPhysicalDeviceDescriptorSetHostMappingFeaturesVALVE; + +typedef struct VkDescriptorSetBindingReferenceVALVE { + VkStructureType sType; + const void* pNext; + VkDescriptorSetLayout descriptorSetLayout; + uint32_t binding; +} VkDescriptorSetBindingReferenceVALVE; + +typedef struct VkDescriptorSetLayoutHostMappingInfoVALVE { + VkStructureType sType; + void* pNext; + size_t descriptorOffset; + uint32_t descriptorSize; +} VkDescriptorSetLayoutHostMappingInfoVALVE; + +typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutHostMappingInfoVALVE)(VkDevice device, const VkDescriptorSetBindingReferenceVALVE* pBindingReference, VkDescriptorSetLayoutHostMappingInfoVALVE* pHostMapping); +typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetHostMappingVALVE)(VkDevice device, VkDescriptorSet descriptorSet, void** ppData); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutHostMappingInfoVALVE( + VkDevice device, + const VkDescriptorSetBindingReferenceVALVE* pBindingReference, + VkDescriptorSetLayoutHostMappingInfoVALVE* pHostMapping); + +VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetHostMappingVALVE( + VkDevice device, + VkDescriptorSet descriptorSet, + void** ppData); +#endif + + +#define VK_QCOM_fragment_density_map_offset 1 +#define VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_SPEC_VERSION 1 +#define VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME "VK_QCOM_fragment_density_map_offset" +typedef struct VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 fragmentDensityMapOffset; +} VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM; + +typedef struct VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM { + VkStructureType sType; + void* pNext; + VkExtent2D fragmentDensityOffsetGranularity; +} VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM; + +typedef struct VkSubpassFragmentDensityMapOffsetEndInfoQCOM { + VkStructureType sType; + const void* pNext; + uint32_t fragmentDensityOffsetCount; + const VkOffset2D* pFragmentDensityOffsets; +} VkSubpassFragmentDensityMapOffsetEndInfoQCOM; + + + +#define VK_NV_linear_color_attachment 1 +#define VK_NV_LINEAR_COLOR_ATTACHMENT_SPEC_VERSION 1 +#define VK_NV_LINEAR_COLOR_ATTACHMENT_EXTENSION_NAME "VK_NV_linear_color_attachment" +typedef struct VkPhysicalDeviceLinearColorAttachmentFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 linearColorAttachment; +} VkPhysicalDeviceLinearColorAttachmentFeaturesNV; + + + +#define VK_GOOGLE_surfaceless_query 1 +#define VK_GOOGLE_SURFACELESS_QUERY_SPEC_VERSION 1 +#define VK_GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME "VK_GOOGLE_surfaceless_query" + + #define VK_KHR_acceleration_structure 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureKHR) -#define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 12 +#define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 13 #define VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME "VK_KHR_acceleration_structure" typedef enum VkBuildAccelerationStructureModeKHR { diff --git a/vendor/vulkan/_gen/vulkan_ios.h b/vendor/vulkan/_gen/vulkan_ios.h index 6e7e6afea..579220543 100644 --- a/vendor/vulkan/_gen/vulkan_ios.h +++ b/vendor/vulkan/_gen/vulkan_ios.h @@ -2,7 +2,7 @@ #define VULKAN_IOS_H_ 1 /* -** Copyright 2015-2021 The Khronos Group Inc. +** Copyright 2015-2022 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ diff --git a/vendor/vulkan/_gen/vulkan_macos.h b/vendor/vulkan/_gen/vulkan_macos.h index c49b123d0..8e197c7cf 100644 --- a/vendor/vulkan/_gen/vulkan_macos.h +++ b/vendor/vulkan/_gen/vulkan_macos.h @@ -2,7 +2,7 @@ #define VULKAN_MACOS_H_ 1 /* -** Copyright 2015-2021 The Khronos Group Inc. +** Copyright 2015-2022 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ diff --git a/vendor/vulkan/_gen/vulkan_metal.h b/vendor/vulkan/_gen/vulkan_metal.h index 5cf4a703a..3631f1200 100644 --- a/vendor/vulkan/_gen/vulkan_metal.h +++ b/vendor/vulkan/_gen/vulkan_metal.h @@ -2,7 +2,7 @@ #define VULKAN_METAL_H_ 1 /* -** Copyright 2015-2021 The Khronos Group Inc. +** Copyright 2015-2022 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ diff --git a/vendor/vulkan/_gen/vulkan_win32.h b/vendor/vulkan/_gen/vulkan_win32.h index 1b680f0b1..affe0c02a 100644 --- a/vendor/vulkan/_gen/vulkan_win32.h +++ b/vendor/vulkan/_gen/vulkan_win32.h @@ -2,7 +2,7 @@ #define VULKAN_WIN32_H_ 1 /* -** Copyright 2015-2021 The Khronos Group Inc. +** Copyright 2015-2022 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ diff --git a/vendor/vulkan/core.odin b/vendor/vulkan/core.odin index 67ca47553..b90bfad17 100644 --- a/vendor/vulkan/core.odin +++ b/vendor/vulkan/core.odin @@ -3,6 +3,9 @@ // package vulkan API_VERSION_1_0 :: (1<<22) | (0<<12) | (0) +API_VERSION_1_1 :: (1<<22) | (1<<12) | (0) +API_VERSION_1_2 :: (1<<22) | (2<<12) | (0) +API_VERSION_1_3 :: (1<<22) | (3<<12) | (0) MAKE_VERSION :: proc(major, minor, patch: u32) -> u32 { return (major<<22) | (minor<<12) | (patch) @@ -39,18 +42,15 @@ MAX_MEMORY_TYPES :: 32 MAX_MEMORY_HEAPS :: 16 MAX_EXTENSION_NAME_SIZE :: 256 MAX_DESCRIPTION_SIZE :: 256 -MAX_DEVICE_GROUP_SIZE_KHX :: 32 MAX_DEVICE_GROUP_SIZE :: 32 LUID_SIZE_KHX :: 8 -LUID_SIZE_KHR :: 8 LUID_SIZE :: 8 -MAX_DRIVER_NAME_SIZE_KHR :: 256 -MAX_DRIVER_INFO_SIZE_KHR :: 256 -MAX_QUEUE_FAMILY_EXTERNAL :: ~u32(0)-1 +MAX_QUEUE_FAMILY_EXTERNAL :: ~u32(1) MAX_GLOBAL_PRIORITY_SIZE_EXT :: 16 +QUEUE_FAMILY_EXTERNAL :: MAX_QUEUE_FAMILY_EXTERNAL // General Constants -HEADER_VERSION :: 191 +HEADER_VERSION :: 211 MAX_DRIVER_NAME_SIZE :: 256 MAX_DRIVER_INFO_SIZE :: 256 @@ -70,6 +70,9 @@ KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME :: "VK_KHR_display_swapc KHR_sampler_mirror_clamp_to_edge :: 1 KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION :: 3 KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME :: "VK_KHR_sampler_mirror_clamp_to_edge" +KHR_dynamic_rendering :: 1 +KHR_DYNAMIC_RENDERING_SPEC_VERSION :: 1 +KHR_DYNAMIC_RENDERING_EXTENSION_NAME :: "VK_KHR_dynamic_rendering" KHR_multiview :: 1 KHR_MULTIVIEW_SPEC_VERSION :: 1 KHR_MULTIVIEW_EXTENSION_NAME :: "VK_KHR_multiview" @@ -83,17 +86,22 @@ KHR_shader_draw_parameters :: 1 KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION :: 1 KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME :: "VK_KHR_shader_draw_parameters" KHR_maintenance1 :: 1 -KHR_MAINTENANCE1_SPEC_VERSION :: 2 -KHR_MAINTENANCE1_EXTENSION_NAME :: "VK_KHR_maintenance1" +KHR_MAINTENANCE_1_SPEC_VERSION :: 2 +KHR_MAINTENANCE_1_EXTENSION_NAME :: "VK_KHR_maintenance1" +KHR_MAINTENANCE1_SPEC_VERSION :: KHR_MAINTENANCE_1_SPEC_VERSION +KHR_MAINTENANCE1_EXTENSION_NAME :: KHR_MAINTENANCE_1_EXTENSION_NAME KHR_device_group_creation :: 1 KHR_DEVICE_GROUP_CREATION_SPEC_VERSION :: 1 KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME :: "VK_KHR_device_group_creation" +MAX_DEVICE_GROUP_SIZE_KHR :: MAX_DEVICE_GROUP_SIZE KHR_external_memory_capabilities :: 1 KHR_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION :: 1 KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME :: "VK_KHR_external_memory_capabilities" +LUID_SIZE_KHR :: LUID_SIZE KHR_external_memory :: 1 KHR_EXTERNAL_MEMORY_SPEC_VERSION :: 1 KHR_EXTERNAL_MEMORY_EXTENSION_NAME :: "VK_KHR_external_memory" +QUEUE_FAMILY_EXTERNAL_KHR :: QUEUE_FAMILY_EXTERNAL KHR_external_memory_fd :: 1 KHR_EXTERNAL_MEMORY_FD_SPEC_VERSION :: 1 KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME :: "VK_KHR_external_memory_fd" @@ -143,8 +151,10 @@ KHR_performance_query :: 1 KHR_PERFORMANCE_QUERY_SPEC_VERSION :: 1 KHR_PERFORMANCE_QUERY_EXTENSION_NAME :: "VK_KHR_performance_query" KHR_maintenance2 :: 1 -KHR_MAINTENANCE2_SPEC_VERSION :: 1 -KHR_MAINTENANCE2_EXTENSION_NAME :: "VK_KHR_maintenance2" +KHR_MAINTENANCE_2_SPEC_VERSION :: 1 +KHR_MAINTENANCE_2_EXTENSION_NAME :: "VK_KHR_maintenance2" +KHR_MAINTENANCE2_SPEC_VERSION :: KHR_MAINTENANCE_2_SPEC_VERSION +KHR_MAINTENANCE2_EXTENSION_NAME :: KHR_MAINTENANCE_2_EXTENSION_NAME KHR_get_surface_capabilities2 :: 1 KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION :: 1 KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME :: "VK_KHR_get_surface_capabilities2" @@ -176,8 +186,10 @@ KHR_bind_memory2 :: 1 KHR_BIND_MEMORY_2_SPEC_VERSION :: 1 KHR_BIND_MEMORY_2_EXTENSION_NAME :: "VK_KHR_bind_memory2" KHR_maintenance3 :: 1 -KHR_MAINTENANCE3_SPEC_VERSION :: 1 -KHR_MAINTENANCE3_EXTENSION_NAME :: "VK_KHR_maintenance3" +KHR_MAINTENANCE_3_SPEC_VERSION :: 1 +KHR_MAINTENANCE_3_EXTENSION_NAME :: "VK_KHR_maintenance3" +KHR_MAINTENANCE3_SPEC_VERSION :: KHR_MAINTENANCE_3_SPEC_VERSION +KHR_MAINTENANCE3_EXTENSION_NAME :: KHR_MAINTENANCE_3_EXTENSION_NAME KHR_draw_indirect_count :: 1 KHR_DRAW_INDIRECT_COUNT_SPEC_VERSION :: 1 KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME :: "VK_KHR_draw_indirect_count" @@ -193,9 +205,15 @@ KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME :: "VK_KHR_shader_atomic KHR_shader_clock :: 1 KHR_SHADER_CLOCK_SPEC_VERSION :: 1 KHR_SHADER_CLOCK_EXTENSION_NAME :: "VK_KHR_shader_clock" +KHR_global_priority :: 1 +MAX_GLOBAL_PRIORITY_SIZE_KHR :: 16 +KHR_GLOBAL_PRIORITY_SPEC_VERSION :: 1 +KHR_GLOBAL_PRIORITY_EXTENSION_NAME :: "VK_KHR_global_priority" KHR_driver_properties :: 1 KHR_DRIVER_PROPERTIES_SPEC_VERSION :: 1 KHR_DRIVER_PROPERTIES_EXTENSION_NAME :: "VK_KHR_driver_properties" +MAX_DRIVER_NAME_SIZE_KHR :: MAX_DRIVER_NAME_SIZE +MAX_DRIVER_INFO_SIZE_KHR :: MAX_DRIVER_INFO_SIZE KHR_shader_float_controls :: 1 KHR_SHADER_FLOAT_CONTROLS_SPEC_VERSION :: 4 KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME :: "VK_KHR_shader_float_controls" @@ -215,7 +233,7 @@ KHR_shader_terminate_invocation :: 1 KHR_SHADER_TERMINATE_INVOCATION_SPEC_VERSION :: 1 KHR_SHADER_TERMINATE_INVOCATION_EXTENSION_NAME :: "VK_KHR_shader_terminate_invocation" KHR_fragment_shading_rate :: 1 -KHR_FRAGMENT_SHADING_RATE_SPEC_VERSION :: 1 +KHR_FRAGMENT_SHADING_RATE_SPEC_VERSION :: 2 KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME :: "VK_KHR_fragment_shading_rate" KHR_spirv_1_4 :: 1 KHR_SPIRV_1_4_SPEC_VERSION :: 1 @@ -268,6 +286,15 @@ KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME :: "VK_KHR_workgroup_mem KHR_copy_commands2 :: 1 KHR_COPY_COMMANDS_2_SPEC_VERSION :: 1 KHR_COPY_COMMANDS_2_EXTENSION_NAME :: "VK_KHR_copy_commands2" +KHR_format_feature_flags2 :: 1 +KHR_FORMAT_FEATURE_FLAGS_2_SPEC_VERSION :: 1 +KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME :: "VK_KHR_format_feature_flags2" +KHR_portability_enumeration :: 1 +KHR_PORTABILITY_ENUMERATION_SPEC_VERSION :: 1 +KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME :: "VK_KHR_portability_enumeration" +KHR_maintenance4 :: 1 +KHR_MAINTENANCE_4_SPEC_VERSION :: 2 +KHR_MAINTENANCE_4_EXTENSION_NAME :: "VK_KHR_maintenance4" EXT_debug_report :: 1 EXT_DEBUG_REPORT_SPEC_VERSION :: 10 EXT_DEBUG_REPORT_EXTENSION_NAME :: "VK_EXT_debug_report" @@ -374,8 +401,10 @@ NV_geometry_shader_passthrough :: 1 NV_GEOMETRY_SHADER_PASSTHROUGH_SPEC_VERSION :: 1 NV_GEOMETRY_SHADER_PASSTHROUGH_EXTENSION_NAME :: "VK_NV_geometry_shader_passthrough" NV_viewport_array2 :: 1 -NV_VIEWPORT_ARRAY2_SPEC_VERSION :: 1 -NV_VIEWPORT_ARRAY2_EXTENSION_NAME :: "VK_NV_viewport_array2" +NV_VIEWPORT_ARRAY_2_SPEC_VERSION :: 1 +NV_VIEWPORT_ARRAY_2_EXTENSION_NAME :: "VK_NV_viewport_array2" +NV_VIEWPORT_ARRAY2_SPEC_VERSION :: NV_VIEWPORT_ARRAY_2_SPEC_VERSION +NV_VIEWPORT_ARRAY2_EXTENSION_NAME :: NV_VIEWPORT_ARRAY_2_EXTENSION_NAME NVX_multiview_per_view_attributes :: 1 NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_SPEC_VERSION :: 1 NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_EXTENSION_NAME :: "VK_NVX_multiview_per_view_attributes" @@ -446,7 +475,7 @@ EXT_post_depth_coverage :: 1 EXT_POST_DEPTH_COVERAGE_SPEC_VERSION :: 1 EXT_POST_DEPTH_COVERAGE_EXTENSION_NAME :: "VK_EXT_post_depth_coverage" EXT_image_drm_format_modifier :: 1 -EXT_IMAGE_DRM_FORMAT_MODIFIER_SPEC_VERSION :: 1 +EXT_IMAGE_DRM_FORMAT_MODIFIER_SPEC_VERSION :: 2 EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME :: "VK_EXT_image_drm_format_modifier" EXT_validation_cache :: 1 EXT_VALIDATION_CACHE_SPEC_VERSION :: 1 @@ -463,6 +492,7 @@ NV_SHADING_RATE_IMAGE_EXTENSION_NAME :: "VK_NV_shading_rate_i NV_ray_tracing :: 1 NV_RAY_TRACING_SPEC_VERSION :: 3 NV_RAY_TRACING_EXTENSION_NAME :: "VK_NV_ray_tracing" +SHADER_UNUSED_KHR :: 0 NV_representative_fragment_test :: 1 NV_REPRESENTATIVE_FRAGMENT_TEST_SPEC_VERSION :: 2 NV_REPRESENTATIVE_FRAGMENT_TEST_EXTENSION_NAME :: "VK_NV_representative_fragment_test" @@ -524,14 +554,16 @@ AMD_display_native_hdr :: 1 AMD_DISPLAY_NATIVE_HDR_SPEC_VERSION :: 1 AMD_DISPLAY_NATIVE_HDR_EXTENSION_NAME :: "VK_AMD_display_native_hdr" EXT_fragment_density_map :: 1 -EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION :: 1 +EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION :: 2 EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME :: "VK_EXT_fragment_density_map" EXT_scalar_block_layout :: 1 EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION :: 1 EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME :: "VK_EXT_scalar_block_layout" GOOGLE_hlsl_functionality1 :: 1 -GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION :: 1 -GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME :: "VK_GOOGLE_hlsl_functionality1" +GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION :: 1 +GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME :: "VK_GOOGLE_hlsl_functionality1" +GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION :: GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION +GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME :: GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME GOOGLE_decorate_string :: 1 GOOGLE_DECORATE_STRING_SPEC_VERSION :: 1 GOOGLE_DECORATE_STRING_EXTENSION_NAME :: "VK_GOOGLE_decorate_string" @@ -640,6 +672,9 @@ EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME :: "VK_EXT_pipeline_crea NV_device_diagnostics_config :: 1 NV_DEVICE_DIAGNOSTICS_CONFIG_SPEC_VERSION :: 1 NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME :: "VK_NV_device_diagnostics_config" +EXT_graphics_pipeline_library :: 1 +EXT_GRAPHICS_PIPELINE_LIBRARY_SPEC_VERSION :: 1 +EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME :: "VK_EXT_graphics_pipeline_library" NV_fragment_shading_rate_enums :: 1 NV_FRAGMENT_SHADING_RATE_ENUMS_SPEC_VERSION :: 1 NV_FRAGMENT_SHADING_RATE_ENUMS_EXTENSION_NAME :: "VK_NV_fragment_shading_rate_enums" @@ -658,6 +693,9 @@ EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME :: "VK_EXT_image_robustn EXT_4444_formats :: 1 EXT_4444_FORMATS_SPEC_VERSION :: 1 EXT_4444_FORMATS_EXTENSION_NAME :: "VK_EXT_4444_formats" +EXT_rgba10x6_formats :: 1 +EXT_RGBA10X6_FORMATS_SPEC_VERSION :: 1 +EXT_RGBA10X6_FORMATS_EXTENSION_NAME :: "VK_EXT_rgba10x6_formats" NV_acquire_winrt_display :: 1 NV_ACQUIRE_WINRT_DISPLAY_SPEC_VERSION :: 1 NV_ACQUIRE_WINRT_DISPLAY_EXTENSION_NAME :: "VK_NV_acquire_winrt_display" @@ -667,6 +705,9 @@ EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME :: "VK_EXT_vertex_input_ EXT_physical_device_drm :: 1 EXT_PHYSICAL_DEVICE_DRM_SPEC_VERSION :: 1 EXT_PHYSICAL_DEVICE_DRM_EXTENSION_NAME :: "VK_EXT_physical_device_drm" +EXT_depth_clip_control :: 1 +EXT_DEPTH_CLIP_CONTROL_SPEC_VERSION :: 1 +EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME :: "VK_EXT_depth_clip_control" EXT_primitive_topology_list_restart :: 1 EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_SPEC_VERSION :: 1 EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME :: "VK_EXT_primitive_topology_list_restart" @@ -679,20 +720,38 @@ EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME :: "VK_EXT_extended_dyna EXT_color_write_enable :: 1 EXT_COLOR_WRITE_ENABLE_SPEC_VERSION :: 1 EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME :: "VK_EXT_color_write_enable" +EXT_primitives_generated_query :: 1 +EXT_PRIMITIVES_GENERATED_QUERY_SPEC_VERSION :: 1 +EXT_PRIMITIVES_GENERATED_QUERY_EXTENSION_NAME :: "VK_EXT_primitives_generated_query" EXT_global_priority_query :: 1 EXT_GLOBAL_PRIORITY_QUERY_SPEC_VERSION :: 1 EXT_GLOBAL_PRIORITY_QUERY_EXTENSION_NAME :: "VK_EXT_global_priority_query" +EXT_image_view_min_lod :: 1 +EXT_IMAGE_VIEW_MIN_LOD_SPEC_VERSION :: 1 +EXT_IMAGE_VIEW_MIN_LOD_EXTENSION_NAME :: "VK_EXT_image_view_min_lod" EXT_multi_draw :: 1 EXT_MULTI_DRAW_SPEC_VERSION :: 1 EXT_MULTI_DRAW_EXTENSION_NAME :: "VK_EXT_multi_draw" +EXT_image_2d_view_of_3d :: 1 +EXT_IMAGE_2D_VIEW_OF_3D_SPEC_VERSION :: 1 +EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME :: "VK_EXT_image_2d_view_of_3d" EXT_load_store_op_none :: 1 EXT_LOAD_STORE_OP_NONE_SPEC_VERSION :: 1 EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME :: "VK_EXT_load_store_op_none" +EXT_border_color_swizzle :: 1 +EXT_BORDER_COLOR_SWIZZLE_SPEC_VERSION :: 1 +EXT_BORDER_COLOR_SWIZZLE_EXTENSION_NAME :: "VK_EXT_border_color_swizzle" EXT_pageable_device_local_memory :: 1 EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_SPEC_VERSION :: 1 EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_EXTENSION_NAME :: "VK_EXT_pageable_device_local_memory" +NV_linear_color_attachment :: 1 +NV_LINEAR_COLOR_ATTACHMENT_SPEC_VERSION :: 1 +NV_LINEAR_COLOR_ATTACHMENT_EXTENSION_NAME :: "VK_NV_linear_color_attachment" +GOOGLE_surfaceless_query :: 1 +GOOGLE_SURFACELESS_QUERY_SPEC_VERSION :: 1 +GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME :: "VK_GOOGLE_surfaceless_query" KHR_acceleration_structure :: 1 -KHR_ACCELERATION_STRUCTURE_SPEC_VERSION :: 12 +KHR_ACCELERATION_STRUCTURE_SPEC_VERSION :: 13 KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME :: "VK_KHR_acceleration_structure" KHR_ray_tracing_pipeline :: 1 KHR_RAY_TRACING_PIPELINE_SPEC_VERSION :: 1 @@ -756,6 +815,7 @@ Framebuffer :: distinct NonDispatchableHandle CommandPool :: distinct NonDispatchableHandle SamplerYcbcrConversion :: distinct NonDispatchableHandle DescriptorUpdateTemplate :: distinct NonDispatchableHandle +PrivateDataSlot :: distinct NonDispatchableHandle SurfaceKHR :: distinct NonDispatchableHandle SwapchainKHR :: distinct NonDispatchableHandle DisplayKHR :: distinct NonDispatchableHandle @@ -769,7 +829,6 @@ ValidationCacheEXT :: distinct NonDispatchableHandle AccelerationStructureNV :: distinct NonDispatchableHandle PerformanceConfigurationINTEL :: distinct NonDispatchableHandle IndirectCommandsLayoutNV :: distinct NonDispatchableHandle -PrivateDataSlotEXT :: distinct NonDispatchableHandle AccelerationStructureKHR :: distinct NonDispatchableHandle diff --git a/vendor/vulkan/enums.odin b/vendor/vulkan/enums.odin index be6691ab4..b2eec06ab 100644 --- a/vendor/vulkan/enums.odin +++ b/vendor/vulkan/enums.odin @@ -78,7 +78,7 @@ AccessFlag :: enum Flags { ACCELERATION_STRUCTURE_WRITE_NV = ACCELERATION_STRUCTURE_WRITE_KHR, } -AccessFlags_NONE_KHR :: AccessFlags{} +AccessFlags_NONE :: AccessFlags{} AcquireProfilingLockFlagsKHR :: distinct bit_set[AcquireProfilingLockFlagKHR; Flags] @@ -100,8 +100,7 @@ AttachmentLoadOp :: enum c.int { AttachmentStoreOp :: enum c.int { STORE = 0, DONT_CARE = 1, - NONE_EXT = 1000301000, - NONE_QCOM = NONE_EXT, + NONE = 1000301000, } BlendFactor :: enum c.int { @@ -460,6 +459,7 @@ DebugReportObjectTypeEXT :: enum c.int { CU_FUNCTION_NVX = 1000029001, ACCELERATION_STRUCTURE_KHR = 1000150000, ACCELERATION_STRUCTURE_NV = 1000165000, + BUFFER_COLLECTION_FUCHSIA = 1000366000, DEBUG_REPORT = DEBUG_REPORT_CALLBACK_EXT, VALIDATION_CACHE = VALIDATION_CACHE_EXT, DESCRIPTOR_UPDATE_TEMPLATE_KHR = DESCRIPTOR_UPDATE_TEMPLATE, @@ -530,10 +530,11 @@ DescriptorType :: enum c.int { UNIFORM_BUFFER_DYNAMIC = 8, STORAGE_BUFFER_DYNAMIC = 9, INPUT_ATTACHMENT = 10, - INLINE_UNIFORM_BLOCK_EXT = 1000138000, + INLINE_UNIFORM_BLOCK = 1000138000, ACCELERATION_STRUCTURE_KHR = 1000150000, ACCELERATION_STRUCTURE_NV = 1000165000, MUTABLE_VALVE = 1000351000, + INLINE_UNIFORM_BLOCK_EXT = INLINE_UNIFORM_BLOCK, } DescriptorUpdateTemplateType :: enum c.int { @@ -615,6 +616,11 @@ DriverId :: enum c.int { COREAVI_PROPRIETARY = 15, JUICE_PROPRIETARY = 16, VERISILICON_PROPRIETARY = 17, + MESA_TURNIP = 18, + MESA_V3DV = 19, + MESA_PANVK = 20, + SAMSUNG_PROPRIETARY = 21, + MESA_VENUS = 22, AMD_PROPRIETARY_KHR = AMD_PROPRIETARY, AMD_OPEN_SOURCE_KHR = AMD_OPEN_SOURCE, MESA_RADV_KHR = MESA_RADV, @@ -639,6 +645,21 @@ DynamicState :: enum c.int { STENCIL_COMPARE_MASK = 6, STENCIL_WRITE_MASK = 7, STENCIL_REFERENCE = 8, + CULL_MODE = 1000267000, + FRONT_FACE = 1000267001, + PRIMITIVE_TOPOLOGY = 1000267002, + VIEWPORT_WITH_COUNT = 1000267003, + SCISSOR_WITH_COUNT = 1000267004, + VERTEX_INPUT_BINDING_STRIDE = 1000267005, + DEPTH_TEST_ENABLE = 1000267006, + DEPTH_WRITE_ENABLE = 1000267007, + DEPTH_COMPARE_OP = 1000267008, + DEPTH_BOUNDS_TEST_ENABLE = 1000267009, + STENCIL_TEST_ENABLE = 1000267010, + STENCIL_OP = 1000267011, + RASTERIZER_DISCARD_ENABLE = 1000377001, + DEPTH_BIAS_ENABLE = 1000377002, + PRIMITIVE_RESTART_ENABLE = 1000377004, VIEWPORT_W_SCALING_NV = 1000087000, DISCARD_RECTANGLE_EXT = 1000099000, SAMPLE_LOCATIONS_EXT = 1000143000, @@ -648,30 +669,31 @@ DynamicState :: enum c.int { EXCLUSIVE_SCISSOR_NV = 1000205001, FRAGMENT_SHADING_RATE_KHR = 1000226000, LINE_STIPPLE_EXT = 1000259000, - CULL_MODE_EXT = 1000267000, - FRONT_FACE_EXT = 1000267001, - PRIMITIVE_TOPOLOGY_EXT = 1000267002, - VIEWPORT_WITH_COUNT_EXT = 1000267003, - SCISSOR_WITH_COUNT_EXT = 1000267004, - VERTEX_INPUT_BINDING_STRIDE_EXT = 1000267005, - DEPTH_TEST_ENABLE_EXT = 1000267006, - DEPTH_WRITE_ENABLE_EXT = 1000267007, - DEPTH_COMPARE_OP_EXT = 1000267008, - DEPTH_BOUNDS_TEST_ENABLE_EXT = 1000267009, - STENCIL_TEST_ENABLE_EXT = 1000267010, - STENCIL_OP_EXT = 1000267011, VERTEX_INPUT_EXT = 1000352000, PATCH_CONTROL_POINTS_EXT = 1000377000, - RASTERIZER_DISCARD_ENABLE_EXT = 1000377001, - DEPTH_BIAS_ENABLE_EXT = 1000377002, LOGIC_OP_EXT = 1000377003, - PRIMITIVE_RESTART_ENABLE_EXT = 1000377004, COLOR_WRITE_ENABLE_EXT = 1000381000, + CULL_MODE_EXT = CULL_MODE, + FRONT_FACE_EXT = FRONT_FACE, + PRIMITIVE_TOPOLOGY_EXT = PRIMITIVE_TOPOLOGY, + VIEWPORT_WITH_COUNT_EXT = VIEWPORT_WITH_COUNT, + SCISSOR_WITH_COUNT_EXT = SCISSOR_WITH_COUNT, + VERTEX_INPUT_BINDING_STRIDE_EXT = VERTEX_INPUT_BINDING_STRIDE, + DEPTH_TEST_ENABLE_EXT = DEPTH_TEST_ENABLE, + DEPTH_WRITE_ENABLE_EXT = DEPTH_WRITE_ENABLE, + DEPTH_COMPARE_OP_EXT = DEPTH_COMPARE_OP, + DEPTH_BOUNDS_TEST_ENABLE_EXT = DEPTH_BOUNDS_TEST_ENABLE, + STENCIL_TEST_ENABLE_EXT = STENCIL_TEST_ENABLE, + STENCIL_OP_EXT = STENCIL_OP, + RASTERIZER_DISCARD_ENABLE_EXT = RASTERIZER_DISCARD_ENABLE, + DEPTH_BIAS_ENABLE_EXT = DEPTH_BIAS_ENABLE, + PRIMITIVE_RESTART_ENABLE_EXT = PRIMITIVE_RESTART_ENABLE, } EventCreateFlags :: distinct bit_set[EventCreateFlag; Flags] EventCreateFlag :: enum Flags { - DEVICE_ONLY_KHR = 0, + DEVICE_ONLY = 0, + DEVICE_ONLY_KHR = DEVICE_ONLY, } ExternalFenceFeatureFlags :: distinct bit_set[ExternalFenceFeatureFlag; Flags] @@ -1005,6 +1027,26 @@ Format :: enum c.int { G16_B16_R16_3PLANE_422_UNORM = 1000156031, G16_B16R16_2PLANE_422_UNORM = 1000156032, G16_B16_R16_3PLANE_444_UNORM = 1000156033, + G8_B8R8_2PLANE_444_UNORM = 1000330000, + G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16 = 1000330001, + G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16 = 1000330002, + G16_B16R16_2PLANE_444_UNORM = 1000330003, + A4R4G4B4_UNORM_PACK16 = 1000340000, + A4B4G4R4_UNORM_PACK16 = 1000340001, + ASTC_4x4_SFLOAT_BLOCK = 1000066000, + ASTC_5x4_SFLOAT_BLOCK = 1000066001, + ASTC_5x5_SFLOAT_BLOCK = 1000066002, + ASTC_6x5_SFLOAT_BLOCK = 1000066003, + ASTC_6x6_SFLOAT_BLOCK = 1000066004, + ASTC_8x5_SFLOAT_BLOCK = 1000066005, + ASTC_8x6_SFLOAT_BLOCK = 1000066006, + ASTC_8x8_SFLOAT_BLOCK = 1000066007, + ASTC_10x5_SFLOAT_BLOCK = 1000066008, + ASTC_10x6_SFLOAT_BLOCK = 1000066009, + ASTC_10x8_SFLOAT_BLOCK = 1000066010, + ASTC_10x10_SFLOAT_BLOCK = 1000066011, + ASTC_12x10_SFLOAT_BLOCK = 1000066012, + ASTC_12x12_SFLOAT_BLOCK = 1000066013, PVRTC1_2BPP_UNORM_BLOCK_IMG = 1000054000, PVRTC1_4BPP_UNORM_BLOCK_IMG = 1000054001, PVRTC2_2BPP_UNORM_BLOCK_IMG = 1000054002, @@ -1013,26 +1055,20 @@ Format :: enum c.int { PVRTC1_4BPP_SRGB_BLOCK_IMG = 1000054005, PVRTC2_2BPP_SRGB_BLOCK_IMG = 1000054006, PVRTC2_4BPP_SRGB_BLOCK_IMG = 1000054007, - ASTC_4x4_SFLOAT_BLOCK_EXT = 1000066000, - ASTC_5x4_SFLOAT_BLOCK_EXT = 1000066001, - ASTC_5x5_SFLOAT_BLOCK_EXT = 1000066002, - ASTC_6x5_SFLOAT_BLOCK_EXT = 1000066003, - ASTC_6x6_SFLOAT_BLOCK_EXT = 1000066004, - ASTC_8x5_SFLOAT_BLOCK_EXT = 1000066005, - ASTC_8x6_SFLOAT_BLOCK_EXT = 1000066006, - ASTC_8x8_SFLOAT_BLOCK_EXT = 1000066007, - ASTC_10x5_SFLOAT_BLOCK_EXT = 1000066008, - ASTC_10x6_SFLOAT_BLOCK_EXT = 1000066009, - ASTC_10x8_SFLOAT_BLOCK_EXT = 1000066010, - ASTC_10x10_SFLOAT_BLOCK_EXT = 1000066011, - ASTC_12x10_SFLOAT_BLOCK_EXT = 1000066012, - ASTC_12x12_SFLOAT_BLOCK_EXT = 1000066013, - G8_B8R8_2PLANE_444_UNORM_EXT = 1000330000, - G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT = 1000330001, - G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT = 1000330002, - G16_B16R16_2PLANE_444_UNORM_EXT = 1000330003, - A4R4G4B4_UNORM_PACK16_EXT = 1000340000, - A4B4G4R4_UNORM_PACK16_EXT = 1000340001, + ASTC_4x4_SFLOAT_BLOCK_EXT = ASTC_4x4_SFLOAT_BLOCK, + ASTC_5x4_SFLOAT_BLOCK_EXT = ASTC_5x4_SFLOAT_BLOCK, + ASTC_5x5_SFLOAT_BLOCK_EXT = ASTC_5x5_SFLOAT_BLOCK, + ASTC_6x5_SFLOAT_BLOCK_EXT = ASTC_6x5_SFLOAT_BLOCK, + ASTC_6x6_SFLOAT_BLOCK_EXT = ASTC_6x6_SFLOAT_BLOCK, + ASTC_8x5_SFLOAT_BLOCK_EXT = ASTC_8x5_SFLOAT_BLOCK, + ASTC_8x6_SFLOAT_BLOCK_EXT = ASTC_8x6_SFLOAT_BLOCK, + ASTC_8x8_SFLOAT_BLOCK_EXT = ASTC_8x8_SFLOAT_BLOCK, + ASTC_10x5_SFLOAT_BLOCK_EXT = ASTC_10x5_SFLOAT_BLOCK, + ASTC_10x6_SFLOAT_BLOCK_EXT = ASTC_10x6_SFLOAT_BLOCK, + ASTC_10x8_SFLOAT_BLOCK_EXT = ASTC_10x8_SFLOAT_BLOCK, + ASTC_10x10_SFLOAT_BLOCK_EXT = ASTC_10x10_SFLOAT_BLOCK, + ASTC_12x10_SFLOAT_BLOCK_EXT = ASTC_12x10_SFLOAT_BLOCK, + ASTC_12x12_SFLOAT_BLOCK_EXT = ASTC_12x12_SFLOAT_BLOCK, G8B8G8R8_422_UNORM_KHR = G8B8G8R8_422_UNORM, B8G8R8G8_422_UNORM_KHR = B8G8R8G8_422_UNORM, G8_B8_R8_3PLANE_420_UNORM_KHR = G8_B8_R8_3PLANE_420_UNORM, @@ -1067,6 +1103,12 @@ Format :: enum c.int { G16_B16_R16_3PLANE_422_UNORM_KHR = G16_B16_R16_3PLANE_422_UNORM, G16_B16R16_2PLANE_422_UNORM_KHR = G16_B16R16_2PLANE_422_UNORM, G16_B16_R16_3PLANE_444_UNORM_KHR = G16_B16_R16_3PLANE_444_UNORM, + G8_B8R8_2PLANE_444_UNORM_EXT = G8_B8R8_2PLANE_444_UNORM, + G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT = G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16, + G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT = G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16, + G16_B16R16_2PLANE_444_UNORM_EXT = G16_B16R16_2PLANE_444_UNORM, + A4R4G4B4_UNORM_PACK16_EXT = A4R4G4B4_UNORM_PACK16, + A4B4G4R4_UNORM_PACK16_EXT = A4B4G4R4_UNORM_PACK16, } FormatFeatureFlags :: distinct bit_set[FormatFeatureFlag; Flags] @@ -1190,6 +1232,14 @@ GeometryTypeKHR :: enum c.int { AABBS_NV = AABBS, } +GraphicsPipelineLibraryFlagsEXT :: distinct bit_set[GraphicsPipelineLibraryFlagEXT; Flags] +GraphicsPipelineLibraryFlagEXT :: enum Flags { + VERTEX_INPUT_INTERFACE = 0, + PRE_RASTERIZATION_SHADERS = 1, + FRAGMENT_SHADER = 2, + FRAGMENT_OUTPUT_INTERFACE = 3, +} + ImageAspectFlags :: distinct bit_set[ImageAspectFlag; Flags] ImageAspectFlag :: enum Flags { COLOR = 0, @@ -1208,6 +1258,9 @@ ImageAspectFlag :: enum Flags { PLANE_2_KHR = PLANE_2, } +ImageAspectFlags_NONE :: ImageAspectFlags{} + + ImageCreateFlags :: distinct bit_set[ImageCreateFlag; Flags] ImageCreateFlag :: enum Flags { SPARSE_BINDING = 0, @@ -1225,6 +1278,8 @@ ImageCreateFlag :: enum Flags { CORNER_SAMPLED_NV = 13, SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_EXT = 12, SUBSAMPLED_EXT = 14, + D2_VIEW_COMPATIBLE_EXT = 17, + FRAGMENT_DENSITY_MAP_OFFSET_QCOM = 15, SPLIT_INSTANCE_BIND_REGIONS_KHR = SPLIT_INSTANCE_BIND_REGIONS, D2_ARRAY_COMPATIBLE_KHR = D2_ARRAY_COMPATIBLE, BLOCK_TEXEL_VIEW_COMPATIBLE_KHR = BLOCK_TEXEL_VIEW_COMPATIBLE, @@ -1249,6 +1304,8 @@ ImageLayout :: enum c.int { DEPTH_READ_ONLY_OPTIMAL = 1000241001, STENCIL_ATTACHMENT_OPTIMAL = 1000241002, STENCIL_READ_ONLY_OPTIMAL = 1000241003, + READ_ONLY_OPTIMAL = 1000314000, + ATTACHMENT_OPTIMAL = 1000314001, PRESENT_SRC_KHR = 1000001002, VIDEO_DECODE_DST_KHR = 1000024000, VIDEO_DECODE_SRC_KHR = 1000024001, @@ -1259,8 +1316,6 @@ ImageLayout :: enum c.int { VIDEO_ENCODE_DST_KHR = 1000299000, VIDEO_ENCODE_SRC_KHR = 1000299001, VIDEO_ENCODE_DPB_KHR = 1000299002, - READ_ONLY_OPTIMAL_KHR = 1000314000, - ATTACHMENT_OPTIMAL_KHR = 1000314001, DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, SHADING_RATE_OPTIMAL_NV = FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR, @@ -1268,6 +1323,8 @@ ImageLayout :: enum c.int { DEPTH_READ_ONLY_OPTIMAL_KHR = DEPTH_READ_ONLY_OPTIMAL, STENCIL_ATTACHMENT_OPTIMAL_KHR = STENCIL_ATTACHMENT_OPTIMAL, STENCIL_READ_ONLY_OPTIMAL_KHR = STENCIL_READ_ONLY_OPTIMAL, + READ_ONLY_OPTIMAL_KHR = READ_ONLY_OPTIMAL, + ATTACHMENT_OPTIMAL_KHR = ATTACHMENT_OPTIMAL, } ImageTiling :: enum c.int { @@ -1351,6 +1408,11 @@ IndirectStateFlagNV :: enum Flags { FLAG_FRONTFACE = 0, } +InstanceCreateFlags :: distinct bit_set[InstanceCreateFlag; Flags] +InstanceCreateFlag :: enum Flags { + ENUMERATE_PORTABILITY_KHR = 0, +} + InternalAllocationType :: enum c.int { EXECUTABLE = 0, } @@ -1446,6 +1508,7 @@ ObjectType :: enum c.int { COMMAND_POOL = 25, SAMPLER_YCBCR_CONVERSION = 1000156000, DESCRIPTOR_UPDATE_TEMPLATE = 1000085000, + PRIVATE_DATA_SLOT = 1000295000, SURFACE_KHR = 1000000000, SWAPCHAIN_KHR = 1000001000, DISPLAY_KHR = 1000002000, @@ -1462,9 +1525,10 @@ ObjectType :: enum c.int { PERFORMANCE_CONFIGURATION_INTEL = 1000210000, DEFERRED_OPERATION_KHR = 1000268000, INDIRECT_COMMANDS_LAYOUT_NV = 1000277000, - PRIVATE_DATA_SLOT_EXT = 1000295000, + BUFFER_COLLECTION_FUCHSIA = 1000366000, DESCRIPTOR_UPDATE_TEMPLATE_KHR = DESCRIPTOR_UPDATE_TEMPLATE, SAMPLER_YCBCR_CONVERSION_KHR = SAMPLER_YCBCR_CONVERSION, + PRIVATE_DATA_SLOT_EXT = PRIVATE_DATA_SLOT, } PeerMemoryFeatureFlags :: distinct bit_set[PeerMemoryFeatureFlag; Flags] @@ -1557,48 +1621,71 @@ PipelineBindPoint :: enum c.int { PipelineCacheCreateFlags :: distinct bit_set[PipelineCacheCreateFlag; Flags] PipelineCacheCreateFlag :: enum Flags { - EXTERNALLY_SYNCHRONIZED_EXT = 0, + EXTERNALLY_SYNCHRONIZED = 0, + EXTERNALLY_SYNCHRONIZED_EXT = EXTERNALLY_SYNCHRONIZED, } PipelineCacheHeaderVersion :: enum c.int { ONE = 1, } +PipelineColorBlendStateCreateFlags :: distinct bit_set[PipelineColorBlendStateCreateFlag; Flags] +PipelineColorBlendStateCreateFlag :: enum Flags { + RASTERIZATION_ORDER_ATTACHMENT_ACCESS_ARM = 0, +} + PipelineCompilerControlFlagsAMD :: distinct bit_set[PipelineCompilerControlFlagAMD; Flags] PipelineCompilerControlFlagAMD :: enum Flags { } PipelineCreateFlags :: distinct bit_set[PipelineCreateFlag; Flags] PipelineCreateFlag :: enum Flags { - DISABLE_OPTIMIZATION = 0, - ALLOW_DERIVATIVES = 1, - DERIVATIVE = 2, - VIEW_INDEX_FROM_DEVICE_INDEX = 3, - DISPATCH_BASE = 4, - RAY_TRACING_NO_NULL_ANY_HIT_SHADERS_KHR = 14, - RAY_TRACING_NO_NULL_CLOSEST_HIT_SHADERS_KHR = 15, - RAY_TRACING_NO_NULL_MISS_SHADERS_KHR = 16, - RAY_TRACING_NO_NULL_INTERSECTION_SHADERS_KHR = 17, - RAY_TRACING_SKIP_TRIANGLES_KHR = 12, - RAY_TRACING_SKIP_AABBS_KHR = 13, - RAY_TRACING_SHADER_GROUP_HANDLE_CAPTURE_REPLAY_KHR = 19, - DEFER_COMPILE_NV = 5, - CAPTURE_STATISTICS_KHR = 6, - CAPTURE_INTERNAL_REPRESENTATIONS_KHR = 7, - INDIRECT_BINDABLE_NV = 18, - LIBRARY_KHR = 11, - FAIL_ON_PIPELINE_COMPILE_REQUIRED_EXT = 8, - EARLY_RETURN_ON_FAILURE_EXT = 9, - RAY_TRACING_ALLOW_MOTION_NV = 20, - VIEW_INDEX_FROM_DEVICE_INDEX_KHR = VIEW_INDEX_FROM_DEVICE_INDEX, - DISPATCH_BASE_KHR = DISPATCH_BASE, + DISABLE_OPTIMIZATION = 0, + ALLOW_DERIVATIVES = 1, + DERIVATIVE = 2, + VIEW_INDEX_FROM_DEVICE_INDEX = 3, + DISPATCH_BASE = 4, + FAIL_ON_PIPELINE_COMPILE_REQUIRED = 8, + EARLY_RETURN_ON_FAILURE = 9, + RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_KHR = 21, + RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_EXT = 22, + RAY_TRACING_NO_NULL_ANY_HIT_SHADERS_KHR = 14, + RAY_TRACING_NO_NULL_CLOSEST_HIT_SHADERS_KHR = 15, + RAY_TRACING_NO_NULL_MISS_SHADERS_KHR = 16, + RAY_TRACING_NO_NULL_INTERSECTION_SHADERS_KHR = 17, + RAY_TRACING_SKIP_TRIANGLES_KHR = 12, + RAY_TRACING_SKIP_AABBS_KHR = 13, + RAY_TRACING_SHADER_GROUP_HANDLE_CAPTURE_REPLAY_KHR = 19, + DEFER_COMPILE_NV = 5, + CAPTURE_STATISTICS_KHR = 6, + CAPTURE_INTERNAL_REPRESENTATIONS_KHR = 7, + INDIRECT_BINDABLE_NV = 18, + LIBRARY_KHR = 11, + RETAIN_LINK_TIME_OPTIMIZATION_INFO_EXT = 23, + LINK_TIME_OPTIMIZATION_EXT = 10, + RAY_TRACING_ALLOW_MOTION_NV = 20, + PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_KHR = RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_KHR, + PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_EXT = RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_EXT, + VIEW_INDEX_FROM_DEVICE_INDEX_KHR = VIEW_INDEX_FROM_DEVICE_INDEX, + DISPATCH_BASE_KHR = DISPATCH_BASE, + FAIL_ON_PIPELINE_COMPILE_REQUIRED_EXT = FAIL_ON_PIPELINE_COMPILE_REQUIRED, + EARLY_RETURN_ON_FAILURE_EXT = EARLY_RETURN_ON_FAILURE, } -PipelineCreationFeedbackFlagsEXT :: distinct bit_set[PipelineCreationFeedbackFlagEXT; Flags] -PipelineCreationFeedbackFlagEXT :: enum Flags { - VALID = 0, - APPLICATION_PIPELINE_CACHE_HIT = 1, - BASE_PIPELINE_ACCELERATION = 2, +PipelineCreationFeedbackFlags :: distinct bit_set[PipelineCreationFeedbackFlag; Flags] +PipelineCreationFeedbackFlag :: enum Flags { + VALID = 0, + APPLICATION_PIPELINE_CACHE_HIT = 1, + BASE_PIPELINE_ACCELERATION = 2, + VALID_EXT = VALID, + APPLICATION_PIPELINE_CACHE_HIT_EXT = APPLICATION_PIPELINE_CACHE_HIT, + BASE_PIPELINE_ACCELERATION_EXT = BASE_PIPELINE_ACCELERATION, +} + +PipelineDepthStencilStateCreateFlags :: distinct bit_set[PipelineDepthStencilStateCreateFlag; Flags] +PipelineDepthStencilStateCreateFlag :: enum Flags { + RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_ARM = 0, + RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_ARM = 1, } PipelineExecutableStatisticFormatKHR :: enum c.int { @@ -1608,10 +1695,17 @@ PipelineExecutableStatisticFormatKHR :: enum c.int { FLOAT64 = 3, } +PipelineLayoutCreateFlags :: distinct bit_set[PipelineLayoutCreateFlag; Flags] +PipelineLayoutCreateFlag :: enum Flags { + INDEPENDENT_SETS_EXT = 1, +} + PipelineShaderStageCreateFlags :: distinct bit_set[PipelineShaderStageCreateFlag; Flags] PipelineShaderStageCreateFlag :: enum Flags { - ALLOW_VARYING_SUBGROUP_SIZE_EXT = 0, - REQUIRE_FULL_SUBGROUPS_EXT = 1, + ALLOW_VARYING_SUBGROUP_SIZE = 0, + REQUIRE_FULL_SUBGROUPS = 1, + ALLOW_VARYING_SUBGROUP_SIZE_EXT = ALLOW_VARYING_SUBGROUP_SIZE, + REQUIRE_FULL_SUBGROUPS_EXT = REQUIRE_FULL_SUBGROUPS, } PipelineStageFlags :: distinct bit_set[PipelineStageFlag; Flags] @@ -1647,7 +1741,7 @@ PipelineStageFlag :: enum Flags { ACCELERATION_STRUCTURE_BUILD_NV = ACCELERATION_STRUCTURE_BUILD_KHR, } -PipelineStageFlags_NONE_KHR :: PipelineStageFlags{} +PipelineStageFlags_NONE :: PipelineStageFlags{} PointClippingBehavior :: enum c.int { @@ -1687,10 +1781,6 @@ PrimitiveTopology :: enum c.int { PATCH_LIST = 10, } -PrivateDataSlotCreateFlagsEXT :: distinct bit_set[PrivateDataSlotCreateFlagEXT; Flags] -PrivateDataSlotCreateFlagEXT :: enum Flags { -} - ProvokingVertexModeEXT :: enum c.int { FIRST_VERTEX = 0, LAST_VERTEX = 1, @@ -1741,6 +1831,7 @@ QueryType :: enum c.int { ACCELERATION_STRUCTURE_COMPACTED_SIZE_NV = 1000165000, PERFORMANCE_QUERY_INTEL = 1000210000, VIDEO_ENCODE_BITSTREAM_BUFFER_RANGE_KHR = 1000299000, + PRIMITIVES_GENERATED_EXT = 1000382000, } QueueFlags :: distinct bit_set[QueueFlag; Flags] @@ -1754,11 +1845,15 @@ QueueFlag :: enum Flags { VIDEO_ENCODE_KHR = 6, } -QueueGlobalPriorityEXT :: enum c.int { - LOW = 128, - MEDIUM = 256, - HIGH = 512, - REALTIME = 1024, +QueueGlobalPriorityKHR :: enum c.int { + LOW = 128, + MEDIUM = 256, + HIGH = 512, + REALTIME = 1024, + LOW_EXT = LOW, + MEDIUM_EXT = MEDIUM, + HIGH_EXT = HIGH, + REALTIME_EXT = REALTIME, } RasterizationOrderAMD :: enum c.int { @@ -1780,6 +1875,16 @@ RenderPassCreateFlag :: enum Flags { TRANSFORM_QCOM = 1, } +RenderingFlags :: distinct bit_set[RenderingFlag; Flags] +RenderingFlag :: enum Flags { + CONTENTS_SECONDARY_COMMAND_BUFFERS = 0, + SUSPENDING = 1, + RESUMING = 2, + CONTENTS_SECONDARY_COMMAND_BUFFERS_KHR = CONTENTS_SECONDARY_COMMAND_BUFFERS, + SUSPENDING_KHR = SUSPENDING, + RESUMING_KHR = RESUMING, +} + ResolveModeFlags :: distinct bit_set[ResolveModeFlag; Flags] ResolveModeFlag :: enum Flags { SAMPLE_ZERO = 0, @@ -1819,6 +1924,7 @@ Result :: enum c.int { ERROR_INVALID_EXTERNAL_HANDLE = -1000072003, ERROR_FRAGMENTATION = -1000161000, ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = -1000257000, + PIPELINE_COMPILE_REQUIRED = 1000297000, ERROR_SURFACE_LOST_KHR = -1000000000, ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001, SUBOPTIMAL_KHR = 1000001003, @@ -1827,19 +1933,20 @@ Result :: enum c.int { ERROR_VALIDATION_FAILED_EXT = -1000011001, ERROR_INVALID_SHADER_NV = -1000012000, ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT = -1000158000, - ERROR_NOT_PERMITTED_EXT = -1000174001, + ERROR_NOT_PERMITTED_KHR = -1000174001, ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT = -1000255000, THREAD_IDLE_KHR = 1000268000, THREAD_DONE_KHR = 1000268001, OPERATION_DEFERRED_KHR = 1000268002, OPERATION_NOT_DEFERRED_KHR = 1000268003, - PIPELINE_COMPILE_REQUIRED_EXT = 1000297000, ERROR_OUT_OF_POOL_MEMORY_KHR = ERROR_OUT_OF_POOL_MEMORY, ERROR_INVALID_EXTERNAL_HANDLE_KHR = ERROR_INVALID_EXTERNAL_HANDLE, ERROR_FRAGMENTATION_EXT = ERROR_FRAGMENTATION, + ERROR_NOT_PERMITTED_EXT = ERROR_NOT_PERMITTED_KHR, ERROR_INVALID_DEVICE_ADDRESS_EXT = ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR = ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, - ERROR_PIPELINE_COMPILE_REQUIRED_EXT = PIPELINE_COMPILE_REQUIRED_EXT, + PIPELINE_COMPILE_REQUIRED_EXT = PIPELINE_COMPILE_REQUIRED, + ERROR_PIPELINE_COMPILE_REQUIRED_EXT = PIPELINE_COMPILE_REQUIRED, } SampleCountFlags :: distinct bit_set[SampleCountFlag; Flags] @@ -2036,692 +2143,809 @@ StencilOp :: enum c.int { } StructureType :: enum c.int { - APPLICATION_INFO = 0, - INSTANCE_CREATE_INFO = 1, - DEVICE_QUEUE_CREATE_INFO = 2, - DEVICE_CREATE_INFO = 3, - SUBMIT_INFO = 4, - MEMORY_ALLOCATE_INFO = 5, - MAPPED_MEMORY_RANGE = 6, - BIND_SPARSE_INFO = 7, - FENCE_CREATE_INFO = 8, - SEMAPHORE_CREATE_INFO = 9, - EVENT_CREATE_INFO = 10, - QUERY_POOL_CREATE_INFO = 11, - BUFFER_CREATE_INFO = 12, - BUFFER_VIEW_CREATE_INFO = 13, - IMAGE_CREATE_INFO = 14, - IMAGE_VIEW_CREATE_INFO = 15, - SHADER_MODULE_CREATE_INFO = 16, - PIPELINE_CACHE_CREATE_INFO = 17, - PIPELINE_SHADER_STAGE_CREATE_INFO = 18, - PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO = 19, - PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 20, - PIPELINE_TESSELLATION_STATE_CREATE_INFO = 21, - PIPELINE_VIEWPORT_STATE_CREATE_INFO = 22, - PIPELINE_RASTERIZATION_STATE_CREATE_INFO = 23, - PIPELINE_MULTISAMPLE_STATE_CREATE_INFO = 24, - PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO = 25, - PIPELINE_COLOR_BLEND_STATE_CREATE_INFO = 26, - PIPELINE_DYNAMIC_STATE_CREATE_INFO = 27, - GRAPHICS_PIPELINE_CREATE_INFO = 28, - COMPUTE_PIPELINE_CREATE_INFO = 29, - PIPELINE_LAYOUT_CREATE_INFO = 30, - SAMPLER_CREATE_INFO = 31, - DESCRIPTOR_SET_LAYOUT_CREATE_INFO = 32, - DESCRIPTOR_POOL_CREATE_INFO = 33, - DESCRIPTOR_SET_ALLOCATE_INFO = 34, - WRITE_DESCRIPTOR_SET = 35, - COPY_DESCRIPTOR_SET = 36, - FRAMEBUFFER_CREATE_INFO = 37, - RENDER_PASS_CREATE_INFO = 38, - COMMAND_POOL_CREATE_INFO = 39, - COMMAND_BUFFER_ALLOCATE_INFO = 40, - COMMAND_BUFFER_INHERITANCE_INFO = 41, - COMMAND_BUFFER_BEGIN_INFO = 42, - RENDER_PASS_BEGIN_INFO = 43, - BUFFER_MEMORY_BARRIER = 44, - IMAGE_MEMORY_BARRIER = 45, - MEMORY_BARRIER = 46, - LOADER_INSTANCE_CREATE_INFO = 47, - LOADER_DEVICE_CREATE_INFO = 48, - PHYSICAL_DEVICE_SUBGROUP_PROPERTIES = 1000094000, - BIND_BUFFER_MEMORY_INFO = 1000157000, - BIND_IMAGE_MEMORY_INFO = 1000157001, - PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES = 1000083000, - MEMORY_DEDICATED_REQUIREMENTS = 1000127000, - MEMORY_DEDICATED_ALLOCATE_INFO = 1000127001, - MEMORY_ALLOCATE_FLAGS_INFO = 1000060000, - DEVICE_GROUP_RENDER_PASS_BEGIN_INFO = 1000060003, - DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO = 1000060004, - DEVICE_GROUP_SUBMIT_INFO = 1000060005, - DEVICE_GROUP_BIND_SPARSE_INFO = 1000060006, - BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO = 1000060013, - BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO = 1000060014, - PHYSICAL_DEVICE_GROUP_PROPERTIES = 1000070000, - DEVICE_GROUP_DEVICE_CREATE_INFO = 1000070001, - BUFFER_MEMORY_REQUIREMENTS_INFO_2 = 1000146000, - IMAGE_MEMORY_REQUIREMENTS_INFO_2 = 1000146001, - IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2 = 1000146002, - MEMORY_REQUIREMENTS_2 = 1000146003, - SPARSE_IMAGE_MEMORY_REQUIREMENTS_2 = 1000146004, - PHYSICAL_DEVICE_FEATURES_2 = 1000059000, - PHYSICAL_DEVICE_PROPERTIES_2 = 1000059001, - FORMAT_PROPERTIES_2 = 1000059002, - IMAGE_FORMAT_PROPERTIES_2 = 1000059003, - PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2 = 1000059004, - QUEUE_FAMILY_PROPERTIES_2 = 1000059005, - PHYSICAL_DEVICE_MEMORY_PROPERTIES_2 = 1000059006, - SPARSE_IMAGE_FORMAT_PROPERTIES_2 = 1000059007, - PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2 = 1000059008, - PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES = 1000117000, - RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO = 1000117001, - IMAGE_VIEW_USAGE_CREATE_INFO = 1000117002, - PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO = 1000117003, - RENDER_PASS_MULTIVIEW_CREATE_INFO = 1000053000, - PHYSICAL_DEVICE_MULTIVIEW_FEATURES = 1000053001, - PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES = 1000053002, - PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES = 1000120000, - PROTECTED_SUBMIT_INFO = 1000145000, - PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES = 1000145001, - PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES = 1000145002, - DEVICE_QUEUE_INFO_2 = 1000145003, - SAMPLER_YCBCR_CONVERSION_CREATE_INFO = 1000156000, - SAMPLER_YCBCR_CONVERSION_INFO = 1000156001, - BIND_IMAGE_PLANE_MEMORY_INFO = 1000156002, - IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO = 1000156003, - PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES = 1000156004, - SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES = 1000156005, - DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO = 1000085000, - PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO = 1000071000, - EXTERNAL_IMAGE_FORMAT_PROPERTIES = 1000071001, - PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO = 1000071002, - EXTERNAL_BUFFER_PROPERTIES = 1000071003, - PHYSICAL_DEVICE_ID_PROPERTIES = 1000071004, - EXTERNAL_MEMORY_BUFFER_CREATE_INFO = 1000072000, - EXTERNAL_MEMORY_IMAGE_CREATE_INFO = 1000072001, - EXPORT_MEMORY_ALLOCATE_INFO = 1000072002, - PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO = 1000112000, - EXTERNAL_FENCE_PROPERTIES = 1000112001, - EXPORT_FENCE_CREATE_INFO = 1000113000, - EXPORT_SEMAPHORE_CREATE_INFO = 1000077000, - PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO = 1000076000, - EXTERNAL_SEMAPHORE_PROPERTIES = 1000076001, - PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES = 1000168000, - DESCRIPTOR_SET_LAYOUT_SUPPORT = 1000168001, - PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES = 1000063000, - PHYSICAL_DEVICE_VULKAN_1_1_FEATURES = 49, - PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES = 50, - PHYSICAL_DEVICE_VULKAN_1_2_FEATURES = 51, - PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES = 52, - IMAGE_FORMAT_LIST_CREATE_INFO = 1000147000, - ATTACHMENT_DESCRIPTION_2 = 1000109000, - ATTACHMENT_REFERENCE_2 = 1000109001, - SUBPASS_DESCRIPTION_2 = 1000109002, - SUBPASS_DEPENDENCY_2 = 1000109003, - RENDER_PASS_CREATE_INFO_2 = 1000109004, - SUBPASS_BEGIN_INFO = 1000109005, - SUBPASS_END_INFO = 1000109006, - PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES = 1000177000, - PHYSICAL_DEVICE_DRIVER_PROPERTIES = 1000196000, - PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES = 1000180000, - PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES = 1000082000, - PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES = 1000197000, - DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO = 1000161000, - PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES = 1000161001, - PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES = 1000161002, - DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO = 1000161003, - DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT = 1000161004, - PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES = 1000199000, - SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE = 1000199001, - PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES = 1000221000, - IMAGE_STENCIL_USAGE_CREATE_INFO = 1000246000, - PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES = 1000130000, - SAMPLER_REDUCTION_MODE_CREATE_INFO = 1000130001, - PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES = 1000211000, - PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES = 1000108000, - FRAMEBUFFER_ATTACHMENTS_CREATE_INFO = 1000108001, - FRAMEBUFFER_ATTACHMENT_IMAGE_INFO = 1000108002, - RENDER_PASS_ATTACHMENT_BEGIN_INFO = 1000108003, - PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES = 1000253000, - PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES = 1000175000, - PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES = 1000241000, - ATTACHMENT_REFERENCE_STENCIL_LAYOUT = 1000241001, - ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT = 1000241002, - PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES = 1000261000, - PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES = 1000207000, - PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES = 1000207001, - SEMAPHORE_TYPE_CREATE_INFO = 1000207002, - TIMELINE_SEMAPHORE_SUBMIT_INFO = 1000207003, - SEMAPHORE_WAIT_INFO = 1000207004, - SEMAPHORE_SIGNAL_INFO = 1000207005, - PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES = 1000257000, - BUFFER_DEVICE_ADDRESS_INFO = 1000244001, - BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO = 1000257002, - MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO = 1000257003, - DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO = 1000257004, - SWAPCHAIN_CREATE_INFO_KHR = 1000001000, - PRESENT_INFO_KHR = 1000001001, - DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007, - IMAGE_SWAPCHAIN_CREATE_INFO_KHR = 1000060008, - BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR = 1000060009, - ACQUIRE_NEXT_IMAGE_INFO_KHR = 1000060010, - DEVICE_GROUP_PRESENT_INFO_KHR = 1000060011, - DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR = 1000060012, - DISPLAY_MODE_CREATE_INFO_KHR = 1000002000, - DISPLAY_SURFACE_CREATE_INFO_KHR = 1000002001, - DISPLAY_PRESENT_INFO_KHR = 1000003000, - XLIB_SURFACE_CREATE_INFO_KHR = 1000004000, - XCB_SURFACE_CREATE_INFO_KHR = 1000005000, - WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000, - ANDROID_SURFACE_CREATE_INFO_KHR = 1000008000, - WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, - DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000, - PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD = 1000018000, - DEBUG_MARKER_OBJECT_NAME_INFO_EXT = 1000022000, - DEBUG_MARKER_OBJECT_TAG_INFO_EXT = 1000022001, - DEBUG_MARKER_MARKER_INFO_EXT = 1000022002, - VIDEO_PROFILE_KHR = 1000023000, - VIDEO_CAPABILITIES_KHR = 1000023001, - VIDEO_PICTURE_RESOURCE_KHR = 1000023002, - VIDEO_GET_MEMORY_PROPERTIES_KHR = 1000023003, - VIDEO_BIND_MEMORY_KHR = 1000023004, - VIDEO_SESSION_CREATE_INFO_KHR = 1000023005, - VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR = 1000023006, - VIDEO_SESSION_PARAMETERS_UPDATE_INFO_KHR = 1000023007, - VIDEO_BEGIN_CODING_INFO_KHR = 1000023008, - VIDEO_END_CODING_INFO_KHR = 1000023009, - VIDEO_CODING_CONTROL_INFO_KHR = 1000023010, - VIDEO_REFERENCE_SLOT_KHR = 1000023011, - VIDEO_QUEUE_FAMILY_PROPERTIES_2_KHR = 1000023012, - VIDEO_PROFILES_KHR = 1000023013, - PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR = 1000023014, - VIDEO_FORMAT_PROPERTIES_KHR = 1000023015, - VIDEO_DECODE_INFO_KHR = 1000024000, - DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000, - DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001, - DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002, - PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT = 1000028000, - PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT = 1000028001, - PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT = 1000028002, - CU_MODULE_CREATE_INFO_NVX = 1000029000, - CU_FUNCTION_CREATE_INFO_NVX = 1000029001, - CU_LAUNCH_INFO_NVX = 1000029002, - IMAGE_VIEW_HANDLE_INFO_NVX = 1000030000, - IMAGE_VIEW_ADDRESS_PROPERTIES_NVX = 1000030001, - VIDEO_ENCODE_H264_CAPABILITIES_EXT = 1000038000, - VIDEO_ENCODE_H264_SESSION_CREATE_INFO_EXT = 1000038001, - VIDEO_ENCODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000038002, - VIDEO_ENCODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000038003, - VIDEO_ENCODE_H264_VCL_FRAME_INFO_EXT = 1000038004, - VIDEO_ENCODE_H264_DPB_SLOT_INFO_EXT = 1000038005, - VIDEO_ENCODE_H264_NALU_SLICE_EXT = 1000038006, - VIDEO_ENCODE_H264_EMIT_PICTURE_PARAMETERS_EXT = 1000038007, - VIDEO_ENCODE_H264_PROFILE_EXT = 1000038008, - VIDEO_DECODE_H264_CAPABILITIES_EXT = 1000040000, - VIDEO_DECODE_H264_SESSION_CREATE_INFO_EXT = 1000040001, - VIDEO_DECODE_H264_PICTURE_INFO_EXT = 1000040002, - VIDEO_DECODE_H264_MVC_EXT = 1000040003, - VIDEO_DECODE_H264_PROFILE_EXT = 1000040004, - VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000040005, - VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000040006, - VIDEO_DECODE_H264_DPB_SLOT_INFO_EXT = 1000040007, - TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000, - STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP = 1000049000, - PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV = 1000050000, - EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV = 1000056000, - EXPORT_MEMORY_ALLOCATE_INFO_NV = 1000056001, - IMPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057000, - EXPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057001, - WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV = 1000058000, - VALIDATION_FLAGS_EXT = 1000061000, - VI_SURFACE_CREATE_INFO_NN = 1000062000, - PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT = 1000066000, - IMAGE_VIEW_ASTC_DECODE_MODE_EXT = 1000067000, - PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT = 1000067001, - IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073000, - EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073001, - MEMORY_WIN32_HANDLE_PROPERTIES_KHR = 1000073002, - MEMORY_GET_WIN32_HANDLE_INFO_KHR = 1000073003, - IMPORT_MEMORY_FD_INFO_KHR = 1000074000, - MEMORY_FD_PROPERTIES_KHR = 1000074001, - MEMORY_GET_FD_INFO_KHR = 1000074002, - WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR = 1000075000, - IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078000, - EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078001, - D3D12_FENCE_SUBMIT_INFO_KHR = 1000078002, - SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR = 1000078003, - IMPORT_SEMAPHORE_FD_INFO_KHR = 1000079000, - SEMAPHORE_GET_FD_INFO_KHR = 1000079001, - PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR = 1000080000, - COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT = 1000081000, - PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT = 1000081001, - CONDITIONAL_RENDERING_BEGIN_INFO_EXT = 1000081002, - PRESENT_REGIONS_KHR = 1000084000, - PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV = 1000087000, - SURFACE_CAPABILITIES_2_EXT = 1000090000, - DISPLAY_POWER_INFO_EXT = 1000091000, - DEVICE_EVENT_INFO_EXT = 1000091001, - DISPLAY_EVENT_INFO_EXT = 1000091002, - SWAPCHAIN_COUNTER_CREATE_INFO_EXT = 1000091003, - PRESENT_TIMES_INFO_GOOGLE = 1000092000, - PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_ATTRIBUTES_PROPERTIES_NVX = 1000097000, - PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV = 1000098000, - PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT = 1000099000, - PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT = 1000099001, - PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT = 1000101000, - PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT = 1000101001, - PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT = 1000102000, - PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT = 1000102001, - HDR_METADATA_EXT = 1000105000, - SHARED_PRESENT_SURFACE_CAPABILITIES_KHR = 1000111000, - IMPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114000, - EXPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114001, - FENCE_GET_WIN32_HANDLE_INFO_KHR = 1000114002, - IMPORT_FENCE_FD_INFO_KHR = 1000115000, - FENCE_GET_FD_INFO_KHR = 1000115001, - PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR = 1000116000, - PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR = 1000116001, - QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR = 1000116002, - PERFORMANCE_QUERY_SUBMIT_INFO_KHR = 1000116003, - ACQUIRE_PROFILING_LOCK_INFO_KHR = 1000116004, - PERFORMANCE_COUNTER_KHR = 1000116005, - PERFORMANCE_COUNTER_DESCRIPTION_KHR = 1000116006, - PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000, - SURFACE_CAPABILITIES_2_KHR = 1000119001, - SURFACE_FORMAT_2_KHR = 1000119002, - DISPLAY_PROPERTIES_2_KHR = 1000121000, - DISPLAY_PLANE_PROPERTIES_2_KHR = 1000121001, - DISPLAY_MODE_PROPERTIES_2_KHR = 1000121002, - DISPLAY_PLANE_INFO_2_KHR = 1000121003, - DISPLAY_PLANE_CAPABILITIES_2_KHR = 1000121004, - IOS_SURFACE_CREATE_INFO_MVK = 1000122000, - MACOS_SURFACE_CREATE_INFO_MVK = 1000123000, - DEBUG_UTILS_OBJECT_NAME_INFO_EXT = 1000128000, - DEBUG_UTILS_OBJECT_TAG_INFO_EXT = 1000128001, - DEBUG_UTILS_LABEL_EXT = 1000128002, - DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT = 1000128003, - DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT = 1000128004, - ANDROID_HARDWARE_BUFFER_USAGE_ANDROID = 1000129000, - ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID = 1000129001, - ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID = 1000129002, - IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129003, - MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129004, - EXTERNAL_FORMAT_ANDROID = 1000129005, - PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = 1000138000, - PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = 1000138001, - WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = 1000138002, - DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT = 1000138003, - SAMPLE_LOCATIONS_INFO_EXT = 1000143000, - RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT = 1000143001, - PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002, - PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT = 1000143003, - MULTISAMPLE_PROPERTIES_EXT = 1000143004, - PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT = 1000148000, - PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT = 1000148001, - PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT = 1000148002, - PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV = 1000149000, - WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR = 1000150007, - ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR = 1000150000, - ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR = 1000150002, - ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR = 1000150003, - ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR = 1000150004, - ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR = 1000150005, - ACCELERATION_STRUCTURE_GEOMETRY_KHR = 1000150006, - ACCELERATION_STRUCTURE_VERSION_INFO_KHR = 1000150009, - COPY_ACCELERATION_STRUCTURE_INFO_KHR = 1000150010, - COPY_ACCELERATION_STRUCTURE_TO_MEMORY_INFO_KHR = 1000150011, - COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR = 1000150012, - PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR = 1000150013, - PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR = 1000150014, - ACCELERATION_STRUCTURE_CREATE_INFO_KHR = 1000150017, - ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR = 1000150020, - PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR = 1000347000, - PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR = 1000347001, - RAY_TRACING_PIPELINE_CREATE_INFO_KHR = 1000150015, - RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR = 1000150016, - RAY_TRACING_PIPELINE_INTERFACE_CREATE_INFO_KHR = 1000150018, - PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR = 1000348013, - PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV = 1000152000, - PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV = 1000154000, - PHYSICAL_DEVICE_SHADER_SM_BUILTINS_PROPERTIES_NV = 1000154001, - DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT = 1000158000, - PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT = 1000158002, - IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT = 1000158003, - IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT = 1000158004, - IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT = 1000158005, - VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000, - SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001, - PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR = 1000163000, - PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR = 1000163001, - PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV = 1000164000, - PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV = 1000164001, - PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV = 1000164002, - PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV = 1000164005, - RAY_TRACING_PIPELINE_CREATE_INFO_NV = 1000165000, - ACCELERATION_STRUCTURE_CREATE_INFO_NV = 1000165001, - GEOMETRY_NV = 1000165003, - GEOMETRY_TRIANGLES_NV = 1000165004, - GEOMETRY_AABB_NV = 1000165005, - BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV = 1000165006, - WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV = 1000165007, - ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV = 1000165008, - PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV = 1000165009, - RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV = 1000165011, - ACCELERATION_STRUCTURE_INFO_NV = 1000165012, - PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV = 1000166000, - PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV = 1000166001, - PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT = 1000170000, - FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT = 1000170001, - DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = 1000174000, - IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000, - MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001, - PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002, - PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR = 1000181000, - PIPELINE_COMPILER_CONTROL_CREATE_INFO_AMD = 1000183000, - CALIBRATED_TIMESTAMP_INFO_EXT = 1000184000, - PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD = 1000185000, - VIDEO_DECODE_H265_CAPABILITIES_EXT = 1000187000, - VIDEO_DECODE_H265_SESSION_CREATE_INFO_EXT = 1000187001, - VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000187002, - VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT = 1000187003, - VIDEO_DECODE_H265_PROFILE_EXT = 1000187004, - VIDEO_DECODE_H265_PICTURE_INFO_EXT = 1000187005, - VIDEO_DECODE_H265_DPB_SLOT_INFO_EXT = 1000187006, - DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD = 1000189000, - PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000, - PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = 1000190001, - PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = 1000190002, - PRESENT_FRAME_TOKEN_GGP = 1000191000, - PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT = 1000192000, - PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000, - PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000, - PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001, - PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV = 1000203000, - PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV = 1000204000, - PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV = 1000205000, - PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV = 1000205002, - CHECKPOINT_DATA_NV = 1000206000, - QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV = 1000206001, - PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL = 1000209000, - QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL = 1000210000, - INITIALIZE_PERFORMANCE_API_INFO_INTEL = 1000210001, - PERFORMANCE_MARKER_INFO_INTEL = 1000210002, - PERFORMANCE_STREAM_MARKER_INFO_INTEL = 1000210003, - PERFORMANCE_OVERRIDE_INFO_INTEL = 1000210004, - PERFORMANCE_CONFIGURATION_ACQUIRE_INFO_INTEL = 1000210005, - PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000, - DISPLAY_NATIVE_HDR_SURFACE_CAPABILITIES_AMD = 1000213000, - SWAPCHAIN_DISPLAY_NATIVE_HDR_CREATE_INFO_AMD = 1000213001, - IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000, - PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR = 1000215000, - METAL_SURFACE_CREATE_INFO_EXT = 1000217000, - PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000, - PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001, - RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002, - PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT = 1000225000, - PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = 1000225001, - PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT = 1000225002, - FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000226000, - PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR = 1000226001, - PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR = 1000226002, - PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR = 1000226003, - PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR = 1000226004, - PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD = 1000227000, - PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD = 1000229000, - PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT = 1000234000, - PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT = 1000237000, - PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT = 1000238000, - MEMORY_PRIORITY_ALLOCATE_INFO_EXT = 1000238001, - SURFACE_PROTECTED_CAPABILITIES_KHR = 1000239000, - PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV = 1000240000, - PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT = 1000244000, - BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002, - PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = 1000245000, - VALIDATION_FEATURES_EXT = 1000247000, - PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR = 1000248000, - PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV = 1000249000, - COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249001, - PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249002, - PHYSICAL_DEVICE_COVERAGE_REDUCTION_MODE_FEATURES_NV = 1000250000, - PIPELINE_COVERAGE_REDUCTION_STATE_CREATE_INFO_NV = 1000250001, - FRAMEBUFFER_MIXED_SAMPLES_COMBINATION_NV = 1000250002, - PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT = 1000251000, - PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT = 1000252000, - PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT = 1000254000, - PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT = 1000254001, - PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT = 1000254002, - SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT = 1000255000, - SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT = 1000255002, - SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT = 1000255001, - HEADLESS_SURFACE_CREATE_INFO_EXT = 1000256000, - PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT = 1000259000, - PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT = 1000259001, - PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT = 1000259002, - PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT = 1000260000, - PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT = 1000265000, - PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT = 1000267000, - PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR = 1000269000, - PIPELINE_INFO_KHR = 1000269001, - PIPELINE_EXECUTABLE_PROPERTIES_KHR = 1000269002, - PIPELINE_EXECUTABLE_INFO_KHR = 1000269003, - PIPELINE_EXECUTABLE_STATISTIC_KHR = 1000269004, - PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR = 1000269005, - PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT = 1000273000, - PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = 1000276000, - PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV = 1000277000, - GRAPHICS_SHADER_GROUP_CREATE_INFO_NV = 1000277001, - GRAPHICS_PIPELINE_SHADER_GROUPS_CREATE_INFO_NV = 1000277002, - INDIRECT_COMMANDS_LAYOUT_TOKEN_NV = 1000277003, - INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NV = 1000277004, - GENERATED_COMMANDS_INFO_NV = 1000277005, - GENERATED_COMMANDS_MEMORY_REQUIREMENTS_INFO_NV = 1000277006, - PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV = 1000277007, - PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV = 1000278000, - COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV = 1000278001, - PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR = 1000280000, - PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR = 1000280001, - PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT = 1000281000, - PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = 1000281001, - COMMAND_BUFFER_INHERITANCE_RENDER_PASS_TRANSFORM_INFO_QCOM = 1000282000, - RENDER_PASS_TRANSFORM_BEGIN_INFO_QCOM = 1000282001, - PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT = 1000284000, - DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT = 1000284001, - DEVICE_MEMORY_REPORT_CALLBACK_DATA_EXT = 1000284002, - PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT = 1000286000, - PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT = 1000286001, - SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT = 1000287000, - PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT = 1000287001, - PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT = 1000287002, - PIPELINE_LIBRARY_CREATE_INFO_KHR = 1000290000, - PRESENT_ID_KHR = 1000294000, - PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR = 1000294001, - PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT = 1000295000, - DEVICE_PRIVATE_DATA_CREATE_INFO_EXT = 1000295001, - PRIVATE_DATA_SLOT_CREATE_INFO_EXT = 1000295002, - PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT = 1000297000, - VIDEO_ENCODE_INFO_KHR = 1000299000, - VIDEO_ENCODE_RATE_CONTROL_INFO_KHR = 1000299001, - PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV = 1000300000, - DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV = 1000300001, - MEMORY_BARRIER_2_KHR = 1000314000, - BUFFER_MEMORY_BARRIER_2_KHR = 1000314001, - IMAGE_MEMORY_BARRIER_2_KHR = 1000314002, - DEPENDENCY_INFO_KHR = 1000314003, - SUBMIT_INFO_2_KHR = 1000314004, - SEMAPHORE_SUBMIT_INFO_KHR = 1000314005, - COMMAND_BUFFER_SUBMIT_INFO_KHR = 1000314006, - PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR = 1000314007, - QUEUE_FAMILY_CHECKPOINT_PROPERTIES_2_NV = 1000314008, - CHECKPOINT_DATA_2_NV = 1000314009, - PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR = 1000323000, - PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES_KHR = 1000325000, - PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_PROPERTIES_NV = 1000326000, - PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_FEATURES_NV = 1000326001, - PIPELINE_FRAGMENT_SHADING_RATE_ENUM_STATE_CREATE_INFO_NV = 1000326002, - ACCELERATION_STRUCTURE_GEOMETRY_MOTION_TRIANGLES_DATA_NV = 1000327000, - PHYSICAL_DEVICE_RAY_TRACING_MOTION_BLUR_FEATURES_NV = 1000327001, - ACCELERATION_STRUCTURE_MOTION_INFO_NV = 1000327002, - PHYSICAL_DEVICE_YCBCR_2_PLANE_444_FORMATS_FEATURES_EXT = 1000330000, - PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT = 1000332000, - PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_PROPERTIES_EXT = 1000332001, - COPY_COMMAND_TRANSFORM_INFO_QCOM = 1000333000, - PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT = 1000335000, - PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR = 1000336000, - COPY_BUFFER_INFO_2_KHR = 1000337000, - COPY_IMAGE_INFO_2_KHR = 1000337001, - COPY_BUFFER_TO_IMAGE_INFO_2_KHR = 1000337002, - COPY_IMAGE_TO_BUFFER_INFO_2_KHR = 1000337003, - BLIT_IMAGE_INFO_2_KHR = 1000337004, - RESOLVE_IMAGE_INFO_2_KHR = 1000337005, - BUFFER_COPY_2_KHR = 1000337006, - IMAGE_COPY_2_KHR = 1000337007, - IMAGE_BLIT_2_KHR = 1000337008, - BUFFER_IMAGE_COPY_2_KHR = 1000337009, - IMAGE_RESOLVE_2_KHR = 1000337010, - PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT = 1000340000, - DIRECTFB_SURFACE_CREATE_INFO_EXT = 1000346000, - PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_VALVE = 1000351000, - MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE = 1000351002, - PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT = 1000352000, - VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT = 1000352001, - VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT = 1000352002, - PHYSICAL_DEVICE_DRM_PROPERTIES_EXT = 1000353000, - PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT = 1000356000, - IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364000, - MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA = 1000364001, - MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364002, - IMPORT_SEMAPHORE_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365000, - SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365001, - SUBPASS_SHADING_PIPELINE_CREATE_INFO_HUAWEI = 1000369000, - PHYSICAL_DEVICE_SUBPASS_SHADING_FEATURES_HUAWEI = 1000369001, - PHYSICAL_DEVICE_SUBPASS_SHADING_PROPERTIES_HUAWEI = 1000369002, - PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI = 1000370000, - MEMORY_GET_REMOTE_ADDRESS_INFO_NV = 1000371000, - PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV = 1000371001, - PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT = 1000377000, - SCREEN_SURFACE_CREATE_INFO_QNX = 1000378000, - PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT = 1000381000, - PIPELINE_COLOR_WRITE_CREATE_INFO_EXT = 1000381001, - PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT = 1000388000, - QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT = 1000388001, - PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT = 1000392000, - PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT = 1000392001, - PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT = 1000412000, - PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, - PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, - DEBUG_REPORT_CREATE_INFO_EXT = DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, - RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR = RENDER_PASS_MULTIVIEW_CREATE_INFO, - PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR = PHYSICAL_DEVICE_MULTIVIEW_FEATURES, - PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR = PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES, - PHYSICAL_DEVICE_FEATURES_2_KHR = PHYSICAL_DEVICE_FEATURES_2, - PHYSICAL_DEVICE_PROPERTIES_2_KHR = PHYSICAL_DEVICE_PROPERTIES_2, - FORMAT_PROPERTIES_2_KHR = FORMAT_PROPERTIES_2, - IMAGE_FORMAT_PROPERTIES_2_KHR = IMAGE_FORMAT_PROPERTIES_2, - PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR = PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, - QUEUE_FAMILY_PROPERTIES_2_KHR = QUEUE_FAMILY_PROPERTIES_2, - PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR = PHYSICAL_DEVICE_MEMORY_PROPERTIES_2, - SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR = SPARSE_IMAGE_FORMAT_PROPERTIES_2, - PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2_KHR = PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2, - MEMORY_ALLOCATE_FLAGS_INFO_KHR = MEMORY_ALLOCATE_FLAGS_INFO, - DEVICE_GROUP_RENDER_PASS_BEGIN_INFO_KHR = DEVICE_GROUP_RENDER_PASS_BEGIN_INFO, - DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO_KHR = DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO, - DEVICE_GROUP_SUBMIT_INFO_KHR = DEVICE_GROUP_SUBMIT_INFO, - DEVICE_GROUP_BIND_SPARSE_INFO_KHR = DEVICE_GROUP_BIND_SPARSE_INFO, - BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO_KHR = BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO, - BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO_KHR = BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO, - PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR = PHYSICAL_DEVICE_GROUP_PROPERTIES, - DEVICE_GROUP_DEVICE_CREATE_INFO_KHR = DEVICE_GROUP_DEVICE_CREATE_INFO, - PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR = PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, - EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR = EXTERNAL_IMAGE_FORMAT_PROPERTIES, - PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR = PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO, - EXTERNAL_BUFFER_PROPERTIES_KHR = EXTERNAL_BUFFER_PROPERTIES, - PHYSICAL_DEVICE_ID_PROPERTIES_KHR = PHYSICAL_DEVICE_ID_PROPERTIES, - EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR = EXTERNAL_MEMORY_BUFFER_CREATE_INFO, - EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR = EXTERNAL_MEMORY_IMAGE_CREATE_INFO, - EXPORT_MEMORY_ALLOCATE_INFO_KHR = EXPORT_MEMORY_ALLOCATE_INFO, - PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR = PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO, - EXTERNAL_SEMAPHORE_PROPERTIES_KHR = EXTERNAL_SEMAPHORE_PROPERTIES, - EXPORT_SEMAPHORE_CREATE_INFO_KHR = EXPORT_SEMAPHORE_CREATE_INFO, - PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR = PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, - PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR = PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, - PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR = PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, - DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR = DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO, - SURFACE_CAPABILITIES2_EXT = SURFACE_CAPABILITIES_2_EXT, - PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR = PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES, - FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR = FRAMEBUFFER_ATTACHMENTS_CREATE_INFO, - FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR = FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, - RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR = RENDER_PASS_ATTACHMENT_BEGIN_INFO, - ATTACHMENT_DESCRIPTION_2_KHR = ATTACHMENT_DESCRIPTION_2, - ATTACHMENT_REFERENCE_2_KHR = ATTACHMENT_REFERENCE_2, - SUBPASS_DESCRIPTION_2_KHR = SUBPASS_DESCRIPTION_2, - SUBPASS_DEPENDENCY_2_KHR = SUBPASS_DEPENDENCY_2, - RENDER_PASS_CREATE_INFO_2_KHR = RENDER_PASS_CREATE_INFO_2, - SUBPASS_BEGIN_INFO_KHR = SUBPASS_BEGIN_INFO, - SUBPASS_END_INFO_KHR = SUBPASS_END_INFO, - PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR = PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO, - EXTERNAL_FENCE_PROPERTIES_KHR = EXTERNAL_FENCE_PROPERTIES, - EXPORT_FENCE_CREATE_INFO_KHR = EXPORT_FENCE_CREATE_INFO, - PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES_KHR = PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES, - RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_KHR = RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO, - IMAGE_VIEW_USAGE_CREATE_INFO_KHR = IMAGE_VIEW_USAGE_CREATE_INFO, - PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO_KHR = PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO, - PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR = PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, - PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR = PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR, - MEMORY_DEDICATED_REQUIREMENTS_KHR = MEMORY_DEDICATED_REQUIREMENTS, - MEMORY_DEDICATED_ALLOCATE_INFO_KHR = MEMORY_DEDICATED_ALLOCATE_INFO, - PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES, - SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = SAMPLER_REDUCTION_MODE_CREATE_INFO, - BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = BUFFER_MEMORY_REQUIREMENTS_INFO_2, - IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = IMAGE_MEMORY_REQUIREMENTS_INFO_2, - IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR = IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2, - MEMORY_REQUIREMENTS_2_KHR = MEMORY_REQUIREMENTS_2, - SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR = SPARSE_IMAGE_MEMORY_REQUIREMENTS_2, - IMAGE_FORMAT_LIST_CREATE_INFO_KHR = IMAGE_FORMAT_LIST_CREATE_INFO, - SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR = SAMPLER_YCBCR_CONVERSION_CREATE_INFO, - SAMPLER_YCBCR_CONVERSION_INFO_KHR = SAMPLER_YCBCR_CONVERSION_INFO, - BIND_IMAGE_PLANE_MEMORY_INFO_KHR = BIND_IMAGE_PLANE_MEMORY_INFO, - IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR = IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO, - PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR = PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES, - SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES_KHR = SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES, - BIND_BUFFER_MEMORY_INFO_KHR = BIND_BUFFER_MEMORY_INFO, - BIND_IMAGE_MEMORY_INFO_KHR = BIND_IMAGE_MEMORY_INFO, - DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, - PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, - PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES, - DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO, - DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT, - PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR = PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, - DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR = DESCRIPTOR_SET_LAYOUT_SUPPORT, - PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR = PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES, - PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES, - PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, - PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = PHYSICAL_DEVICE_DRIVER_PROPERTIES, - PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES, - PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES, - SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR = SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE, - PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR = PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, - PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR = PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES, - SEMAPHORE_TYPE_CREATE_INFO_KHR = SEMAPHORE_TYPE_CREATE_INFO, - TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR = TIMELINE_SEMAPHORE_SUBMIT_INFO, - SEMAPHORE_WAIT_INFO_KHR = SEMAPHORE_WAIT_INFO, - SEMAPHORE_SIGNAL_INFO_KHR = SEMAPHORE_SIGNAL_INFO, - QUERY_POOL_CREATE_INFO_INTEL = QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL, - PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES, - PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES, - PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR = PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, - ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR = ATTACHMENT_REFERENCE_STENCIL_LAYOUT, - ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR = ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT, - PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT = PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT, - BUFFER_DEVICE_ADDRESS_INFO_EXT = BUFFER_DEVICE_ADDRESS_INFO, - IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = IMAGE_STENCIL_USAGE_CREATE_INFO, - PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR = PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, - PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR = PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES, - BUFFER_DEVICE_ADDRESS_INFO_KHR = BUFFER_DEVICE_ADDRESS_INFO, - BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR = BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO, - MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR = MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO, - DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR = DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO, - PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT = PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, + APPLICATION_INFO = 0, + INSTANCE_CREATE_INFO = 1, + DEVICE_QUEUE_CREATE_INFO = 2, + DEVICE_CREATE_INFO = 3, + SUBMIT_INFO = 4, + MEMORY_ALLOCATE_INFO = 5, + MAPPED_MEMORY_RANGE = 6, + BIND_SPARSE_INFO = 7, + FENCE_CREATE_INFO = 8, + SEMAPHORE_CREATE_INFO = 9, + EVENT_CREATE_INFO = 10, + QUERY_POOL_CREATE_INFO = 11, + BUFFER_CREATE_INFO = 12, + BUFFER_VIEW_CREATE_INFO = 13, + IMAGE_CREATE_INFO = 14, + IMAGE_VIEW_CREATE_INFO = 15, + SHADER_MODULE_CREATE_INFO = 16, + PIPELINE_CACHE_CREATE_INFO = 17, + PIPELINE_SHADER_STAGE_CREATE_INFO = 18, + PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO = 19, + PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 20, + PIPELINE_TESSELLATION_STATE_CREATE_INFO = 21, + PIPELINE_VIEWPORT_STATE_CREATE_INFO = 22, + PIPELINE_RASTERIZATION_STATE_CREATE_INFO = 23, + PIPELINE_MULTISAMPLE_STATE_CREATE_INFO = 24, + PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO = 25, + PIPELINE_COLOR_BLEND_STATE_CREATE_INFO = 26, + PIPELINE_DYNAMIC_STATE_CREATE_INFO = 27, + GRAPHICS_PIPELINE_CREATE_INFO = 28, + COMPUTE_PIPELINE_CREATE_INFO = 29, + PIPELINE_LAYOUT_CREATE_INFO = 30, + SAMPLER_CREATE_INFO = 31, + DESCRIPTOR_SET_LAYOUT_CREATE_INFO = 32, + DESCRIPTOR_POOL_CREATE_INFO = 33, + DESCRIPTOR_SET_ALLOCATE_INFO = 34, + WRITE_DESCRIPTOR_SET = 35, + COPY_DESCRIPTOR_SET = 36, + FRAMEBUFFER_CREATE_INFO = 37, + RENDER_PASS_CREATE_INFO = 38, + COMMAND_POOL_CREATE_INFO = 39, + COMMAND_BUFFER_ALLOCATE_INFO = 40, + COMMAND_BUFFER_INHERITANCE_INFO = 41, + COMMAND_BUFFER_BEGIN_INFO = 42, + RENDER_PASS_BEGIN_INFO = 43, + BUFFER_MEMORY_BARRIER = 44, + IMAGE_MEMORY_BARRIER = 45, + MEMORY_BARRIER = 46, + LOADER_INSTANCE_CREATE_INFO = 47, + LOADER_DEVICE_CREATE_INFO = 48, + PHYSICAL_DEVICE_SUBGROUP_PROPERTIES = 1000094000, + BIND_BUFFER_MEMORY_INFO = 1000157000, + BIND_IMAGE_MEMORY_INFO = 1000157001, + PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES = 1000083000, + MEMORY_DEDICATED_REQUIREMENTS = 1000127000, + MEMORY_DEDICATED_ALLOCATE_INFO = 1000127001, + MEMORY_ALLOCATE_FLAGS_INFO = 1000060000, + DEVICE_GROUP_RENDER_PASS_BEGIN_INFO = 1000060003, + DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO = 1000060004, + DEVICE_GROUP_SUBMIT_INFO = 1000060005, + DEVICE_GROUP_BIND_SPARSE_INFO = 1000060006, + BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO = 1000060013, + BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO = 1000060014, + PHYSICAL_DEVICE_GROUP_PROPERTIES = 1000070000, + DEVICE_GROUP_DEVICE_CREATE_INFO = 1000070001, + BUFFER_MEMORY_REQUIREMENTS_INFO_2 = 1000146000, + IMAGE_MEMORY_REQUIREMENTS_INFO_2 = 1000146001, + IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2 = 1000146002, + MEMORY_REQUIREMENTS_2 = 1000146003, + SPARSE_IMAGE_MEMORY_REQUIREMENTS_2 = 1000146004, + PHYSICAL_DEVICE_FEATURES_2 = 1000059000, + PHYSICAL_DEVICE_PROPERTIES_2 = 1000059001, + FORMAT_PROPERTIES_2 = 1000059002, + IMAGE_FORMAT_PROPERTIES_2 = 1000059003, + PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2 = 1000059004, + QUEUE_FAMILY_PROPERTIES_2 = 1000059005, + PHYSICAL_DEVICE_MEMORY_PROPERTIES_2 = 1000059006, + SPARSE_IMAGE_FORMAT_PROPERTIES_2 = 1000059007, + PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2 = 1000059008, + PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES = 1000117000, + RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO = 1000117001, + IMAGE_VIEW_USAGE_CREATE_INFO = 1000117002, + PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO = 1000117003, + RENDER_PASS_MULTIVIEW_CREATE_INFO = 1000053000, + PHYSICAL_DEVICE_MULTIVIEW_FEATURES = 1000053001, + PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES = 1000053002, + PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES = 1000120000, + PROTECTED_SUBMIT_INFO = 1000145000, + PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES = 1000145001, + PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES = 1000145002, + DEVICE_QUEUE_INFO_2 = 1000145003, + SAMPLER_YCBCR_CONVERSION_CREATE_INFO = 1000156000, + SAMPLER_YCBCR_CONVERSION_INFO = 1000156001, + BIND_IMAGE_PLANE_MEMORY_INFO = 1000156002, + IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO = 1000156003, + PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES = 1000156004, + SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES = 1000156005, + DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO = 1000085000, + PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO = 1000071000, + EXTERNAL_IMAGE_FORMAT_PROPERTIES = 1000071001, + PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO = 1000071002, + EXTERNAL_BUFFER_PROPERTIES = 1000071003, + PHYSICAL_DEVICE_ID_PROPERTIES = 1000071004, + EXTERNAL_MEMORY_BUFFER_CREATE_INFO = 1000072000, + EXTERNAL_MEMORY_IMAGE_CREATE_INFO = 1000072001, + EXPORT_MEMORY_ALLOCATE_INFO = 1000072002, + PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO = 1000112000, + EXTERNAL_FENCE_PROPERTIES = 1000112001, + EXPORT_FENCE_CREATE_INFO = 1000113000, + EXPORT_SEMAPHORE_CREATE_INFO = 1000077000, + PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO = 1000076000, + EXTERNAL_SEMAPHORE_PROPERTIES = 1000076001, + PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES = 1000168000, + DESCRIPTOR_SET_LAYOUT_SUPPORT = 1000168001, + PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES = 1000063000, + PHYSICAL_DEVICE_VULKAN_1_1_FEATURES = 49, + PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES = 50, + PHYSICAL_DEVICE_VULKAN_1_2_FEATURES = 51, + PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES = 52, + IMAGE_FORMAT_LIST_CREATE_INFO = 1000147000, + ATTACHMENT_DESCRIPTION_2 = 1000109000, + ATTACHMENT_REFERENCE_2 = 1000109001, + SUBPASS_DESCRIPTION_2 = 1000109002, + SUBPASS_DEPENDENCY_2 = 1000109003, + RENDER_PASS_CREATE_INFO_2 = 1000109004, + SUBPASS_BEGIN_INFO = 1000109005, + SUBPASS_END_INFO = 1000109006, + PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES = 1000177000, + PHYSICAL_DEVICE_DRIVER_PROPERTIES = 1000196000, + PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES = 1000180000, + PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES = 1000082000, + PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES = 1000197000, + DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO = 1000161000, + PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES = 1000161001, + PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES = 1000161002, + DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO = 1000161003, + DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT = 1000161004, + PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES = 1000199000, + SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE = 1000199001, + PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES = 1000221000, + IMAGE_STENCIL_USAGE_CREATE_INFO = 1000246000, + PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES = 1000130000, + SAMPLER_REDUCTION_MODE_CREATE_INFO = 1000130001, + PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES = 1000211000, + PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES = 1000108000, + FRAMEBUFFER_ATTACHMENTS_CREATE_INFO = 1000108001, + FRAMEBUFFER_ATTACHMENT_IMAGE_INFO = 1000108002, + RENDER_PASS_ATTACHMENT_BEGIN_INFO = 1000108003, + PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES = 1000253000, + PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES = 1000175000, + PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES = 1000241000, + ATTACHMENT_REFERENCE_STENCIL_LAYOUT = 1000241001, + ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT = 1000241002, + PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES = 1000261000, + PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES = 1000207000, + PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES = 1000207001, + SEMAPHORE_TYPE_CREATE_INFO = 1000207002, + TIMELINE_SEMAPHORE_SUBMIT_INFO = 1000207003, + SEMAPHORE_WAIT_INFO = 1000207004, + SEMAPHORE_SIGNAL_INFO = 1000207005, + PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES = 1000257000, + BUFFER_DEVICE_ADDRESS_INFO = 1000244001, + BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO = 1000257002, + MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO = 1000257003, + DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO = 1000257004, + PHYSICAL_DEVICE_VULKAN_1_3_FEATURES = 53, + PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES = 54, + PIPELINE_CREATION_FEEDBACK_CREATE_INFO = 1000192000, + PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES = 1000215000, + PHYSICAL_DEVICE_TOOL_PROPERTIES = 1000245000, + PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES = 1000276000, + PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES = 1000295000, + DEVICE_PRIVATE_DATA_CREATE_INFO = 1000295001, + PRIVATE_DATA_SLOT_CREATE_INFO = 1000295002, + PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES = 1000297000, + MEMORY_BARRIER_2 = 1000314000, + BUFFER_MEMORY_BARRIER_2 = 1000314001, + IMAGE_MEMORY_BARRIER_2 = 1000314002, + DEPENDENCY_INFO = 1000314003, + SUBMIT_INFO_2 = 1000314004, + SEMAPHORE_SUBMIT_INFO = 1000314005, + COMMAND_BUFFER_SUBMIT_INFO = 1000314006, + PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES = 1000314007, + PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES = 1000325000, + PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES = 1000335000, + COPY_BUFFER_INFO_2 = 1000337000, + COPY_IMAGE_INFO_2 = 1000337001, + COPY_BUFFER_TO_IMAGE_INFO_2 = 1000337002, + COPY_IMAGE_TO_BUFFER_INFO_2 = 1000337003, + BLIT_IMAGE_INFO_2 = 1000337004, + RESOLVE_IMAGE_INFO_2 = 1000337005, + BUFFER_COPY_2 = 1000337006, + IMAGE_COPY_2 = 1000337007, + IMAGE_BLIT_2 = 1000337008, + BUFFER_IMAGE_COPY_2 = 1000337009, + IMAGE_RESOLVE_2 = 1000337010, + PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES = 1000225000, + PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO = 1000225001, + PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES = 1000225002, + PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES = 1000138000, + PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES = 1000138001, + WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK = 1000138002, + DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO = 1000138003, + PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES = 1000066000, + RENDERING_INFO = 1000044000, + RENDERING_ATTACHMENT_INFO = 1000044001, + PIPELINE_RENDERING_CREATE_INFO = 1000044002, + PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES = 1000044003, + COMMAND_BUFFER_INHERITANCE_RENDERING_INFO = 1000044004, + PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES = 1000280000, + PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES = 1000280001, + PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES = 1000281001, + FORMAT_PROPERTIES_3 = 1000360000, + PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES = 1000413000, + PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES = 1000413001, + DEVICE_BUFFER_MEMORY_REQUIREMENTS = 1000413002, + DEVICE_IMAGE_MEMORY_REQUIREMENTS = 1000413003, + SWAPCHAIN_CREATE_INFO_KHR = 1000001000, + PRESENT_INFO_KHR = 1000001001, + DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007, + IMAGE_SWAPCHAIN_CREATE_INFO_KHR = 1000060008, + BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR = 1000060009, + ACQUIRE_NEXT_IMAGE_INFO_KHR = 1000060010, + DEVICE_GROUP_PRESENT_INFO_KHR = 1000060011, + DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR = 1000060012, + DISPLAY_MODE_CREATE_INFO_KHR = 1000002000, + DISPLAY_SURFACE_CREATE_INFO_KHR = 1000002001, + DISPLAY_PRESENT_INFO_KHR = 1000003000, + XLIB_SURFACE_CREATE_INFO_KHR = 1000004000, + XCB_SURFACE_CREATE_INFO_KHR = 1000005000, + WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000, + ANDROID_SURFACE_CREATE_INFO_KHR = 1000008000, + WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, + DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000, + PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD = 1000018000, + DEBUG_MARKER_OBJECT_NAME_INFO_EXT = 1000022000, + DEBUG_MARKER_OBJECT_TAG_INFO_EXT = 1000022001, + DEBUG_MARKER_MARKER_INFO_EXT = 1000022002, + VIDEO_PROFILE_KHR = 1000023000, + VIDEO_CAPABILITIES_KHR = 1000023001, + VIDEO_PICTURE_RESOURCE_KHR = 1000023002, + VIDEO_GET_MEMORY_PROPERTIES_KHR = 1000023003, + VIDEO_BIND_MEMORY_KHR = 1000023004, + VIDEO_SESSION_CREATE_INFO_KHR = 1000023005, + VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR = 1000023006, + VIDEO_SESSION_PARAMETERS_UPDATE_INFO_KHR = 1000023007, + VIDEO_BEGIN_CODING_INFO_KHR = 1000023008, + VIDEO_END_CODING_INFO_KHR = 1000023009, + VIDEO_CODING_CONTROL_INFO_KHR = 1000023010, + VIDEO_REFERENCE_SLOT_KHR = 1000023011, + VIDEO_QUEUE_FAMILY_PROPERTIES_2_KHR = 1000023012, + VIDEO_PROFILES_KHR = 1000023013, + PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR = 1000023014, + VIDEO_FORMAT_PROPERTIES_KHR = 1000023015, + QUEUE_FAMILY_QUERY_RESULT_STATUS_PROPERTIES_2_KHR = 1000023016, + VIDEO_DECODE_INFO_KHR = 1000024000, + VIDEO_DECODE_CAPABILITIES_KHR = 1000024001, + DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000, + DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001, + DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002, + PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT = 1000028000, + PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT = 1000028001, + PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT = 1000028002, + CU_MODULE_CREATE_INFO_NVX = 1000029000, + CU_FUNCTION_CREATE_INFO_NVX = 1000029001, + CU_LAUNCH_INFO_NVX = 1000029002, + IMAGE_VIEW_HANDLE_INFO_NVX = 1000030000, + IMAGE_VIEW_ADDRESS_PROPERTIES_NVX = 1000030001, + VIDEO_ENCODE_H264_CAPABILITIES_EXT = 1000038000, + VIDEO_ENCODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000038001, + VIDEO_ENCODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000038002, + VIDEO_ENCODE_H264_VCL_FRAME_INFO_EXT = 1000038003, + VIDEO_ENCODE_H264_DPB_SLOT_INFO_EXT = 1000038004, + VIDEO_ENCODE_H264_NALU_SLICE_EXT = 1000038005, + VIDEO_ENCODE_H264_EMIT_PICTURE_PARAMETERS_EXT = 1000038006, + VIDEO_ENCODE_H264_PROFILE_EXT = 1000038007, + VIDEO_ENCODE_H264_RATE_CONTROL_INFO_EXT = 1000038008, + VIDEO_ENCODE_H264_RATE_CONTROL_LAYER_INFO_EXT = 1000038009, + VIDEO_ENCODE_H264_REFERENCE_LISTS_EXT = 1000038010, + VIDEO_ENCODE_H265_CAPABILITIES_EXT = 1000039000, + VIDEO_ENCODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000039001, + VIDEO_ENCODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT = 1000039002, + VIDEO_ENCODE_H265_VCL_FRAME_INFO_EXT = 1000039003, + VIDEO_ENCODE_H265_DPB_SLOT_INFO_EXT = 1000039004, + VIDEO_ENCODE_H265_NALU_SLICE_SEGMENT_EXT = 1000039005, + VIDEO_ENCODE_H265_EMIT_PICTURE_PARAMETERS_EXT = 1000039006, + VIDEO_ENCODE_H265_PROFILE_EXT = 1000039007, + VIDEO_ENCODE_H265_REFERENCE_LISTS_EXT = 1000039008, + VIDEO_ENCODE_H265_RATE_CONTROL_INFO_EXT = 1000039009, + VIDEO_ENCODE_H265_RATE_CONTROL_LAYER_INFO_EXT = 1000039010, + VIDEO_DECODE_H264_CAPABILITIES_EXT = 1000040000, + VIDEO_DECODE_H264_PICTURE_INFO_EXT = 1000040001, + VIDEO_DECODE_H264_MVC_EXT = 1000040002, + VIDEO_DECODE_H264_PROFILE_EXT = 1000040003, + VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000040004, + VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000040005, + VIDEO_DECODE_H264_DPB_SLOT_INFO_EXT = 1000040006, + TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000, + RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000044006, + RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_INFO_EXT = 1000044007, + ATTACHMENT_SAMPLE_COUNT_INFO_AMD = 1000044008, + MULTIVIEW_PER_VIEW_ATTRIBUTES_INFO_NVX = 1000044009, + STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP = 1000049000, + PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV = 1000050000, + EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV = 1000056000, + EXPORT_MEMORY_ALLOCATE_INFO_NV = 1000056001, + IMPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057000, + EXPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057001, + WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV = 1000058000, + VALIDATION_FLAGS_EXT = 1000061000, + VI_SURFACE_CREATE_INFO_NN = 1000062000, + IMAGE_VIEW_ASTC_DECODE_MODE_EXT = 1000067000, + PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT = 1000067001, + IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073000, + EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073001, + MEMORY_WIN32_HANDLE_PROPERTIES_KHR = 1000073002, + MEMORY_GET_WIN32_HANDLE_INFO_KHR = 1000073003, + IMPORT_MEMORY_FD_INFO_KHR = 1000074000, + MEMORY_FD_PROPERTIES_KHR = 1000074001, + MEMORY_GET_FD_INFO_KHR = 1000074002, + WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR = 1000075000, + IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078000, + EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078001, + D3D12_FENCE_SUBMIT_INFO_KHR = 1000078002, + SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR = 1000078003, + IMPORT_SEMAPHORE_FD_INFO_KHR = 1000079000, + SEMAPHORE_GET_FD_INFO_KHR = 1000079001, + PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR = 1000080000, + COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT = 1000081000, + PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT = 1000081001, + CONDITIONAL_RENDERING_BEGIN_INFO_EXT = 1000081002, + PRESENT_REGIONS_KHR = 1000084000, + PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV = 1000087000, + SURFACE_CAPABILITIES_2_EXT = 1000090000, + DISPLAY_POWER_INFO_EXT = 1000091000, + DEVICE_EVENT_INFO_EXT = 1000091001, + DISPLAY_EVENT_INFO_EXT = 1000091002, + SWAPCHAIN_COUNTER_CREATE_INFO_EXT = 1000091003, + PRESENT_TIMES_INFO_GOOGLE = 1000092000, + PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_ATTRIBUTES_PROPERTIES_NVX = 1000097000, + PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV = 1000098000, + PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT = 1000099000, + PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT = 1000099001, + PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT = 1000101000, + PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT = 1000101001, + PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT = 1000102000, + PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT = 1000102001, + HDR_METADATA_EXT = 1000105000, + SHARED_PRESENT_SURFACE_CAPABILITIES_KHR = 1000111000, + IMPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114000, + EXPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114001, + FENCE_GET_WIN32_HANDLE_INFO_KHR = 1000114002, + IMPORT_FENCE_FD_INFO_KHR = 1000115000, + FENCE_GET_FD_INFO_KHR = 1000115001, + PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR = 1000116000, + PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR = 1000116001, + QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR = 1000116002, + PERFORMANCE_QUERY_SUBMIT_INFO_KHR = 1000116003, + ACQUIRE_PROFILING_LOCK_INFO_KHR = 1000116004, + PERFORMANCE_COUNTER_KHR = 1000116005, + PERFORMANCE_COUNTER_DESCRIPTION_KHR = 1000116006, + PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000, + SURFACE_CAPABILITIES_2_KHR = 1000119001, + SURFACE_FORMAT_2_KHR = 1000119002, + DISPLAY_PROPERTIES_2_KHR = 1000121000, + DISPLAY_PLANE_PROPERTIES_2_KHR = 1000121001, + DISPLAY_MODE_PROPERTIES_2_KHR = 1000121002, + DISPLAY_PLANE_INFO_2_KHR = 1000121003, + DISPLAY_PLANE_CAPABILITIES_2_KHR = 1000121004, + IOS_SURFACE_CREATE_INFO_MVK = 1000122000, + MACOS_SURFACE_CREATE_INFO_MVK = 1000123000, + DEBUG_UTILS_OBJECT_NAME_INFO_EXT = 1000128000, + DEBUG_UTILS_OBJECT_TAG_INFO_EXT = 1000128001, + DEBUG_UTILS_LABEL_EXT = 1000128002, + DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT = 1000128003, + DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT = 1000128004, + ANDROID_HARDWARE_BUFFER_USAGE_ANDROID = 1000129000, + ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID = 1000129001, + ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID = 1000129002, + IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129003, + MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129004, + EXTERNAL_FORMAT_ANDROID = 1000129005, + ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID = 1000129006, + SAMPLE_LOCATIONS_INFO_EXT = 1000143000, + RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT = 1000143001, + PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002, + PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT = 1000143003, + MULTISAMPLE_PROPERTIES_EXT = 1000143004, + PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT = 1000148000, + PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT = 1000148001, + PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT = 1000148002, + PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV = 1000149000, + WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR = 1000150007, + ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR = 1000150000, + ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR = 1000150002, + ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR = 1000150003, + ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR = 1000150004, + ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR = 1000150005, + ACCELERATION_STRUCTURE_GEOMETRY_KHR = 1000150006, + ACCELERATION_STRUCTURE_VERSION_INFO_KHR = 1000150009, + COPY_ACCELERATION_STRUCTURE_INFO_KHR = 1000150010, + COPY_ACCELERATION_STRUCTURE_TO_MEMORY_INFO_KHR = 1000150011, + COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR = 1000150012, + PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR = 1000150013, + PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR = 1000150014, + ACCELERATION_STRUCTURE_CREATE_INFO_KHR = 1000150017, + ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR = 1000150020, + PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR = 1000347000, + PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR = 1000347001, + RAY_TRACING_PIPELINE_CREATE_INFO_KHR = 1000150015, + RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR = 1000150016, + RAY_TRACING_PIPELINE_INTERFACE_CREATE_INFO_KHR = 1000150018, + PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR = 1000348013, + PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV = 1000152000, + PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV = 1000154000, + PHYSICAL_DEVICE_SHADER_SM_BUILTINS_PROPERTIES_NV = 1000154001, + DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT = 1000158000, + PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT = 1000158002, + IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT = 1000158003, + IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT = 1000158004, + IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT = 1000158005, + DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT = 1000158006, + VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000, + SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001, + PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR = 1000163000, + PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR = 1000163001, + PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV = 1000164000, + PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV = 1000164001, + PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV = 1000164002, + PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV = 1000164005, + RAY_TRACING_PIPELINE_CREATE_INFO_NV = 1000165000, + ACCELERATION_STRUCTURE_CREATE_INFO_NV = 1000165001, + GEOMETRY_NV = 1000165003, + GEOMETRY_TRIANGLES_NV = 1000165004, + GEOMETRY_AABB_NV = 1000165005, + BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV = 1000165006, + WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV = 1000165007, + ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV = 1000165008, + PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV = 1000165009, + RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV = 1000165011, + ACCELERATION_STRUCTURE_INFO_NV = 1000165012, + PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV = 1000166000, + PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV = 1000166001, + PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT = 1000170000, + FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT = 1000170001, + IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000, + MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001, + PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002, + PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR = 1000181000, + PIPELINE_COMPILER_CONTROL_CREATE_INFO_AMD = 1000183000, + CALIBRATED_TIMESTAMP_INFO_EXT = 1000184000, + PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD = 1000185000, + VIDEO_DECODE_H265_CAPABILITIES_EXT = 1000187000, + VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000187001, + VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT = 1000187002, + VIDEO_DECODE_H265_PROFILE_EXT = 1000187003, + VIDEO_DECODE_H265_PICTURE_INFO_EXT = 1000187004, + VIDEO_DECODE_H265_DPB_SLOT_INFO_EXT = 1000187005, + DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR = 1000174000, + PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR = 1000388000, + QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR = 1000388001, + DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD = 1000189000, + PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000, + PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = 1000190001, + PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = 1000190002, + PRESENT_FRAME_TOKEN_GGP = 1000191000, + PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000, + PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000, + PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001, + PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV = 1000203000, + PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV = 1000204000, + PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV = 1000205000, + PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV = 1000205002, + CHECKPOINT_DATA_NV = 1000206000, + QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV = 1000206001, + PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL = 1000209000, + QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL = 1000210000, + INITIALIZE_PERFORMANCE_API_INFO_INTEL = 1000210001, + PERFORMANCE_MARKER_INFO_INTEL = 1000210002, + PERFORMANCE_STREAM_MARKER_INFO_INTEL = 1000210003, + PERFORMANCE_OVERRIDE_INFO_INTEL = 1000210004, + PERFORMANCE_CONFIGURATION_ACQUIRE_INFO_INTEL = 1000210005, + PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000, + DISPLAY_NATIVE_HDR_SURFACE_CAPABILITIES_AMD = 1000213000, + SWAPCHAIN_DISPLAY_NATIVE_HDR_CREATE_INFO_AMD = 1000213001, + IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000, + METAL_SURFACE_CREATE_INFO_EXT = 1000217000, + PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000, + PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001, + RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002, + FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000226000, + PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR = 1000226001, + PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR = 1000226002, + PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR = 1000226003, + PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR = 1000226004, + PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD = 1000227000, + PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD = 1000229000, + PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT = 1000234000, + PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT = 1000237000, + PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT = 1000238000, + MEMORY_PRIORITY_ALLOCATE_INFO_EXT = 1000238001, + SURFACE_PROTECTED_CAPABILITIES_KHR = 1000239000, + PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV = 1000240000, + PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT = 1000244000, + BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002, + VALIDATION_FEATURES_EXT = 1000247000, + PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR = 1000248000, + PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV = 1000249000, + COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249001, + PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249002, + PHYSICAL_DEVICE_COVERAGE_REDUCTION_MODE_FEATURES_NV = 1000250000, + PIPELINE_COVERAGE_REDUCTION_STATE_CREATE_INFO_NV = 1000250001, + FRAMEBUFFER_MIXED_SAMPLES_COMBINATION_NV = 1000250002, + PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT = 1000251000, + PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT = 1000252000, + PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT = 1000254000, + PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT = 1000254001, + PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT = 1000254002, + SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT = 1000255000, + SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT = 1000255002, + SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT = 1000255001, + HEADLESS_SURFACE_CREATE_INFO_EXT = 1000256000, + PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT = 1000259000, + PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT = 1000259001, + PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT = 1000259002, + PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT = 1000260000, + PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT = 1000265000, + PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT = 1000267000, + PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR = 1000269000, + PIPELINE_INFO_KHR = 1000269001, + PIPELINE_EXECUTABLE_PROPERTIES_KHR = 1000269002, + PIPELINE_EXECUTABLE_INFO_KHR = 1000269003, + PIPELINE_EXECUTABLE_STATISTIC_KHR = 1000269004, + PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR = 1000269005, + PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT = 1000273000, + PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV = 1000277000, + GRAPHICS_SHADER_GROUP_CREATE_INFO_NV = 1000277001, + GRAPHICS_PIPELINE_SHADER_GROUPS_CREATE_INFO_NV = 1000277002, + INDIRECT_COMMANDS_LAYOUT_TOKEN_NV = 1000277003, + INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NV = 1000277004, + GENERATED_COMMANDS_INFO_NV = 1000277005, + GENERATED_COMMANDS_MEMORY_REQUIREMENTS_INFO_NV = 1000277006, + PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV = 1000277007, + PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV = 1000278000, + COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV = 1000278001, + PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT = 1000281000, + COMMAND_BUFFER_INHERITANCE_RENDER_PASS_TRANSFORM_INFO_QCOM = 1000282000, + RENDER_PASS_TRANSFORM_BEGIN_INFO_QCOM = 1000282001, + PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT = 1000284000, + DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT = 1000284001, + DEVICE_MEMORY_REPORT_CALLBACK_DATA_EXT = 1000284002, + PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT = 1000286000, + PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT = 1000286001, + SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT = 1000287000, + PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT = 1000287001, + PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT = 1000287002, + PIPELINE_LIBRARY_CREATE_INFO_KHR = 1000290000, + PRESENT_ID_KHR = 1000294000, + PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR = 1000294001, + VIDEO_ENCODE_INFO_KHR = 1000299000, + VIDEO_ENCODE_RATE_CONTROL_INFO_KHR = 1000299001, + VIDEO_ENCODE_RATE_CONTROL_LAYER_INFO_KHR = 1000299002, + VIDEO_ENCODE_CAPABILITIES_KHR = 1000299003, + PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV = 1000300000, + DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV = 1000300001, + QUEUE_FAMILY_CHECKPOINT_PROPERTIES_2_NV = 1000314008, + CHECKPOINT_DATA_2_NV = 1000314009, + PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT = 1000320000, + PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT = 1000320001, + GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT = 1000320002, + PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR = 1000323000, + PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_PROPERTIES_NV = 1000326000, + PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_FEATURES_NV = 1000326001, + PIPELINE_FRAGMENT_SHADING_RATE_ENUM_STATE_CREATE_INFO_NV = 1000326002, + ACCELERATION_STRUCTURE_GEOMETRY_MOTION_TRIANGLES_DATA_NV = 1000327000, + PHYSICAL_DEVICE_RAY_TRACING_MOTION_BLUR_FEATURES_NV = 1000327001, + ACCELERATION_STRUCTURE_MOTION_INFO_NV = 1000327002, + PHYSICAL_DEVICE_YCBCR_2_PLANE_444_FORMATS_FEATURES_EXT = 1000330000, + PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT = 1000332000, + PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_PROPERTIES_EXT = 1000332001, + COPY_COMMAND_TRANSFORM_INFO_QCOM = 1000333000, + PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR = 1000336000, + PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT = 1000340000, + PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_ARM = 1000342000, + PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT = 1000344000, + DIRECTFB_SURFACE_CREATE_INFO_EXT = 1000346000, + PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_VALVE = 1000351000, + MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE = 1000351002, + PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT = 1000352000, + VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT = 1000352001, + VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT = 1000352002, + PHYSICAL_DEVICE_DRM_PROPERTIES_EXT = 1000353000, + PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT = 1000355000, + PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT = 1000355001, + PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT = 1000356000, + IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364000, + MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA = 1000364001, + MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364002, + IMPORT_SEMAPHORE_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365000, + SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365001, + BUFFER_COLLECTION_CREATE_INFO_FUCHSIA = 1000366000, + IMPORT_MEMORY_BUFFER_COLLECTION_FUCHSIA = 1000366001, + BUFFER_COLLECTION_IMAGE_CREATE_INFO_FUCHSIA = 1000366002, + BUFFER_COLLECTION_PROPERTIES_FUCHSIA = 1000366003, + BUFFER_CONSTRAINTS_INFO_FUCHSIA = 1000366004, + BUFFER_COLLECTION_BUFFER_CREATE_INFO_FUCHSIA = 1000366005, + IMAGE_CONSTRAINTS_INFO_FUCHSIA = 1000366006, + IMAGE_FORMAT_CONSTRAINTS_INFO_FUCHSIA = 1000366007, + SYSMEM_COLOR_SPACE_FUCHSIA = 1000366008, + BUFFER_COLLECTION_CONSTRAINTS_INFO_FUCHSIA = 1000366009, + SUBPASS_SHADING_PIPELINE_CREATE_INFO_HUAWEI = 1000369000, + PHYSICAL_DEVICE_SUBPASS_SHADING_FEATURES_HUAWEI = 1000369001, + PHYSICAL_DEVICE_SUBPASS_SHADING_PROPERTIES_HUAWEI = 1000369002, + PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI = 1000370000, + MEMORY_GET_REMOTE_ADDRESS_INFO_NV = 1000371000, + PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV = 1000371001, + PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT = 1000377000, + SCREEN_SURFACE_CREATE_INFO_QNX = 1000378000, + PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT = 1000381000, + PIPELINE_COLOR_WRITE_CREATE_INFO_EXT = 1000381001, + PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT = 1000382000, + PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT = 1000391000, + IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT = 1000391001, + PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT = 1000392000, + PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT = 1000392001, + PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT = 1000393000, + PHYSICAL_DEVICE_BORDER_COLOR_SWIZZLE_FEATURES_EXT = 1000411000, + SAMPLER_BORDER_COLOR_COMPONENT_MAPPING_CREATE_INFO_EXT = 1000411001, + PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT = 1000412000, + PHYSICAL_DEVICE_DESCRIPTOR_SET_HOST_MAPPING_FEATURES_VALVE = 1000420000, + DESCRIPTOR_SET_BINDING_REFERENCE_VALVE = 1000420001, + DESCRIPTOR_SET_LAYOUT_HOST_MAPPING_INFO_VALVE = 1000420002, + PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_QCOM = 1000425000, + PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_PROPERTIES_QCOM = 1000425001, + SUBPASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_QCOM = 1000425002, + PHYSICAL_DEVICE_LINEAR_COLOR_ATTACHMENT_FEATURES_NV = 1000430000, + PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, + PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, + DEBUG_REPORT_CREATE_INFO_EXT = DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, + RENDERING_INFO_KHR = RENDERING_INFO, + RENDERING_ATTACHMENT_INFO_KHR = RENDERING_ATTACHMENT_INFO, + PIPELINE_RENDERING_CREATE_INFO_KHR = PIPELINE_RENDERING_CREATE_INFO, + PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR = PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, + COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR = COMMAND_BUFFER_INHERITANCE_RENDERING_INFO, + ATTACHMENT_SAMPLE_COUNT_INFO_NV = ATTACHMENT_SAMPLE_COUNT_INFO_AMD, + RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR = RENDER_PASS_MULTIVIEW_CREATE_INFO, + PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR = PHYSICAL_DEVICE_MULTIVIEW_FEATURES, + PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR = PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES, + PHYSICAL_DEVICE_FEATURES_2_KHR = PHYSICAL_DEVICE_FEATURES_2, + PHYSICAL_DEVICE_PROPERTIES_2_KHR = PHYSICAL_DEVICE_PROPERTIES_2, + FORMAT_PROPERTIES_2_KHR = FORMAT_PROPERTIES_2, + IMAGE_FORMAT_PROPERTIES_2_KHR = IMAGE_FORMAT_PROPERTIES_2, + PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR = PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, + QUEUE_FAMILY_PROPERTIES_2_KHR = QUEUE_FAMILY_PROPERTIES_2, + PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR = PHYSICAL_DEVICE_MEMORY_PROPERTIES_2, + SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR = SPARSE_IMAGE_FORMAT_PROPERTIES_2, + PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2_KHR = PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2, + MEMORY_ALLOCATE_FLAGS_INFO_KHR = MEMORY_ALLOCATE_FLAGS_INFO, + DEVICE_GROUP_RENDER_PASS_BEGIN_INFO_KHR = DEVICE_GROUP_RENDER_PASS_BEGIN_INFO, + DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO_KHR = DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO, + DEVICE_GROUP_SUBMIT_INFO_KHR = DEVICE_GROUP_SUBMIT_INFO, + DEVICE_GROUP_BIND_SPARSE_INFO_KHR = DEVICE_GROUP_BIND_SPARSE_INFO, + BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO_KHR = BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO, + BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO_KHR = BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO, + PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT = PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES, + PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR = PHYSICAL_DEVICE_GROUP_PROPERTIES, + DEVICE_GROUP_DEVICE_CREATE_INFO_KHR = DEVICE_GROUP_DEVICE_CREATE_INFO, + PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR = PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, + EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR = EXTERNAL_IMAGE_FORMAT_PROPERTIES, + PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR = PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO, + EXTERNAL_BUFFER_PROPERTIES_KHR = EXTERNAL_BUFFER_PROPERTIES, + PHYSICAL_DEVICE_ID_PROPERTIES_KHR = PHYSICAL_DEVICE_ID_PROPERTIES, + EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR = EXTERNAL_MEMORY_BUFFER_CREATE_INFO, + EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR = EXTERNAL_MEMORY_IMAGE_CREATE_INFO, + EXPORT_MEMORY_ALLOCATE_INFO_KHR = EXPORT_MEMORY_ALLOCATE_INFO, + PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR = PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO, + EXTERNAL_SEMAPHORE_PROPERTIES_KHR = EXTERNAL_SEMAPHORE_PROPERTIES, + EXPORT_SEMAPHORE_CREATE_INFO_KHR = EXPORT_SEMAPHORE_CREATE_INFO, + PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR = PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, + PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR = PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, + PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR = PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, + DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR = DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO, + SURFACE_CAPABILITIES2_EXT = SURFACE_CAPABILITIES_2_EXT, + PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR = PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES, + FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR = FRAMEBUFFER_ATTACHMENTS_CREATE_INFO, + FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR = FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, + RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR = RENDER_PASS_ATTACHMENT_BEGIN_INFO, + ATTACHMENT_DESCRIPTION_2_KHR = ATTACHMENT_DESCRIPTION_2, + ATTACHMENT_REFERENCE_2_KHR = ATTACHMENT_REFERENCE_2, + SUBPASS_DESCRIPTION_2_KHR = SUBPASS_DESCRIPTION_2, + SUBPASS_DEPENDENCY_2_KHR = SUBPASS_DEPENDENCY_2, + RENDER_PASS_CREATE_INFO_2_KHR = RENDER_PASS_CREATE_INFO_2, + SUBPASS_BEGIN_INFO_KHR = SUBPASS_BEGIN_INFO, + SUBPASS_END_INFO_KHR = SUBPASS_END_INFO, + PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR = PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO, + EXTERNAL_FENCE_PROPERTIES_KHR = EXTERNAL_FENCE_PROPERTIES, + EXPORT_FENCE_CREATE_INFO_KHR = EXPORT_FENCE_CREATE_INFO, + PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES_KHR = PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES, + RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_KHR = RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO, + IMAGE_VIEW_USAGE_CREATE_INFO_KHR = IMAGE_VIEW_USAGE_CREATE_INFO, + PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO_KHR = PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO, + PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR = PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, + PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR = PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR, + MEMORY_DEDICATED_REQUIREMENTS_KHR = MEMORY_DEDICATED_REQUIREMENTS, + MEMORY_DEDICATED_ALLOCATE_INFO_KHR = MEMORY_DEDICATED_ALLOCATE_INFO, + PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES, + SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = SAMPLER_REDUCTION_MODE_CREATE_INFO, + PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES, + PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES, + WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK, + DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT = DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO, + BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = BUFFER_MEMORY_REQUIREMENTS_INFO_2, + IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = IMAGE_MEMORY_REQUIREMENTS_INFO_2, + IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR = IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2, + MEMORY_REQUIREMENTS_2_KHR = MEMORY_REQUIREMENTS_2, + SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR = SPARSE_IMAGE_MEMORY_REQUIREMENTS_2, + IMAGE_FORMAT_LIST_CREATE_INFO_KHR = IMAGE_FORMAT_LIST_CREATE_INFO, + SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR = SAMPLER_YCBCR_CONVERSION_CREATE_INFO, + SAMPLER_YCBCR_CONVERSION_INFO_KHR = SAMPLER_YCBCR_CONVERSION_INFO, + BIND_IMAGE_PLANE_MEMORY_INFO_KHR = BIND_IMAGE_PLANE_MEMORY_INFO, + IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR = IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO, + PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR = PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES, + SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES_KHR = SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES, + BIND_BUFFER_MEMORY_INFO_KHR = BIND_BUFFER_MEMORY_INFO, + BIND_IMAGE_MEMORY_INFO_KHR = BIND_IMAGE_MEMORY_INFO, + DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, + PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, + PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES, + DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO, + DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT, + PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR = PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, + DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR = DESCRIPTOR_SET_LAYOUT_SUPPORT, + DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR, + PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR = PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES, + PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES, + PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, + PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT = PIPELINE_CREATION_FEEDBACK_CREATE_INFO, + PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = PHYSICAL_DEVICE_DRIVER_PROPERTIES, + PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES, + PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES, + SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR = SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE, + PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR = PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, + PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR = PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES, + SEMAPHORE_TYPE_CREATE_INFO_KHR = SEMAPHORE_TYPE_CREATE_INFO, + TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR = TIMELINE_SEMAPHORE_SUBMIT_INFO, + SEMAPHORE_WAIT_INFO_KHR = SEMAPHORE_WAIT_INFO, + SEMAPHORE_SIGNAL_INFO_KHR = SEMAPHORE_SIGNAL_INFO, + QUERY_POOL_CREATE_INFO_INTEL = QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL, + PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES, + PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR = PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES, + PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES, + PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT = PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES, + PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO, + PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT = PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES, + PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR = PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, + ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR = ATTACHMENT_REFERENCE_STENCIL_LAYOUT, + ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR = ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT, + PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT = PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT, + BUFFER_DEVICE_ADDRESS_INFO_EXT = BUFFER_DEVICE_ADDRESS_INFO, + PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = PHYSICAL_DEVICE_TOOL_PROPERTIES, + IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = IMAGE_STENCIL_USAGE_CREATE_INFO, + PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR = PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, + PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR = PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES, + BUFFER_DEVICE_ADDRESS_INFO_KHR = BUFFER_DEVICE_ADDRESS_INFO, + BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR = BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO, + MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR = MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO, + DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR = DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO, + PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT = PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, + PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES, + PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR = PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES, + PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR = PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES, + PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES, + PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT = PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES, + DEVICE_PRIVATE_DATA_CREATE_INFO_EXT = DEVICE_PRIVATE_DATA_CREATE_INFO, + PRIVATE_DATA_SLOT_CREATE_INFO_EXT = PRIVATE_DATA_SLOT_CREATE_INFO, + PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT = PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES, + MEMORY_BARRIER_2_KHR = MEMORY_BARRIER_2, + BUFFER_MEMORY_BARRIER_2_KHR = BUFFER_MEMORY_BARRIER_2, + IMAGE_MEMORY_BARRIER_2_KHR = IMAGE_MEMORY_BARRIER_2, + DEPENDENCY_INFO_KHR = DEPENDENCY_INFO, + SUBMIT_INFO_2_KHR = SUBMIT_INFO_2, + SEMAPHORE_SUBMIT_INFO_KHR = SEMAPHORE_SUBMIT_INFO, + COMMAND_BUFFER_SUBMIT_INFO_KHR = COMMAND_BUFFER_SUBMIT_INFO, + PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR = PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES, + PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES_KHR = PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES, + PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT = PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES, + COPY_BUFFER_INFO_2_KHR = COPY_BUFFER_INFO_2, + COPY_IMAGE_INFO_2_KHR = COPY_IMAGE_INFO_2, + COPY_BUFFER_TO_IMAGE_INFO_2_KHR = COPY_BUFFER_TO_IMAGE_INFO_2, + COPY_IMAGE_TO_BUFFER_INFO_2_KHR = COPY_IMAGE_TO_BUFFER_INFO_2, + BLIT_IMAGE_INFO_2_KHR = BLIT_IMAGE_INFO_2, + RESOLVE_IMAGE_INFO_2_KHR = RESOLVE_IMAGE_INFO_2, + BUFFER_COPY_2_KHR = BUFFER_COPY_2, + IMAGE_COPY_2_KHR = IMAGE_COPY_2, + IMAGE_BLIT_2_KHR = IMAGE_BLIT_2, + BUFFER_IMAGE_COPY_2_KHR = BUFFER_IMAGE_COPY_2, + IMAGE_RESOLVE_2_KHR = IMAGE_RESOLVE_2, + FORMAT_PROPERTIES_3_KHR = FORMAT_PROPERTIES_3, + PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT = PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR, + QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT = QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR, + PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR = PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES, + PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR = PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES, + DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR = DEVICE_BUFFER_MEMORY_REQUIREMENTS, + DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR = DEVICE_IMAGE_MEMORY_REQUIREMENTS, } SubgroupFeatureFlags :: distinct bit_set[SubgroupFeatureFlag; Flags] @@ -2737,9 +2961,10 @@ SubgroupFeatureFlag :: enum Flags { PARTITIONED_NV = 8, } -SubmitFlagsKHR :: distinct bit_set[SubmitFlagKHR; Flags] -SubmitFlagKHR :: enum Flags { - PROTECTED = 0, +SubmitFlags :: distinct bit_set[SubmitFlag; Flags] +SubmitFlag :: enum Flags { + PROTECTED = 0, + PROTECTED_KHR = PROTECTED, } SubpassContents :: enum c.int { @@ -2749,10 +2974,13 @@ SubpassContents :: enum c.int { SubpassDescriptionFlags :: distinct bit_set[SubpassDescriptionFlag; Flags] SubpassDescriptionFlag :: enum Flags { - PER_VIEW_ATTRIBUTES_NVX = 0, - PER_VIEW_POSITION_X_ONLY_NVX = 1, - FRAGMENT_REGION_QCOM = 2, - SHADER_RESOLVE_QCOM = 3, + PER_VIEW_ATTRIBUTES_NVX = 0, + PER_VIEW_POSITION_X_ONLY_NVX = 1, + FRAGMENT_REGION_QCOM = 2, + SHADER_RESOLVE_QCOM = 3, + RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_ARM = 4, + RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_ARM = 5, + RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_ARM = 6, } SurfaceCounterFlagsEXT :: distinct bit_set[SurfaceCounterFlagEXT; Flags] @@ -2802,15 +3030,20 @@ TimeDomainEXT :: enum c.int { QUERY_PERFORMANCE_COUNTER = 3, } -ToolPurposeFlagsEXT :: distinct bit_set[ToolPurposeFlagEXT; Flags] -ToolPurposeFlagEXT :: enum Flags { - VALIDATION = 0, - PROFILING = 1, - TRACING = 2, - ADDITIONAL_FEATURES = 3, - MODIFYING_FEATURES = 4, - DEBUG_REPORTING = 5, - DEBUG_MARKERS = 6, +ToolPurposeFlags :: distinct bit_set[ToolPurposeFlag; Flags] +ToolPurposeFlag :: enum Flags { + VALIDATION = 0, + PROFILING = 1, + TRACING = 2, + ADDITIONAL_FEATURES = 3, + MODIFYING_FEATURES = 4, + DEBUG_REPORTING_EXT = 5, + DEBUG_MARKERS_EXT = 6, + VALIDATION_EXT = VALIDATION, + PROFILING_EXT = PROFILING, + TRACING_EXT = TRACING, + ADDITIONAL_FEATURES_EXT = ADDITIONAL_FEATURES, + MODIFYING_FEATURES_EXT = MODIFYING_FEATURES, } ValidationCacheHeaderVersionEXT :: enum c.int { @@ -2894,32 +3127,24 @@ HeadlessSurfaceCreateFlagsEXT :: distinct bit_set[Headles HeadlessSurfaceCreateFlagEXT :: enum u32 {} IOSSurfaceCreateFlagsMVK :: distinct bit_set[IOSSurfaceCreateFlagMVK; Flags] IOSSurfaceCreateFlagMVK :: enum u32 {} -InstanceCreateFlags :: distinct bit_set[InstanceCreateFlag; Flags] -InstanceCreateFlag :: enum u32 {} MacOSSurfaceCreateFlagsMVK :: distinct bit_set[MacOSSurfaceCreateFlagMVK; Flags] MacOSSurfaceCreateFlagMVK :: enum u32 {} MemoryMapFlags :: distinct bit_set[MemoryMapFlag; Flags] MemoryMapFlag :: enum u32 {} MetalSurfaceCreateFlagsEXT :: distinct bit_set[MetalSurfaceCreateFlagEXT; Flags] MetalSurfaceCreateFlagEXT :: enum u32 {} -PipelineColorBlendStateCreateFlags :: distinct bit_set[PipelineColorBlendStateCreateFlag; Flags] -PipelineColorBlendStateCreateFlag :: enum u32 {} PipelineCoverageModulationStateCreateFlagsNV :: distinct bit_set[PipelineCoverageModulationStateCreateFlagNV; Flags] PipelineCoverageModulationStateCreateFlagNV :: enum u32 {} PipelineCoverageReductionStateCreateFlagsNV :: distinct bit_set[PipelineCoverageReductionStateCreateFlagNV; Flags] PipelineCoverageReductionStateCreateFlagNV :: enum u32 {} PipelineCoverageToColorStateCreateFlagsNV :: distinct bit_set[PipelineCoverageToColorStateCreateFlagNV; Flags] PipelineCoverageToColorStateCreateFlagNV :: enum u32 {} -PipelineDepthStencilStateCreateFlags :: distinct bit_set[PipelineDepthStencilStateCreateFlag; Flags] -PipelineDepthStencilStateCreateFlag :: enum u32 {} PipelineDiscardRectangleStateCreateFlagsEXT :: distinct bit_set[PipelineDiscardRectangleStateCreateFlagEXT; Flags] PipelineDiscardRectangleStateCreateFlagEXT :: enum u32 {} PipelineDynamicStateCreateFlags :: distinct bit_set[PipelineDynamicStateCreateFlag; Flags] PipelineDynamicStateCreateFlag :: enum u32 {} PipelineInputAssemblyStateCreateFlags :: distinct bit_set[PipelineInputAssemblyStateCreateFlag; Flags] PipelineInputAssemblyStateCreateFlag :: enum u32 {} -PipelineLayoutCreateFlags :: distinct bit_set[PipelineLayoutCreateFlag; Flags] -PipelineLayoutCreateFlag :: enum u32 {} PipelineMultisampleStateCreateFlags :: distinct bit_set[PipelineMultisampleStateCreateFlag; Flags] PipelineMultisampleStateCreateFlag :: enum u32 {} PipelineRasterizationConservativeStateCreateFlagsEXT :: distinct bit_set[PipelineRasterizationConservativeStateCreateFlagEXT; Flags] @@ -2938,6 +3163,8 @@ PipelineViewportStateCreateFlags :: distinct bit_set[Pipelin PipelineViewportStateCreateFlag :: enum u32 {} PipelineViewportSwizzleStateCreateFlagsNV :: distinct bit_set[PipelineViewportSwizzleStateCreateFlagNV; Flags] PipelineViewportSwizzleStateCreateFlagNV :: enum u32 {} +PrivateDataSlotCreateFlags :: distinct bit_set[PrivateDataSlotCreateFlag; Flags] +PrivateDataSlotCreateFlag :: enum u32 {} QueryPoolCreateFlags :: distinct bit_set[QueryPoolCreateFlag; Flags] QueryPoolCreateFlag :: enum u32 {} SemaphoreCreateFlags :: distinct bit_set[SemaphoreCreateFlag; Flags] diff --git a/vendor/vulkan/procedures.odin b/vendor/vulkan/procedures.odin index b40523b6d..227f02a87 100644 --- a/vendor/vulkan/procedures.odin +++ b/vendor/vulkan/procedures.odin @@ -5,1412 +5,3330 @@ package vulkan import "core:c" -// Procedure Types +// Loader Procedure Types +ProcCreateInstance :: #type proc "system" (pCreateInfo: ^InstanceCreateInfo, pAllocator: ^AllocationCallbacks, pInstance: ^Instance) -> Result +ProcDebugUtilsMessengerCallbackEXT :: #type proc "system" (messageSeverity: DebugUtilsMessageSeverityFlagsEXT, messageTypes: DebugUtilsMessageTypeFlagsEXT, pCallbackData: ^DebugUtilsMessengerCallbackDataEXT, pUserData: rawptr) -> b32 +ProcDeviceMemoryReportCallbackEXT :: #type proc "system" (pCallbackData: ^DeviceMemoryReportCallbackDataEXT, pUserData: rawptr) +ProcEnumerateInstanceExtensionProperties :: #type proc "system" (pLayerName: cstring, pPropertyCount: ^u32, pProperties: [^]ExtensionProperties) -> Result +ProcEnumerateInstanceLayerProperties :: #type proc "system" (pPropertyCount: ^u32, pProperties: [^]LayerProperties) -> Result +ProcEnumerateInstanceVersion :: #type proc "system" (pApiVersion: ^u32) -> Result -ProcAllocationFunction :: #type proc "system" (pUserData: rawptr, size: int, alignment: int, allocationScope: SystemAllocationScope) -> rawptr -ProcFreeFunction :: #type proc "system" (pUserData: rawptr, pMemory: rawptr) -ProcInternalAllocationNotification :: #type proc "system" (pUserData: rawptr, size: int, allocationType: InternalAllocationType, allocationScope: SystemAllocationScope) -ProcInternalFreeNotification :: #type proc "system" (pUserData: rawptr, size: int, allocationType: InternalAllocationType, allocationScope: SystemAllocationScope) -ProcReallocationFunction :: #type proc "system" (pUserData: rawptr, pOriginal: rawptr, size: int, alignment: int, allocationScope: SystemAllocationScope) -> rawptr -ProcVoidFunction :: #type proc "system" () -ProcCreateInstance :: #type proc "system" (pCreateInfo: ^InstanceCreateInfo, pAllocator: ^AllocationCallbacks, pInstance: ^Instance) -> Result -ProcDestroyInstance :: #type proc "system" (instance: Instance, pAllocator: ^AllocationCallbacks) -ProcEnumeratePhysicalDevices :: #type proc "system" (instance: Instance, pPhysicalDeviceCount: ^u32, pPhysicalDevices: [^]PhysicalDevice) -> Result -ProcGetPhysicalDeviceFeatures :: #type proc "system" (physicalDevice: PhysicalDevice, pFeatures: [^]PhysicalDeviceFeatures) -ProcGetPhysicalDeviceFormatProperties :: #type proc "system" (physicalDevice: PhysicalDevice, format: Format, pFormatProperties: [^]FormatProperties) -ProcGetPhysicalDeviceImageFormatProperties :: #type proc "system" (physicalDevice: PhysicalDevice, format: Format, type: ImageType, tiling: ImageTiling, usage: ImageUsageFlags, flags: ImageCreateFlags, pImageFormatProperties: [^]ImageFormatProperties) -> Result -ProcGetPhysicalDeviceProperties :: #type proc "system" (physicalDevice: PhysicalDevice, pProperties: [^]PhysicalDeviceProperties) -ProcGetPhysicalDeviceQueueFamilyProperties :: #type proc "system" (physicalDevice: PhysicalDevice, pQueueFamilyPropertyCount: ^u32, pQueueFamilyProperties: [^]QueueFamilyProperties) -ProcGetPhysicalDeviceMemoryProperties :: #type proc "system" (physicalDevice: PhysicalDevice, pMemoryProperties: [^]PhysicalDeviceMemoryProperties) -ProcGetInstanceProcAddr :: #type proc "system" (instance: Instance, pName: cstring) -> ProcVoidFunction -ProcGetDeviceProcAddr :: #type proc "system" (device: Device, pName: cstring) -> ProcVoidFunction -ProcCreateDevice :: #type proc "system" (physicalDevice: PhysicalDevice, pCreateInfo: ^DeviceCreateInfo, pAllocator: ^AllocationCallbacks, pDevice: ^Device) -> Result -ProcDestroyDevice :: #type proc "system" (device: Device, pAllocator: ^AllocationCallbacks) -ProcEnumerateInstanceExtensionProperties :: #type proc "system" (pLayerName: cstring, pPropertyCount: ^u32, pProperties: [^]ExtensionProperties) -> Result -ProcEnumerateDeviceExtensionProperties :: #type proc "system" (physicalDevice: PhysicalDevice, pLayerName: cstring, pPropertyCount: ^u32, pProperties: [^]ExtensionProperties) -> Result -ProcEnumerateInstanceLayerProperties :: #type proc "system" (pPropertyCount: ^u32, pProperties: [^]LayerProperties) -> Result -ProcEnumerateDeviceLayerProperties :: #type proc "system" (physicalDevice: PhysicalDevice, pPropertyCount: ^u32, pProperties: [^]LayerProperties) -> Result -ProcGetDeviceQueue :: #type proc "system" (device: Device, queueFamilyIndex: u32, queueIndex: u32, pQueue: ^Queue) -ProcQueueSubmit :: #type proc "system" (queue: Queue, submitCount: u32, pSubmits: [^]SubmitInfo, fence: Fence) -> Result -ProcQueueWaitIdle :: #type proc "system" (queue: Queue) -> Result -ProcDeviceWaitIdle :: #type proc "system" (device: Device) -> Result -ProcAllocateMemory :: #type proc "system" (device: Device, pAllocateInfo: ^MemoryAllocateInfo, pAllocator: ^AllocationCallbacks, pMemory: ^DeviceMemory) -> Result -ProcFreeMemory :: #type proc "system" (device: Device, memory: DeviceMemory, pAllocator: ^AllocationCallbacks) -ProcMapMemory :: #type proc "system" (device: Device, memory: DeviceMemory, offset: DeviceSize, size: DeviceSize, flags: MemoryMapFlags, ppData: ^rawptr) -> Result -ProcUnmapMemory :: #type proc "system" (device: Device, memory: DeviceMemory) -ProcFlushMappedMemoryRanges :: #type proc "system" (device: Device, memoryRangeCount: u32, pMemoryRanges: [^]MappedMemoryRange) -> Result -ProcInvalidateMappedMemoryRanges :: #type proc "system" (device: Device, memoryRangeCount: u32, pMemoryRanges: [^]MappedMemoryRange) -> Result -ProcGetDeviceMemoryCommitment :: #type proc "system" (device: Device, memory: DeviceMemory, pCommittedMemoryInBytes: [^]DeviceSize) -ProcBindBufferMemory :: #type proc "system" (device: Device, buffer: Buffer, memory: DeviceMemory, memoryOffset: DeviceSize) -> Result -ProcBindImageMemory :: #type proc "system" (device: Device, image: Image, memory: DeviceMemory, memoryOffset: DeviceSize) -> Result -ProcGetBufferMemoryRequirements :: #type proc "system" (device: Device, buffer: Buffer, pMemoryRequirements: [^]MemoryRequirements) -ProcGetImageMemoryRequirements :: #type proc "system" (device: Device, image: Image, pMemoryRequirements: [^]MemoryRequirements) -ProcGetImageSparseMemoryRequirements :: #type proc "system" (device: Device, image: Image, pSparseMemoryRequirementCount: ^u32, pSparseMemoryRequirements: [^]SparseImageMemoryRequirements) -ProcGetPhysicalDeviceSparseImageFormatProperties :: #type proc "system" (physicalDevice: PhysicalDevice, format: Format, type: ImageType, samples: SampleCountFlags, usage: ImageUsageFlags, tiling: ImageTiling, pPropertyCount: ^u32, pProperties: [^]SparseImageFormatProperties) -ProcQueueBindSparse :: #type proc "system" (queue: Queue, bindInfoCount: u32, pBindInfo: ^BindSparseInfo, fence: Fence) -> Result -ProcCreateFence :: #type proc "system" (device: Device, pCreateInfo: ^FenceCreateInfo, pAllocator: ^AllocationCallbacks, pFence: ^Fence) -> Result -ProcDestroyFence :: #type proc "system" (device: Device, fence: Fence, pAllocator: ^AllocationCallbacks) -ProcResetFences :: #type proc "system" (device: Device, fenceCount: u32, pFences: [^]Fence) -> Result -ProcGetFenceStatus :: #type proc "system" (device: Device, fence: Fence) -> Result -ProcWaitForFences :: #type proc "system" (device: Device, fenceCount: u32, pFences: [^]Fence, waitAll: b32, timeout: u64) -> Result -ProcCreateSemaphore :: #type proc "system" (device: Device, pCreateInfo: ^SemaphoreCreateInfo, pAllocator: ^AllocationCallbacks, pSemaphore: ^Semaphore) -> Result -ProcDestroySemaphore :: #type proc "system" (device: Device, semaphore: Semaphore, pAllocator: ^AllocationCallbacks) -ProcCreateEvent :: #type proc "system" (device: Device, pCreateInfo: ^EventCreateInfo, pAllocator: ^AllocationCallbacks, pEvent: ^Event) -> Result -ProcDestroyEvent :: #type proc "system" (device: Device, event: Event, pAllocator: ^AllocationCallbacks) -ProcGetEventStatus :: #type proc "system" (device: Device, event: Event) -> Result -ProcSetEvent :: #type proc "system" (device: Device, event: Event) -> Result -ProcResetEvent :: #type proc "system" (device: Device, event: Event) -> Result -ProcCreateQueryPool :: #type proc "system" (device: Device, pCreateInfo: ^QueryPoolCreateInfo, pAllocator: ^AllocationCallbacks, pQueryPool: ^QueryPool) -> Result -ProcDestroyQueryPool :: #type proc "system" (device: Device, queryPool: QueryPool, pAllocator: ^AllocationCallbacks) -ProcGetQueryPoolResults :: #type proc "system" (device: Device, queryPool: QueryPool, firstQuery: u32, queryCount: u32, dataSize: int, pData: rawptr, stride: DeviceSize, flags: QueryResultFlags) -> Result -ProcCreateBuffer :: #type proc "system" (device: Device, pCreateInfo: ^BufferCreateInfo, pAllocator: ^AllocationCallbacks, pBuffer: ^Buffer) -> Result -ProcDestroyBuffer :: #type proc "system" (device: Device, buffer: Buffer, pAllocator: ^AllocationCallbacks) -ProcCreateBufferView :: #type proc "system" (device: Device, pCreateInfo: ^BufferViewCreateInfo, pAllocator: ^AllocationCallbacks, pView: ^BufferView) -> Result -ProcDestroyBufferView :: #type proc "system" (device: Device, bufferView: BufferView, pAllocator: ^AllocationCallbacks) -ProcCreateImage :: #type proc "system" (device: Device, pCreateInfo: ^ImageCreateInfo, pAllocator: ^AllocationCallbacks, pImage: ^Image) -> Result -ProcDestroyImage :: #type proc "system" (device: Device, image: Image, pAllocator: ^AllocationCallbacks) -ProcGetImageSubresourceLayout :: #type proc "system" (device: Device, image: Image, pSubresource: ^ImageSubresource, pLayout: ^SubresourceLayout) -ProcCreateImageView :: #type proc "system" (device: Device, pCreateInfo: ^ImageViewCreateInfo, pAllocator: ^AllocationCallbacks, pView: ^ImageView) -> Result -ProcDestroyImageView :: #type proc "system" (device: Device, imageView: ImageView, pAllocator: ^AllocationCallbacks) -ProcCreateShaderModule :: #type proc "system" (device: Device, pCreateInfo: ^ShaderModuleCreateInfo, pAllocator: ^AllocationCallbacks, pShaderModule: ^ShaderModule) -> Result -ProcDestroyShaderModule :: #type proc "system" (device: Device, shaderModule: ShaderModule, pAllocator: ^AllocationCallbacks) -ProcCreatePipelineCache :: #type proc "system" (device: Device, pCreateInfo: ^PipelineCacheCreateInfo, pAllocator: ^AllocationCallbacks, pPipelineCache: ^PipelineCache) -> Result -ProcDestroyPipelineCache :: #type proc "system" (device: Device, pipelineCache: PipelineCache, pAllocator: ^AllocationCallbacks) -ProcGetPipelineCacheData :: #type proc "system" (device: Device, pipelineCache: PipelineCache, pDataSize: ^int, pData: rawptr) -> Result -ProcMergePipelineCaches :: #type proc "system" (device: Device, dstCache: PipelineCache, srcCacheCount: u32, pSrcCaches: [^]PipelineCache) -> Result -ProcCreateGraphicsPipelines :: #type proc "system" (device: Device, pipelineCache: PipelineCache, createInfoCount: u32, pCreateInfos: [^]GraphicsPipelineCreateInfo, pAllocator: ^AllocationCallbacks, pPipelines: [^]Pipeline) -> Result -ProcCreateComputePipelines :: #type proc "system" (device: Device, pipelineCache: PipelineCache, createInfoCount: u32, pCreateInfos: [^]ComputePipelineCreateInfo, pAllocator: ^AllocationCallbacks, pPipelines: [^]Pipeline) -> Result -ProcDestroyPipeline :: #type proc "system" (device: Device, pipeline: Pipeline, pAllocator: ^AllocationCallbacks) -ProcCreatePipelineLayout :: #type proc "system" (device: Device, pCreateInfo: ^PipelineLayoutCreateInfo, pAllocator: ^AllocationCallbacks, pPipelineLayout: ^PipelineLayout) -> Result -ProcDestroyPipelineLayout :: #type proc "system" (device: Device, pipelineLayout: PipelineLayout, pAllocator: ^AllocationCallbacks) -ProcCreateSampler :: #type proc "system" (device: Device, pCreateInfo: ^SamplerCreateInfo, pAllocator: ^AllocationCallbacks, pSampler: ^Sampler) -> Result -ProcDestroySampler :: #type proc "system" (device: Device, sampler: Sampler, pAllocator: ^AllocationCallbacks) -ProcCreateDescriptorSetLayout :: #type proc "system" (device: Device, pCreateInfo: ^DescriptorSetLayoutCreateInfo, pAllocator: ^AllocationCallbacks, pSetLayout: ^DescriptorSetLayout) -> Result -ProcDestroyDescriptorSetLayout :: #type proc "system" (device: Device, descriptorSetLayout: DescriptorSetLayout, pAllocator: ^AllocationCallbacks) -ProcCreateDescriptorPool :: #type proc "system" (device: Device, pCreateInfo: ^DescriptorPoolCreateInfo, pAllocator: ^AllocationCallbacks, pDescriptorPool: ^DescriptorPool) -> Result -ProcDestroyDescriptorPool :: #type proc "system" (device: Device, descriptorPool: DescriptorPool, pAllocator: ^AllocationCallbacks) -ProcResetDescriptorPool :: #type proc "system" (device: Device, descriptorPool: DescriptorPool, flags: DescriptorPoolResetFlags) -> Result -ProcAllocateDescriptorSets :: #type proc "system" (device: Device, pAllocateInfo: ^DescriptorSetAllocateInfo, pDescriptorSets: [^]DescriptorSet) -> Result -ProcFreeDescriptorSets :: #type proc "system" (device: Device, descriptorPool: DescriptorPool, descriptorSetCount: u32, pDescriptorSets: [^]DescriptorSet) -> Result -ProcUpdateDescriptorSets :: #type proc "system" (device: Device, descriptorWriteCount: u32, pDescriptorWrites: [^]WriteDescriptorSet, descriptorCopyCount: u32, pDescriptorCopies: [^]CopyDescriptorSet) -ProcCreateFramebuffer :: #type proc "system" (device: Device, pCreateInfo: ^FramebufferCreateInfo, pAllocator: ^AllocationCallbacks, pFramebuffer: ^Framebuffer) -> Result -ProcDestroyFramebuffer :: #type proc "system" (device: Device, framebuffer: Framebuffer, pAllocator: ^AllocationCallbacks) -ProcCreateRenderPass :: #type proc "system" (device: Device, pCreateInfo: ^RenderPassCreateInfo, pAllocator: ^AllocationCallbacks, pRenderPass: [^]RenderPass) -> Result -ProcDestroyRenderPass :: #type proc "system" (device: Device, renderPass: RenderPass, pAllocator: ^AllocationCallbacks) -ProcGetRenderAreaGranularity :: #type proc "system" (device: Device, renderPass: RenderPass, pGranularity: ^Extent2D) -ProcCreateCommandPool :: #type proc "system" (device: Device, pCreateInfo: ^CommandPoolCreateInfo, pAllocator: ^AllocationCallbacks, pCommandPool: ^CommandPool) -> Result -ProcDestroyCommandPool :: #type proc "system" (device: Device, commandPool: CommandPool, pAllocator: ^AllocationCallbacks) -ProcResetCommandPool :: #type proc "system" (device: Device, commandPool: CommandPool, flags: CommandPoolResetFlags) -> Result -ProcAllocateCommandBuffers :: #type proc "system" (device: Device, pAllocateInfo: ^CommandBufferAllocateInfo, pCommandBuffers: [^]CommandBuffer) -> Result -ProcFreeCommandBuffers :: #type proc "system" (device: Device, commandPool: CommandPool, commandBufferCount: u32, pCommandBuffers: [^]CommandBuffer) -ProcBeginCommandBuffer :: #type proc "system" (commandBuffer: CommandBuffer, pBeginInfo: ^CommandBufferBeginInfo) -> Result -ProcEndCommandBuffer :: #type proc "system" (commandBuffer: CommandBuffer) -> Result -ProcResetCommandBuffer :: #type proc "system" (commandBuffer: CommandBuffer, flags: CommandBufferResetFlags) -> Result -ProcCmdBindPipeline :: #type proc "system" (commandBuffer: CommandBuffer, pipelineBindPoint: PipelineBindPoint, pipeline: Pipeline) -ProcCmdSetViewport :: #type proc "system" (commandBuffer: CommandBuffer, firstViewport: u32, viewportCount: u32, pViewports: [^]Viewport) -ProcCmdSetScissor :: #type proc "system" (commandBuffer: CommandBuffer, firstScissor: u32, scissorCount: u32, pScissors: [^]Rect2D) -ProcCmdSetLineWidth :: #type proc "system" (commandBuffer: CommandBuffer, lineWidth: f32) -ProcCmdSetDepthBias :: #type proc "system" (commandBuffer: CommandBuffer, depthBiasConstantFactor: f32, depthBiasClamp: f32, depthBiasSlopeFactor: f32) -ProcCmdSetBlendConstants :: #type proc "system" (commandBuffer: CommandBuffer) -ProcCmdSetDepthBounds :: #type proc "system" (commandBuffer: CommandBuffer, minDepthBounds: f32, maxDepthBounds: f32) -ProcCmdSetStencilCompareMask :: #type proc "system" (commandBuffer: CommandBuffer, faceMask: StencilFaceFlags, compareMask: u32) -ProcCmdSetStencilWriteMask :: #type proc "system" (commandBuffer: CommandBuffer, faceMask: StencilFaceFlags, writeMask: u32) -ProcCmdSetStencilReference :: #type proc "system" (commandBuffer: CommandBuffer, faceMask: StencilFaceFlags, reference: u32) -ProcCmdBindDescriptorSets :: #type proc "system" (commandBuffer: CommandBuffer, pipelineBindPoint: PipelineBindPoint, layout: PipelineLayout, firstSet: u32, descriptorSetCount: u32, pDescriptorSets: [^]DescriptorSet, dynamicOffsetCount: u32, pDynamicOffsets: [^]u32) -ProcCmdBindIndexBuffer :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, indexType: IndexType) -ProcCmdBindVertexBuffers :: #type proc "system" (commandBuffer: CommandBuffer, firstBinding: u32, bindingCount: u32, pBuffers: [^]Buffer, pOffsets: [^]DeviceSize) -ProcCmdDraw :: #type proc "system" (commandBuffer: CommandBuffer, vertexCount: u32, instanceCount: u32, firstVertex: u32, firstInstance: u32) -ProcCmdDrawIndexed :: #type proc "system" (commandBuffer: CommandBuffer, indexCount: u32, instanceCount: u32, firstIndex: u32, vertexOffset: i32, firstInstance: u32) -ProcCmdDrawIndirect :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, drawCount: u32, stride: u32) -ProcCmdDrawIndexedIndirect :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, drawCount: u32, stride: u32) -ProcCmdDispatch :: #type proc "system" (commandBuffer: CommandBuffer, groupCountX: u32, groupCountY: u32, groupCountZ: u32) -ProcCmdDispatchIndirect :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize) -ProcCmdCopyBuffer :: #type proc "system" (commandBuffer: CommandBuffer, srcBuffer: Buffer, dstBuffer: Buffer, regionCount: u32, pRegions: [^]BufferCopy) -ProcCmdCopyImage :: #type proc "system" (commandBuffer: CommandBuffer, srcImage: Image, srcImageLayout: ImageLayout, dstImage: Image, dstImageLayout: ImageLayout, regionCount: u32, pRegions: [^]ImageCopy) -ProcCmdBlitImage :: #type proc "system" (commandBuffer: CommandBuffer, srcImage: Image, srcImageLayout: ImageLayout, dstImage: Image, dstImageLayout: ImageLayout, regionCount: u32, pRegions: [^]ImageBlit, filter: Filter) -ProcCmdCopyBufferToImage :: #type proc "system" (commandBuffer: CommandBuffer, srcBuffer: Buffer, dstImage: Image, dstImageLayout: ImageLayout, regionCount: u32, pRegions: [^]BufferImageCopy) -ProcCmdCopyImageToBuffer :: #type proc "system" (commandBuffer: CommandBuffer, srcImage: Image, srcImageLayout: ImageLayout, dstBuffer: Buffer, regionCount: u32, pRegions: [^]BufferImageCopy) -ProcCmdUpdateBuffer :: #type proc "system" (commandBuffer: CommandBuffer, dstBuffer: Buffer, dstOffset: DeviceSize, dataSize: DeviceSize, pData: rawptr) -ProcCmdFillBuffer :: #type proc "system" (commandBuffer: CommandBuffer, dstBuffer: Buffer, dstOffset: DeviceSize, size: DeviceSize, data: u32) -ProcCmdClearColorImage :: #type proc "system" (commandBuffer: CommandBuffer, image: Image, imageLayout: ImageLayout, pColor: ^ClearColorValue, rangeCount: u32, pRanges: [^]ImageSubresourceRange) -ProcCmdClearDepthStencilImage :: #type proc "system" (commandBuffer: CommandBuffer, image: Image, imageLayout: ImageLayout, pDepthStencil: ^ClearDepthStencilValue, rangeCount: u32, pRanges: [^]ImageSubresourceRange) -ProcCmdClearAttachments :: #type proc "system" (commandBuffer: CommandBuffer, attachmentCount: u32, pAttachments: [^]ClearAttachment, rectCount: u32, pRects: [^]ClearRect) -ProcCmdResolveImage :: #type proc "system" (commandBuffer: CommandBuffer, srcImage: Image, srcImageLayout: ImageLayout, dstImage: Image, dstImageLayout: ImageLayout, regionCount: u32, pRegions: [^]ImageResolve) -ProcCmdSetEvent :: #type proc "system" (commandBuffer: CommandBuffer, event: Event, stageMask: PipelineStageFlags) -ProcCmdResetEvent :: #type proc "system" (commandBuffer: CommandBuffer, event: Event, stageMask: PipelineStageFlags) -ProcCmdWaitEvents :: #type proc "system" (commandBuffer: CommandBuffer, eventCount: u32, pEvents: [^]Event, srcStageMask: PipelineStageFlags, dstStageMask: PipelineStageFlags, memoryBarrierCount: u32, pMemoryBarriers: [^]MemoryBarrier, bufferMemoryBarrierCount: u32, pBufferMemoryBarriers: [^]BufferMemoryBarrier, imageMemoryBarrierCount: u32, pImageMemoryBarriers: [^]ImageMemoryBarrier) -ProcCmdPipelineBarrier :: #type proc "system" (commandBuffer: CommandBuffer, srcStageMask: PipelineStageFlags, dstStageMask: PipelineStageFlags, dependencyFlags: DependencyFlags, memoryBarrierCount: u32, pMemoryBarriers: [^]MemoryBarrier, bufferMemoryBarrierCount: u32, pBufferMemoryBarriers: [^]BufferMemoryBarrier, imageMemoryBarrierCount: u32, pImageMemoryBarriers: [^]ImageMemoryBarrier) -ProcCmdBeginQuery :: #type proc "system" (commandBuffer: CommandBuffer, queryPool: QueryPool, query: u32, flags: QueryControlFlags) -ProcCmdEndQuery :: #type proc "system" (commandBuffer: CommandBuffer, queryPool: QueryPool, query: u32) -ProcCmdResetQueryPool :: #type proc "system" (commandBuffer: CommandBuffer, queryPool: QueryPool, firstQuery: u32, queryCount: u32) -ProcCmdWriteTimestamp :: #type proc "system" (commandBuffer: CommandBuffer, pipelineStage: PipelineStageFlags, queryPool: QueryPool, query: u32) -ProcCmdCopyQueryPoolResults :: #type proc "system" (commandBuffer: CommandBuffer, queryPool: QueryPool, firstQuery: u32, queryCount: u32, dstBuffer: Buffer, dstOffset: DeviceSize, stride: DeviceSize, flags: QueryResultFlags) -ProcCmdPushConstants :: #type proc "system" (commandBuffer: CommandBuffer, layout: PipelineLayout, stageFlags: ShaderStageFlags, offset: u32, size: u32, pValues: rawptr) -ProcCmdBeginRenderPass :: #type proc "system" (commandBuffer: CommandBuffer, pRenderPassBegin: ^RenderPassBeginInfo, contents: SubpassContents) -ProcCmdNextSubpass :: #type proc "system" (commandBuffer: CommandBuffer, contents: SubpassContents) -ProcCmdEndRenderPass :: #type proc "system" (commandBuffer: CommandBuffer) -ProcCmdExecuteCommands :: #type proc "system" (commandBuffer: CommandBuffer, commandBufferCount: u32, pCommandBuffers: [^]CommandBuffer) -ProcEnumerateInstanceVersion :: #type proc "system" (pApiVersion: ^u32) -> Result -ProcBindBufferMemory2 :: #type proc "system" (device: Device, bindInfoCount: u32, pBindInfos: [^]BindBufferMemoryInfo) -> Result -ProcBindImageMemory2 :: #type proc "system" (device: Device, bindInfoCount: u32, pBindInfos: [^]BindImageMemoryInfo) -> Result -ProcGetDeviceGroupPeerMemoryFeatures :: #type proc "system" (device: Device, heapIndex: u32, localDeviceIndex: u32, remoteDeviceIndex: u32, pPeerMemoryFeatures: [^]PeerMemoryFeatureFlags) -ProcCmdSetDeviceMask :: #type proc "system" (commandBuffer: CommandBuffer, deviceMask: u32) -ProcCmdDispatchBase :: #type proc "system" (commandBuffer: CommandBuffer, baseGroupX: u32, baseGroupY: u32, baseGroupZ: u32, groupCountX: u32, groupCountY: u32, groupCountZ: u32) -ProcEnumeratePhysicalDeviceGroups :: #type proc "system" (instance: Instance, pPhysicalDeviceGroupCount: ^u32, pPhysicalDeviceGroupProperties: [^]PhysicalDeviceGroupProperties) -> Result -ProcGetImageMemoryRequirements2 :: #type proc "system" (device: Device, pInfo: ^ImageMemoryRequirementsInfo2, pMemoryRequirements: [^]MemoryRequirements2) -ProcGetBufferMemoryRequirements2 :: #type proc "system" (device: Device, pInfo: ^BufferMemoryRequirementsInfo2, pMemoryRequirements: [^]MemoryRequirements2) -ProcGetImageSparseMemoryRequirements2 :: #type proc "system" (device: Device, pInfo: ^ImageSparseMemoryRequirementsInfo2, pSparseMemoryRequirementCount: ^u32, pSparseMemoryRequirements: [^]SparseImageMemoryRequirements2) -ProcGetPhysicalDeviceFeatures2 :: #type proc "system" (physicalDevice: PhysicalDevice, pFeatures: [^]PhysicalDeviceFeatures2) -ProcGetPhysicalDeviceProperties2 :: #type proc "system" (physicalDevice: PhysicalDevice, pProperties: [^]PhysicalDeviceProperties2) -ProcGetPhysicalDeviceFormatProperties2 :: #type proc "system" (physicalDevice: PhysicalDevice, format: Format, pFormatProperties: [^]FormatProperties2) -ProcGetPhysicalDeviceImageFormatProperties2 :: #type proc "system" (physicalDevice: PhysicalDevice, pImageFormatInfo: ^PhysicalDeviceImageFormatInfo2, pImageFormatProperties: [^]ImageFormatProperties2) -> Result -ProcGetPhysicalDeviceQueueFamilyProperties2 :: #type proc "system" (physicalDevice: PhysicalDevice, pQueueFamilyPropertyCount: ^u32, pQueueFamilyProperties: [^]QueueFamilyProperties2) -ProcGetPhysicalDeviceMemoryProperties2 :: #type proc "system" (physicalDevice: PhysicalDevice, pMemoryProperties: [^]PhysicalDeviceMemoryProperties2) -ProcGetPhysicalDeviceSparseImageFormatProperties2 :: #type proc "system" (physicalDevice: PhysicalDevice, pFormatInfo: ^PhysicalDeviceSparseImageFormatInfo2, pPropertyCount: ^u32, pProperties: [^]SparseImageFormatProperties2) -ProcTrimCommandPool :: #type proc "system" (device: Device, commandPool: CommandPool, flags: CommandPoolTrimFlags) -ProcGetDeviceQueue2 :: #type proc "system" (device: Device, pQueueInfo: ^DeviceQueueInfo2, pQueue: ^Queue) -ProcCreateSamplerYcbcrConversion :: #type proc "system" (device: Device, pCreateInfo: ^SamplerYcbcrConversionCreateInfo, pAllocator: ^AllocationCallbacks, pYcbcrConversion: ^SamplerYcbcrConversion) -> Result -ProcDestroySamplerYcbcrConversion :: #type proc "system" (device: Device, ycbcrConversion: SamplerYcbcrConversion, pAllocator: ^AllocationCallbacks) -ProcCreateDescriptorUpdateTemplate :: #type proc "system" (device: Device, pCreateInfo: ^DescriptorUpdateTemplateCreateInfo, pAllocator: ^AllocationCallbacks, pDescriptorUpdateTemplate: ^DescriptorUpdateTemplate) -> Result -ProcDestroyDescriptorUpdateTemplate :: #type proc "system" (device: Device, descriptorUpdateTemplate: DescriptorUpdateTemplate, pAllocator: ^AllocationCallbacks) -ProcUpdateDescriptorSetWithTemplate :: #type proc "system" (device: Device, descriptorSet: DescriptorSet, descriptorUpdateTemplate: DescriptorUpdateTemplate, pData: rawptr) -ProcGetPhysicalDeviceExternalBufferProperties :: #type proc "system" (physicalDevice: PhysicalDevice, pExternalBufferInfo: ^PhysicalDeviceExternalBufferInfo, pExternalBufferProperties: [^]ExternalBufferProperties) -ProcGetPhysicalDeviceExternalFenceProperties :: #type proc "system" (physicalDevice: PhysicalDevice, pExternalFenceInfo: ^PhysicalDeviceExternalFenceInfo, pExternalFenceProperties: [^]ExternalFenceProperties) -ProcGetPhysicalDeviceExternalSemaphoreProperties :: #type proc "system" (physicalDevice: PhysicalDevice, pExternalSemaphoreInfo: ^PhysicalDeviceExternalSemaphoreInfo, pExternalSemaphoreProperties: [^]ExternalSemaphoreProperties) -ProcGetDescriptorSetLayoutSupport :: #type proc "system" (device: Device, pCreateInfo: ^DescriptorSetLayoutCreateInfo, pSupport: ^DescriptorSetLayoutSupport) -ProcCmdDrawIndirectCount :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, countBuffer: Buffer, countBufferOffset: DeviceSize, maxDrawCount: u32, stride: u32) -ProcCmdDrawIndexedIndirectCount :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, countBuffer: Buffer, countBufferOffset: DeviceSize, maxDrawCount: u32, stride: u32) -ProcCreateRenderPass2 :: #type proc "system" (device: Device, pCreateInfo: ^RenderPassCreateInfo2, pAllocator: ^AllocationCallbacks, pRenderPass: [^]RenderPass) -> Result -ProcCmdBeginRenderPass2 :: #type proc "system" (commandBuffer: CommandBuffer, pRenderPassBegin: ^RenderPassBeginInfo, pSubpassBeginInfo: ^SubpassBeginInfo) -ProcCmdNextSubpass2 :: #type proc "system" (commandBuffer: CommandBuffer, pSubpassBeginInfo: ^SubpassBeginInfo, pSubpassEndInfo: ^SubpassEndInfo) -ProcCmdEndRenderPass2 :: #type proc "system" (commandBuffer: CommandBuffer, pSubpassEndInfo: ^SubpassEndInfo) -ProcResetQueryPool :: #type proc "system" (device: Device, queryPool: QueryPool, firstQuery: u32, queryCount: u32) -ProcGetSemaphoreCounterValue :: #type proc "system" (device: Device, semaphore: Semaphore, pValue: ^u64) -> Result -ProcWaitSemaphores :: #type proc "system" (device: Device, pWaitInfo: ^SemaphoreWaitInfo, timeout: u64) -> Result -ProcSignalSemaphore :: #type proc "system" (device: Device, pSignalInfo: ^SemaphoreSignalInfo) -> Result -ProcGetBufferDeviceAddress :: #type proc "system" (device: Device, pInfo: ^BufferDeviceAddressInfo) -> DeviceAddress -ProcGetBufferOpaqueCaptureAddress :: #type proc "system" (device: Device, pInfo: ^BufferDeviceAddressInfo) -> u64 -ProcGetDeviceMemoryOpaqueCaptureAddress :: #type proc "system" (device: Device, pInfo: ^DeviceMemoryOpaqueCaptureAddressInfo) -> u64 -ProcDestroySurfaceKHR :: #type proc "system" (instance: Instance, surface: SurfaceKHR, pAllocator: ^AllocationCallbacks) -ProcGetPhysicalDeviceSurfaceSupportKHR :: #type proc "system" (physicalDevice: PhysicalDevice, queueFamilyIndex: u32, surface: SurfaceKHR, pSupported: ^b32) -> Result -ProcGetPhysicalDeviceSurfaceCapabilitiesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, surface: SurfaceKHR, pSurfaceCapabilities: [^]SurfaceCapabilitiesKHR) -> Result -ProcGetPhysicalDeviceSurfaceFormatsKHR :: #type proc "system" (physicalDevice: PhysicalDevice, surface: SurfaceKHR, pSurfaceFormatCount: ^u32, pSurfaceFormats: [^]SurfaceFormatKHR) -> Result -ProcGetPhysicalDeviceSurfacePresentModesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, surface: SurfaceKHR, pPresentModeCount: ^u32, pPresentModes: [^]PresentModeKHR) -> Result -ProcCreateSwapchainKHR :: #type proc "system" (device: Device, pCreateInfo: ^SwapchainCreateInfoKHR, pAllocator: ^AllocationCallbacks, pSwapchain: ^SwapchainKHR) -> Result -ProcDestroySwapchainKHR :: #type proc "system" (device: Device, swapchain: SwapchainKHR, pAllocator: ^AllocationCallbacks) -ProcGetSwapchainImagesKHR :: #type proc "system" (device: Device, swapchain: SwapchainKHR, pSwapchainImageCount: ^u32, pSwapchainImages: [^]Image) -> Result -ProcAcquireNextImageKHR :: #type proc "system" (device: Device, swapchain: SwapchainKHR, timeout: u64, semaphore: Semaphore, fence: Fence, pImageIndex: ^u32) -> Result -ProcQueuePresentKHR :: #type proc "system" (queue: Queue, pPresentInfo: ^PresentInfoKHR) -> Result -ProcGetDeviceGroupPresentCapabilitiesKHR :: #type proc "system" (device: Device, pDeviceGroupPresentCapabilities: [^]DeviceGroupPresentCapabilitiesKHR) -> Result -ProcGetDeviceGroupSurfacePresentModesKHR :: #type proc "system" (device: Device, surface: SurfaceKHR, pModes: [^]DeviceGroupPresentModeFlagsKHR) -> Result -ProcGetPhysicalDevicePresentRectanglesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, surface: SurfaceKHR, pRectCount: ^u32, pRects: [^]Rect2D) -> Result -ProcAcquireNextImage2KHR :: #type proc "system" (device: Device, pAcquireInfo: ^AcquireNextImageInfoKHR, pImageIndex: ^u32) -> Result -ProcGetPhysicalDeviceDisplayPropertiesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, pPropertyCount: ^u32, pProperties: [^]DisplayPropertiesKHR) -> Result -ProcGetPhysicalDeviceDisplayPlanePropertiesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, pPropertyCount: ^u32, pProperties: [^]DisplayPlanePropertiesKHR) -> Result -ProcGetDisplayPlaneSupportedDisplaysKHR :: #type proc "system" (physicalDevice: PhysicalDevice, planeIndex: u32, pDisplayCount: ^u32, pDisplays: [^]DisplayKHR) -> Result -ProcGetDisplayModePropertiesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, display: DisplayKHR, pPropertyCount: ^u32, pProperties: [^]DisplayModePropertiesKHR) -> Result -ProcCreateDisplayModeKHR :: #type proc "system" (physicalDevice: PhysicalDevice, display: DisplayKHR, pCreateInfo: ^DisplayModeCreateInfoKHR, pAllocator: ^AllocationCallbacks, pMode: ^DisplayModeKHR) -> Result -ProcGetDisplayPlaneCapabilitiesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, mode: DisplayModeKHR, planeIndex: u32, pCapabilities: [^]DisplayPlaneCapabilitiesKHR) -> Result -ProcCreateDisplayPlaneSurfaceKHR :: #type proc "system" (instance: Instance, pCreateInfo: ^DisplaySurfaceCreateInfoKHR, pAllocator: ^AllocationCallbacks, pSurface: ^SurfaceKHR) -> Result -ProcCreateSharedSwapchainsKHR :: #type proc "system" (device: Device, swapchainCount: u32, pCreateInfos: [^]SwapchainCreateInfoKHR, pAllocator: ^AllocationCallbacks, pSwapchains: [^]SwapchainKHR) -> Result -ProcGetPhysicalDeviceFeatures2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pFeatures: [^]PhysicalDeviceFeatures2) -ProcGetPhysicalDeviceProperties2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pProperties: [^]PhysicalDeviceProperties2) -ProcGetPhysicalDeviceFormatProperties2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, format: Format, pFormatProperties: [^]FormatProperties2) -ProcGetPhysicalDeviceImageFormatProperties2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pImageFormatInfo: ^PhysicalDeviceImageFormatInfo2, pImageFormatProperties: [^]ImageFormatProperties2) -> Result -ProcGetPhysicalDeviceQueueFamilyProperties2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pQueueFamilyPropertyCount: ^u32, pQueueFamilyProperties: [^]QueueFamilyProperties2) -ProcGetPhysicalDeviceMemoryProperties2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pMemoryProperties: [^]PhysicalDeviceMemoryProperties2) -ProcGetPhysicalDeviceSparseImageFormatProperties2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pFormatInfo: ^PhysicalDeviceSparseImageFormatInfo2, pPropertyCount: ^u32, pProperties: [^]SparseImageFormatProperties2) -ProcGetDeviceGroupPeerMemoryFeaturesKHR :: #type proc "system" (device: Device, heapIndex: u32, localDeviceIndex: u32, remoteDeviceIndex: u32, pPeerMemoryFeatures: [^]PeerMemoryFeatureFlags) -ProcCmdSetDeviceMaskKHR :: #type proc "system" (commandBuffer: CommandBuffer, deviceMask: u32) -ProcCmdDispatchBaseKHR :: #type proc "system" (commandBuffer: CommandBuffer, baseGroupX: u32, baseGroupY: u32, baseGroupZ: u32, groupCountX: u32, groupCountY: u32, groupCountZ: u32) -ProcTrimCommandPoolKHR :: #type proc "system" (device: Device, commandPool: CommandPool, flags: CommandPoolTrimFlags) -ProcEnumeratePhysicalDeviceGroupsKHR :: #type proc "system" (instance: Instance, pPhysicalDeviceGroupCount: ^u32, pPhysicalDeviceGroupProperties: [^]PhysicalDeviceGroupProperties) -> Result -ProcGetPhysicalDeviceExternalBufferPropertiesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, pExternalBufferInfo: ^PhysicalDeviceExternalBufferInfo, pExternalBufferProperties: [^]ExternalBufferProperties) -ProcGetMemoryFdKHR :: #type proc "system" (device: Device, pGetFdInfo: ^MemoryGetFdInfoKHR, pFd: ^c.int) -> Result -ProcGetMemoryFdPropertiesKHR :: #type proc "system" (device: Device, handleType: ExternalMemoryHandleTypeFlags, fd: c.int, pMemoryFdProperties: [^]MemoryFdPropertiesKHR) -> Result -ProcGetPhysicalDeviceExternalSemaphorePropertiesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, pExternalSemaphoreInfo: ^PhysicalDeviceExternalSemaphoreInfo, pExternalSemaphoreProperties: [^]ExternalSemaphoreProperties) -ProcImportSemaphoreFdKHR :: #type proc "system" (device: Device, pImportSemaphoreFdInfo: ^ImportSemaphoreFdInfoKHR) -> Result -ProcGetSemaphoreFdKHR :: #type proc "system" (device: Device, pGetFdInfo: ^SemaphoreGetFdInfoKHR, pFd: ^c.int) -> Result -ProcCmdPushDescriptorSetKHR :: #type proc "system" (commandBuffer: CommandBuffer, pipelineBindPoint: PipelineBindPoint, layout: PipelineLayout, set: u32, descriptorWriteCount: u32, pDescriptorWrites: [^]WriteDescriptorSet) -ProcCmdPushDescriptorSetWithTemplateKHR :: #type proc "system" (commandBuffer: CommandBuffer, descriptorUpdateTemplate: DescriptorUpdateTemplate, layout: PipelineLayout, set: u32, pData: rawptr) -ProcCreateDescriptorUpdateTemplateKHR :: #type proc "system" (device: Device, pCreateInfo: ^DescriptorUpdateTemplateCreateInfo, pAllocator: ^AllocationCallbacks, pDescriptorUpdateTemplate: ^DescriptorUpdateTemplate) -> Result -ProcDestroyDescriptorUpdateTemplateKHR :: #type proc "system" (device: Device, descriptorUpdateTemplate: DescriptorUpdateTemplate, pAllocator: ^AllocationCallbacks) -ProcUpdateDescriptorSetWithTemplateKHR :: #type proc "system" (device: Device, descriptorSet: DescriptorSet, descriptorUpdateTemplate: DescriptorUpdateTemplate, pData: rawptr) -ProcCreateRenderPass2KHR :: #type proc "system" (device: Device, pCreateInfo: ^RenderPassCreateInfo2, pAllocator: ^AllocationCallbacks, pRenderPass: [^]RenderPass) -> Result -ProcCmdBeginRenderPass2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pRenderPassBegin: ^RenderPassBeginInfo, pSubpassBeginInfo: ^SubpassBeginInfo) -ProcCmdNextSubpass2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pSubpassBeginInfo: ^SubpassBeginInfo, pSubpassEndInfo: ^SubpassEndInfo) -ProcCmdEndRenderPass2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pSubpassEndInfo: ^SubpassEndInfo) -ProcGetSwapchainStatusKHR :: #type proc "system" (device: Device, swapchain: SwapchainKHR) -> Result -ProcGetPhysicalDeviceExternalFencePropertiesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, pExternalFenceInfo: ^PhysicalDeviceExternalFenceInfo, pExternalFenceProperties: [^]ExternalFenceProperties) -ProcImportFenceFdKHR :: #type proc "system" (device: Device, pImportFenceFdInfo: ^ImportFenceFdInfoKHR) -> Result -ProcGetFenceFdKHR :: #type proc "system" (device: Device, pGetFdInfo: ^FenceGetFdInfoKHR, pFd: ^c.int) -> Result -ProcEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR :: #type proc "system" (physicalDevice: PhysicalDevice, queueFamilyIndex: u32, pCounterCount: ^u32, pCounters: [^]PerformanceCounterKHR, pCounterDescriptions: [^]PerformanceCounterDescriptionKHR) -> Result -ProcGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, pPerformanceQueryCreateInfo: ^QueryPoolPerformanceCreateInfoKHR, pNumPasses: [^]u32) -ProcAcquireProfilingLockKHR :: #type proc "system" (device: Device, pInfo: ^AcquireProfilingLockInfoKHR) -> Result -ProcReleaseProfilingLockKHR :: #type proc "system" (device: Device) -ProcGetPhysicalDeviceSurfaceCapabilities2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pSurfaceInfo: ^PhysicalDeviceSurfaceInfo2KHR, pSurfaceCapabilities: [^]SurfaceCapabilities2KHR) -> Result -ProcGetPhysicalDeviceSurfaceFormats2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pSurfaceInfo: ^PhysicalDeviceSurfaceInfo2KHR, pSurfaceFormatCount: ^u32, pSurfaceFormats: [^]SurfaceFormat2KHR) -> Result -ProcGetPhysicalDeviceDisplayProperties2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pPropertyCount: ^u32, pProperties: [^]DisplayProperties2KHR) -> Result -ProcGetPhysicalDeviceDisplayPlaneProperties2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pPropertyCount: ^u32, pProperties: [^]DisplayPlaneProperties2KHR) -> Result -ProcGetDisplayModeProperties2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, display: DisplayKHR, pPropertyCount: ^u32, pProperties: [^]DisplayModeProperties2KHR) -> Result -ProcGetDisplayPlaneCapabilities2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pDisplayPlaneInfo: ^DisplayPlaneInfo2KHR, pCapabilities: [^]DisplayPlaneCapabilities2KHR) -> Result -ProcGetImageMemoryRequirements2KHR :: #type proc "system" (device: Device, pInfo: ^ImageMemoryRequirementsInfo2, pMemoryRequirements: [^]MemoryRequirements2) -ProcGetBufferMemoryRequirements2KHR :: #type proc "system" (device: Device, pInfo: ^BufferMemoryRequirementsInfo2, pMemoryRequirements: [^]MemoryRequirements2) -ProcGetImageSparseMemoryRequirements2KHR :: #type proc "system" (device: Device, pInfo: ^ImageSparseMemoryRequirementsInfo2, pSparseMemoryRequirementCount: ^u32, pSparseMemoryRequirements: [^]SparseImageMemoryRequirements2) -ProcCreateSamplerYcbcrConversionKHR :: #type proc "system" (device: Device, pCreateInfo: ^SamplerYcbcrConversionCreateInfo, pAllocator: ^AllocationCallbacks, pYcbcrConversion: ^SamplerYcbcrConversion) -> Result -ProcDestroySamplerYcbcrConversionKHR :: #type proc "system" (device: Device, ycbcrConversion: SamplerYcbcrConversion, pAllocator: ^AllocationCallbacks) -ProcBindBufferMemory2KHR :: #type proc "system" (device: Device, bindInfoCount: u32, pBindInfos: [^]BindBufferMemoryInfo) -> Result -ProcBindImageMemory2KHR :: #type proc "system" (device: Device, bindInfoCount: u32, pBindInfos: [^]BindImageMemoryInfo) -> Result -ProcGetDescriptorSetLayoutSupportKHR :: #type proc "system" (device: Device, pCreateInfo: ^DescriptorSetLayoutCreateInfo, pSupport: ^DescriptorSetLayoutSupport) -ProcCmdDrawIndirectCountKHR :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, countBuffer: Buffer, countBufferOffset: DeviceSize, maxDrawCount: u32, stride: u32) -ProcCmdDrawIndexedIndirectCountKHR :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, countBuffer: Buffer, countBufferOffset: DeviceSize, maxDrawCount: u32, stride: u32) -ProcGetSemaphoreCounterValueKHR :: #type proc "system" (device: Device, semaphore: Semaphore, pValue: ^u64) -> Result -ProcWaitSemaphoresKHR :: #type proc "system" (device: Device, pWaitInfo: ^SemaphoreWaitInfo, timeout: u64) -> Result -ProcSignalSemaphoreKHR :: #type proc "system" (device: Device, pSignalInfo: ^SemaphoreSignalInfo) -> Result -ProcGetPhysicalDeviceFragmentShadingRatesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, pFragmentShadingRateCount: ^u32, pFragmentShadingRates: [^]PhysicalDeviceFragmentShadingRateKHR) -> Result -ProcCmdSetFragmentShadingRateKHR :: #type proc "system" (commandBuffer: CommandBuffer, pFragmentSize: ^Extent2D) -ProcWaitForPresentKHR :: #type proc "system" (device: Device, swapchain: SwapchainKHR, presentId: u64, timeout: u64) -> Result -ProcGetBufferDeviceAddressKHR :: #type proc "system" (device: Device, pInfo: ^BufferDeviceAddressInfo) -> DeviceAddress -ProcGetBufferOpaqueCaptureAddressKHR :: #type proc "system" (device: Device, pInfo: ^BufferDeviceAddressInfo) -> u64 -ProcGetDeviceMemoryOpaqueCaptureAddressKHR :: #type proc "system" (device: Device, pInfo: ^DeviceMemoryOpaqueCaptureAddressInfo) -> u64 -ProcCreateDeferredOperationKHR :: #type proc "system" (device: Device, pAllocator: ^AllocationCallbacks, pDeferredOperation: ^DeferredOperationKHR) -> Result -ProcDestroyDeferredOperationKHR :: #type proc "system" (device: Device, operation: DeferredOperationKHR, pAllocator: ^AllocationCallbacks) -ProcGetDeferredOperationMaxConcurrencyKHR :: #type proc "system" (device: Device, operation: DeferredOperationKHR) -> u32 -ProcGetDeferredOperationResultKHR :: #type proc "system" (device: Device, operation: DeferredOperationKHR) -> Result -ProcDeferredOperationJoinKHR :: #type proc "system" (device: Device, operation: DeferredOperationKHR) -> Result -ProcGetPipelineExecutablePropertiesKHR :: #type proc "system" (device: Device, pPipelineInfo: ^PipelineInfoKHR, pExecutableCount: ^u32, pProperties: [^]PipelineExecutablePropertiesKHR) -> Result -ProcGetPipelineExecutableStatisticsKHR :: #type proc "system" (device: Device, pExecutableInfo: ^PipelineExecutableInfoKHR, pStatisticCount: ^u32, pStatistics: [^]PipelineExecutableStatisticKHR) -> Result -ProcGetPipelineExecutableInternalRepresentationsKHR :: #type proc "system" (device: Device, pExecutableInfo: ^PipelineExecutableInfoKHR, pInternalRepresentationCount: ^u32, pInternalRepresentations: [^]PipelineExecutableInternalRepresentationKHR) -> Result -ProcCmdSetEvent2KHR :: #type proc "system" (commandBuffer: CommandBuffer, event: Event, pDependencyInfo: ^DependencyInfoKHR) -ProcCmdResetEvent2KHR :: #type proc "system" (commandBuffer: CommandBuffer, event: Event, stageMask: PipelineStageFlags2KHR) -ProcCmdWaitEvents2KHR :: #type proc "system" (commandBuffer: CommandBuffer, eventCount: u32, pEvents: [^]Event, pDependencyInfos: [^]DependencyInfoKHR) -ProcCmdPipelineBarrier2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pDependencyInfo: ^DependencyInfoKHR) -ProcCmdWriteTimestamp2KHR :: #type proc "system" (commandBuffer: CommandBuffer, stage: PipelineStageFlags2KHR, queryPool: QueryPool, query: u32) -ProcQueueSubmit2KHR :: #type proc "system" (queue: Queue, submitCount: u32, pSubmits: [^]SubmitInfo2KHR, fence: Fence) -> Result -ProcCmdWriteBufferMarker2AMD :: #type proc "system" (commandBuffer: CommandBuffer, stage: PipelineStageFlags2KHR, dstBuffer: Buffer, dstOffset: DeviceSize, marker: u32) -ProcGetQueueCheckpointData2NV :: #type proc "system" (queue: Queue, pCheckpointDataCount: ^u32, pCheckpointData: ^CheckpointData2NV) -ProcCmdCopyBuffer2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pCopyBufferInfo: ^CopyBufferInfo2KHR) -ProcCmdCopyImage2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pCopyImageInfo: ^CopyImageInfo2KHR) -ProcCmdCopyBufferToImage2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pCopyBufferToImageInfo: ^CopyBufferToImageInfo2KHR) -ProcCmdCopyImageToBuffer2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pCopyImageToBufferInfo: ^CopyImageToBufferInfo2KHR) -ProcCmdBlitImage2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pBlitImageInfo: ^BlitImageInfo2KHR) -ProcCmdResolveImage2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pResolveImageInfo: ^ResolveImageInfo2KHR) -ProcDebugReportCallbackEXT :: #type proc "system" (flags: DebugReportFlagsEXT, objectType: DebugReportObjectTypeEXT, object: u64, location: int, messageCode: i32, pLayerPrefix: cstring, pMessage: cstring, pUserData: rawptr) -> b32 -ProcCreateDebugReportCallbackEXT :: #type proc "system" (instance: Instance, pCreateInfo: ^DebugReportCallbackCreateInfoEXT, pAllocator: ^AllocationCallbacks, pCallback: ^DebugReportCallbackEXT) -> Result -ProcDestroyDebugReportCallbackEXT :: #type proc "system" (instance: Instance, callback: DebugReportCallbackEXT, pAllocator: ^AllocationCallbacks) -ProcDebugReportMessageEXT :: #type proc "system" (instance: Instance, flags: DebugReportFlagsEXT, objectType: DebugReportObjectTypeEXT, object: u64, location: int, messageCode: i32, pLayerPrefix: cstring, pMessage: cstring) -ProcDebugMarkerSetObjectTagEXT :: #type proc "system" (device: Device, pTagInfo: ^DebugMarkerObjectTagInfoEXT) -> Result -ProcDebugMarkerSetObjectNameEXT :: #type proc "system" (device: Device, pNameInfo: ^DebugMarkerObjectNameInfoEXT) -> Result -ProcCmdDebugMarkerBeginEXT :: #type proc "system" (commandBuffer: CommandBuffer, pMarkerInfo: ^DebugMarkerMarkerInfoEXT) -ProcCmdDebugMarkerEndEXT :: #type proc "system" (commandBuffer: CommandBuffer) -ProcCmdDebugMarkerInsertEXT :: #type proc "system" (commandBuffer: CommandBuffer, pMarkerInfo: ^DebugMarkerMarkerInfoEXT) -ProcCmdBindTransformFeedbackBuffersEXT :: #type proc "system" (commandBuffer: CommandBuffer, firstBinding: u32, bindingCount: u32, pBuffers: [^]Buffer, pOffsets: [^]DeviceSize, pSizes: [^]DeviceSize) -ProcCmdBeginTransformFeedbackEXT :: #type proc "system" (commandBuffer: CommandBuffer, firstCounterBuffer: u32, counterBufferCount: u32, pCounterBuffers: [^]Buffer, pCounterBufferOffsets: [^]DeviceSize) -ProcCmdEndTransformFeedbackEXT :: #type proc "system" (commandBuffer: CommandBuffer, firstCounterBuffer: u32, counterBufferCount: u32, pCounterBuffers: [^]Buffer, pCounterBufferOffsets: [^]DeviceSize) -ProcCmdBeginQueryIndexedEXT :: #type proc "system" (commandBuffer: CommandBuffer, queryPool: QueryPool, query: u32, flags: QueryControlFlags, index: u32) -ProcCmdEndQueryIndexedEXT :: #type proc "system" (commandBuffer: CommandBuffer, queryPool: QueryPool, query: u32, index: u32) -ProcCmdDrawIndirectByteCountEXT :: #type proc "system" (commandBuffer: CommandBuffer, instanceCount: u32, firstInstance: u32, counterBuffer: Buffer, counterBufferOffset: DeviceSize, counterOffset: u32, vertexStride: u32) -ProcCreateCuModuleNVX :: #type proc "system" (device: Device, pCreateInfo: ^CuModuleCreateInfoNVX, pAllocator: ^AllocationCallbacks, pModule: ^CuModuleNVX) -> Result -ProcCreateCuFunctionNVX :: #type proc "system" (device: Device, pCreateInfo: ^CuFunctionCreateInfoNVX, pAllocator: ^AllocationCallbacks, pFunction: ^CuFunctionNVX) -> Result -ProcDestroyCuModuleNVX :: #type proc "system" (device: Device, module: CuModuleNVX, pAllocator: ^AllocationCallbacks) -ProcDestroyCuFunctionNVX :: #type proc "system" (device: Device, function: CuFunctionNVX, pAllocator: ^AllocationCallbacks) -ProcCmdCuLaunchKernelNVX :: #type proc "system" (commandBuffer: CommandBuffer, pLaunchInfo: ^CuLaunchInfoNVX) -ProcGetImageViewHandleNVX :: #type proc "system" (device: Device, pInfo: ^ImageViewHandleInfoNVX) -> u32 -ProcGetImageViewAddressNVX :: #type proc "system" (device: Device, imageView: ImageView, pProperties: [^]ImageViewAddressPropertiesNVX) -> Result -ProcCmdDrawIndirectCountAMD :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, countBuffer: Buffer, countBufferOffset: DeviceSize, maxDrawCount: u32, stride: u32) -ProcCmdDrawIndexedIndirectCountAMD :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, countBuffer: Buffer, countBufferOffset: DeviceSize, maxDrawCount: u32, stride: u32) -ProcGetShaderInfoAMD :: #type proc "system" (device: Device, pipeline: Pipeline, shaderStage: ShaderStageFlags, infoType: ShaderInfoTypeAMD, pInfoSize: ^int, pInfo: rawptr) -> Result -ProcGetPhysicalDeviceExternalImageFormatPropertiesNV :: #type proc "system" (physicalDevice: PhysicalDevice, format: Format, type: ImageType, tiling: ImageTiling, usage: ImageUsageFlags, flags: ImageCreateFlags, externalHandleType: ExternalMemoryHandleTypeFlagsNV, pExternalImageFormatProperties: [^]ExternalImageFormatPropertiesNV) -> Result -ProcCmdBeginConditionalRenderingEXT :: #type proc "system" (commandBuffer: CommandBuffer, pConditionalRenderingBegin: ^ConditionalRenderingBeginInfoEXT) -ProcCmdEndConditionalRenderingEXT :: #type proc "system" (commandBuffer: CommandBuffer) -ProcCmdSetViewportWScalingNV :: #type proc "system" (commandBuffer: CommandBuffer, firstViewport: u32, viewportCount: u32, pViewportWScalings: [^]ViewportWScalingNV) -ProcReleaseDisplayEXT :: #type proc "system" (physicalDevice: PhysicalDevice, display: DisplayKHR) -> Result -ProcGetPhysicalDeviceSurfaceCapabilities2EXT :: #type proc "system" (physicalDevice: PhysicalDevice, surface: SurfaceKHR, pSurfaceCapabilities: [^]SurfaceCapabilities2EXT) -> Result -ProcDisplayPowerControlEXT :: #type proc "system" (device: Device, display: DisplayKHR, pDisplayPowerInfo: ^DisplayPowerInfoEXT) -> Result -ProcRegisterDeviceEventEXT :: #type proc "system" (device: Device, pDeviceEventInfo: ^DeviceEventInfoEXT, pAllocator: ^AllocationCallbacks, pFence: ^Fence) -> Result -ProcRegisterDisplayEventEXT :: #type proc "system" (device: Device, display: DisplayKHR, pDisplayEventInfo: ^DisplayEventInfoEXT, pAllocator: ^AllocationCallbacks, pFence: ^Fence) -> Result -ProcGetSwapchainCounterEXT :: #type proc "system" (device: Device, swapchain: SwapchainKHR, counter: SurfaceCounterFlagsEXT, pCounterValue: ^u64) -> Result -ProcGetRefreshCycleDurationGOOGLE :: #type proc "system" (device: Device, swapchain: SwapchainKHR, pDisplayTimingProperties: [^]RefreshCycleDurationGOOGLE) -> Result -ProcGetPastPresentationTimingGOOGLE :: #type proc "system" (device: Device, swapchain: SwapchainKHR, pPresentationTimingCount: ^u32, pPresentationTimings: [^]PastPresentationTimingGOOGLE) -> Result -ProcCmdSetDiscardRectangleEXT :: #type proc "system" (commandBuffer: CommandBuffer, firstDiscardRectangle: u32, discardRectangleCount: u32, pDiscardRectangles: [^]Rect2D) -ProcSetHdrMetadataEXT :: #type proc "system" (device: Device, swapchainCount: u32, pSwapchains: [^]SwapchainKHR, pMetadata: ^HdrMetadataEXT) -ProcDebugUtilsMessengerCallbackEXT :: #type proc "system" (messageSeverity: DebugUtilsMessageSeverityFlagsEXT, messageTypes: DebugUtilsMessageTypeFlagsEXT, pCallbackData: ^DebugUtilsMessengerCallbackDataEXT, pUserData: rawptr) -> b32 -ProcSetDebugUtilsObjectNameEXT :: #type proc "system" (device: Device, pNameInfo: ^DebugUtilsObjectNameInfoEXT) -> Result -ProcSetDebugUtilsObjectTagEXT :: #type proc "system" (device: Device, pTagInfo: ^DebugUtilsObjectTagInfoEXT) -> Result -ProcQueueBeginDebugUtilsLabelEXT :: #type proc "system" (queue: Queue, pLabelInfo: ^DebugUtilsLabelEXT) -ProcQueueEndDebugUtilsLabelEXT :: #type proc "system" (queue: Queue) -ProcQueueInsertDebugUtilsLabelEXT :: #type proc "system" (queue: Queue, pLabelInfo: ^DebugUtilsLabelEXT) -ProcCmdBeginDebugUtilsLabelEXT :: #type proc "system" (commandBuffer: CommandBuffer, pLabelInfo: ^DebugUtilsLabelEXT) -ProcCmdEndDebugUtilsLabelEXT :: #type proc "system" (commandBuffer: CommandBuffer) -ProcCmdInsertDebugUtilsLabelEXT :: #type proc "system" (commandBuffer: CommandBuffer, pLabelInfo: ^DebugUtilsLabelEXT) -ProcCreateDebugUtilsMessengerEXT :: #type proc "system" (instance: Instance, pCreateInfo: ^DebugUtilsMessengerCreateInfoEXT, pAllocator: ^AllocationCallbacks, pMessenger: ^DebugUtilsMessengerEXT) -> Result -ProcDestroyDebugUtilsMessengerEXT :: #type proc "system" (instance: Instance, messenger: DebugUtilsMessengerEXT, pAllocator: ^AllocationCallbacks) -ProcSubmitDebugUtilsMessageEXT :: #type proc "system" (instance: Instance, messageSeverity: DebugUtilsMessageSeverityFlagsEXT, messageTypes: DebugUtilsMessageTypeFlagsEXT, pCallbackData: ^DebugUtilsMessengerCallbackDataEXT) -ProcCmdSetSampleLocationsEXT :: #type proc "system" (commandBuffer: CommandBuffer, pSampleLocationsInfo: ^SampleLocationsInfoEXT) -ProcGetPhysicalDeviceMultisamplePropertiesEXT :: #type proc "system" (physicalDevice: PhysicalDevice, samples: SampleCountFlags, pMultisampleProperties: [^]MultisamplePropertiesEXT) -ProcGetImageDrmFormatModifierPropertiesEXT :: #type proc "system" (device: Device, image: Image, pProperties: [^]ImageDrmFormatModifierPropertiesEXT) -> Result -ProcCreateValidationCacheEXT :: #type proc "system" (device: Device, pCreateInfo: ^ValidationCacheCreateInfoEXT, pAllocator: ^AllocationCallbacks, pValidationCache: ^ValidationCacheEXT) -> Result -ProcDestroyValidationCacheEXT :: #type proc "system" (device: Device, validationCache: ValidationCacheEXT, pAllocator: ^AllocationCallbacks) -ProcMergeValidationCachesEXT :: #type proc "system" (device: Device, dstCache: ValidationCacheEXT, srcCacheCount: u32, pSrcCaches: [^]ValidationCacheEXT) -> Result -ProcGetValidationCacheDataEXT :: #type proc "system" (device: Device, validationCache: ValidationCacheEXT, pDataSize: ^int, pData: rawptr) -> Result -ProcCmdBindShadingRateImageNV :: #type proc "system" (commandBuffer: CommandBuffer, imageView: ImageView, imageLayout: ImageLayout) -ProcCmdSetViewportShadingRatePaletteNV :: #type proc "system" (commandBuffer: CommandBuffer, firstViewport: u32, viewportCount: u32, pShadingRatePalettes: [^]ShadingRatePaletteNV) -ProcCmdSetCoarseSampleOrderNV :: #type proc "system" (commandBuffer: CommandBuffer, sampleOrderType: CoarseSampleOrderTypeNV, customSampleOrderCount: u32, pCustomSampleOrders: [^]CoarseSampleOrderCustomNV) -ProcCreateAccelerationStructureNV :: #type proc "system" (device: Device, pCreateInfo: ^AccelerationStructureCreateInfoNV, pAllocator: ^AllocationCallbacks, pAccelerationStructure: ^AccelerationStructureNV) -> Result -ProcDestroyAccelerationStructureNV :: #type proc "system" (device: Device, accelerationStructure: AccelerationStructureNV, pAllocator: ^AllocationCallbacks) -ProcGetAccelerationStructureMemoryRequirementsNV :: #type proc "system" (device: Device, pInfo: ^AccelerationStructureMemoryRequirementsInfoNV, pMemoryRequirements: [^]MemoryRequirements2KHR) -ProcBindAccelerationStructureMemoryNV :: #type proc "system" (device: Device, bindInfoCount: u32, pBindInfos: [^]BindAccelerationStructureMemoryInfoNV) -> Result -ProcCmdBuildAccelerationStructureNV :: #type proc "system" (commandBuffer: CommandBuffer, pInfo: ^AccelerationStructureInfoNV, instanceData: Buffer, instanceOffset: DeviceSize, update: b32, dst: AccelerationStructureNV, src: AccelerationStructureNV, scratch: Buffer, scratchOffset: DeviceSize) -ProcCmdCopyAccelerationStructureNV :: #type proc "system" (commandBuffer: CommandBuffer, dst: AccelerationStructureNV, src: AccelerationStructureNV, mode: CopyAccelerationStructureModeKHR) -ProcCmdTraceRaysNV :: #type proc "system" (commandBuffer: CommandBuffer, raygenShaderBindingTableBuffer: Buffer, raygenShaderBindingOffset: DeviceSize, missShaderBindingTableBuffer: Buffer, missShaderBindingOffset: DeviceSize, missShaderBindingStride: DeviceSize, hitShaderBindingTableBuffer: Buffer, hitShaderBindingOffset: DeviceSize, hitShaderBindingStride: DeviceSize, callableShaderBindingTableBuffer: Buffer, callableShaderBindingOffset: DeviceSize, callableShaderBindingStride: DeviceSize, width: u32, height: u32, depth: u32) -ProcCreateRayTracingPipelinesNV :: #type proc "system" (device: Device, pipelineCache: PipelineCache, createInfoCount: u32, pCreateInfos: [^]RayTracingPipelineCreateInfoNV, pAllocator: ^AllocationCallbacks, pPipelines: [^]Pipeline) -> Result -ProcGetRayTracingShaderGroupHandlesKHR :: #type proc "system" (device: Device, pipeline: Pipeline, firstGroup: u32, groupCount: u32, dataSize: int, pData: rawptr) -> Result -ProcGetRayTracingShaderGroupHandlesNV :: #type proc "system" (device: Device, pipeline: Pipeline, firstGroup: u32, groupCount: u32, dataSize: int, pData: rawptr) -> Result -ProcGetAccelerationStructureHandleNV :: #type proc "system" (device: Device, accelerationStructure: AccelerationStructureNV, dataSize: int, pData: rawptr) -> Result -ProcCmdWriteAccelerationStructuresPropertiesNV :: #type proc "system" (commandBuffer: CommandBuffer, accelerationStructureCount: u32, pAccelerationStructures: [^]AccelerationStructureNV, queryType: QueryType, queryPool: QueryPool, firstQuery: u32) -ProcCompileDeferredNV :: #type proc "system" (device: Device, pipeline: Pipeline, shader: u32) -> Result -ProcGetMemoryHostPointerPropertiesEXT :: #type proc "system" (device: Device, handleType: ExternalMemoryHandleTypeFlags, pHostPointer: rawptr, pMemoryHostPointerProperties: [^]MemoryHostPointerPropertiesEXT) -> Result -ProcCmdWriteBufferMarkerAMD :: #type proc "system" (commandBuffer: CommandBuffer, pipelineStage: PipelineStageFlags, dstBuffer: Buffer, dstOffset: DeviceSize, marker: u32) -ProcGetPhysicalDeviceCalibrateableTimeDomainsEXT :: #type proc "system" (physicalDevice: PhysicalDevice, pTimeDomainCount: ^u32, pTimeDomains: [^]TimeDomainEXT) -> Result -ProcGetCalibratedTimestampsEXT :: #type proc "system" (device: Device, timestampCount: u32, pTimestampInfos: [^]CalibratedTimestampInfoEXT, pTimestamps: [^]u64, pMaxDeviation: ^u64) -> Result -ProcCmdDrawMeshTasksNV :: #type proc "system" (commandBuffer: CommandBuffer, taskCount: u32, firstTask: u32) -ProcCmdDrawMeshTasksIndirectNV :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, drawCount: u32, stride: u32) -ProcCmdDrawMeshTasksIndirectCountNV :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, countBuffer: Buffer, countBufferOffset: DeviceSize, maxDrawCount: u32, stride: u32) -ProcCmdSetExclusiveScissorNV :: #type proc "system" (commandBuffer: CommandBuffer, firstExclusiveScissor: u32, exclusiveScissorCount: u32, pExclusiveScissors: [^]Rect2D) -ProcCmdSetCheckpointNV :: #type proc "system" (commandBuffer: CommandBuffer, pCheckpointMarker: rawptr) -ProcGetQueueCheckpointDataNV :: #type proc "system" (queue: Queue, pCheckpointDataCount: ^u32, pCheckpointData: ^CheckpointDataNV) -ProcInitializePerformanceApiINTEL :: #type proc "system" (device: Device, pInitializeInfo: ^InitializePerformanceApiInfoINTEL) -> Result -ProcUninitializePerformanceApiINTEL :: #type proc "system" (device: Device) -ProcCmdSetPerformanceMarkerINTEL :: #type proc "system" (commandBuffer: CommandBuffer, pMarkerInfo: ^PerformanceMarkerInfoINTEL) -> Result -ProcCmdSetPerformanceStreamMarkerINTEL :: #type proc "system" (commandBuffer: CommandBuffer, pMarkerInfo: ^PerformanceStreamMarkerInfoINTEL) -> Result -ProcCmdSetPerformanceOverrideINTEL :: #type proc "system" (commandBuffer: CommandBuffer, pOverrideInfo: ^PerformanceOverrideInfoINTEL) -> Result -ProcAcquirePerformanceConfigurationINTEL :: #type proc "system" (device: Device, pAcquireInfo: ^PerformanceConfigurationAcquireInfoINTEL, pConfiguration: ^PerformanceConfigurationINTEL) -> Result -ProcReleasePerformanceConfigurationINTEL :: #type proc "system" (device: Device, configuration: PerformanceConfigurationINTEL) -> Result -ProcQueueSetPerformanceConfigurationINTEL :: #type proc "system" (queue: Queue, configuration: PerformanceConfigurationINTEL) -> Result -ProcGetPerformanceParameterINTEL :: #type proc "system" (device: Device, parameter: PerformanceParameterTypeINTEL, pValue: ^PerformanceValueINTEL) -> Result -ProcSetLocalDimmingAMD :: #type proc "system" (device: Device, swapChain: SwapchainKHR, localDimmingEnable: b32) -ProcGetBufferDeviceAddressEXT :: #type proc "system" (device: Device, pInfo: ^BufferDeviceAddressInfo) -> DeviceAddress -ProcGetPhysicalDeviceToolPropertiesEXT :: #type proc "system" (physicalDevice: PhysicalDevice, pToolCount: ^u32, pToolProperties: [^]PhysicalDeviceToolPropertiesEXT) -> Result -ProcGetPhysicalDeviceCooperativeMatrixPropertiesNV :: #type proc "system" (physicalDevice: PhysicalDevice, pPropertyCount: ^u32, pProperties: [^]CooperativeMatrixPropertiesNV) -> Result -ProcGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV :: #type proc "system" (physicalDevice: PhysicalDevice, pCombinationCount: ^u32, pCombinations: [^]FramebufferMixedSamplesCombinationNV) -> Result -ProcCreateHeadlessSurfaceEXT :: #type proc "system" (instance: Instance, pCreateInfo: ^HeadlessSurfaceCreateInfoEXT, pAllocator: ^AllocationCallbacks, pSurface: ^SurfaceKHR) -> Result -ProcCmdSetLineStippleEXT :: #type proc "system" (commandBuffer: CommandBuffer, lineStippleFactor: u32, lineStipplePattern: u16) -ProcResetQueryPoolEXT :: #type proc "system" (device: Device, queryPool: QueryPool, firstQuery: u32, queryCount: u32) -ProcCmdSetCullModeEXT :: #type proc "system" (commandBuffer: CommandBuffer, cullMode: CullModeFlags) -ProcCmdSetFrontFaceEXT :: #type proc "system" (commandBuffer: CommandBuffer, frontFace: FrontFace) -ProcCmdSetPrimitiveTopologyEXT :: #type proc "system" (commandBuffer: CommandBuffer, primitiveTopology: PrimitiveTopology) -ProcCmdSetViewportWithCountEXT :: #type proc "system" (commandBuffer: CommandBuffer, viewportCount: u32, pViewports: [^]Viewport) -ProcCmdSetScissorWithCountEXT :: #type proc "system" (commandBuffer: CommandBuffer, scissorCount: u32, pScissors: [^]Rect2D) -ProcCmdBindVertexBuffers2EXT :: #type proc "system" (commandBuffer: CommandBuffer, firstBinding: u32, bindingCount: u32, pBuffers: [^]Buffer, pOffsets: [^]DeviceSize, pSizes: [^]DeviceSize, pStrides: [^]DeviceSize) -ProcCmdSetDepthTestEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, depthTestEnable: b32) -ProcCmdSetDepthWriteEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, depthWriteEnable: b32) -ProcCmdSetDepthCompareOpEXT :: #type proc "system" (commandBuffer: CommandBuffer, depthCompareOp: CompareOp) -ProcCmdSetDepthBoundsTestEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, depthBoundsTestEnable: b32) -ProcCmdSetStencilTestEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, stencilTestEnable: b32) -ProcCmdSetStencilOpEXT :: #type proc "system" (commandBuffer: CommandBuffer, faceMask: StencilFaceFlags, failOp: StencilOp, passOp: StencilOp, depthFailOp: StencilOp, compareOp: CompareOp) -ProcGetGeneratedCommandsMemoryRequirementsNV :: #type proc "system" (device: Device, pInfo: ^GeneratedCommandsMemoryRequirementsInfoNV, pMemoryRequirements: [^]MemoryRequirements2) -ProcCmdPreprocessGeneratedCommandsNV :: #type proc "system" (commandBuffer: CommandBuffer, pGeneratedCommandsInfo: ^GeneratedCommandsInfoNV) -ProcCmdExecuteGeneratedCommandsNV :: #type proc "system" (commandBuffer: CommandBuffer, isPreprocessed: b32, pGeneratedCommandsInfo: ^GeneratedCommandsInfoNV) -ProcCmdBindPipelineShaderGroupNV :: #type proc "system" (commandBuffer: CommandBuffer, pipelineBindPoint: PipelineBindPoint, pipeline: Pipeline, groupIndex: u32) -ProcCreateIndirectCommandsLayoutNV :: #type proc "system" (device: Device, pCreateInfo: ^IndirectCommandsLayoutCreateInfoNV, pAllocator: ^AllocationCallbacks, pIndirectCommandsLayout: ^IndirectCommandsLayoutNV) -> Result -ProcDestroyIndirectCommandsLayoutNV :: #type proc "system" (device: Device, indirectCommandsLayout: IndirectCommandsLayoutNV, pAllocator: ^AllocationCallbacks) -ProcDeviceMemoryReportCallbackEXT :: #type proc "system" (pCallbackData: ^DeviceMemoryReportCallbackDataEXT, pUserData: rawptr) +// Misc Procedure Types +ProcAllocationFunction :: #type proc "system" (pUserData: rawptr, size: int, alignment: int, allocationScope: SystemAllocationScope) -> rawptr +ProcDebugReportCallbackEXT :: #type proc "system" (flags: DebugReportFlagsEXT, objectType: DebugReportObjectTypeEXT, object: u64, location: int, messageCode: i32, pLayerPrefix: cstring, pMessage: cstring, pUserData: rawptr) -> b32 +ProcFreeFunction :: #type proc "system" (pUserData: rawptr, pMemory: rawptr) +ProcInternalAllocationNotification :: #type proc "system" (pUserData: rawptr, size: int, allocationType: InternalAllocationType, allocationScope: SystemAllocationScope) +ProcInternalFreeNotification :: #type proc "system" (pUserData: rawptr, size: int, allocationType: InternalAllocationType, allocationScope: SystemAllocationScope) +ProcReallocationFunction :: #type proc "system" (pUserData: rawptr, pOriginal: rawptr, size: int, alignment: int, allocationScope: SystemAllocationScope) -> rawptr +ProcVoidFunction :: #type proc "system" () + +// Instance Procedure Types ProcAcquireDrmDisplayEXT :: #type proc "system" (physicalDevice: PhysicalDevice, drmFd: i32, display: DisplayKHR) -> Result -ProcGetDrmDisplayEXT :: #type proc "system" (physicalDevice: PhysicalDevice, drmFd: i32, connectorId: u32, display: ^DisplayKHR) -> Result -ProcCreatePrivateDataSlotEXT :: #type proc "system" (device: Device, pCreateInfo: ^PrivateDataSlotCreateInfoEXT, pAllocator: ^AllocationCallbacks, pPrivateDataSlot: ^PrivateDataSlotEXT) -> Result -ProcDestroyPrivateDataSlotEXT :: #type proc "system" (device: Device, privateDataSlot: PrivateDataSlotEXT, pAllocator: ^AllocationCallbacks) -ProcSetPrivateDataEXT :: #type proc "system" (device: Device, objectType: ObjectType, objectHandle: u64, privateDataSlot: PrivateDataSlotEXT, data: u64) -> Result -ProcGetPrivateDataEXT :: #type proc "system" (device: Device, objectType: ObjectType, objectHandle: u64, privateDataSlot: PrivateDataSlotEXT, pData: ^u64) -ProcCmdSetFragmentShadingRateEnumNV :: #type proc "system" (commandBuffer: CommandBuffer, shadingRate: FragmentShadingRateNV) ProcAcquireWinrtDisplayNV :: #type proc "system" (physicalDevice: PhysicalDevice, display: DisplayKHR) -> Result -ProcGetWinrtDisplayNV :: #type proc "system" (physicalDevice: PhysicalDevice, deviceRelativeId: u32, pDisplay: ^DisplayKHR) -> Result -ProcCmdSetVertexInputEXT :: #type proc "system" (commandBuffer: CommandBuffer, vertexBindingDescriptionCount: u32, pVertexBindingDescriptions: [^]VertexInputBindingDescription2EXT, vertexAttributeDescriptionCount: u32, pVertexAttributeDescriptions: [^]VertexInputAttributeDescription2EXT) -ProcGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI :: #type proc "system" (device: Device, renderpass: RenderPass, pMaxWorkgroupSize: ^Extent2D) -> Result -ProcCmdSubpassShadingHUAWEI :: #type proc "system" (commandBuffer: CommandBuffer) -ProcCmdBindInvocationMaskHUAWEI :: #type proc "system" (commandBuffer: CommandBuffer, imageView: ImageView, imageLayout: ImageLayout) -ProcGetMemoryRemoteAddressNV :: #type proc "system" (device: Device, pMemoryGetRemoteAddressInfo: ^MemoryGetRemoteAddressInfoNV, pAddress: [^]RemoteAddressNV) -> Result -ProcCmdSetPatchControlPointsEXT :: #type proc "system" (commandBuffer: CommandBuffer, patchControlPoints: u32) -ProcCmdSetRasterizerDiscardEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, rasterizerDiscardEnable: b32) -ProcCmdSetDepthBiasEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, depthBiasEnable: b32) -ProcCmdSetLogicOpEXT :: #type proc "system" (commandBuffer: CommandBuffer, logicOp: LogicOp) -ProcCmdSetPrimitiveRestartEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, primitiveRestartEnable: b32) -ProcCmdDrawMultiEXT :: #type proc "system" (commandBuffer: CommandBuffer, drawCount: u32, pVertexInfo: ^MultiDrawInfoEXT, instanceCount: u32, firstInstance: u32, stride: u32) -ProcCmdDrawMultiIndexedEXT :: #type proc "system" (commandBuffer: CommandBuffer, drawCount: u32, pIndexInfo: ^MultiDrawIndexedInfoEXT, instanceCount: u32, firstInstance: u32, stride: u32, pVertexOffset: ^i32) -ProcSetDeviceMemoryPriorityEXT :: #type proc "system" (device: Device, memory: DeviceMemory, priority: f32) -ProcCreateAccelerationStructureKHR :: #type proc "system" (device: Device, pCreateInfo: ^AccelerationStructureCreateInfoKHR, pAllocator: ^AllocationCallbacks, pAccelerationStructure: ^AccelerationStructureKHR) -> Result -ProcDestroyAccelerationStructureKHR :: #type proc "system" (device: Device, accelerationStructure: AccelerationStructureKHR, pAllocator: ^AllocationCallbacks) -ProcCmdBuildAccelerationStructuresKHR :: #type proc "system" (commandBuffer: CommandBuffer, infoCount: u32, pInfos: [^]AccelerationStructureBuildGeometryInfoKHR, ppBuildRangeInfos: ^[^]AccelerationStructureBuildRangeInfoKHR) -ProcCmdBuildAccelerationStructuresIndirectKHR :: #type proc "system" (commandBuffer: CommandBuffer, infoCount: u32, pInfos: [^]AccelerationStructureBuildGeometryInfoKHR, pIndirectDeviceAddresses: [^]DeviceAddress, pIndirectStrides: [^]u32, ppMaxPrimitiveCounts: ^[^]u32) -ProcBuildAccelerationStructuresKHR :: #type proc "system" (device: Device, deferredOperation: DeferredOperationKHR, infoCount: u32, pInfos: [^]AccelerationStructureBuildGeometryInfoKHR, ppBuildRangeInfos: ^[^]AccelerationStructureBuildRangeInfoKHR) -> Result -ProcCopyAccelerationStructureKHR :: #type proc "system" (device: Device, deferredOperation: DeferredOperationKHR, pInfo: ^CopyAccelerationStructureInfoKHR) -> Result -ProcCopyAccelerationStructureToMemoryKHR :: #type proc "system" (device: Device, deferredOperation: DeferredOperationKHR, pInfo: ^CopyAccelerationStructureToMemoryInfoKHR) -> Result -ProcCopyMemoryToAccelerationStructureKHR :: #type proc "system" (device: Device, deferredOperation: DeferredOperationKHR, pInfo: ^CopyMemoryToAccelerationStructureInfoKHR) -> Result -ProcWriteAccelerationStructuresPropertiesKHR :: #type proc "system" (device: Device, accelerationStructureCount: u32, pAccelerationStructures: [^]AccelerationStructureKHR, queryType: QueryType, dataSize: int, pData: rawptr, stride: int) -> Result -ProcCmdCopyAccelerationStructureKHR :: #type proc "system" (commandBuffer: CommandBuffer, pInfo: ^CopyAccelerationStructureInfoKHR) -ProcCmdCopyAccelerationStructureToMemoryKHR :: #type proc "system" (commandBuffer: CommandBuffer, pInfo: ^CopyAccelerationStructureToMemoryInfoKHR) -ProcCmdCopyMemoryToAccelerationStructureKHR :: #type proc "system" (commandBuffer: CommandBuffer, pInfo: ^CopyMemoryToAccelerationStructureInfoKHR) -ProcGetAccelerationStructureDeviceAddressKHR :: #type proc "system" (device: Device, pInfo: ^AccelerationStructureDeviceAddressInfoKHR) -> DeviceAddress -ProcCmdWriteAccelerationStructuresPropertiesKHR :: #type proc "system" (commandBuffer: CommandBuffer, accelerationStructureCount: u32, pAccelerationStructures: [^]AccelerationStructureKHR, queryType: QueryType, queryPool: QueryPool, firstQuery: u32) -ProcGetDeviceAccelerationStructureCompatibilityKHR :: #type proc "system" (device: Device, pVersionInfo: ^AccelerationStructureVersionInfoKHR, pCompatibility: ^AccelerationStructureCompatibilityKHR) -ProcGetAccelerationStructureBuildSizesKHR :: #type proc "system" (device: Device, buildType: AccelerationStructureBuildTypeKHR, pBuildInfo: ^AccelerationStructureBuildGeometryInfoKHR, pMaxPrimitiveCounts: [^]u32, pSizeInfo: ^AccelerationStructureBuildSizesInfoKHR) -ProcCmdTraceRaysKHR :: #type proc "system" (commandBuffer: CommandBuffer, pRaygenShaderBindingTable: [^]StridedDeviceAddressRegionKHR, pMissShaderBindingTable: [^]StridedDeviceAddressRegionKHR, pHitShaderBindingTable: [^]StridedDeviceAddressRegionKHR, pCallableShaderBindingTable: [^]StridedDeviceAddressRegionKHR, width: u32, height: u32, depth: u32) -ProcCreateRayTracingPipelinesKHR :: #type proc "system" (device: Device, deferredOperation: DeferredOperationKHR, pipelineCache: PipelineCache, createInfoCount: u32, pCreateInfos: [^]RayTracingPipelineCreateInfoKHR, pAllocator: ^AllocationCallbacks, pPipelines: [^]Pipeline) -> Result -ProcGetRayTracingCaptureReplayShaderGroupHandlesKHR :: #type proc "system" (device: Device, pipeline: Pipeline, firstGroup: u32, groupCount: u32, dataSize: int, pData: rawptr) -> Result -ProcCmdTraceRaysIndirectKHR :: #type proc "system" (commandBuffer: CommandBuffer, pRaygenShaderBindingTable: [^]StridedDeviceAddressRegionKHR, pMissShaderBindingTable: [^]StridedDeviceAddressRegionKHR, pHitShaderBindingTable: [^]StridedDeviceAddressRegionKHR, pCallableShaderBindingTable: [^]StridedDeviceAddressRegionKHR, indirectDeviceAddress: DeviceAddress) -ProcGetRayTracingShaderGroupStackSizeKHR :: #type proc "system" (device: Device, pipeline: Pipeline, group: u32, groupShader: ShaderGroupShaderKHR) -> DeviceSize -ProcCmdSetRayTracingPipelineStackSizeKHR :: #type proc "system" (commandBuffer: CommandBuffer, pipelineStackSize: u32) -ProcCreateWin32SurfaceKHR :: #type proc "system" (instance: Instance, pCreateInfo: ^Win32SurfaceCreateInfoKHR, pAllocator: ^AllocationCallbacks, pSurface: ^SurfaceKHR) -> Result -ProcGetPhysicalDeviceWin32PresentationSupportKHR :: #type proc "system" (physicalDevice: PhysicalDevice, queueFamilyIndex: u32) -> b32 -ProcGetMemoryWin32HandleKHR :: #type proc "system" (device: Device, pGetWin32HandleInfo: ^MemoryGetWin32HandleInfoKHR, pHandle: ^HANDLE) -> Result -ProcGetMemoryWin32HandlePropertiesKHR :: #type proc "system" (device: Device, handleType: ExternalMemoryHandleTypeFlags, handle: HANDLE, pMemoryWin32HandleProperties: [^]MemoryWin32HandlePropertiesKHR) -> Result -ProcImportSemaphoreWin32HandleKHR :: #type proc "system" (device: Device, pImportSemaphoreWin32HandleInfo: ^ImportSemaphoreWin32HandleInfoKHR) -> Result -ProcGetSemaphoreWin32HandleKHR :: #type proc "system" (device: Device, pGetWin32HandleInfo: ^SemaphoreGetWin32HandleInfoKHR, pHandle: ^HANDLE) -> Result -ProcImportFenceWin32HandleKHR :: #type proc "system" (device: Device, pImportFenceWin32HandleInfo: ^ImportFenceWin32HandleInfoKHR) -> Result -ProcGetFenceWin32HandleKHR :: #type proc "system" (device: Device, pGetWin32HandleInfo: ^FenceGetWin32HandleInfoKHR, pHandle: ^HANDLE) -> Result -ProcGetMemoryWin32HandleNV :: #type proc "system" (device: Device, memory: DeviceMemory, handleType: ExternalMemoryHandleTypeFlagsNV, pHandle: ^HANDLE) -> Result -ProcGetPhysicalDeviceSurfacePresentModes2EXT :: #type proc "system" (physicalDevice: PhysicalDevice, pSurfaceInfo: ^PhysicalDeviceSurfaceInfo2KHR, pPresentModeCount: ^u32, pPresentModes: [^]PresentModeKHR) -> Result -ProcAcquireFullScreenExclusiveModeEXT :: #type proc "system" (device: Device, swapchain: SwapchainKHR) -> Result -ProcReleaseFullScreenExclusiveModeEXT :: #type proc "system" (device: Device, swapchain: SwapchainKHR) -> Result -ProcGetDeviceGroupSurfacePresentModes2EXT :: #type proc "system" (device: Device, pSurfaceInfo: ^PhysicalDeviceSurfaceInfo2KHR, pModes: [^]DeviceGroupPresentModeFlagsKHR) -> Result -ProcCreateMetalSurfaceEXT :: #type proc "system" (instance: Instance, pCreateInfo: ^MetalSurfaceCreateInfoEXT, pAllocator: ^AllocationCallbacks, pSurface: ^SurfaceKHR) -> Result -ProcCreateMacOSSurfaceMVK :: #type proc "system" (instance: Instance, pCreateInfo: ^MacOSSurfaceCreateInfoMVK, pAllocator: ^AllocationCallbacks, pSurface: ^SurfaceKHR) -> Result +ProcCreateDebugReportCallbackEXT :: #type proc "system" (instance: Instance, pCreateInfo: ^DebugReportCallbackCreateInfoEXT, pAllocator: ^AllocationCallbacks, pCallback: ^DebugReportCallbackEXT) -> Result +ProcCreateDebugUtilsMessengerEXT :: #type proc "system" (instance: Instance, pCreateInfo: ^DebugUtilsMessengerCreateInfoEXT, pAllocator: ^AllocationCallbacks, pMessenger: ^DebugUtilsMessengerEXT) -> Result +ProcCreateDevice :: #type proc "system" (physicalDevice: PhysicalDevice, pCreateInfo: ^DeviceCreateInfo, pAllocator: ^AllocationCallbacks, pDevice: ^Device) -> Result +ProcCreateDisplayModeKHR :: #type proc "system" (physicalDevice: PhysicalDevice, display: DisplayKHR, pCreateInfo: ^DisplayModeCreateInfoKHR, pAllocator: ^AllocationCallbacks, pMode: ^DisplayModeKHR) -> Result +ProcCreateDisplayPlaneSurfaceKHR :: #type proc "system" (instance: Instance, pCreateInfo: ^DisplaySurfaceCreateInfoKHR, pAllocator: ^AllocationCallbacks, pSurface: ^SurfaceKHR) -> Result +ProcCreateHeadlessSurfaceEXT :: #type proc "system" (instance: Instance, pCreateInfo: ^HeadlessSurfaceCreateInfoEXT, pAllocator: ^AllocationCallbacks, pSurface: ^SurfaceKHR) -> Result ProcCreateIOSSurfaceMVK :: #type proc "system" (instance: Instance, pCreateInfo: ^IOSSurfaceCreateInfoMVK, pAllocator: ^AllocationCallbacks, pSurface: ^SurfaceKHR) -> Result +ProcCreateMacOSSurfaceMVK :: #type proc "system" (instance: Instance, pCreateInfo: ^MacOSSurfaceCreateInfoMVK, pAllocator: ^AllocationCallbacks, pSurface: ^SurfaceKHR) -> Result +ProcCreateMetalSurfaceEXT :: #type proc "system" (instance: Instance, pCreateInfo: ^MetalSurfaceCreateInfoEXT, pAllocator: ^AllocationCallbacks, pSurface: ^SurfaceKHR) -> Result +ProcCreateWin32SurfaceKHR :: #type proc "system" (instance: Instance, pCreateInfo: ^Win32SurfaceCreateInfoKHR, pAllocator: ^AllocationCallbacks, pSurface: ^SurfaceKHR) -> Result +ProcDebugReportMessageEXT :: #type proc "system" (instance: Instance, flags: DebugReportFlagsEXT, objectType: DebugReportObjectTypeEXT, object: u64, location: int, messageCode: i32, pLayerPrefix: cstring, pMessage: cstring) +ProcDestroyDebugReportCallbackEXT :: #type proc "system" (instance: Instance, callback: DebugReportCallbackEXT, pAllocator: ^AllocationCallbacks) +ProcDestroyDebugUtilsMessengerEXT :: #type proc "system" (instance: Instance, messenger: DebugUtilsMessengerEXT, pAllocator: ^AllocationCallbacks) +ProcDestroyInstance :: #type proc "system" (instance: Instance, pAllocator: ^AllocationCallbacks) +ProcDestroySurfaceKHR :: #type proc "system" (instance: Instance, surface: SurfaceKHR, pAllocator: ^AllocationCallbacks) +ProcEnumerateDeviceExtensionProperties :: #type proc "system" (physicalDevice: PhysicalDevice, pLayerName: cstring, pPropertyCount: ^u32, pProperties: [^]ExtensionProperties) -> Result +ProcEnumerateDeviceLayerProperties :: #type proc "system" (physicalDevice: PhysicalDevice, pPropertyCount: ^u32, pProperties: [^]LayerProperties) -> Result +ProcEnumeratePhysicalDeviceGroups :: #type proc "system" (instance: Instance, pPhysicalDeviceGroupCount: ^u32, pPhysicalDeviceGroupProperties: [^]PhysicalDeviceGroupProperties) -> Result +ProcEnumeratePhysicalDeviceGroupsKHR :: #type proc "system" (instance: Instance, pPhysicalDeviceGroupCount: ^u32, pPhysicalDeviceGroupProperties: [^]PhysicalDeviceGroupProperties) -> Result +ProcEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR :: #type proc "system" (physicalDevice: PhysicalDevice, queueFamilyIndex: u32, pCounterCount: ^u32, pCounters: [^]PerformanceCounterKHR, pCounterDescriptions: [^]PerformanceCounterDescriptionKHR) -> Result +ProcEnumeratePhysicalDevices :: #type proc "system" (instance: Instance, pPhysicalDeviceCount: ^u32, pPhysicalDevices: [^]PhysicalDevice) -> Result +ProcGetDisplayModeProperties2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, display: DisplayKHR, pPropertyCount: ^u32, pProperties: [^]DisplayModeProperties2KHR) -> Result +ProcGetDisplayModePropertiesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, display: DisplayKHR, pPropertyCount: ^u32, pProperties: [^]DisplayModePropertiesKHR) -> Result +ProcGetDisplayPlaneCapabilities2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pDisplayPlaneInfo: ^DisplayPlaneInfo2KHR, pCapabilities: [^]DisplayPlaneCapabilities2KHR) -> Result +ProcGetDisplayPlaneCapabilitiesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, mode: DisplayModeKHR, planeIndex: u32, pCapabilities: [^]DisplayPlaneCapabilitiesKHR) -> Result +ProcGetDisplayPlaneSupportedDisplaysKHR :: #type proc "system" (physicalDevice: PhysicalDevice, planeIndex: u32, pDisplayCount: ^u32, pDisplays: [^]DisplayKHR) -> Result +ProcGetDrmDisplayEXT :: #type proc "system" (physicalDevice: PhysicalDevice, drmFd: i32, connectorId: u32, display: ^DisplayKHR) -> Result +ProcGetInstanceProcAddr :: #type proc "system" (instance: Instance, pName: cstring) -> ProcVoidFunction +ProcGetPhysicalDeviceCalibrateableTimeDomainsEXT :: #type proc "system" (physicalDevice: PhysicalDevice, pTimeDomainCount: ^u32, pTimeDomains: [^]TimeDomainEXT) -> Result +ProcGetPhysicalDeviceCooperativeMatrixPropertiesNV :: #type proc "system" (physicalDevice: PhysicalDevice, pPropertyCount: ^u32, pProperties: [^]CooperativeMatrixPropertiesNV) -> Result +ProcGetPhysicalDeviceDisplayPlaneProperties2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pPropertyCount: ^u32, pProperties: [^]DisplayPlaneProperties2KHR) -> Result +ProcGetPhysicalDeviceDisplayPlanePropertiesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, pPropertyCount: ^u32, pProperties: [^]DisplayPlanePropertiesKHR) -> Result +ProcGetPhysicalDeviceDisplayProperties2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pPropertyCount: ^u32, pProperties: [^]DisplayProperties2KHR) -> Result +ProcGetPhysicalDeviceDisplayPropertiesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, pPropertyCount: ^u32, pProperties: [^]DisplayPropertiesKHR) -> Result +ProcGetPhysicalDeviceExternalBufferProperties :: #type proc "system" (physicalDevice: PhysicalDevice, pExternalBufferInfo: ^PhysicalDeviceExternalBufferInfo, pExternalBufferProperties: [^]ExternalBufferProperties) +ProcGetPhysicalDeviceExternalBufferPropertiesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, pExternalBufferInfo: ^PhysicalDeviceExternalBufferInfo, pExternalBufferProperties: [^]ExternalBufferProperties) +ProcGetPhysicalDeviceExternalFenceProperties :: #type proc "system" (physicalDevice: PhysicalDevice, pExternalFenceInfo: ^PhysicalDeviceExternalFenceInfo, pExternalFenceProperties: [^]ExternalFenceProperties) +ProcGetPhysicalDeviceExternalFencePropertiesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, pExternalFenceInfo: ^PhysicalDeviceExternalFenceInfo, pExternalFenceProperties: [^]ExternalFenceProperties) +ProcGetPhysicalDeviceExternalImageFormatPropertiesNV :: #type proc "system" (physicalDevice: PhysicalDevice, format: Format, type: ImageType, tiling: ImageTiling, usage: ImageUsageFlags, flags: ImageCreateFlags, externalHandleType: ExternalMemoryHandleTypeFlagsNV, pExternalImageFormatProperties: [^]ExternalImageFormatPropertiesNV) -> Result +ProcGetPhysicalDeviceExternalSemaphoreProperties :: #type proc "system" (physicalDevice: PhysicalDevice, pExternalSemaphoreInfo: ^PhysicalDeviceExternalSemaphoreInfo, pExternalSemaphoreProperties: [^]ExternalSemaphoreProperties) +ProcGetPhysicalDeviceExternalSemaphorePropertiesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, pExternalSemaphoreInfo: ^PhysicalDeviceExternalSemaphoreInfo, pExternalSemaphoreProperties: [^]ExternalSemaphoreProperties) +ProcGetPhysicalDeviceFeatures :: #type proc "system" (physicalDevice: PhysicalDevice, pFeatures: [^]PhysicalDeviceFeatures) +ProcGetPhysicalDeviceFeatures2 :: #type proc "system" (physicalDevice: PhysicalDevice, pFeatures: [^]PhysicalDeviceFeatures2) +ProcGetPhysicalDeviceFeatures2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pFeatures: [^]PhysicalDeviceFeatures2) +ProcGetPhysicalDeviceFormatProperties :: #type proc "system" (physicalDevice: PhysicalDevice, format: Format, pFormatProperties: [^]FormatProperties) +ProcGetPhysicalDeviceFormatProperties2 :: #type proc "system" (physicalDevice: PhysicalDevice, format: Format, pFormatProperties: [^]FormatProperties2) +ProcGetPhysicalDeviceFormatProperties2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, format: Format, pFormatProperties: [^]FormatProperties2) +ProcGetPhysicalDeviceFragmentShadingRatesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, pFragmentShadingRateCount: ^u32, pFragmentShadingRates: [^]PhysicalDeviceFragmentShadingRateKHR) -> Result +ProcGetPhysicalDeviceImageFormatProperties :: #type proc "system" (physicalDevice: PhysicalDevice, format: Format, type: ImageType, tiling: ImageTiling, usage: ImageUsageFlags, flags: ImageCreateFlags, pImageFormatProperties: [^]ImageFormatProperties) -> Result +ProcGetPhysicalDeviceImageFormatProperties2 :: #type proc "system" (physicalDevice: PhysicalDevice, pImageFormatInfo: ^PhysicalDeviceImageFormatInfo2, pImageFormatProperties: [^]ImageFormatProperties2) -> Result +ProcGetPhysicalDeviceImageFormatProperties2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pImageFormatInfo: ^PhysicalDeviceImageFormatInfo2, pImageFormatProperties: [^]ImageFormatProperties2) -> Result +ProcGetPhysicalDeviceMemoryProperties :: #type proc "system" (physicalDevice: PhysicalDevice, pMemoryProperties: [^]PhysicalDeviceMemoryProperties) +ProcGetPhysicalDeviceMemoryProperties2 :: #type proc "system" (physicalDevice: PhysicalDevice, pMemoryProperties: [^]PhysicalDeviceMemoryProperties2) +ProcGetPhysicalDeviceMemoryProperties2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pMemoryProperties: [^]PhysicalDeviceMemoryProperties2) +ProcGetPhysicalDeviceMultisamplePropertiesEXT :: #type proc "system" (physicalDevice: PhysicalDevice, samples: SampleCountFlags, pMultisampleProperties: [^]MultisamplePropertiesEXT) +ProcGetPhysicalDevicePresentRectanglesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, surface: SurfaceKHR, pRectCount: ^u32, pRects: [^]Rect2D) -> Result +ProcGetPhysicalDeviceProperties :: #type proc "system" (physicalDevice: PhysicalDevice, pProperties: [^]PhysicalDeviceProperties) +ProcGetPhysicalDeviceProperties2 :: #type proc "system" (physicalDevice: PhysicalDevice, pProperties: [^]PhysicalDeviceProperties2) +ProcGetPhysicalDeviceProperties2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pProperties: [^]PhysicalDeviceProperties2) +ProcGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, pPerformanceQueryCreateInfo: ^QueryPoolPerformanceCreateInfoKHR, pNumPasses: [^]u32) +ProcGetPhysicalDeviceQueueFamilyProperties :: #type proc "system" (physicalDevice: PhysicalDevice, pQueueFamilyPropertyCount: ^u32, pQueueFamilyProperties: [^]QueueFamilyProperties) +ProcGetPhysicalDeviceQueueFamilyProperties2 :: #type proc "system" (physicalDevice: PhysicalDevice, pQueueFamilyPropertyCount: ^u32, pQueueFamilyProperties: [^]QueueFamilyProperties2) +ProcGetPhysicalDeviceQueueFamilyProperties2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pQueueFamilyPropertyCount: ^u32, pQueueFamilyProperties: [^]QueueFamilyProperties2) +ProcGetPhysicalDeviceSparseImageFormatProperties :: #type proc "system" (physicalDevice: PhysicalDevice, format: Format, type: ImageType, samples: SampleCountFlags, usage: ImageUsageFlags, tiling: ImageTiling, pPropertyCount: ^u32, pProperties: [^]SparseImageFormatProperties) +ProcGetPhysicalDeviceSparseImageFormatProperties2 :: #type proc "system" (physicalDevice: PhysicalDevice, pFormatInfo: ^PhysicalDeviceSparseImageFormatInfo2, pPropertyCount: ^u32, pProperties: [^]SparseImageFormatProperties2) +ProcGetPhysicalDeviceSparseImageFormatProperties2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pFormatInfo: ^PhysicalDeviceSparseImageFormatInfo2, pPropertyCount: ^u32, pProperties: [^]SparseImageFormatProperties2) +ProcGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV :: #type proc "system" (physicalDevice: PhysicalDevice, pCombinationCount: ^u32, pCombinations: [^]FramebufferMixedSamplesCombinationNV) -> Result +ProcGetPhysicalDeviceSurfaceCapabilities2EXT :: #type proc "system" (physicalDevice: PhysicalDevice, surface: SurfaceKHR, pSurfaceCapabilities: [^]SurfaceCapabilities2EXT) -> Result +ProcGetPhysicalDeviceSurfaceCapabilities2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pSurfaceInfo: ^PhysicalDeviceSurfaceInfo2KHR, pSurfaceCapabilities: [^]SurfaceCapabilities2KHR) -> Result +ProcGetPhysicalDeviceSurfaceCapabilitiesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, surface: SurfaceKHR, pSurfaceCapabilities: [^]SurfaceCapabilitiesKHR) -> Result +ProcGetPhysicalDeviceSurfaceFormats2KHR :: #type proc "system" (physicalDevice: PhysicalDevice, pSurfaceInfo: ^PhysicalDeviceSurfaceInfo2KHR, pSurfaceFormatCount: ^u32, pSurfaceFormats: [^]SurfaceFormat2KHR) -> Result +ProcGetPhysicalDeviceSurfaceFormatsKHR :: #type proc "system" (physicalDevice: PhysicalDevice, surface: SurfaceKHR, pSurfaceFormatCount: ^u32, pSurfaceFormats: [^]SurfaceFormatKHR) -> Result +ProcGetPhysicalDeviceSurfacePresentModes2EXT :: #type proc "system" (physicalDevice: PhysicalDevice, pSurfaceInfo: ^PhysicalDeviceSurfaceInfo2KHR, pPresentModeCount: ^u32, pPresentModes: [^]PresentModeKHR) -> Result +ProcGetPhysicalDeviceSurfacePresentModesKHR :: #type proc "system" (physicalDevice: PhysicalDevice, surface: SurfaceKHR, pPresentModeCount: ^u32, pPresentModes: [^]PresentModeKHR) -> Result +ProcGetPhysicalDeviceSurfaceSupportKHR :: #type proc "system" (physicalDevice: PhysicalDevice, queueFamilyIndex: u32, surface: SurfaceKHR, pSupported: ^b32) -> Result +ProcGetPhysicalDeviceToolProperties :: #type proc "system" (physicalDevice: PhysicalDevice, pToolCount: ^u32, pToolProperties: [^]PhysicalDeviceToolProperties) -> Result +ProcGetPhysicalDeviceToolPropertiesEXT :: #type proc "system" (physicalDevice: PhysicalDevice, pToolCount: ^u32, pToolProperties: [^]PhysicalDeviceToolProperties) -> Result +ProcGetPhysicalDeviceWin32PresentationSupportKHR :: #type proc "system" (physicalDevice: PhysicalDevice, queueFamilyIndex: u32) -> b32 +ProcGetWinrtDisplayNV :: #type proc "system" (physicalDevice: PhysicalDevice, deviceRelativeId: u32, pDisplay: ^DisplayKHR) -> Result +ProcReleaseDisplayEXT :: #type proc "system" (physicalDevice: PhysicalDevice, display: DisplayKHR) -> Result +ProcSubmitDebugUtilsMessageEXT :: #type proc "system" (instance: Instance, messageSeverity: DebugUtilsMessageSeverityFlagsEXT, messageTypes: DebugUtilsMessageTypeFlagsEXT, pCallbackData: ^DebugUtilsMessengerCallbackDataEXT) -// Instance Procedures -DestroyInstance: ProcDestroyInstance -EnumeratePhysicalDevices: ProcEnumeratePhysicalDevices -GetPhysicalDeviceFeatures: ProcGetPhysicalDeviceFeatures -GetPhysicalDeviceFormatProperties: ProcGetPhysicalDeviceFormatProperties -GetPhysicalDeviceImageFormatProperties: ProcGetPhysicalDeviceImageFormatProperties -GetPhysicalDeviceProperties: ProcGetPhysicalDeviceProperties -GetPhysicalDeviceQueueFamilyProperties: ProcGetPhysicalDeviceQueueFamilyProperties -GetPhysicalDeviceMemoryProperties: ProcGetPhysicalDeviceMemoryProperties -GetInstanceProcAddr: ProcGetInstanceProcAddr -CreateDevice: ProcCreateDevice -EnumerateDeviceExtensionProperties: ProcEnumerateDeviceExtensionProperties -EnumerateDeviceLayerProperties: ProcEnumerateDeviceLayerProperties -GetPhysicalDeviceSparseImageFormatProperties: ProcGetPhysicalDeviceSparseImageFormatProperties -EnumeratePhysicalDeviceGroups: ProcEnumeratePhysicalDeviceGroups -GetPhysicalDeviceFeatures2: ProcGetPhysicalDeviceFeatures2 -GetPhysicalDeviceProperties2: ProcGetPhysicalDeviceProperties2 -GetPhysicalDeviceFormatProperties2: ProcGetPhysicalDeviceFormatProperties2 -GetPhysicalDeviceImageFormatProperties2: ProcGetPhysicalDeviceImageFormatProperties2 -GetPhysicalDeviceQueueFamilyProperties2: ProcGetPhysicalDeviceQueueFamilyProperties2 -GetPhysicalDeviceMemoryProperties2: ProcGetPhysicalDeviceMemoryProperties2 -GetPhysicalDeviceSparseImageFormatProperties2: ProcGetPhysicalDeviceSparseImageFormatProperties2 -GetPhysicalDeviceExternalBufferProperties: ProcGetPhysicalDeviceExternalBufferProperties -GetPhysicalDeviceExternalFenceProperties: ProcGetPhysicalDeviceExternalFenceProperties -GetPhysicalDeviceExternalSemaphoreProperties: ProcGetPhysicalDeviceExternalSemaphoreProperties -DestroySurfaceKHR: ProcDestroySurfaceKHR -GetPhysicalDeviceSurfaceSupportKHR: ProcGetPhysicalDeviceSurfaceSupportKHR -GetPhysicalDeviceSurfaceCapabilitiesKHR: ProcGetPhysicalDeviceSurfaceCapabilitiesKHR -GetPhysicalDeviceSurfaceFormatsKHR: ProcGetPhysicalDeviceSurfaceFormatsKHR -GetPhysicalDeviceSurfacePresentModesKHR: ProcGetPhysicalDeviceSurfacePresentModesKHR -GetPhysicalDevicePresentRectanglesKHR: ProcGetPhysicalDevicePresentRectanglesKHR -GetPhysicalDeviceDisplayPropertiesKHR: ProcGetPhysicalDeviceDisplayPropertiesKHR -GetPhysicalDeviceDisplayPlanePropertiesKHR: ProcGetPhysicalDeviceDisplayPlanePropertiesKHR -GetDisplayPlaneSupportedDisplaysKHR: ProcGetDisplayPlaneSupportedDisplaysKHR -GetDisplayModePropertiesKHR: ProcGetDisplayModePropertiesKHR -CreateDisplayModeKHR: ProcCreateDisplayModeKHR -GetDisplayPlaneCapabilitiesKHR: ProcGetDisplayPlaneCapabilitiesKHR -CreateDisplayPlaneSurfaceKHR: ProcCreateDisplayPlaneSurfaceKHR -GetPhysicalDeviceFeatures2KHR: ProcGetPhysicalDeviceFeatures2KHR -GetPhysicalDeviceProperties2KHR: ProcGetPhysicalDeviceProperties2KHR -GetPhysicalDeviceFormatProperties2KHR: ProcGetPhysicalDeviceFormatProperties2KHR -GetPhysicalDeviceImageFormatProperties2KHR: ProcGetPhysicalDeviceImageFormatProperties2KHR -GetPhysicalDeviceQueueFamilyProperties2KHR: ProcGetPhysicalDeviceQueueFamilyProperties2KHR -GetPhysicalDeviceMemoryProperties2KHR: ProcGetPhysicalDeviceMemoryProperties2KHR -GetPhysicalDeviceSparseImageFormatProperties2KHR: ProcGetPhysicalDeviceSparseImageFormatProperties2KHR -EnumeratePhysicalDeviceGroupsKHR: ProcEnumeratePhysicalDeviceGroupsKHR -GetPhysicalDeviceExternalBufferPropertiesKHR: ProcGetPhysicalDeviceExternalBufferPropertiesKHR -GetPhysicalDeviceExternalSemaphorePropertiesKHR: ProcGetPhysicalDeviceExternalSemaphorePropertiesKHR -GetPhysicalDeviceExternalFencePropertiesKHR: ProcGetPhysicalDeviceExternalFencePropertiesKHR -EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR: ProcEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR -GetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR: ProcGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR -GetPhysicalDeviceSurfaceCapabilities2KHR: ProcGetPhysicalDeviceSurfaceCapabilities2KHR -GetPhysicalDeviceSurfaceFormats2KHR: ProcGetPhysicalDeviceSurfaceFormats2KHR -GetPhysicalDeviceDisplayProperties2KHR: ProcGetPhysicalDeviceDisplayProperties2KHR -GetPhysicalDeviceDisplayPlaneProperties2KHR: ProcGetPhysicalDeviceDisplayPlaneProperties2KHR -GetDisplayModeProperties2KHR: ProcGetDisplayModeProperties2KHR -GetDisplayPlaneCapabilities2KHR: ProcGetDisplayPlaneCapabilities2KHR -GetPhysicalDeviceFragmentShadingRatesKHR: ProcGetPhysicalDeviceFragmentShadingRatesKHR -CreateDebugReportCallbackEXT: ProcCreateDebugReportCallbackEXT -DestroyDebugReportCallbackEXT: ProcDestroyDebugReportCallbackEXT -DebugReportMessageEXT: ProcDebugReportMessageEXT -GetPhysicalDeviceExternalImageFormatPropertiesNV: ProcGetPhysicalDeviceExternalImageFormatPropertiesNV -ReleaseDisplayEXT: ProcReleaseDisplayEXT -GetPhysicalDeviceSurfaceCapabilities2EXT: ProcGetPhysicalDeviceSurfaceCapabilities2EXT -CreateDebugUtilsMessengerEXT: ProcCreateDebugUtilsMessengerEXT -DestroyDebugUtilsMessengerEXT: ProcDestroyDebugUtilsMessengerEXT -SubmitDebugUtilsMessageEXT: ProcSubmitDebugUtilsMessageEXT -GetPhysicalDeviceMultisamplePropertiesEXT: ProcGetPhysicalDeviceMultisamplePropertiesEXT -GetPhysicalDeviceCalibrateableTimeDomainsEXT: ProcGetPhysicalDeviceCalibrateableTimeDomainsEXT -GetPhysicalDeviceToolPropertiesEXT: ProcGetPhysicalDeviceToolPropertiesEXT -GetPhysicalDeviceCooperativeMatrixPropertiesNV: ProcGetPhysicalDeviceCooperativeMatrixPropertiesNV -GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV: ProcGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV -CreateHeadlessSurfaceEXT: ProcCreateHeadlessSurfaceEXT -AcquireDrmDisplayEXT: ProcAcquireDrmDisplayEXT -GetDrmDisplayEXT: ProcGetDrmDisplayEXT -AcquireWinrtDisplayNV: ProcAcquireWinrtDisplayNV -GetWinrtDisplayNV: ProcGetWinrtDisplayNV -CreateWin32SurfaceKHR: ProcCreateWin32SurfaceKHR -GetPhysicalDeviceWin32PresentationSupportKHR: ProcGetPhysicalDeviceWin32PresentationSupportKHR -GetPhysicalDeviceSurfacePresentModes2EXT: ProcGetPhysicalDeviceSurfacePresentModes2EXT -CreateMetalSurfaceEXT: ProcCreateMetalSurfaceEXT -CreateMacOSSurfaceMVK: ProcCreateMacOSSurfaceMVK -CreateIOSSurfaceMVK: ProcCreateIOSSurfaceMVK +// Device Procedure Types +ProcAcquireFullScreenExclusiveModeEXT :: #type proc "system" (device: Device, swapchain: SwapchainKHR) -> Result +ProcAcquireNextImage2KHR :: #type proc "system" (device: Device, pAcquireInfo: ^AcquireNextImageInfoKHR, pImageIndex: ^u32) -> Result +ProcAcquireNextImageKHR :: #type proc "system" (device: Device, swapchain: SwapchainKHR, timeout: u64, semaphore: Semaphore, fence: Fence, pImageIndex: ^u32) -> Result +ProcAcquirePerformanceConfigurationINTEL :: #type proc "system" (device: Device, pAcquireInfo: ^PerformanceConfigurationAcquireInfoINTEL, pConfiguration: ^PerformanceConfigurationINTEL) -> Result +ProcAcquireProfilingLockKHR :: #type proc "system" (device: Device, pInfo: ^AcquireProfilingLockInfoKHR) -> Result +ProcAllocateCommandBuffers :: #type proc "system" (device: Device, pAllocateInfo: ^CommandBufferAllocateInfo, pCommandBuffers: [^]CommandBuffer) -> Result +ProcAllocateDescriptorSets :: #type proc "system" (device: Device, pAllocateInfo: ^DescriptorSetAllocateInfo, pDescriptorSets: [^]DescriptorSet) -> Result +ProcAllocateMemory :: #type proc "system" (device: Device, pAllocateInfo: ^MemoryAllocateInfo, pAllocator: ^AllocationCallbacks, pMemory: ^DeviceMemory) -> Result +ProcBeginCommandBuffer :: #type proc "system" (commandBuffer: CommandBuffer, pBeginInfo: ^CommandBufferBeginInfo) -> Result +ProcBindAccelerationStructureMemoryNV :: #type proc "system" (device: Device, bindInfoCount: u32, pBindInfos: [^]BindAccelerationStructureMemoryInfoNV) -> Result +ProcBindBufferMemory :: #type proc "system" (device: Device, buffer: Buffer, memory: DeviceMemory, memoryOffset: DeviceSize) -> Result +ProcBindBufferMemory2 :: #type proc "system" (device: Device, bindInfoCount: u32, pBindInfos: [^]BindBufferMemoryInfo) -> Result +ProcBindBufferMemory2KHR :: #type proc "system" (device: Device, bindInfoCount: u32, pBindInfos: [^]BindBufferMemoryInfo) -> Result +ProcBindImageMemory :: #type proc "system" (device: Device, image: Image, memory: DeviceMemory, memoryOffset: DeviceSize) -> Result +ProcBindImageMemory2 :: #type proc "system" (device: Device, bindInfoCount: u32, pBindInfos: [^]BindImageMemoryInfo) -> Result +ProcBindImageMemory2KHR :: #type proc "system" (device: Device, bindInfoCount: u32, pBindInfos: [^]BindImageMemoryInfo) -> Result +ProcBuildAccelerationStructuresKHR :: #type proc "system" (device: Device, deferredOperation: DeferredOperationKHR, infoCount: u32, pInfos: [^]AccelerationStructureBuildGeometryInfoKHR, ppBuildRangeInfos: ^[^]AccelerationStructureBuildRangeInfoKHR) -> Result +ProcCmdBeginConditionalRenderingEXT :: #type proc "system" (commandBuffer: CommandBuffer, pConditionalRenderingBegin: ^ConditionalRenderingBeginInfoEXT) +ProcCmdBeginDebugUtilsLabelEXT :: #type proc "system" (commandBuffer: CommandBuffer, pLabelInfo: ^DebugUtilsLabelEXT) +ProcCmdBeginQuery :: #type proc "system" (commandBuffer: CommandBuffer, queryPool: QueryPool, query: u32, flags: QueryControlFlags) +ProcCmdBeginQueryIndexedEXT :: #type proc "system" (commandBuffer: CommandBuffer, queryPool: QueryPool, query: u32, flags: QueryControlFlags, index: u32) +ProcCmdBeginRenderPass :: #type proc "system" (commandBuffer: CommandBuffer, pRenderPassBegin: ^RenderPassBeginInfo, contents: SubpassContents) +ProcCmdBeginRenderPass2 :: #type proc "system" (commandBuffer: CommandBuffer, pRenderPassBegin: ^RenderPassBeginInfo, pSubpassBeginInfo: ^SubpassBeginInfo) +ProcCmdBeginRenderPass2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pRenderPassBegin: ^RenderPassBeginInfo, pSubpassBeginInfo: ^SubpassBeginInfo) +ProcCmdBeginRendering :: #type proc "system" (commandBuffer: CommandBuffer, pRenderingInfo: ^RenderingInfo) +ProcCmdBeginRenderingKHR :: #type proc "system" (commandBuffer: CommandBuffer, pRenderingInfo: ^RenderingInfo) +ProcCmdBeginTransformFeedbackEXT :: #type proc "system" (commandBuffer: CommandBuffer, firstCounterBuffer: u32, counterBufferCount: u32, pCounterBuffers: [^]Buffer, pCounterBufferOffsets: [^]DeviceSize) +ProcCmdBindDescriptorSets :: #type proc "system" (commandBuffer: CommandBuffer, pipelineBindPoint: PipelineBindPoint, layout: PipelineLayout, firstSet: u32, descriptorSetCount: u32, pDescriptorSets: [^]DescriptorSet, dynamicOffsetCount: u32, pDynamicOffsets: [^]u32) +ProcCmdBindIndexBuffer :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, indexType: IndexType) +ProcCmdBindInvocationMaskHUAWEI :: #type proc "system" (commandBuffer: CommandBuffer, imageView: ImageView, imageLayout: ImageLayout) +ProcCmdBindPipeline :: #type proc "system" (commandBuffer: CommandBuffer, pipelineBindPoint: PipelineBindPoint, pipeline: Pipeline) +ProcCmdBindPipelineShaderGroupNV :: #type proc "system" (commandBuffer: CommandBuffer, pipelineBindPoint: PipelineBindPoint, pipeline: Pipeline, groupIndex: u32) +ProcCmdBindShadingRateImageNV :: #type proc "system" (commandBuffer: CommandBuffer, imageView: ImageView, imageLayout: ImageLayout) +ProcCmdBindTransformFeedbackBuffersEXT :: #type proc "system" (commandBuffer: CommandBuffer, firstBinding: u32, bindingCount: u32, pBuffers: [^]Buffer, pOffsets: [^]DeviceSize, pSizes: [^]DeviceSize) +ProcCmdBindVertexBuffers :: #type proc "system" (commandBuffer: CommandBuffer, firstBinding: u32, bindingCount: u32, pBuffers: [^]Buffer, pOffsets: [^]DeviceSize) +ProcCmdBindVertexBuffers2 :: #type proc "system" (commandBuffer: CommandBuffer, firstBinding: u32, bindingCount: u32, pBuffers: [^]Buffer, pOffsets: [^]DeviceSize, pSizes: [^]DeviceSize, pStrides: [^]DeviceSize) +ProcCmdBindVertexBuffers2EXT :: #type proc "system" (commandBuffer: CommandBuffer, firstBinding: u32, bindingCount: u32, pBuffers: [^]Buffer, pOffsets: [^]DeviceSize, pSizes: [^]DeviceSize, pStrides: [^]DeviceSize) +ProcCmdBlitImage :: #type proc "system" (commandBuffer: CommandBuffer, srcImage: Image, srcImageLayout: ImageLayout, dstImage: Image, dstImageLayout: ImageLayout, regionCount: u32, pRegions: [^]ImageBlit, filter: Filter) +ProcCmdBlitImage2 :: #type proc "system" (commandBuffer: CommandBuffer, pBlitImageInfo: ^BlitImageInfo2) +ProcCmdBlitImage2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pBlitImageInfo: ^BlitImageInfo2) +ProcCmdBuildAccelerationStructureNV :: #type proc "system" (commandBuffer: CommandBuffer, pInfo: ^AccelerationStructureInfoNV, instanceData: Buffer, instanceOffset: DeviceSize, update: b32, dst: AccelerationStructureNV, src: AccelerationStructureNV, scratch: Buffer, scratchOffset: DeviceSize) +ProcCmdBuildAccelerationStructuresIndirectKHR :: #type proc "system" (commandBuffer: CommandBuffer, infoCount: u32, pInfos: [^]AccelerationStructureBuildGeometryInfoKHR, pIndirectDeviceAddresses: [^]DeviceAddress, pIndirectStrides: [^]u32, ppMaxPrimitiveCounts: ^[^]u32) +ProcCmdBuildAccelerationStructuresKHR :: #type proc "system" (commandBuffer: CommandBuffer, infoCount: u32, pInfos: [^]AccelerationStructureBuildGeometryInfoKHR, ppBuildRangeInfos: ^[^]AccelerationStructureBuildRangeInfoKHR) +ProcCmdClearAttachments :: #type proc "system" (commandBuffer: CommandBuffer, attachmentCount: u32, pAttachments: [^]ClearAttachment, rectCount: u32, pRects: [^]ClearRect) +ProcCmdClearColorImage :: #type proc "system" (commandBuffer: CommandBuffer, image: Image, imageLayout: ImageLayout, pColor: ^ClearColorValue, rangeCount: u32, pRanges: [^]ImageSubresourceRange) +ProcCmdClearDepthStencilImage :: #type proc "system" (commandBuffer: CommandBuffer, image: Image, imageLayout: ImageLayout, pDepthStencil: ^ClearDepthStencilValue, rangeCount: u32, pRanges: [^]ImageSubresourceRange) +ProcCmdCopyAccelerationStructureKHR :: #type proc "system" (commandBuffer: CommandBuffer, pInfo: ^CopyAccelerationStructureInfoKHR) +ProcCmdCopyAccelerationStructureNV :: #type proc "system" (commandBuffer: CommandBuffer, dst: AccelerationStructureNV, src: AccelerationStructureNV, mode: CopyAccelerationStructureModeKHR) +ProcCmdCopyAccelerationStructureToMemoryKHR :: #type proc "system" (commandBuffer: CommandBuffer, pInfo: ^CopyAccelerationStructureToMemoryInfoKHR) +ProcCmdCopyBuffer :: #type proc "system" (commandBuffer: CommandBuffer, srcBuffer: Buffer, dstBuffer: Buffer, regionCount: u32, pRegions: [^]BufferCopy) +ProcCmdCopyBuffer2 :: #type proc "system" (commandBuffer: CommandBuffer, pCopyBufferInfo: ^CopyBufferInfo2) +ProcCmdCopyBuffer2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pCopyBufferInfo: ^CopyBufferInfo2) +ProcCmdCopyBufferToImage :: #type proc "system" (commandBuffer: CommandBuffer, srcBuffer: Buffer, dstImage: Image, dstImageLayout: ImageLayout, regionCount: u32, pRegions: [^]BufferImageCopy) +ProcCmdCopyBufferToImage2 :: #type proc "system" (commandBuffer: CommandBuffer, pCopyBufferToImageInfo: ^CopyBufferToImageInfo2) +ProcCmdCopyBufferToImage2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pCopyBufferToImageInfo: ^CopyBufferToImageInfo2) +ProcCmdCopyImage :: #type proc "system" (commandBuffer: CommandBuffer, srcImage: Image, srcImageLayout: ImageLayout, dstImage: Image, dstImageLayout: ImageLayout, regionCount: u32, pRegions: [^]ImageCopy) +ProcCmdCopyImage2 :: #type proc "system" (commandBuffer: CommandBuffer, pCopyImageInfo: ^CopyImageInfo2) +ProcCmdCopyImage2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pCopyImageInfo: ^CopyImageInfo2) +ProcCmdCopyImageToBuffer :: #type proc "system" (commandBuffer: CommandBuffer, srcImage: Image, srcImageLayout: ImageLayout, dstBuffer: Buffer, regionCount: u32, pRegions: [^]BufferImageCopy) +ProcCmdCopyImageToBuffer2 :: #type proc "system" (commandBuffer: CommandBuffer, pCopyImageToBufferInfo: ^CopyImageToBufferInfo2) +ProcCmdCopyImageToBuffer2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pCopyImageToBufferInfo: ^CopyImageToBufferInfo2) +ProcCmdCopyMemoryToAccelerationStructureKHR :: #type proc "system" (commandBuffer: CommandBuffer, pInfo: ^CopyMemoryToAccelerationStructureInfoKHR) +ProcCmdCopyQueryPoolResults :: #type proc "system" (commandBuffer: CommandBuffer, queryPool: QueryPool, firstQuery: u32, queryCount: u32, dstBuffer: Buffer, dstOffset: DeviceSize, stride: DeviceSize, flags: QueryResultFlags) +ProcCmdCuLaunchKernelNVX :: #type proc "system" (commandBuffer: CommandBuffer, pLaunchInfo: ^CuLaunchInfoNVX) +ProcCmdDebugMarkerBeginEXT :: #type proc "system" (commandBuffer: CommandBuffer, pMarkerInfo: ^DebugMarkerMarkerInfoEXT) +ProcCmdDebugMarkerEndEXT :: #type proc "system" (commandBuffer: CommandBuffer) +ProcCmdDebugMarkerInsertEXT :: #type proc "system" (commandBuffer: CommandBuffer, pMarkerInfo: ^DebugMarkerMarkerInfoEXT) +ProcCmdDispatch :: #type proc "system" (commandBuffer: CommandBuffer, groupCountX: u32, groupCountY: u32, groupCountZ: u32) +ProcCmdDispatchBase :: #type proc "system" (commandBuffer: CommandBuffer, baseGroupX: u32, baseGroupY: u32, baseGroupZ: u32, groupCountX: u32, groupCountY: u32, groupCountZ: u32) +ProcCmdDispatchBaseKHR :: #type proc "system" (commandBuffer: CommandBuffer, baseGroupX: u32, baseGroupY: u32, baseGroupZ: u32, groupCountX: u32, groupCountY: u32, groupCountZ: u32) +ProcCmdDispatchIndirect :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize) +ProcCmdDraw :: #type proc "system" (commandBuffer: CommandBuffer, vertexCount: u32, instanceCount: u32, firstVertex: u32, firstInstance: u32) +ProcCmdDrawIndexed :: #type proc "system" (commandBuffer: CommandBuffer, indexCount: u32, instanceCount: u32, firstIndex: u32, vertexOffset: i32, firstInstance: u32) +ProcCmdDrawIndexedIndirect :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, drawCount: u32, stride: u32) +ProcCmdDrawIndexedIndirectCount :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, countBuffer: Buffer, countBufferOffset: DeviceSize, maxDrawCount: u32, stride: u32) +ProcCmdDrawIndexedIndirectCountAMD :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, countBuffer: Buffer, countBufferOffset: DeviceSize, maxDrawCount: u32, stride: u32) +ProcCmdDrawIndexedIndirectCountKHR :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, countBuffer: Buffer, countBufferOffset: DeviceSize, maxDrawCount: u32, stride: u32) +ProcCmdDrawIndirect :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, drawCount: u32, stride: u32) +ProcCmdDrawIndirectByteCountEXT :: #type proc "system" (commandBuffer: CommandBuffer, instanceCount: u32, firstInstance: u32, counterBuffer: Buffer, counterBufferOffset: DeviceSize, counterOffset: u32, vertexStride: u32) +ProcCmdDrawIndirectCount :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, countBuffer: Buffer, countBufferOffset: DeviceSize, maxDrawCount: u32, stride: u32) +ProcCmdDrawIndirectCountAMD :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, countBuffer: Buffer, countBufferOffset: DeviceSize, maxDrawCount: u32, stride: u32) +ProcCmdDrawIndirectCountKHR :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, countBuffer: Buffer, countBufferOffset: DeviceSize, maxDrawCount: u32, stride: u32) +ProcCmdDrawMeshTasksIndirectCountNV :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, countBuffer: Buffer, countBufferOffset: DeviceSize, maxDrawCount: u32, stride: u32) +ProcCmdDrawMeshTasksIndirectNV :: #type proc "system" (commandBuffer: CommandBuffer, buffer: Buffer, offset: DeviceSize, drawCount: u32, stride: u32) +ProcCmdDrawMeshTasksNV :: #type proc "system" (commandBuffer: CommandBuffer, taskCount: u32, firstTask: u32) +ProcCmdDrawMultiEXT :: #type proc "system" (commandBuffer: CommandBuffer, drawCount: u32, pVertexInfo: ^MultiDrawInfoEXT, instanceCount: u32, firstInstance: u32, stride: u32) +ProcCmdDrawMultiIndexedEXT :: #type proc "system" (commandBuffer: CommandBuffer, drawCount: u32, pIndexInfo: ^MultiDrawIndexedInfoEXT, instanceCount: u32, firstInstance: u32, stride: u32, pVertexOffset: ^i32) +ProcCmdEndConditionalRenderingEXT :: #type proc "system" (commandBuffer: CommandBuffer) +ProcCmdEndDebugUtilsLabelEXT :: #type proc "system" (commandBuffer: CommandBuffer) +ProcCmdEndQuery :: #type proc "system" (commandBuffer: CommandBuffer, queryPool: QueryPool, query: u32) +ProcCmdEndQueryIndexedEXT :: #type proc "system" (commandBuffer: CommandBuffer, queryPool: QueryPool, query: u32, index: u32) +ProcCmdEndRenderPass :: #type proc "system" (commandBuffer: CommandBuffer) +ProcCmdEndRenderPass2 :: #type proc "system" (commandBuffer: CommandBuffer, pSubpassEndInfo: ^SubpassEndInfo) +ProcCmdEndRenderPass2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pSubpassEndInfo: ^SubpassEndInfo) +ProcCmdEndRendering :: #type proc "system" (commandBuffer: CommandBuffer) +ProcCmdEndRenderingKHR :: #type proc "system" (commandBuffer: CommandBuffer) +ProcCmdEndTransformFeedbackEXT :: #type proc "system" (commandBuffer: CommandBuffer, firstCounterBuffer: u32, counterBufferCount: u32, pCounterBuffers: [^]Buffer, pCounterBufferOffsets: [^]DeviceSize) +ProcCmdExecuteCommands :: #type proc "system" (commandBuffer: CommandBuffer, commandBufferCount: u32, pCommandBuffers: [^]CommandBuffer) +ProcCmdExecuteGeneratedCommandsNV :: #type proc "system" (commandBuffer: CommandBuffer, isPreprocessed: b32, pGeneratedCommandsInfo: ^GeneratedCommandsInfoNV) +ProcCmdFillBuffer :: #type proc "system" (commandBuffer: CommandBuffer, dstBuffer: Buffer, dstOffset: DeviceSize, size: DeviceSize, data: u32) +ProcCmdInsertDebugUtilsLabelEXT :: #type proc "system" (commandBuffer: CommandBuffer, pLabelInfo: ^DebugUtilsLabelEXT) +ProcCmdNextSubpass :: #type proc "system" (commandBuffer: CommandBuffer, contents: SubpassContents) +ProcCmdNextSubpass2 :: #type proc "system" (commandBuffer: CommandBuffer, pSubpassBeginInfo: ^SubpassBeginInfo, pSubpassEndInfo: ^SubpassEndInfo) +ProcCmdNextSubpass2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pSubpassBeginInfo: ^SubpassBeginInfo, pSubpassEndInfo: ^SubpassEndInfo) +ProcCmdPipelineBarrier :: #type proc "system" (commandBuffer: CommandBuffer, srcStageMask: PipelineStageFlags, dstStageMask: PipelineStageFlags, dependencyFlags: DependencyFlags, memoryBarrierCount: u32, pMemoryBarriers: [^]MemoryBarrier, bufferMemoryBarrierCount: u32, pBufferMemoryBarriers: [^]BufferMemoryBarrier, imageMemoryBarrierCount: u32, pImageMemoryBarriers: [^]ImageMemoryBarrier) +ProcCmdPipelineBarrier2 :: #type proc "system" (commandBuffer: CommandBuffer, pDependencyInfo: ^DependencyInfo) +ProcCmdPipelineBarrier2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pDependencyInfo: ^DependencyInfo) +ProcCmdPreprocessGeneratedCommandsNV :: #type proc "system" (commandBuffer: CommandBuffer, pGeneratedCommandsInfo: ^GeneratedCommandsInfoNV) +ProcCmdPushConstants :: #type proc "system" (commandBuffer: CommandBuffer, layout: PipelineLayout, stageFlags: ShaderStageFlags, offset: u32, size: u32, pValues: rawptr) +ProcCmdPushDescriptorSetKHR :: #type proc "system" (commandBuffer: CommandBuffer, pipelineBindPoint: PipelineBindPoint, layout: PipelineLayout, set: u32, descriptorWriteCount: u32, pDescriptorWrites: [^]WriteDescriptorSet) +ProcCmdPushDescriptorSetWithTemplateKHR :: #type proc "system" (commandBuffer: CommandBuffer, descriptorUpdateTemplate: DescriptorUpdateTemplate, layout: PipelineLayout, set: u32, pData: rawptr) +ProcCmdResetEvent :: #type proc "system" (commandBuffer: CommandBuffer, event: Event, stageMask: PipelineStageFlags) +ProcCmdResetEvent2 :: #type proc "system" (commandBuffer: CommandBuffer, event: Event, stageMask: PipelineStageFlags2) +ProcCmdResetEvent2KHR :: #type proc "system" (commandBuffer: CommandBuffer, event: Event, stageMask: PipelineStageFlags2) +ProcCmdResetQueryPool :: #type proc "system" (commandBuffer: CommandBuffer, queryPool: QueryPool, firstQuery: u32, queryCount: u32) +ProcCmdResolveImage :: #type proc "system" (commandBuffer: CommandBuffer, srcImage: Image, srcImageLayout: ImageLayout, dstImage: Image, dstImageLayout: ImageLayout, regionCount: u32, pRegions: [^]ImageResolve) +ProcCmdResolveImage2 :: #type proc "system" (commandBuffer: CommandBuffer, pResolveImageInfo: ^ResolveImageInfo2) +ProcCmdResolveImage2KHR :: #type proc "system" (commandBuffer: CommandBuffer, pResolveImageInfo: ^ResolveImageInfo2) +ProcCmdSetBlendConstants :: #type proc "system" (commandBuffer: CommandBuffer) +ProcCmdSetCheckpointNV :: #type proc "system" (commandBuffer: CommandBuffer, pCheckpointMarker: rawptr) +ProcCmdSetCoarseSampleOrderNV :: #type proc "system" (commandBuffer: CommandBuffer, sampleOrderType: CoarseSampleOrderTypeNV, customSampleOrderCount: u32, pCustomSampleOrders: [^]CoarseSampleOrderCustomNV) +ProcCmdSetCullMode :: #type proc "system" (commandBuffer: CommandBuffer, cullMode: CullModeFlags) +ProcCmdSetCullModeEXT :: #type proc "system" (commandBuffer: CommandBuffer, cullMode: CullModeFlags) +ProcCmdSetDepthBias :: #type proc "system" (commandBuffer: CommandBuffer, depthBiasConstantFactor: f32, depthBiasClamp: f32, depthBiasSlopeFactor: f32) +ProcCmdSetDepthBiasEnable :: #type proc "system" (commandBuffer: CommandBuffer, depthBiasEnable: b32) +ProcCmdSetDepthBiasEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, depthBiasEnable: b32) +ProcCmdSetDepthBounds :: #type proc "system" (commandBuffer: CommandBuffer, minDepthBounds: f32, maxDepthBounds: f32) +ProcCmdSetDepthBoundsTestEnable :: #type proc "system" (commandBuffer: CommandBuffer, depthBoundsTestEnable: b32) +ProcCmdSetDepthBoundsTestEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, depthBoundsTestEnable: b32) +ProcCmdSetDepthCompareOp :: #type proc "system" (commandBuffer: CommandBuffer, depthCompareOp: CompareOp) +ProcCmdSetDepthCompareOpEXT :: #type proc "system" (commandBuffer: CommandBuffer, depthCompareOp: CompareOp) +ProcCmdSetDepthTestEnable :: #type proc "system" (commandBuffer: CommandBuffer, depthTestEnable: b32) +ProcCmdSetDepthTestEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, depthTestEnable: b32) +ProcCmdSetDepthWriteEnable :: #type proc "system" (commandBuffer: CommandBuffer, depthWriteEnable: b32) +ProcCmdSetDepthWriteEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, depthWriteEnable: b32) +ProcCmdSetDeviceMask :: #type proc "system" (commandBuffer: CommandBuffer, deviceMask: u32) +ProcCmdSetDeviceMaskKHR :: #type proc "system" (commandBuffer: CommandBuffer, deviceMask: u32) +ProcCmdSetDiscardRectangleEXT :: #type proc "system" (commandBuffer: CommandBuffer, firstDiscardRectangle: u32, discardRectangleCount: u32, pDiscardRectangles: [^]Rect2D) +ProcCmdSetEvent :: #type proc "system" (commandBuffer: CommandBuffer, event: Event, stageMask: PipelineStageFlags) +ProcCmdSetEvent2 :: #type proc "system" (commandBuffer: CommandBuffer, event: Event, pDependencyInfo: ^DependencyInfo) +ProcCmdSetEvent2KHR :: #type proc "system" (commandBuffer: CommandBuffer, event: Event, pDependencyInfo: ^DependencyInfo) +ProcCmdSetExclusiveScissorNV :: #type proc "system" (commandBuffer: CommandBuffer, firstExclusiveScissor: u32, exclusiveScissorCount: u32, pExclusiveScissors: [^]Rect2D) +ProcCmdSetFragmentShadingRateEnumNV :: #type proc "system" (commandBuffer: CommandBuffer, shadingRate: FragmentShadingRateNV) +ProcCmdSetFragmentShadingRateKHR :: #type proc "system" (commandBuffer: CommandBuffer, pFragmentSize: ^Extent2D) +ProcCmdSetFrontFace :: #type proc "system" (commandBuffer: CommandBuffer, frontFace: FrontFace) +ProcCmdSetFrontFaceEXT :: #type proc "system" (commandBuffer: CommandBuffer, frontFace: FrontFace) +ProcCmdSetLineStippleEXT :: #type proc "system" (commandBuffer: CommandBuffer, lineStippleFactor: u32, lineStipplePattern: u16) +ProcCmdSetLineWidth :: #type proc "system" (commandBuffer: CommandBuffer, lineWidth: f32) +ProcCmdSetLogicOpEXT :: #type proc "system" (commandBuffer: CommandBuffer, logicOp: LogicOp) +ProcCmdSetPatchControlPointsEXT :: #type proc "system" (commandBuffer: CommandBuffer, patchControlPoints: u32) +ProcCmdSetPerformanceMarkerINTEL :: #type proc "system" (commandBuffer: CommandBuffer, pMarkerInfo: ^PerformanceMarkerInfoINTEL) -> Result +ProcCmdSetPerformanceOverrideINTEL :: #type proc "system" (commandBuffer: CommandBuffer, pOverrideInfo: ^PerformanceOverrideInfoINTEL) -> Result +ProcCmdSetPerformanceStreamMarkerINTEL :: #type proc "system" (commandBuffer: CommandBuffer, pMarkerInfo: ^PerformanceStreamMarkerInfoINTEL) -> Result +ProcCmdSetPrimitiveRestartEnable :: #type proc "system" (commandBuffer: CommandBuffer, primitiveRestartEnable: b32) +ProcCmdSetPrimitiveRestartEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, primitiveRestartEnable: b32) +ProcCmdSetPrimitiveTopology :: #type proc "system" (commandBuffer: CommandBuffer, primitiveTopology: PrimitiveTopology) +ProcCmdSetPrimitiveTopologyEXT :: #type proc "system" (commandBuffer: CommandBuffer, primitiveTopology: PrimitiveTopology) +ProcCmdSetRasterizerDiscardEnable :: #type proc "system" (commandBuffer: CommandBuffer, rasterizerDiscardEnable: b32) +ProcCmdSetRasterizerDiscardEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, rasterizerDiscardEnable: b32) +ProcCmdSetRayTracingPipelineStackSizeKHR :: #type proc "system" (commandBuffer: CommandBuffer, pipelineStackSize: u32) +ProcCmdSetSampleLocationsEXT :: #type proc "system" (commandBuffer: CommandBuffer, pSampleLocationsInfo: ^SampleLocationsInfoEXT) +ProcCmdSetScissor :: #type proc "system" (commandBuffer: CommandBuffer, firstScissor: u32, scissorCount: u32, pScissors: [^]Rect2D) +ProcCmdSetScissorWithCount :: #type proc "system" (commandBuffer: CommandBuffer, scissorCount: u32, pScissors: [^]Rect2D) +ProcCmdSetScissorWithCountEXT :: #type proc "system" (commandBuffer: CommandBuffer, scissorCount: u32, pScissors: [^]Rect2D) +ProcCmdSetStencilCompareMask :: #type proc "system" (commandBuffer: CommandBuffer, faceMask: StencilFaceFlags, compareMask: u32) +ProcCmdSetStencilOp :: #type proc "system" (commandBuffer: CommandBuffer, faceMask: StencilFaceFlags, failOp: StencilOp, passOp: StencilOp, depthFailOp: StencilOp, compareOp: CompareOp) +ProcCmdSetStencilOpEXT :: #type proc "system" (commandBuffer: CommandBuffer, faceMask: StencilFaceFlags, failOp: StencilOp, passOp: StencilOp, depthFailOp: StencilOp, compareOp: CompareOp) +ProcCmdSetStencilReference :: #type proc "system" (commandBuffer: CommandBuffer, faceMask: StencilFaceFlags, reference: u32) +ProcCmdSetStencilTestEnable :: #type proc "system" (commandBuffer: CommandBuffer, stencilTestEnable: b32) +ProcCmdSetStencilTestEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, stencilTestEnable: b32) +ProcCmdSetStencilWriteMask :: #type proc "system" (commandBuffer: CommandBuffer, faceMask: StencilFaceFlags, writeMask: u32) +ProcCmdSetVertexInputEXT :: #type proc "system" (commandBuffer: CommandBuffer, vertexBindingDescriptionCount: u32, pVertexBindingDescriptions: [^]VertexInputBindingDescription2EXT, vertexAttributeDescriptionCount: u32, pVertexAttributeDescriptions: [^]VertexInputAttributeDescription2EXT) +ProcCmdSetViewport :: #type proc "system" (commandBuffer: CommandBuffer, firstViewport: u32, viewportCount: u32, pViewports: [^]Viewport) +ProcCmdSetViewportShadingRatePaletteNV :: #type proc "system" (commandBuffer: CommandBuffer, firstViewport: u32, viewportCount: u32, pShadingRatePalettes: [^]ShadingRatePaletteNV) +ProcCmdSetViewportWScalingNV :: #type proc "system" (commandBuffer: CommandBuffer, firstViewport: u32, viewportCount: u32, pViewportWScalings: [^]ViewportWScalingNV) +ProcCmdSetViewportWithCount :: #type proc "system" (commandBuffer: CommandBuffer, viewportCount: u32, pViewports: [^]Viewport) +ProcCmdSetViewportWithCountEXT :: #type proc "system" (commandBuffer: CommandBuffer, viewportCount: u32, pViewports: [^]Viewport) +ProcCmdSubpassShadingHUAWEI :: #type proc "system" (commandBuffer: CommandBuffer) +ProcCmdTraceRaysIndirectKHR :: #type proc "system" (commandBuffer: CommandBuffer, pRaygenShaderBindingTable: [^]StridedDeviceAddressRegionKHR, pMissShaderBindingTable: [^]StridedDeviceAddressRegionKHR, pHitShaderBindingTable: [^]StridedDeviceAddressRegionKHR, pCallableShaderBindingTable: [^]StridedDeviceAddressRegionKHR, indirectDeviceAddress: DeviceAddress) +ProcCmdTraceRaysKHR :: #type proc "system" (commandBuffer: CommandBuffer, pRaygenShaderBindingTable: [^]StridedDeviceAddressRegionKHR, pMissShaderBindingTable: [^]StridedDeviceAddressRegionKHR, pHitShaderBindingTable: [^]StridedDeviceAddressRegionKHR, pCallableShaderBindingTable: [^]StridedDeviceAddressRegionKHR, width: u32, height: u32, depth: u32) +ProcCmdTraceRaysNV :: #type proc "system" (commandBuffer: CommandBuffer, raygenShaderBindingTableBuffer: Buffer, raygenShaderBindingOffset: DeviceSize, missShaderBindingTableBuffer: Buffer, missShaderBindingOffset: DeviceSize, missShaderBindingStride: DeviceSize, hitShaderBindingTableBuffer: Buffer, hitShaderBindingOffset: DeviceSize, hitShaderBindingStride: DeviceSize, callableShaderBindingTableBuffer: Buffer, callableShaderBindingOffset: DeviceSize, callableShaderBindingStride: DeviceSize, width: u32, height: u32, depth: u32) +ProcCmdUpdateBuffer :: #type proc "system" (commandBuffer: CommandBuffer, dstBuffer: Buffer, dstOffset: DeviceSize, dataSize: DeviceSize, pData: rawptr) +ProcCmdWaitEvents :: #type proc "system" (commandBuffer: CommandBuffer, eventCount: u32, pEvents: [^]Event, srcStageMask: PipelineStageFlags, dstStageMask: PipelineStageFlags, memoryBarrierCount: u32, pMemoryBarriers: [^]MemoryBarrier, bufferMemoryBarrierCount: u32, pBufferMemoryBarriers: [^]BufferMemoryBarrier, imageMemoryBarrierCount: u32, pImageMemoryBarriers: [^]ImageMemoryBarrier) +ProcCmdWaitEvents2 :: #type proc "system" (commandBuffer: CommandBuffer, eventCount: u32, pEvents: [^]Event, pDependencyInfos: [^]DependencyInfo) +ProcCmdWaitEvents2KHR :: #type proc "system" (commandBuffer: CommandBuffer, eventCount: u32, pEvents: [^]Event, pDependencyInfos: [^]DependencyInfo) +ProcCmdWriteAccelerationStructuresPropertiesKHR :: #type proc "system" (commandBuffer: CommandBuffer, accelerationStructureCount: u32, pAccelerationStructures: [^]AccelerationStructureKHR, queryType: QueryType, queryPool: QueryPool, firstQuery: u32) +ProcCmdWriteAccelerationStructuresPropertiesNV :: #type proc "system" (commandBuffer: CommandBuffer, accelerationStructureCount: u32, pAccelerationStructures: [^]AccelerationStructureNV, queryType: QueryType, queryPool: QueryPool, firstQuery: u32) +ProcCmdWriteBufferMarker2AMD :: #type proc "system" (commandBuffer: CommandBuffer, stage: PipelineStageFlags2, dstBuffer: Buffer, dstOffset: DeviceSize, marker: u32) +ProcCmdWriteBufferMarkerAMD :: #type proc "system" (commandBuffer: CommandBuffer, pipelineStage: PipelineStageFlags, dstBuffer: Buffer, dstOffset: DeviceSize, marker: u32) +ProcCmdWriteTimestamp :: #type proc "system" (commandBuffer: CommandBuffer, pipelineStage: PipelineStageFlags, queryPool: QueryPool, query: u32) +ProcCmdWriteTimestamp2 :: #type proc "system" (commandBuffer: CommandBuffer, stage: PipelineStageFlags2, queryPool: QueryPool, query: u32) +ProcCmdWriteTimestamp2KHR :: #type proc "system" (commandBuffer: CommandBuffer, stage: PipelineStageFlags2, queryPool: QueryPool, query: u32) +ProcCompileDeferredNV :: #type proc "system" (device: Device, pipeline: Pipeline, shader: u32) -> Result +ProcCopyAccelerationStructureKHR :: #type proc "system" (device: Device, deferredOperation: DeferredOperationKHR, pInfo: ^CopyAccelerationStructureInfoKHR) -> Result +ProcCopyAccelerationStructureToMemoryKHR :: #type proc "system" (device: Device, deferredOperation: DeferredOperationKHR, pInfo: ^CopyAccelerationStructureToMemoryInfoKHR) -> Result +ProcCopyMemoryToAccelerationStructureKHR :: #type proc "system" (device: Device, deferredOperation: DeferredOperationKHR, pInfo: ^CopyMemoryToAccelerationStructureInfoKHR) -> Result +ProcCreateAccelerationStructureKHR :: #type proc "system" (device: Device, pCreateInfo: ^AccelerationStructureCreateInfoKHR, pAllocator: ^AllocationCallbacks, pAccelerationStructure: ^AccelerationStructureKHR) -> Result +ProcCreateAccelerationStructureNV :: #type proc "system" (device: Device, pCreateInfo: ^AccelerationStructureCreateInfoNV, pAllocator: ^AllocationCallbacks, pAccelerationStructure: ^AccelerationStructureNV) -> Result +ProcCreateBuffer :: #type proc "system" (device: Device, pCreateInfo: ^BufferCreateInfo, pAllocator: ^AllocationCallbacks, pBuffer: ^Buffer) -> Result +ProcCreateBufferView :: #type proc "system" (device: Device, pCreateInfo: ^BufferViewCreateInfo, pAllocator: ^AllocationCallbacks, pView: ^BufferView) -> Result +ProcCreateCommandPool :: #type proc "system" (device: Device, pCreateInfo: ^CommandPoolCreateInfo, pAllocator: ^AllocationCallbacks, pCommandPool: ^CommandPool) -> Result +ProcCreateComputePipelines :: #type proc "system" (device: Device, pipelineCache: PipelineCache, createInfoCount: u32, pCreateInfos: [^]ComputePipelineCreateInfo, pAllocator: ^AllocationCallbacks, pPipelines: [^]Pipeline) -> Result +ProcCreateCuFunctionNVX :: #type proc "system" (device: Device, pCreateInfo: ^CuFunctionCreateInfoNVX, pAllocator: ^AllocationCallbacks, pFunction: ^CuFunctionNVX) -> Result +ProcCreateCuModuleNVX :: #type proc "system" (device: Device, pCreateInfo: ^CuModuleCreateInfoNVX, pAllocator: ^AllocationCallbacks, pModule: ^CuModuleNVX) -> Result +ProcCreateDeferredOperationKHR :: #type proc "system" (device: Device, pAllocator: ^AllocationCallbacks, pDeferredOperation: ^DeferredOperationKHR) -> Result +ProcCreateDescriptorPool :: #type proc "system" (device: Device, pCreateInfo: ^DescriptorPoolCreateInfo, pAllocator: ^AllocationCallbacks, pDescriptorPool: ^DescriptorPool) -> Result +ProcCreateDescriptorSetLayout :: #type proc "system" (device: Device, pCreateInfo: ^DescriptorSetLayoutCreateInfo, pAllocator: ^AllocationCallbacks, pSetLayout: ^DescriptorSetLayout) -> Result +ProcCreateDescriptorUpdateTemplate :: #type proc "system" (device: Device, pCreateInfo: ^DescriptorUpdateTemplateCreateInfo, pAllocator: ^AllocationCallbacks, pDescriptorUpdateTemplate: ^DescriptorUpdateTemplate) -> Result +ProcCreateDescriptorUpdateTemplateKHR :: #type proc "system" (device: Device, pCreateInfo: ^DescriptorUpdateTemplateCreateInfo, pAllocator: ^AllocationCallbacks, pDescriptorUpdateTemplate: ^DescriptorUpdateTemplate) -> Result +ProcCreateEvent :: #type proc "system" (device: Device, pCreateInfo: ^EventCreateInfo, pAllocator: ^AllocationCallbacks, pEvent: ^Event) -> Result +ProcCreateFence :: #type proc "system" (device: Device, pCreateInfo: ^FenceCreateInfo, pAllocator: ^AllocationCallbacks, pFence: ^Fence) -> Result +ProcCreateFramebuffer :: #type proc "system" (device: Device, pCreateInfo: ^FramebufferCreateInfo, pAllocator: ^AllocationCallbacks, pFramebuffer: ^Framebuffer) -> Result +ProcCreateGraphicsPipelines :: #type proc "system" (device: Device, pipelineCache: PipelineCache, createInfoCount: u32, pCreateInfos: [^]GraphicsPipelineCreateInfo, pAllocator: ^AllocationCallbacks, pPipelines: [^]Pipeline) -> Result +ProcCreateImage :: #type proc "system" (device: Device, pCreateInfo: ^ImageCreateInfo, pAllocator: ^AllocationCallbacks, pImage: ^Image) -> Result +ProcCreateImageView :: #type proc "system" (device: Device, pCreateInfo: ^ImageViewCreateInfo, pAllocator: ^AllocationCallbacks, pView: ^ImageView) -> Result +ProcCreateIndirectCommandsLayoutNV :: #type proc "system" (device: Device, pCreateInfo: ^IndirectCommandsLayoutCreateInfoNV, pAllocator: ^AllocationCallbacks, pIndirectCommandsLayout: ^IndirectCommandsLayoutNV) -> Result +ProcCreatePipelineCache :: #type proc "system" (device: Device, pCreateInfo: ^PipelineCacheCreateInfo, pAllocator: ^AllocationCallbacks, pPipelineCache: ^PipelineCache) -> Result +ProcCreatePipelineLayout :: #type proc "system" (device: Device, pCreateInfo: ^PipelineLayoutCreateInfo, pAllocator: ^AllocationCallbacks, pPipelineLayout: ^PipelineLayout) -> Result +ProcCreatePrivateDataSlot :: #type proc "system" (device: Device, pCreateInfo: ^PrivateDataSlotCreateInfo, pAllocator: ^AllocationCallbacks, pPrivateDataSlot: ^PrivateDataSlot) -> Result +ProcCreatePrivateDataSlotEXT :: #type proc "system" (device: Device, pCreateInfo: ^PrivateDataSlotCreateInfo, pAllocator: ^AllocationCallbacks, pPrivateDataSlot: ^PrivateDataSlot) -> Result +ProcCreateQueryPool :: #type proc "system" (device: Device, pCreateInfo: ^QueryPoolCreateInfo, pAllocator: ^AllocationCallbacks, pQueryPool: ^QueryPool) -> Result +ProcCreateRayTracingPipelinesKHR :: #type proc "system" (device: Device, deferredOperation: DeferredOperationKHR, pipelineCache: PipelineCache, createInfoCount: u32, pCreateInfos: [^]RayTracingPipelineCreateInfoKHR, pAllocator: ^AllocationCallbacks, pPipelines: [^]Pipeline) -> Result +ProcCreateRayTracingPipelinesNV :: #type proc "system" (device: Device, pipelineCache: PipelineCache, createInfoCount: u32, pCreateInfos: [^]RayTracingPipelineCreateInfoNV, pAllocator: ^AllocationCallbacks, pPipelines: [^]Pipeline) -> Result +ProcCreateRenderPass :: #type proc "system" (device: Device, pCreateInfo: ^RenderPassCreateInfo, pAllocator: ^AllocationCallbacks, pRenderPass: [^]RenderPass) -> Result +ProcCreateRenderPass2 :: #type proc "system" (device: Device, pCreateInfo: ^RenderPassCreateInfo2, pAllocator: ^AllocationCallbacks, pRenderPass: [^]RenderPass) -> Result +ProcCreateRenderPass2KHR :: #type proc "system" (device: Device, pCreateInfo: ^RenderPassCreateInfo2, pAllocator: ^AllocationCallbacks, pRenderPass: [^]RenderPass) -> Result +ProcCreateSampler :: #type proc "system" (device: Device, pCreateInfo: ^SamplerCreateInfo, pAllocator: ^AllocationCallbacks, pSampler: ^Sampler) -> Result +ProcCreateSamplerYcbcrConversion :: #type proc "system" (device: Device, pCreateInfo: ^SamplerYcbcrConversionCreateInfo, pAllocator: ^AllocationCallbacks, pYcbcrConversion: ^SamplerYcbcrConversion) -> Result +ProcCreateSamplerYcbcrConversionKHR :: #type proc "system" (device: Device, pCreateInfo: ^SamplerYcbcrConversionCreateInfo, pAllocator: ^AllocationCallbacks, pYcbcrConversion: ^SamplerYcbcrConversion) -> Result +ProcCreateSemaphore :: #type proc "system" (device: Device, pCreateInfo: ^SemaphoreCreateInfo, pAllocator: ^AllocationCallbacks, pSemaphore: ^Semaphore) -> Result +ProcCreateShaderModule :: #type proc "system" (device: Device, pCreateInfo: ^ShaderModuleCreateInfo, pAllocator: ^AllocationCallbacks, pShaderModule: ^ShaderModule) -> Result +ProcCreateSharedSwapchainsKHR :: #type proc "system" (device: Device, swapchainCount: u32, pCreateInfos: [^]SwapchainCreateInfoKHR, pAllocator: ^AllocationCallbacks, pSwapchains: [^]SwapchainKHR) -> Result +ProcCreateSwapchainKHR :: #type proc "system" (device: Device, pCreateInfo: ^SwapchainCreateInfoKHR, pAllocator: ^AllocationCallbacks, pSwapchain: ^SwapchainKHR) -> Result +ProcCreateValidationCacheEXT :: #type proc "system" (device: Device, pCreateInfo: ^ValidationCacheCreateInfoEXT, pAllocator: ^AllocationCallbacks, pValidationCache: ^ValidationCacheEXT) -> Result +ProcDebugMarkerSetObjectNameEXT :: #type proc "system" (device: Device, pNameInfo: ^DebugMarkerObjectNameInfoEXT) -> Result +ProcDebugMarkerSetObjectTagEXT :: #type proc "system" (device: Device, pTagInfo: ^DebugMarkerObjectTagInfoEXT) -> Result +ProcDeferredOperationJoinKHR :: #type proc "system" (device: Device, operation: DeferredOperationKHR) -> Result +ProcDestroyAccelerationStructureKHR :: #type proc "system" (device: Device, accelerationStructure: AccelerationStructureKHR, pAllocator: ^AllocationCallbacks) +ProcDestroyAccelerationStructureNV :: #type proc "system" (device: Device, accelerationStructure: AccelerationStructureNV, pAllocator: ^AllocationCallbacks) +ProcDestroyBuffer :: #type proc "system" (device: Device, buffer: Buffer, pAllocator: ^AllocationCallbacks) +ProcDestroyBufferView :: #type proc "system" (device: Device, bufferView: BufferView, pAllocator: ^AllocationCallbacks) +ProcDestroyCommandPool :: #type proc "system" (device: Device, commandPool: CommandPool, pAllocator: ^AllocationCallbacks) +ProcDestroyCuFunctionNVX :: #type proc "system" (device: Device, function: CuFunctionNVX, pAllocator: ^AllocationCallbacks) +ProcDestroyCuModuleNVX :: #type proc "system" (device: Device, module: CuModuleNVX, pAllocator: ^AllocationCallbacks) +ProcDestroyDeferredOperationKHR :: #type proc "system" (device: Device, operation: DeferredOperationKHR, pAllocator: ^AllocationCallbacks) +ProcDestroyDescriptorPool :: #type proc "system" (device: Device, descriptorPool: DescriptorPool, pAllocator: ^AllocationCallbacks) +ProcDestroyDescriptorSetLayout :: #type proc "system" (device: Device, descriptorSetLayout: DescriptorSetLayout, pAllocator: ^AllocationCallbacks) +ProcDestroyDescriptorUpdateTemplate :: #type proc "system" (device: Device, descriptorUpdateTemplate: DescriptorUpdateTemplate, pAllocator: ^AllocationCallbacks) +ProcDestroyDescriptorUpdateTemplateKHR :: #type proc "system" (device: Device, descriptorUpdateTemplate: DescriptorUpdateTemplate, pAllocator: ^AllocationCallbacks) +ProcDestroyDevice :: #type proc "system" (device: Device, pAllocator: ^AllocationCallbacks) +ProcDestroyEvent :: #type proc "system" (device: Device, event: Event, pAllocator: ^AllocationCallbacks) +ProcDestroyFence :: #type proc "system" (device: Device, fence: Fence, pAllocator: ^AllocationCallbacks) +ProcDestroyFramebuffer :: #type proc "system" (device: Device, framebuffer: Framebuffer, pAllocator: ^AllocationCallbacks) +ProcDestroyImage :: #type proc "system" (device: Device, image: Image, pAllocator: ^AllocationCallbacks) +ProcDestroyImageView :: #type proc "system" (device: Device, imageView: ImageView, pAllocator: ^AllocationCallbacks) +ProcDestroyIndirectCommandsLayoutNV :: #type proc "system" (device: Device, indirectCommandsLayout: IndirectCommandsLayoutNV, pAllocator: ^AllocationCallbacks) +ProcDestroyPipeline :: #type proc "system" (device: Device, pipeline: Pipeline, pAllocator: ^AllocationCallbacks) +ProcDestroyPipelineCache :: #type proc "system" (device: Device, pipelineCache: PipelineCache, pAllocator: ^AllocationCallbacks) +ProcDestroyPipelineLayout :: #type proc "system" (device: Device, pipelineLayout: PipelineLayout, pAllocator: ^AllocationCallbacks) +ProcDestroyPrivateDataSlot :: #type proc "system" (device: Device, privateDataSlot: PrivateDataSlot, pAllocator: ^AllocationCallbacks) +ProcDestroyPrivateDataSlotEXT :: #type proc "system" (device: Device, privateDataSlot: PrivateDataSlot, pAllocator: ^AllocationCallbacks) +ProcDestroyQueryPool :: #type proc "system" (device: Device, queryPool: QueryPool, pAllocator: ^AllocationCallbacks) +ProcDestroyRenderPass :: #type proc "system" (device: Device, renderPass: RenderPass, pAllocator: ^AllocationCallbacks) +ProcDestroySampler :: #type proc "system" (device: Device, sampler: Sampler, pAllocator: ^AllocationCallbacks) +ProcDestroySamplerYcbcrConversion :: #type proc "system" (device: Device, ycbcrConversion: SamplerYcbcrConversion, pAllocator: ^AllocationCallbacks) +ProcDestroySamplerYcbcrConversionKHR :: #type proc "system" (device: Device, ycbcrConversion: SamplerYcbcrConversion, pAllocator: ^AllocationCallbacks) +ProcDestroySemaphore :: #type proc "system" (device: Device, semaphore: Semaphore, pAllocator: ^AllocationCallbacks) +ProcDestroyShaderModule :: #type proc "system" (device: Device, shaderModule: ShaderModule, pAllocator: ^AllocationCallbacks) +ProcDestroySwapchainKHR :: #type proc "system" (device: Device, swapchain: SwapchainKHR, pAllocator: ^AllocationCallbacks) +ProcDestroyValidationCacheEXT :: #type proc "system" (device: Device, validationCache: ValidationCacheEXT, pAllocator: ^AllocationCallbacks) +ProcDeviceWaitIdle :: #type proc "system" (device: Device) -> Result +ProcDisplayPowerControlEXT :: #type proc "system" (device: Device, display: DisplayKHR, pDisplayPowerInfo: ^DisplayPowerInfoEXT) -> Result +ProcEndCommandBuffer :: #type proc "system" (commandBuffer: CommandBuffer) -> Result +ProcFlushMappedMemoryRanges :: #type proc "system" (device: Device, memoryRangeCount: u32, pMemoryRanges: [^]MappedMemoryRange) -> Result +ProcFreeCommandBuffers :: #type proc "system" (device: Device, commandPool: CommandPool, commandBufferCount: u32, pCommandBuffers: [^]CommandBuffer) +ProcFreeDescriptorSets :: #type proc "system" (device: Device, descriptorPool: DescriptorPool, descriptorSetCount: u32, pDescriptorSets: [^]DescriptorSet) -> Result +ProcFreeMemory :: #type proc "system" (device: Device, memory: DeviceMemory, pAllocator: ^AllocationCallbacks) +ProcGetAccelerationStructureBuildSizesKHR :: #type proc "system" (device: Device, buildType: AccelerationStructureBuildTypeKHR, pBuildInfo: ^AccelerationStructureBuildGeometryInfoKHR, pMaxPrimitiveCounts: [^]u32, pSizeInfo: ^AccelerationStructureBuildSizesInfoKHR) +ProcGetAccelerationStructureDeviceAddressKHR :: #type proc "system" (device: Device, pInfo: ^AccelerationStructureDeviceAddressInfoKHR) -> DeviceAddress +ProcGetAccelerationStructureHandleNV :: #type proc "system" (device: Device, accelerationStructure: AccelerationStructureNV, dataSize: int, pData: rawptr) -> Result +ProcGetAccelerationStructureMemoryRequirementsNV :: #type proc "system" (device: Device, pInfo: ^AccelerationStructureMemoryRequirementsInfoNV, pMemoryRequirements: [^]MemoryRequirements2KHR) +ProcGetBufferDeviceAddress :: #type proc "system" (device: Device, pInfo: ^BufferDeviceAddressInfo) -> DeviceAddress +ProcGetBufferDeviceAddressEXT :: #type proc "system" (device: Device, pInfo: ^BufferDeviceAddressInfo) -> DeviceAddress +ProcGetBufferDeviceAddressKHR :: #type proc "system" (device: Device, pInfo: ^BufferDeviceAddressInfo) -> DeviceAddress +ProcGetBufferMemoryRequirements :: #type proc "system" (device: Device, buffer: Buffer, pMemoryRequirements: [^]MemoryRequirements) +ProcGetBufferMemoryRequirements2 :: #type proc "system" (device: Device, pInfo: ^BufferMemoryRequirementsInfo2, pMemoryRequirements: [^]MemoryRequirements2) +ProcGetBufferMemoryRequirements2KHR :: #type proc "system" (device: Device, pInfo: ^BufferMemoryRequirementsInfo2, pMemoryRequirements: [^]MemoryRequirements2) +ProcGetBufferOpaqueCaptureAddress :: #type proc "system" (device: Device, pInfo: ^BufferDeviceAddressInfo) -> u64 +ProcGetBufferOpaqueCaptureAddressKHR :: #type proc "system" (device: Device, pInfo: ^BufferDeviceAddressInfo) -> u64 +ProcGetCalibratedTimestampsEXT :: #type proc "system" (device: Device, timestampCount: u32, pTimestampInfos: [^]CalibratedTimestampInfoEXT, pTimestamps: [^]u64, pMaxDeviation: ^u64) -> Result +ProcGetDeferredOperationMaxConcurrencyKHR :: #type proc "system" (device: Device, operation: DeferredOperationKHR) -> u32 +ProcGetDeferredOperationResultKHR :: #type proc "system" (device: Device, operation: DeferredOperationKHR) -> Result +ProcGetDescriptorSetHostMappingVALVE :: #type proc "system" (device: Device, descriptorSet: DescriptorSet, ppData: ^rawptr) +ProcGetDescriptorSetLayoutHostMappingInfoVALVE :: #type proc "system" (device: Device, pBindingReference: ^DescriptorSetBindingReferenceVALVE, pHostMapping: ^DescriptorSetLayoutHostMappingInfoVALVE) +ProcGetDescriptorSetLayoutSupport :: #type proc "system" (device: Device, pCreateInfo: ^DescriptorSetLayoutCreateInfo, pSupport: ^DescriptorSetLayoutSupport) +ProcGetDescriptorSetLayoutSupportKHR :: #type proc "system" (device: Device, pCreateInfo: ^DescriptorSetLayoutCreateInfo, pSupport: ^DescriptorSetLayoutSupport) +ProcGetDeviceAccelerationStructureCompatibilityKHR :: #type proc "system" (device: Device, pVersionInfo: ^AccelerationStructureVersionInfoKHR, pCompatibility: ^AccelerationStructureCompatibilityKHR) +ProcGetDeviceBufferMemoryRequirements :: #type proc "system" (device: Device, pInfo: ^DeviceBufferMemoryRequirements, pMemoryRequirements: [^]MemoryRequirements2) +ProcGetDeviceBufferMemoryRequirementsKHR :: #type proc "system" (device: Device, pInfo: ^DeviceBufferMemoryRequirements, pMemoryRequirements: [^]MemoryRequirements2) +ProcGetDeviceGroupPeerMemoryFeatures :: #type proc "system" (device: Device, heapIndex: u32, localDeviceIndex: u32, remoteDeviceIndex: u32, pPeerMemoryFeatures: [^]PeerMemoryFeatureFlags) +ProcGetDeviceGroupPeerMemoryFeaturesKHR :: #type proc "system" (device: Device, heapIndex: u32, localDeviceIndex: u32, remoteDeviceIndex: u32, pPeerMemoryFeatures: [^]PeerMemoryFeatureFlags) +ProcGetDeviceGroupPresentCapabilitiesKHR :: #type proc "system" (device: Device, pDeviceGroupPresentCapabilities: [^]DeviceGroupPresentCapabilitiesKHR) -> Result +ProcGetDeviceGroupSurfacePresentModes2EXT :: #type proc "system" (device: Device, pSurfaceInfo: ^PhysicalDeviceSurfaceInfo2KHR, pModes: [^]DeviceGroupPresentModeFlagsKHR) -> Result +ProcGetDeviceGroupSurfacePresentModesKHR :: #type proc "system" (device: Device, surface: SurfaceKHR, pModes: [^]DeviceGroupPresentModeFlagsKHR) -> Result +ProcGetDeviceImageMemoryRequirements :: #type proc "system" (device: Device, pInfo: ^DeviceImageMemoryRequirements, pMemoryRequirements: [^]MemoryRequirements2) +ProcGetDeviceImageMemoryRequirementsKHR :: #type proc "system" (device: Device, pInfo: ^DeviceImageMemoryRequirements, pMemoryRequirements: [^]MemoryRequirements2) +ProcGetDeviceImageSparseMemoryRequirements :: #type proc "system" (device: Device, pInfo: ^DeviceImageMemoryRequirements, pSparseMemoryRequirementCount: ^u32, pSparseMemoryRequirements: [^]SparseImageMemoryRequirements2) +ProcGetDeviceImageSparseMemoryRequirementsKHR :: #type proc "system" (device: Device, pInfo: ^DeviceImageMemoryRequirements, pSparseMemoryRequirementCount: ^u32, pSparseMemoryRequirements: [^]SparseImageMemoryRequirements2) +ProcGetDeviceMemoryCommitment :: #type proc "system" (device: Device, memory: DeviceMemory, pCommittedMemoryInBytes: [^]DeviceSize) +ProcGetDeviceMemoryOpaqueCaptureAddress :: #type proc "system" (device: Device, pInfo: ^DeviceMemoryOpaqueCaptureAddressInfo) -> u64 +ProcGetDeviceMemoryOpaqueCaptureAddressKHR :: #type proc "system" (device: Device, pInfo: ^DeviceMemoryOpaqueCaptureAddressInfo) -> u64 +ProcGetDeviceProcAddr :: #type proc "system" (device: Device, pName: cstring) -> ProcVoidFunction +ProcGetDeviceQueue :: #type proc "system" (device: Device, queueFamilyIndex: u32, queueIndex: u32, pQueue: ^Queue) +ProcGetDeviceQueue2 :: #type proc "system" (device: Device, pQueueInfo: ^DeviceQueueInfo2, pQueue: ^Queue) +ProcGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI :: #type proc "system" (device: Device, renderpass: RenderPass, pMaxWorkgroupSize: ^Extent2D) -> Result +ProcGetEventStatus :: #type proc "system" (device: Device, event: Event) -> Result +ProcGetFenceFdKHR :: #type proc "system" (device: Device, pGetFdInfo: ^FenceGetFdInfoKHR, pFd: ^c.int) -> Result +ProcGetFenceStatus :: #type proc "system" (device: Device, fence: Fence) -> Result +ProcGetFenceWin32HandleKHR :: #type proc "system" (device: Device, pGetWin32HandleInfo: ^FenceGetWin32HandleInfoKHR, pHandle: ^HANDLE) -> Result +ProcGetGeneratedCommandsMemoryRequirementsNV :: #type proc "system" (device: Device, pInfo: ^GeneratedCommandsMemoryRequirementsInfoNV, pMemoryRequirements: [^]MemoryRequirements2) +ProcGetImageDrmFormatModifierPropertiesEXT :: #type proc "system" (device: Device, image: Image, pProperties: [^]ImageDrmFormatModifierPropertiesEXT) -> Result +ProcGetImageMemoryRequirements :: #type proc "system" (device: Device, image: Image, pMemoryRequirements: [^]MemoryRequirements) +ProcGetImageMemoryRequirements2 :: #type proc "system" (device: Device, pInfo: ^ImageMemoryRequirementsInfo2, pMemoryRequirements: [^]MemoryRequirements2) +ProcGetImageMemoryRequirements2KHR :: #type proc "system" (device: Device, pInfo: ^ImageMemoryRequirementsInfo2, pMemoryRequirements: [^]MemoryRequirements2) +ProcGetImageSparseMemoryRequirements :: #type proc "system" (device: Device, image: Image, pSparseMemoryRequirementCount: ^u32, pSparseMemoryRequirements: [^]SparseImageMemoryRequirements) +ProcGetImageSparseMemoryRequirements2 :: #type proc "system" (device: Device, pInfo: ^ImageSparseMemoryRequirementsInfo2, pSparseMemoryRequirementCount: ^u32, pSparseMemoryRequirements: [^]SparseImageMemoryRequirements2) +ProcGetImageSparseMemoryRequirements2KHR :: #type proc "system" (device: Device, pInfo: ^ImageSparseMemoryRequirementsInfo2, pSparseMemoryRequirementCount: ^u32, pSparseMemoryRequirements: [^]SparseImageMemoryRequirements2) +ProcGetImageSubresourceLayout :: #type proc "system" (device: Device, image: Image, pSubresource: ^ImageSubresource, pLayout: ^SubresourceLayout) +ProcGetImageViewAddressNVX :: #type proc "system" (device: Device, imageView: ImageView, pProperties: [^]ImageViewAddressPropertiesNVX) -> Result +ProcGetImageViewHandleNVX :: #type proc "system" (device: Device, pInfo: ^ImageViewHandleInfoNVX) -> u32 +ProcGetMemoryFdKHR :: #type proc "system" (device: Device, pGetFdInfo: ^MemoryGetFdInfoKHR, pFd: ^c.int) -> Result +ProcGetMemoryFdPropertiesKHR :: #type proc "system" (device: Device, handleType: ExternalMemoryHandleTypeFlags, fd: c.int, pMemoryFdProperties: [^]MemoryFdPropertiesKHR) -> Result +ProcGetMemoryHostPointerPropertiesEXT :: #type proc "system" (device: Device, handleType: ExternalMemoryHandleTypeFlags, pHostPointer: rawptr, pMemoryHostPointerProperties: [^]MemoryHostPointerPropertiesEXT) -> Result +ProcGetMemoryRemoteAddressNV :: #type proc "system" (device: Device, pMemoryGetRemoteAddressInfo: ^MemoryGetRemoteAddressInfoNV, pAddress: [^]RemoteAddressNV) -> Result +ProcGetMemoryWin32HandleKHR :: #type proc "system" (device: Device, pGetWin32HandleInfo: ^MemoryGetWin32HandleInfoKHR, pHandle: ^HANDLE) -> Result +ProcGetMemoryWin32HandleNV :: #type proc "system" (device: Device, memory: DeviceMemory, handleType: ExternalMemoryHandleTypeFlagsNV, pHandle: ^HANDLE) -> Result +ProcGetMemoryWin32HandlePropertiesKHR :: #type proc "system" (device: Device, handleType: ExternalMemoryHandleTypeFlags, handle: HANDLE, pMemoryWin32HandleProperties: [^]MemoryWin32HandlePropertiesKHR) -> Result +ProcGetPastPresentationTimingGOOGLE :: #type proc "system" (device: Device, swapchain: SwapchainKHR, pPresentationTimingCount: ^u32, pPresentationTimings: [^]PastPresentationTimingGOOGLE) -> Result +ProcGetPerformanceParameterINTEL :: #type proc "system" (device: Device, parameter: PerformanceParameterTypeINTEL, pValue: ^PerformanceValueINTEL) -> Result +ProcGetPipelineCacheData :: #type proc "system" (device: Device, pipelineCache: PipelineCache, pDataSize: ^int, pData: rawptr) -> Result +ProcGetPipelineExecutableInternalRepresentationsKHR :: #type proc "system" (device: Device, pExecutableInfo: ^PipelineExecutableInfoKHR, pInternalRepresentationCount: ^u32, pInternalRepresentations: [^]PipelineExecutableInternalRepresentationKHR) -> Result +ProcGetPipelineExecutablePropertiesKHR :: #type proc "system" (device: Device, pPipelineInfo: ^PipelineInfoKHR, pExecutableCount: ^u32, pProperties: [^]PipelineExecutablePropertiesKHR) -> Result +ProcGetPipelineExecutableStatisticsKHR :: #type proc "system" (device: Device, pExecutableInfo: ^PipelineExecutableInfoKHR, pStatisticCount: ^u32, pStatistics: [^]PipelineExecutableStatisticKHR) -> Result +ProcGetPrivateData :: #type proc "system" (device: Device, objectType: ObjectType, objectHandle: u64, privateDataSlot: PrivateDataSlot, pData: ^u64) +ProcGetPrivateDataEXT :: #type proc "system" (device: Device, objectType: ObjectType, objectHandle: u64, privateDataSlot: PrivateDataSlot, pData: ^u64) +ProcGetQueryPoolResults :: #type proc "system" (device: Device, queryPool: QueryPool, firstQuery: u32, queryCount: u32, dataSize: int, pData: rawptr, stride: DeviceSize, flags: QueryResultFlags) -> Result +ProcGetQueueCheckpointData2NV :: #type proc "system" (queue: Queue, pCheckpointDataCount: ^u32, pCheckpointData: ^CheckpointData2NV) +ProcGetQueueCheckpointDataNV :: #type proc "system" (queue: Queue, pCheckpointDataCount: ^u32, pCheckpointData: ^CheckpointDataNV) +ProcGetRayTracingCaptureReplayShaderGroupHandlesKHR :: #type proc "system" (device: Device, pipeline: Pipeline, firstGroup: u32, groupCount: u32, dataSize: int, pData: rawptr) -> Result +ProcGetRayTracingShaderGroupHandlesKHR :: #type proc "system" (device: Device, pipeline: Pipeline, firstGroup: u32, groupCount: u32, dataSize: int, pData: rawptr) -> Result +ProcGetRayTracingShaderGroupHandlesNV :: #type proc "system" (device: Device, pipeline: Pipeline, firstGroup: u32, groupCount: u32, dataSize: int, pData: rawptr) -> Result +ProcGetRayTracingShaderGroupStackSizeKHR :: #type proc "system" (device: Device, pipeline: Pipeline, group: u32, groupShader: ShaderGroupShaderKHR) -> DeviceSize +ProcGetRefreshCycleDurationGOOGLE :: #type proc "system" (device: Device, swapchain: SwapchainKHR, pDisplayTimingProperties: [^]RefreshCycleDurationGOOGLE) -> Result +ProcGetRenderAreaGranularity :: #type proc "system" (device: Device, renderPass: RenderPass, pGranularity: ^Extent2D) +ProcGetSemaphoreCounterValue :: #type proc "system" (device: Device, semaphore: Semaphore, pValue: ^u64) -> Result +ProcGetSemaphoreCounterValueKHR :: #type proc "system" (device: Device, semaphore: Semaphore, pValue: ^u64) -> Result +ProcGetSemaphoreFdKHR :: #type proc "system" (device: Device, pGetFdInfo: ^SemaphoreGetFdInfoKHR, pFd: ^c.int) -> Result +ProcGetSemaphoreWin32HandleKHR :: #type proc "system" (device: Device, pGetWin32HandleInfo: ^SemaphoreGetWin32HandleInfoKHR, pHandle: ^HANDLE) -> Result +ProcGetShaderInfoAMD :: #type proc "system" (device: Device, pipeline: Pipeline, shaderStage: ShaderStageFlags, infoType: ShaderInfoTypeAMD, pInfoSize: ^int, pInfo: rawptr) -> Result +ProcGetSwapchainCounterEXT :: #type proc "system" (device: Device, swapchain: SwapchainKHR, counter: SurfaceCounterFlagsEXT, pCounterValue: ^u64) -> Result +ProcGetSwapchainImagesKHR :: #type proc "system" (device: Device, swapchain: SwapchainKHR, pSwapchainImageCount: ^u32, pSwapchainImages: [^]Image) -> Result +ProcGetSwapchainStatusKHR :: #type proc "system" (device: Device, swapchain: SwapchainKHR) -> Result +ProcGetValidationCacheDataEXT :: #type proc "system" (device: Device, validationCache: ValidationCacheEXT, pDataSize: ^int, pData: rawptr) -> Result +ProcImportFenceFdKHR :: #type proc "system" (device: Device, pImportFenceFdInfo: ^ImportFenceFdInfoKHR) -> Result +ProcImportFenceWin32HandleKHR :: #type proc "system" (device: Device, pImportFenceWin32HandleInfo: ^ImportFenceWin32HandleInfoKHR) -> Result +ProcImportSemaphoreFdKHR :: #type proc "system" (device: Device, pImportSemaphoreFdInfo: ^ImportSemaphoreFdInfoKHR) -> Result +ProcImportSemaphoreWin32HandleKHR :: #type proc "system" (device: Device, pImportSemaphoreWin32HandleInfo: ^ImportSemaphoreWin32HandleInfoKHR) -> Result +ProcInitializePerformanceApiINTEL :: #type proc "system" (device: Device, pInitializeInfo: ^InitializePerformanceApiInfoINTEL) -> Result +ProcInvalidateMappedMemoryRanges :: #type proc "system" (device: Device, memoryRangeCount: u32, pMemoryRanges: [^]MappedMemoryRange) -> Result +ProcMapMemory :: #type proc "system" (device: Device, memory: DeviceMemory, offset: DeviceSize, size: DeviceSize, flags: MemoryMapFlags, ppData: ^rawptr) -> Result +ProcMergePipelineCaches :: #type proc "system" (device: Device, dstCache: PipelineCache, srcCacheCount: u32, pSrcCaches: [^]PipelineCache) -> Result +ProcMergeValidationCachesEXT :: #type proc "system" (device: Device, dstCache: ValidationCacheEXT, srcCacheCount: u32, pSrcCaches: [^]ValidationCacheEXT) -> Result +ProcQueueBeginDebugUtilsLabelEXT :: #type proc "system" (queue: Queue, pLabelInfo: ^DebugUtilsLabelEXT) +ProcQueueBindSparse :: #type proc "system" (queue: Queue, bindInfoCount: u32, pBindInfo: ^BindSparseInfo, fence: Fence) -> Result +ProcQueueEndDebugUtilsLabelEXT :: #type proc "system" (queue: Queue) +ProcQueueInsertDebugUtilsLabelEXT :: #type proc "system" (queue: Queue, pLabelInfo: ^DebugUtilsLabelEXT) +ProcQueuePresentKHR :: #type proc "system" (queue: Queue, pPresentInfo: ^PresentInfoKHR) -> Result +ProcQueueSetPerformanceConfigurationINTEL :: #type proc "system" (queue: Queue, configuration: PerformanceConfigurationINTEL) -> Result +ProcQueueSubmit :: #type proc "system" (queue: Queue, submitCount: u32, pSubmits: [^]SubmitInfo, fence: Fence) -> Result +ProcQueueSubmit2 :: #type proc "system" (queue: Queue, submitCount: u32, pSubmits: [^]SubmitInfo2, fence: Fence) -> Result +ProcQueueSubmit2KHR :: #type proc "system" (queue: Queue, submitCount: u32, pSubmits: [^]SubmitInfo2, fence: Fence) -> Result +ProcQueueWaitIdle :: #type proc "system" (queue: Queue) -> Result +ProcRegisterDeviceEventEXT :: #type proc "system" (device: Device, pDeviceEventInfo: ^DeviceEventInfoEXT, pAllocator: ^AllocationCallbacks, pFence: ^Fence) -> Result +ProcRegisterDisplayEventEXT :: #type proc "system" (device: Device, display: DisplayKHR, pDisplayEventInfo: ^DisplayEventInfoEXT, pAllocator: ^AllocationCallbacks, pFence: ^Fence) -> Result +ProcReleaseFullScreenExclusiveModeEXT :: #type proc "system" (device: Device, swapchain: SwapchainKHR) -> Result +ProcReleasePerformanceConfigurationINTEL :: #type proc "system" (device: Device, configuration: PerformanceConfigurationINTEL) -> Result +ProcReleaseProfilingLockKHR :: #type proc "system" (device: Device) +ProcResetCommandBuffer :: #type proc "system" (commandBuffer: CommandBuffer, flags: CommandBufferResetFlags) -> Result +ProcResetCommandPool :: #type proc "system" (device: Device, commandPool: CommandPool, flags: CommandPoolResetFlags) -> Result +ProcResetDescriptorPool :: #type proc "system" (device: Device, descriptorPool: DescriptorPool, flags: DescriptorPoolResetFlags) -> Result +ProcResetEvent :: #type proc "system" (device: Device, event: Event) -> Result +ProcResetFences :: #type proc "system" (device: Device, fenceCount: u32, pFences: [^]Fence) -> Result +ProcResetQueryPool :: #type proc "system" (device: Device, queryPool: QueryPool, firstQuery: u32, queryCount: u32) +ProcResetQueryPoolEXT :: #type proc "system" (device: Device, queryPool: QueryPool, firstQuery: u32, queryCount: u32) +ProcSetDebugUtilsObjectNameEXT :: #type proc "system" (device: Device, pNameInfo: ^DebugUtilsObjectNameInfoEXT) -> Result +ProcSetDebugUtilsObjectTagEXT :: #type proc "system" (device: Device, pTagInfo: ^DebugUtilsObjectTagInfoEXT) -> Result +ProcSetDeviceMemoryPriorityEXT :: #type proc "system" (device: Device, memory: DeviceMemory, priority: f32) +ProcSetEvent :: #type proc "system" (device: Device, event: Event) -> Result +ProcSetHdrMetadataEXT :: #type proc "system" (device: Device, swapchainCount: u32, pSwapchains: [^]SwapchainKHR, pMetadata: ^HdrMetadataEXT) +ProcSetLocalDimmingAMD :: #type proc "system" (device: Device, swapChain: SwapchainKHR, localDimmingEnable: b32) +ProcSetPrivateData :: #type proc "system" (device: Device, objectType: ObjectType, objectHandle: u64, privateDataSlot: PrivateDataSlot, data: u64) -> Result +ProcSetPrivateDataEXT :: #type proc "system" (device: Device, objectType: ObjectType, objectHandle: u64, privateDataSlot: PrivateDataSlot, data: u64) -> Result +ProcSignalSemaphore :: #type proc "system" (device: Device, pSignalInfo: ^SemaphoreSignalInfo) -> Result +ProcSignalSemaphoreKHR :: #type proc "system" (device: Device, pSignalInfo: ^SemaphoreSignalInfo) -> Result +ProcTrimCommandPool :: #type proc "system" (device: Device, commandPool: CommandPool, flags: CommandPoolTrimFlags) +ProcTrimCommandPoolKHR :: #type proc "system" (device: Device, commandPool: CommandPool, flags: CommandPoolTrimFlags) +ProcUninitializePerformanceApiINTEL :: #type proc "system" (device: Device) +ProcUnmapMemory :: #type proc "system" (device: Device, memory: DeviceMemory) +ProcUpdateDescriptorSetWithTemplate :: #type proc "system" (device: Device, descriptorSet: DescriptorSet, descriptorUpdateTemplate: DescriptorUpdateTemplate, pData: rawptr) +ProcUpdateDescriptorSetWithTemplateKHR :: #type proc "system" (device: Device, descriptorSet: DescriptorSet, descriptorUpdateTemplate: DescriptorUpdateTemplate, pData: rawptr) +ProcUpdateDescriptorSets :: #type proc "system" (device: Device, descriptorWriteCount: u32, pDescriptorWrites: [^]WriteDescriptorSet, descriptorCopyCount: u32, pDescriptorCopies: [^]CopyDescriptorSet) +ProcWaitForFences :: #type proc "system" (device: Device, fenceCount: u32, pFences: [^]Fence, waitAll: b32, timeout: u64) -> Result +ProcWaitForPresentKHR :: #type proc "system" (device: Device, swapchain: SwapchainKHR, presentId: u64, timeout: u64) -> Result +ProcWaitSemaphores :: #type proc "system" (device: Device, pWaitInfo: ^SemaphoreWaitInfo, timeout: u64) -> Result +ProcWaitSemaphoresKHR :: #type proc "system" (device: Device, pWaitInfo: ^SemaphoreWaitInfo, timeout: u64) -> Result +ProcWriteAccelerationStructuresPropertiesKHR :: #type proc "system" (device: Device, accelerationStructureCount: u32, pAccelerationStructures: [^]AccelerationStructureKHR, queryType: QueryType, dataSize: int, pData: rawptr, stride: int) -> Result -// Device Procedures -GetDeviceProcAddr: ProcGetDeviceProcAddr -DestroyDevice: ProcDestroyDevice -GetDeviceQueue: ProcGetDeviceQueue -QueueSubmit: ProcQueueSubmit -QueueWaitIdle: ProcQueueWaitIdle -DeviceWaitIdle: ProcDeviceWaitIdle -AllocateMemory: ProcAllocateMemory -FreeMemory: ProcFreeMemory -MapMemory: ProcMapMemory -UnmapMemory: ProcUnmapMemory -FlushMappedMemoryRanges: ProcFlushMappedMemoryRanges -InvalidateMappedMemoryRanges: ProcInvalidateMappedMemoryRanges -GetDeviceMemoryCommitment: ProcGetDeviceMemoryCommitment -BindBufferMemory: ProcBindBufferMemory -BindImageMemory: ProcBindImageMemory -GetBufferMemoryRequirements: ProcGetBufferMemoryRequirements -GetImageMemoryRequirements: ProcGetImageMemoryRequirements -GetImageSparseMemoryRequirements: ProcGetImageSparseMemoryRequirements -QueueBindSparse: ProcQueueBindSparse -CreateFence: ProcCreateFence -DestroyFence: ProcDestroyFence -ResetFences: ProcResetFences -GetFenceStatus: ProcGetFenceStatus -WaitForFences: ProcWaitForFences -CreateSemaphore: ProcCreateSemaphore -DestroySemaphore: ProcDestroySemaphore -CreateEvent: ProcCreateEvent -DestroyEvent: ProcDestroyEvent -GetEventStatus: ProcGetEventStatus -SetEvent: ProcSetEvent -ResetEvent: ProcResetEvent -CreateQueryPool: ProcCreateQueryPool -DestroyQueryPool: ProcDestroyQueryPool -GetQueryPoolResults: ProcGetQueryPoolResults -CreateBuffer: ProcCreateBuffer -DestroyBuffer: ProcDestroyBuffer -CreateBufferView: ProcCreateBufferView -DestroyBufferView: ProcDestroyBufferView -CreateImage: ProcCreateImage -DestroyImage: ProcDestroyImage -GetImageSubresourceLayout: ProcGetImageSubresourceLayout -CreateImageView: ProcCreateImageView -DestroyImageView: ProcDestroyImageView -CreateShaderModule: ProcCreateShaderModule -DestroyShaderModule: ProcDestroyShaderModule -CreatePipelineCache: ProcCreatePipelineCache -DestroyPipelineCache: ProcDestroyPipelineCache -GetPipelineCacheData: ProcGetPipelineCacheData -MergePipelineCaches: ProcMergePipelineCaches -CreateGraphicsPipelines: ProcCreateGraphicsPipelines -CreateComputePipelines: ProcCreateComputePipelines -DestroyPipeline: ProcDestroyPipeline -CreatePipelineLayout: ProcCreatePipelineLayout -DestroyPipelineLayout: ProcDestroyPipelineLayout -CreateSampler: ProcCreateSampler -DestroySampler: ProcDestroySampler -CreateDescriptorSetLayout: ProcCreateDescriptorSetLayout -DestroyDescriptorSetLayout: ProcDestroyDescriptorSetLayout -CreateDescriptorPool: ProcCreateDescriptorPool -DestroyDescriptorPool: ProcDestroyDescriptorPool -ResetDescriptorPool: ProcResetDescriptorPool -AllocateDescriptorSets: ProcAllocateDescriptorSets -FreeDescriptorSets: ProcFreeDescriptorSets -UpdateDescriptorSets: ProcUpdateDescriptorSets -CreateFramebuffer: ProcCreateFramebuffer -DestroyFramebuffer: ProcDestroyFramebuffer -CreateRenderPass: ProcCreateRenderPass -DestroyRenderPass: ProcDestroyRenderPass -GetRenderAreaGranularity: ProcGetRenderAreaGranularity -CreateCommandPool: ProcCreateCommandPool -DestroyCommandPool: ProcDestroyCommandPool -ResetCommandPool: ProcResetCommandPool -AllocateCommandBuffers: ProcAllocateCommandBuffers -FreeCommandBuffers: ProcFreeCommandBuffers -BeginCommandBuffer: ProcBeginCommandBuffer -EndCommandBuffer: ProcEndCommandBuffer -ResetCommandBuffer: ProcResetCommandBuffer -CmdBindPipeline: ProcCmdBindPipeline -CmdSetViewport: ProcCmdSetViewport -CmdSetScissor: ProcCmdSetScissor -CmdSetLineWidth: ProcCmdSetLineWidth -CmdSetDepthBias: ProcCmdSetDepthBias -CmdSetBlendConstants: ProcCmdSetBlendConstants -CmdSetDepthBounds: ProcCmdSetDepthBounds -CmdSetStencilCompareMask: ProcCmdSetStencilCompareMask -CmdSetStencilWriteMask: ProcCmdSetStencilWriteMask -CmdSetStencilReference: ProcCmdSetStencilReference -CmdBindDescriptorSets: ProcCmdBindDescriptorSets -CmdBindIndexBuffer: ProcCmdBindIndexBuffer -CmdBindVertexBuffers: ProcCmdBindVertexBuffers -CmdDraw: ProcCmdDraw -CmdDrawIndexed: ProcCmdDrawIndexed -CmdDrawIndirect: ProcCmdDrawIndirect -CmdDrawIndexedIndirect: ProcCmdDrawIndexedIndirect -CmdDispatch: ProcCmdDispatch -CmdDispatchIndirect: ProcCmdDispatchIndirect -CmdCopyBuffer: ProcCmdCopyBuffer -CmdCopyImage: ProcCmdCopyImage -CmdBlitImage: ProcCmdBlitImage -CmdCopyBufferToImage: ProcCmdCopyBufferToImage -CmdCopyImageToBuffer: ProcCmdCopyImageToBuffer -CmdUpdateBuffer: ProcCmdUpdateBuffer -CmdFillBuffer: ProcCmdFillBuffer -CmdClearColorImage: ProcCmdClearColorImage -CmdClearDepthStencilImage: ProcCmdClearDepthStencilImage -CmdClearAttachments: ProcCmdClearAttachments -CmdResolveImage: ProcCmdResolveImage -CmdSetEvent: ProcCmdSetEvent -CmdResetEvent: ProcCmdResetEvent -CmdWaitEvents: ProcCmdWaitEvents -CmdPipelineBarrier: ProcCmdPipelineBarrier -CmdBeginQuery: ProcCmdBeginQuery -CmdEndQuery: ProcCmdEndQuery -CmdResetQueryPool: ProcCmdResetQueryPool -CmdWriteTimestamp: ProcCmdWriteTimestamp -CmdCopyQueryPoolResults: ProcCmdCopyQueryPoolResults -CmdPushConstants: ProcCmdPushConstants -CmdBeginRenderPass: ProcCmdBeginRenderPass -CmdNextSubpass: ProcCmdNextSubpass -CmdEndRenderPass: ProcCmdEndRenderPass -CmdExecuteCommands: ProcCmdExecuteCommands -BindBufferMemory2: ProcBindBufferMemory2 -BindImageMemory2: ProcBindImageMemory2 -GetDeviceGroupPeerMemoryFeatures: ProcGetDeviceGroupPeerMemoryFeatures -CmdSetDeviceMask: ProcCmdSetDeviceMask -CmdDispatchBase: ProcCmdDispatchBase -GetImageMemoryRequirements2: ProcGetImageMemoryRequirements2 -GetBufferMemoryRequirements2: ProcGetBufferMemoryRequirements2 -GetImageSparseMemoryRequirements2: ProcGetImageSparseMemoryRequirements2 -TrimCommandPool: ProcTrimCommandPool -GetDeviceQueue2: ProcGetDeviceQueue2 -CreateSamplerYcbcrConversion: ProcCreateSamplerYcbcrConversion -DestroySamplerYcbcrConversion: ProcDestroySamplerYcbcrConversion -CreateDescriptorUpdateTemplate: ProcCreateDescriptorUpdateTemplate -DestroyDescriptorUpdateTemplate: ProcDestroyDescriptorUpdateTemplate -UpdateDescriptorSetWithTemplate: ProcUpdateDescriptorSetWithTemplate -GetDescriptorSetLayoutSupport: ProcGetDescriptorSetLayoutSupport -CmdDrawIndirectCount: ProcCmdDrawIndirectCount -CmdDrawIndexedIndirectCount: ProcCmdDrawIndexedIndirectCount -CreateRenderPass2: ProcCreateRenderPass2 -CmdBeginRenderPass2: ProcCmdBeginRenderPass2 -CmdNextSubpass2: ProcCmdNextSubpass2 -CmdEndRenderPass2: ProcCmdEndRenderPass2 -ResetQueryPool: ProcResetQueryPool -GetSemaphoreCounterValue: ProcGetSemaphoreCounterValue -WaitSemaphores: ProcWaitSemaphores -SignalSemaphore: ProcSignalSemaphore -GetBufferDeviceAddress: ProcGetBufferDeviceAddress -GetBufferOpaqueCaptureAddress: ProcGetBufferOpaqueCaptureAddress -GetDeviceMemoryOpaqueCaptureAddress: ProcGetDeviceMemoryOpaqueCaptureAddress -CreateSwapchainKHR: ProcCreateSwapchainKHR -DestroySwapchainKHR: ProcDestroySwapchainKHR -GetSwapchainImagesKHR: ProcGetSwapchainImagesKHR -AcquireNextImageKHR: ProcAcquireNextImageKHR -QueuePresentKHR: ProcQueuePresentKHR -GetDeviceGroupPresentCapabilitiesKHR: ProcGetDeviceGroupPresentCapabilitiesKHR -GetDeviceGroupSurfacePresentModesKHR: ProcGetDeviceGroupSurfacePresentModesKHR -AcquireNextImage2KHR: ProcAcquireNextImage2KHR -CreateSharedSwapchainsKHR: ProcCreateSharedSwapchainsKHR -GetDeviceGroupPeerMemoryFeaturesKHR: ProcGetDeviceGroupPeerMemoryFeaturesKHR -CmdSetDeviceMaskKHR: ProcCmdSetDeviceMaskKHR -CmdDispatchBaseKHR: ProcCmdDispatchBaseKHR -TrimCommandPoolKHR: ProcTrimCommandPoolKHR -GetMemoryFdKHR: ProcGetMemoryFdKHR -GetMemoryFdPropertiesKHR: ProcGetMemoryFdPropertiesKHR -ImportSemaphoreFdKHR: ProcImportSemaphoreFdKHR -GetSemaphoreFdKHR: ProcGetSemaphoreFdKHR -CmdPushDescriptorSetKHR: ProcCmdPushDescriptorSetKHR -CmdPushDescriptorSetWithTemplateKHR: ProcCmdPushDescriptorSetWithTemplateKHR -CreateDescriptorUpdateTemplateKHR: ProcCreateDescriptorUpdateTemplateKHR -DestroyDescriptorUpdateTemplateKHR: ProcDestroyDescriptorUpdateTemplateKHR -UpdateDescriptorSetWithTemplateKHR: ProcUpdateDescriptorSetWithTemplateKHR -CreateRenderPass2KHR: ProcCreateRenderPass2KHR -CmdBeginRenderPass2KHR: ProcCmdBeginRenderPass2KHR -CmdNextSubpass2KHR: ProcCmdNextSubpass2KHR -CmdEndRenderPass2KHR: ProcCmdEndRenderPass2KHR -GetSwapchainStatusKHR: ProcGetSwapchainStatusKHR -ImportFenceFdKHR: ProcImportFenceFdKHR -GetFenceFdKHR: ProcGetFenceFdKHR -AcquireProfilingLockKHR: ProcAcquireProfilingLockKHR -ReleaseProfilingLockKHR: ProcReleaseProfilingLockKHR -GetImageMemoryRequirements2KHR: ProcGetImageMemoryRequirements2KHR -GetBufferMemoryRequirements2KHR: ProcGetBufferMemoryRequirements2KHR -GetImageSparseMemoryRequirements2KHR: ProcGetImageSparseMemoryRequirements2KHR -CreateSamplerYcbcrConversionKHR: ProcCreateSamplerYcbcrConversionKHR -DestroySamplerYcbcrConversionKHR: ProcDestroySamplerYcbcrConversionKHR -BindBufferMemory2KHR: ProcBindBufferMemory2KHR -BindImageMemory2KHR: ProcBindImageMemory2KHR -GetDescriptorSetLayoutSupportKHR: ProcGetDescriptorSetLayoutSupportKHR -CmdDrawIndirectCountKHR: ProcCmdDrawIndirectCountKHR -CmdDrawIndexedIndirectCountKHR: ProcCmdDrawIndexedIndirectCountKHR -GetSemaphoreCounterValueKHR: ProcGetSemaphoreCounterValueKHR -WaitSemaphoresKHR: ProcWaitSemaphoresKHR -SignalSemaphoreKHR: ProcSignalSemaphoreKHR -CmdSetFragmentShadingRateKHR: ProcCmdSetFragmentShadingRateKHR -WaitForPresentKHR: ProcWaitForPresentKHR -GetBufferDeviceAddressKHR: ProcGetBufferDeviceAddressKHR -GetBufferOpaqueCaptureAddressKHR: ProcGetBufferOpaqueCaptureAddressKHR -GetDeviceMemoryOpaqueCaptureAddressKHR: ProcGetDeviceMemoryOpaqueCaptureAddressKHR -CreateDeferredOperationKHR: ProcCreateDeferredOperationKHR -DestroyDeferredOperationKHR: ProcDestroyDeferredOperationKHR -GetDeferredOperationMaxConcurrencyKHR: ProcGetDeferredOperationMaxConcurrencyKHR -GetDeferredOperationResultKHR: ProcGetDeferredOperationResultKHR -DeferredOperationJoinKHR: ProcDeferredOperationJoinKHR -GetPipelineExecutablePropertiesKHR: ProcGetPipelineExecutablePropertiesKHR -GetPipelineExecutableStatisticsKHR: ProcGetPipelineExecutableStatisticsKHR -GetPipelineExecutableInternalRepresentationsKHR: ProcGetPipelineExecutableInternalRepresentationsKHR -CmdSetEvent2KHR: ProcCmdSetEvent2KHR -CmdResetEvent2KHR: ProcCmdResetEvent2KHR -CmdWaitEvents2KHR: ProcCmdWaitEvents2KHR -CmdPipelineBarrier2KHR: ProcCmdPipelineBarrier2KHR -CmdWriteTimestamp2KHR: ProcCmdWriteTimestamp2KHR -QueueSubmit2KHR: ProcQueueSubmit2KHR -CmdWriteBufferMarker2AMD: ProcCmdWriteBufferMarker2AMD -GetQueueCheckpointData2NV: ProcGetQueueCheckpointData2NV -CmdCopyBuffer2KHR: ProcCmdCopyBuffer2KHR -CmdCopyImage2KHR: ProcCmdCopyImage2KHR -CmdCopyBufferToImage2KHR: ProcCmdCopyBufferToImage2KHR -CmdCopyImageToBuffer2KHR: ProcCmdCopyImageToBuffer2KHR -CmdBlitImage2KHR: ProcCmdBlitImage2KHR -CmdResolveImage2KHR: ProcCmdResolveImage2KHR -DebugMarkerSetObjectTagEXT: ProcDebugMarkerSetObjectTagEXT -DebugMarkerSetObjectNameEXT: ProcDebugMarkerSetObjectNameEXT -CmdDebugMarkerBeginEXT: ProcCmdDebugMarkerBeginEXT -CmdDebugMarkerEndEXT: ProcCmdDebugMarkerEndEXT -CmdDebugMarkerInsertEXT: ProcCmdDebugMarkerInsertEXT -CmdBindTransformFeedbackBuffersEXT: ProcCmdBindTransformFeedbackBuffersEXT -CmdBeginTransformFeedbackEXT: ProcCmdBeginTransformFeedbackEXT -CmdEndTransformFeedbackEXT: ProcCmdEndTransformFeedbackEXT -CmdBeginQueryIndexedEXT: ProcCmdBeginQueryIndexedEXT -CmdEndQueryIndexedEXT: ProcCmdEndQueryIndexedEXT -CmdDrawIndirectByteCountEXT: ProcCmdDrawIndirectByteCountEXT -CreateCuModuleNVX: ProcCreateCuModuleNVX -CreateCuFunctionNVX: ProcCreateCuFunctionNVX -DestroyCuModuleNVX: ProcDestroyCuModuleNVX -DestroyCuFunctionNVX: ProcDestroyCuFunctionNVX -CmdCuLaunchKernelNVX: ProcCmdCuLaunchKernelNVX -GetImageViewHandleNVX: ProcGetImageViewHandleNVX -GetImageViewAddressNVX: ProcGetImageViewAddressNVX -CmdDrawIndirectCountAMD: ProcCmdDrawIndirectCountAMD -CmdDrawIndexedIndirectCountAMD: ProcCmdDrawIndexedIndirectCountAMD -GetShaderInfoAMD: ProcGetShaderInfoAMD -CmdBeginConditionalRenderingEXT: ProcCmdBeginConditionalRenderingEXT -CmdEndConditionalRenderingEXT: ProcCmdEndConditionalRenderingEXT -CmdSetViewportWScalingNV: ProcCmdSetViewportWScalingNV -DisplayPowerControlEXT: ProcDisplayPowerControlEXT -RegisterDeviceEventEXT: ProcRegisterDeviceEventEXT -RegisterDisplayEventEXT: ProcRegisterDisplayEventEXT -GetSwapchainCounterEXT: ProcGetSwapchainCounterEXT -GetRefreshCycleDurationGOOGLE: ProcGetRefreshCycleDurationGOOGLE -GetPastPresentationTimingGOOGLE: ProcGetPastPresentationTimingGOOGLE -CmdSetDiscardRectangleEXT: ProcCmdSetDiscardRectangleEXT -SetHdrMetadataEXT: ProcSetHdrMetadataEXT -SetDebugUtilsObjectNameEXT: ProcSetDebugUtilsObjectNameEXT -SetDebugUtilsObjectTagEXT: ProcSetDebugUtilsObjectTagEXT -QueueBeginDebugUtilsLabelEXT: ProcQueueBeginDebugUtilsLabelEXT -QueueEndDebugUtilsLabelEXT: ProcQueueEndDebugUtilsLabelEXT -QueueInsertDebugUtilsLabelEXT: ProcQueueInsertDebugUtilsLabelEXT -CmdBeginDebugUtilsLabelEXT: ProcCmdBeginDebugUtilsLabelEXT -CmdEndDebugUtilsLabelEXT: ProcCmdEndDebugUtilsLabelEXT -CmdInsertDebugUtilsLabelEXT: ProcCmdInsertDebugUtilsLabelEXT -CmdSetSampleLocationsEXT: ProcCmdSetSampleLocationsEXT -GetImageDrmFormatModifierPropertiesEXT: ProcGetImageDrmFormatModifierPropertiesEXT -CreateValidationCacheEXT: ProcCreateValidationCacheEXT -DestroyValidationCacheEXT: ProcDestroyValidationCacheEXT -MergeValidationCachesEXT: ProcMergeValidationCachesEXT -GetValidationCacheDataEXT: ProcGetValidationCacheDataEXT -CmdBindShadingRateImageNV: ProcCmdBindShadingRateImageNV -CmdSetViewportShadingRatePaletteNV: ProcCmdSetViewportShadingRatePaletteNV -CmdSetCoarseSampleOrderNV: ProcCmdSetCoarseSampleOrderNV -CreateAccelerationStructureNV: ProcCreateAccelerationStructureNV -DestroyAccelerationStructureNV: ProcDestroyAccelerationStructureNV -GetAccelerationStructureMemoryRequirementsNV: ProcGetAccelerationStructureMemoryRequirementsNV -BindAccelerationStructureMemoryNV: ProcBindAccelerationStructureMemoryNV -CmdBuildAccelerationStructureNV: ProcCmdBuildAccelerationStructureNV -CmdCopyAccelerationStructureNV: ProcCmdCopyAccelerationStructureNV -CmdTraceRaysNV: ProcCmdTraceRaysNV -CreateRayTracingPipelinesNV: ProcCreateRayTracingPipelinesNV -GetRayTracingShaderGroupHandlesKHR: ProcGetRayTracingShaderGroupHandlesKHR -GetRayTracingShaderGroupHandlesNV: ProcGetRayTracingShaderGroupHandlesNV -GetAccelerationStructureHandleNV: ProcGetAccelerationStructureHandleNV -CmdWriteAccelerationStructuresPropertiesNV: ProcCmdWriteAccelerationStructuresPropertiesNV -CompileDeferredNV: ProcCompileDeferredNV -GetMemoryHostPointerPropertiesEXT: ProcGetMemoryHostPointerPropertiesEXT -CmdWriteBufferMarkerAMD: ProcCmdWriteBufferMarkerAMD -GetCalibratedTimestampsEXT: ProcGetCalibratedTimestampsEXT -CmdDrawMeshTasksNV: ProcCmdDrawMeshTasksNV -CmdDrawMeshTasksIndirectNV: ProcCmdDrawMeshTasksIndirectNV -CmdDrawMeshTasksIndirectCountNV: ProcCmdDrawMeshTasksIndirectCountNV -CmdSetExclusiveScissorNV: ProcCmdSetExclusiveScissorNV -CmdSetCheckpointNV: ProcCmdSetCheckpointNV -GetQueueCheckpointDataNV: ProcGetQueueCheckpointDataNV -InitializePerformanceApiINTEL: ProcInitializePerformanceApiINTEL -UninitializePerformanceApiINTEL: ProcUninitializePerformanceApiINTEL -CmdSetPerformanceMarkerINTEL: ProcCmdSetPerformanceMarkerINTEL -CmdSetPerformanceStreamMarkerINTEL: ProcCmdSetPerformanceStreamMarkerINTEL -CmdSetPerformanceOverrideINTEL: ProcCmdSetPerformanceOverrideINTEL -AcquirePerformanceConfigurationINTEL: ProcAcquirePerformanceConfigurationINTEL -ReleasePerformanceConfigurationINTEL: ProcReleasePerformanceConfigurationINTEL -QueueSetPerformanceConfigurationINTEL: ProcQueueSetPerformanceConfigurationINTEL -GetPerformanceParameterINTEL: ProcGetPerformanceParameterINTEL -SetLocalDimmingAMD: ProcSetLocalDimmingAMD -GetBufferDeviceAddressEXT: ProcGetBufferDeviceAddressEXT -CmdSetLineStippleEXT: ProcCmdSetLineStippleEXT -ResetQueryPoolEXT: ProcResetQueryPoolEXT -CmdSetCullModeEXT: ProcCmdSetCullModeEXT -CmdSetFrontFaceEXT: ProcCmdSetFrontFaceEXT -CmdSetPrimitiveTopologyEXT: ProcCmdSetPrimitiveTopologyEXT -CmdSetViewportWithCountEXT: ProcCmdSetViewportWithCountEXT -CmdSetScissorWithCountEXT: ProcCmdSetScissorWithCountEXT -CmdBindVertexBuffers2EXT: ProcCmdBindVertexBuffers2EXT -CmdSetDepthTestEnableEXT: ProcCmdSetDepthTestEnableEXT -CmdSetDepthWriteEnableEXT: ProcCmdSetDepthWriteEnableEXT -CmdSetDepthCompareOpEXT: ProcCmdSetDepthCompareOpEXT -CmdSetDepthBoundsTestEnableEXT: ProcCmdSetDepthBoundsTestEnableEXT -CmdSetStencilTestEnableEXT: ProcCmdSetStencilTestEnableEXT -CmdSetStencilOpEXT: ProcCmdSetStencilOpEXT -GetGeneratedCommandsMemoryRequirementsNV: ProcGetGeneratedCommandsMemoryRequirementsNV -CmdPreprocessGeneratedCommandsNV: ProcCmdPreprocessGeneratedCommandsNV -CmdExecuteGeneratedCommandsNV: ProcCmdExecuteGeneratedCommandsNV -CmdBindPipelineShaderGroupNV: ProcCmdBindPipelineShaderGroupNV -CreateIndirectCommandsLayoutNV: ProcCreateIndirectCommandsLayoutNV -DestroyIndirectCommandsLayoutNV: ProcDestroyIndirectCommandsLayoutNV -CreatePrivateDataSlotEXT: ProcCreatePrivateDataSlotEXT -DestroyPrivateDataSlotEXT: ProcDestroyPrivateDataSlotEXT -SetPrivateDataEXT: ProcSetPrivateDataEXT -GetPrivateDataEXT: ProcGetPrivateDataEXT -CmdSetFragmentShadingRateEnumNV: ProcCmdSetFragmentShadingRateEnumNV -CmdSetVertexInputEXT: ProcCmdSetVertexInputEXT -GetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI: ProcGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI -CmdSubpassShadingHUAWEI: ProcCmdSubpassShadingHUAWEI -CmdBindInvocationMaskHUAWEI: ProcCmdBindInvocationMaskHUAWEI -GetMemoryRemoteAddressNV: ProcGetMemoryRemoteAddressNV -CmdSetPatchControlPointsEXT: ProcCmdSetPatchControlPointsEXT -CmdSetRasterizerDiscardEnableEXT: ProcCmdSetRasterizerDiscardEnableEXT -CmdSetDepthBiasEnableEXT: ProcCmdSetDepthBiasEnableEXT -CmdSetLogicOpEXT: ProcCmdSetLogicOpEXT -CmdSetPrimitiveRestartEnableEXT: ProcCmdSetPrimitiveRestartEnableEXT -CmdDrawMultiEXT: ProcCmdDrawMultiEXT -CmdDrawMultiIndexedEXT: ProcCmdDrawMultiIndexedEXT -SetDeviceMemoryPriorityEXT: ProcSetDeviceMemoryPriorityEXT -CreateAccelerationStructureKHR: ProcCreateAccelerationStructureKHR -DestroyAccelerationStructureKHR: ProcDestroyAccelerationStructureKHR -CmdBuildAccelerationStructuresKHR: ProcCmdBuildAccelerationStructuresKHR -CmdBuildAccelerationStructuresIndirectKHR: ProcCmdBuildAccelerationStructuresIndirectKHR -BuildAccelerationStructuresKHR: ProcBuildAccelerationStructuresKHR -CopyAccelerationStructureKHR: ProcCopyAccelerationStructureKHR -CopyAccelerationStructureToMemoryKHR: ProcCopyAccelerationStructureToMemoryKHR -CopyMemoryToAccelerationStructureKHR: ProcCopyMemoryToAccelerationStructureKHR -WriteAccelerationStructuresPropertiesKHR: ProcWriteAccelerationStructuresPropertiesKHR -CmdCopyAccelerationStructureKHR: ProcCmdCopyAccelerationStructureKHR -CmdCopyAccelerationStructureToMemoryKHR: ProcCmdCopyAccelerationStructureToMemoryKHR -CmdCopyMemoryToAccelerationStructureKHR: ProcCmdCopyMemoryToAccelerationStructureKHR -GetAccelerationStructureDeviceAddressKHR: ProcGetAccelerationStructureDeviceAddressKHR -CmdWriteAccelerationStructuresPropertiesKHR: ProcCmdWriteAccelerationStructuresPropertiesKHR -GetDeviceAccelerationStructureCompatibilityKHR: ProcGetDeviceAccelerationStructureCompatibilityKHR -GetAccelerationStructureBuildSizesKHR: ProcGetAccelerationStructureBuildSizesKHR -CmdTraceRaysKHR: ProcCmdTraceRaysKHR -CreateRayTracingPipelinesKHR: ProcCreateRayTracingPipelinesKHR -GetRayTracingCaptureReplayShaderGroupHandlesKHR: ProcGetRayTracingCaptureReplayShaderGroupHandlesKHR -CmdTraceRaysIndirectKHR: ProcCmdTraceRaysIndirectKHR -GetRayTracingShaderGroupStackSizeKHR: ProcGetRayTracingShaderGroupStackSizeKHR -CmdSetRayTracingPipelineStackSizeKHR: ProcCmdSetRayTracingPipelineStackSizeKHR -GetMemoryWin32HandleKHR: ProcGetMemoryWin32HandleKHR -GetMemoryWin32HandlePropertiesKHR: ProcGetMemoryWin32HandlePropertiesKHR -ImportSemaphoreWin32HandleKHR: ProcImportSemaphoreWin32HandleKHR -GetSemaphoreWin32HandleKHR: ProcGetSemaphoreWin32HandleKHR -ImportFenceWin32HandleKHR: ProcImportFenceWin32HandleKHR -GetFenceWin32HandleKHR: ProcGetFenceWin32HandleKHR -GetMemoryWin32HandleNV: ProcGetMemoryWin32HandleNV -AcquireFullScreenExclusiveModeEXT: ProcAcquireFullScreenExclusiveModeEXT -ReleaseFullScreenExclusiveModeEXT: ProcReleaseFullScreenExclusiveModeEXT -GetDeviceGroupSurfacePresentModes2EXT: ProcGetDeviceGroupSurfacePresentModes2EXT // Loader Procedures CreateInstance: ProcCreateInstance +DebugUtilsMessengerCallbackEXT: ProcDebugUtilsMessengerCallbackEXT +DeviceMemoryReportCallbackEXT: ProcDeviceMemoryReportCallbackEXT EnumerateInstanceExtensionProperties: ProcEnumerateInstanceExtensionProperties EnumerateInstanceLayerProperties: ProcEnumerateInstanceLayerProperties EnumerateInstanceVersion: ProcEnumerateInstanceVersion -DebugUtilsMessengerCallbackEXT: ProcDebugUtilsMessengerCallbackEXT -DeviceMemoryReportCallbackEXT: ProcDeviceMemoryReportCallbackEXT -load_proc_addresses :: proc(set_proc_address: SetProcAddressType) { - // Instance Procedures - set_proc_address(&DestroyInstance, "vkDestroyInstance") - set_proc_address(&EnumeratePhysicalDevices, "vkEnumeratePhysicalDevices") - set_proc_address(&GetPhysicalDeviceFeatures, "vkGetPhysicalDeviceFeatures") - set_proc_address(&GetPhysicalDeviceFormatProperties, "vkGetPhysicalDeviceFormatProperties") - set_proc_address(&GetPhysicalDeviceImageFormatProperties, "vkGetPhysicalDeviceImageFormatProperties") - set_proc_address(&GetPhysicalDeviceProperties, "vkGetPhysicalDeviceProperties") - set_proc_address(&GetPhysicalDeviceQueueFamilyProperties, "vkGetPhysicalDeviceQueueFamilyProperties") - set_proc_address(&GetPhysicalDeviceMemoryProperties, "vkGetPhysicalDeviceMemoryProperties") - set_proc_address(&GetInstanceProcAddr, "vkGetInstanceProcAddr") - set_proc_address(&CreateDevice, "vkCreateDevice") - set_proc_address(&EnumerateDeviceExtensionProperties, "vkEnumerateDeviceExtensionProperties") - set_proc_address(&EnumerateDeviceLayerProperties, "vkEnumerateDeviceLayerProperties") - set_proc_address(&GetPhysicalDeviceSparseImageFormatProperties, "vkGetPhysicalDeviceSparseImageFormatProperties") - set_proc_address(&EnumeratePhysicalDeviceGroups, "vkEnumeratePhysicalDeviceGroups") - set_proc_address(&GetPhysicalDeviceFeatures2, "vkGetPhysicalDeviceFeatures2") - set_proc_address(&GetPhysicalDeviceProperties2, "vkGetPhysicalDeviceProperties2") - set_proc_address(&GetPhysicalDeviceFormatProperties2, "vkGetPhysicalDeviceFormatProperties2") - set_proc_address(&GetPhysicalDeviceImageFormatProperties2, "vkGetPhysicalDeviceImageFormatProperties2") - set_proc_address(&GetPhysicalDeviceQueueFamilyProperties2, "vkGetPhysicalDeviceQueueFamilyProperties2") - set_proc_address(&GetPhysicalDeviceMemoryProperties2, "vkGetPhysicalDeviceMemoryProperties2") - set_proc_address(&GetPhysicalDeviceSparseImageFormatProperties2, "vkGetPhysicalDeviceSparseImageFormatProperties2") - set_proc_address(&GetPhysicalDeviceExternalBufferProperties, "vkGetPhysicalDeviceExternalBufferProperties") - set_proc_address(&GetPhysicalDeviceExternalFenceProperties, "vkGetPhysicalDeviceExternalFenceProperties") - set_proc_address(&GetPhysicalDeviceExternalSemaphoreProperties, "vkGetPhysicalDeviceExternalSemaphoreProperties") - set_proc_address(&DestroySurfaceKHR, "vkDestroySurfaceKHR") - set_proc_address(&GetPhysicalDeviceSurfaceSupportKHR, "vkGetPhysicalDeviceSurfaceSupportKHR") - set_proc_address(&GetPhysicalDeviceSurfaceCapabilitiesKHR, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR") - set_proc_address(&GetPhysicalDeviceSurfaceFormatsKHR, "vkGetPhysicalDeviceSurfaceFormatsKHR") - set_proc_address(&GetPhysicalDeviceSurfacePresentModesKHR, "vkGetPhysicalDeviceSurfacePresentModesKHR") - set_proc_address(&GetPhysicalDevicePresentRectanglesKHR, "vkGetPhysicalDevicePresentRectanglesKHR") - set_proc_address(&GetPhysicalDeviceDisplayPropertiesKHR, "vkGetPhysicalDeviceDisplayPropertiesKHR") - set_proc_address(&GetPhysicalDeviceDisplayPlanePropertiesKHR, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR") - set_proc_address(&GetDisplayPlaneSupportedDisplaysKHR, "vkGetDisplayPlaneSupportedDisplaysKHR") - set_proc_address(&GetDisplayModePropertiesKHR, "vkGetDisplayModePropertiesKHR") - set_proc_address(&CreateDisplayModeKHR, "vkCreateDisplayModeKHR") - set_proc_address(&GetDisplayPlaneCapabilitiesKHR, "vkGetDisplayPlaneCapabilitiesKHR") - set_proc_address(&CreateDisplayPlaneSurfaceKHR, "vkCreateDisplayPlaneSurfaceKHR") - set_proc_address(&GetPhysicalDeviceFeatures2KHR, "vkGetPhysicalDeviceFeatures2KHR") - set_proc_address(&GetPhysicalDeviceProperties2KHR, "vkGetPhysicalDeviceProperties2KHR") - set_proc_address(&GetPhysicalDeviceFormatProperties2KHR, "vkGetPhysicalDeviceFormatProperties2KHR") - set_proc_address(&GetPhysicalDeviceImageFormatProperties2KHR, "vkGetPhysicalDeviceImageFormatProperties2KHR") - set_proc_address(&GetPhysicalDeviceQueueFamilyProperties2KHR, "vkGetPhysicalDeviceQueueFamilyProperties2KHR") - set_proc_address(&GetPhysicalDeviceMemoryProperties2KHR, "vkGetPhysicalDeviceMemoryProperties2KHR") - set_proc_address(&GetPhysicalDeviceSparseImageFormatProperties2KHR, "vkGetPhysicalDeviceSparseImageFormatProperties2KHR") - set_proc_address(&EnumeratePhysicalDeviceGroupsKHR, "vkEnumeratePhysicalDeviceGroupsKHR") - set_proc_address(&GetPhysicalDeviceExternalBufferPropertiesKHR, "vkGetPhysicalDeviceExternalBufferPropertiesKHR") - set_proc_address(&GetPhysicalDeviceExternalSemaphorePropertiesKHR, "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR") - set_proc_address(&GetPhysicalDeviceExternalFencePropertiesKHR, "vkGetPhysicalDeviceExternalFencePropertiesKHR") - set_proc_address(&EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR, "vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR") - set_proc_address(&GetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR, "vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR") - set_proc_address(&GetPhysicalDeviceSurfaceCapabilities2KHR, "vkGetPhysicalDeviceSurfaceCapabilities2KHR") - set_proc_address(&GetPhysicalDeviceSurfaceFormats2KHR, "vkGetPhysicalDeviceSurfaceFormats2KHR") - set_proc_address(&GetPhysicalDeviceDisplayProperties2KHR, "vkGetPhysicalDeviceDisplayProperties2KHR") - set_proc_address(&GetPhysicalDeviceDisplayPlaneProperties2KHR, "vkGetPhysicalDeviceDisplayPlaneProperties2KHR") - set_proc_address(&GetDisplayModeProperties2KHR, "vkGetDisplayModeProperties2KHR") - set_proc_address(&GetDisplayPlaneCapabilities2KHR, "vkGetDisplayPlaneCapabilities2KHR") - set_proc_address(&GetPhysicalDeviceFragmentShadingRatesKHR, "vkGetPhysicalDeviceFragmentShadingRatesKHR") - set_proc_address(&CreateDebugReportCallbackEXT, "vkCreateDebugReportCallbackEXT") - set_proc_address(&DestroyDebugReportCallbackEXT, "vkDestroyDebugReportCallbackEXT") - set_proc_address(&DebugReportMessageEXT, "vkDebugReportMessageEXT") - set_proc_address(&GetPhysicalDeviceExternalImageFormatPropertiesNV, "vkGetPhysicalDeviceExternalImageFormatPropertiesNV") - set_proc_address(&ReleaseDisplayEXT, "vkReleaseDisplayEXT") - set_proc_address(&GetPhysicalDeviceSurfaceCapabilities2EXT, "vkGetPhysicalDeviceSurfaceCapabilities2EXT") - set_proc_address(&CreateDebugUtilsMessengerEXT, "vkCreateDebugUtilsMessengerEXT") - set_proc_address(&DestroyDebugUtilsMessengerEXT, "vkDestroyDebugUtilsMessengerEXT") - set_proc_address(&SubmitDebugUtilsMessageEXT, "vkSubmitDebugUtilsMessageEXT") - set_proc_address(&GetPhysicalDeviceMultisamplePropertiesEXT, "vkGetPhysicalDeviceMultisamplePropertiesEXT") - set_proc_address(&GetPhysicalDeviceCalibrateableTimeDomainsEXT, "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT") - set_proc_address(&GetPhysicalDeviceToolPropertiesEXT, "vkGetPhysicalDeviceToolPropertiesEXT") - set_proc_address(&GetPhysicalDeviceCooperativeMatrixPropertiesNV, "vkGetPhysicalDeviceCooperativeMatrixPropertiesNV") - set_proc_address(&GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV, "vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV") - set_proc_address(&CreateHeadlessSurfaceEXT, "vkCreateHeadlessSurfaceEXT") - set_proc_address(&AcquireDrmDisplayEXT, "vkAcquireDrmDisplayEXT") - set_proc_address(&GetDrmDisplayEXT, "vkGetDrmDisplayEXT") - set_proc_address(&AcquireWinrtDisplayNV, "vkAcquireWinrtDisplayNV") - set_proc_address(&GetWinrtDisplayNV, "vkGetWinrtDisplayNV") - set_proc_address(&CreateWin32SurfaceKHR, "vkCreateWin32SurfaceKHR") - set_proc_address(&GetPhysicalDeviceWin32PresentationSupportKHR, "vkGetPhysicalDeviceWin32PresentationSupportKHR") - set_proc_address(&GetPhysicalDeviceSurfacePresentModes2EXT, "vkGetPhysicalDeviceSurfacePresentModes2EXT") - set_proc_address(&CreateMetalSurfaceEXT, "vkCreateMetalSurfaceEXT") - set_proc_address(&CreateMacOSSurfaceMVK, "vkCreateMacOSSurfaceMVK") - set_proc_address(&CreateIOSSurfaceMVK, "vkCreateIOSSurfaceMVK") +// Instance Procedures +AcquireDrmDisplayEXT: ProcAcquireDrmDisplayEXT +AcquireWinrtDisplayNV: ProcAcquireWinrtDisplayNV +CreateDebugReportCallbackEXT: ProcCreateDebugReportCallbackEXT +CreateDebugUtilsMessengerEXT: ProcCreateDebugUtilsMessengerEXT +CreateDevice: ProcCreateDevice +CreateDisplayModeKHR: ProcCreateDisplayModeKHR +CreateDisplayPlaneSurfaceKHR: ProcCreateDisplayPlaneSurfaceKHR +CreateHeadlessSurfaceEXT: ProcCreateHeadlessSurfaceEXT +CreateIOSSurfaceMVK: ProcCreateIOSSurfaceMVK +CreateMacOSSurfaceMVK: ProcCreateMacOSSurfaceMVK +CreateMetalSurfaceEXT: ProcCreateMetalSurfaceEXT +CreateWin32SurfaceKHR: ProcCreateWin32SurfaceKHR +DebugReportMessageEXT: ProcDebugReportMessageEXT +DestroyDebugReportCallbackEXT: ProcDestroyDebugReportCallbackEXT +DestroyDebugUtilsMessengerEXT: ProcDestroyDebugUtilsMessengerEXT +DestroyInstance: ProcDestroyInstance +DestroySurfaceKHR: ProcDestroySurfaceKHR +EnumerateDeviceExtensionProperties: ProcEnumerateDeviceExtensionProperties +EnumerateDeviceLayerProperties: ProcEnumerateDeviceLayerProperties +EnumeratePhysicalDeviceGroups: ProcEnumeratePhysicalDeviceGroups +EnumeratePhysicalDeviceGroupsKHR: ProcEnumeratePhysicalDeviceGroupsKHR +EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR: ProcEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR +EnumeratePhysicalDevices: ProcEnumeratePhysicalDevices +GetDisplayModeProperties2KHR: ProcGetDisplayModeProperties2KHR +GetDisplayModePropertiesKHR: ProcGetDisplayModePropertiesKHR +GetDisplayPlaneCapabilities2KHR: ProcGetDisplayPlaneCapabilities2KHR +GetDisplayPlaneCapabilitiesKHR: ProcGetDisplayPlaneCapabilitiesKHR +GetDisplayPlaneSupportedDisplaysKHR: ProcGetDisplayPlaneSupportedDisplaysKHR +GetDrmDisplayEXT: ProcGetDrmDisplayEXT +GetInstanceProcAddr: ProcGetInstanceProcAddr +GetPhysicalDeviceCalibrateableTimeDomainsEXT: ProcGetPhysicalDeviceCalibrateableTimeDomainsEXT +GetPhysicalDeviceCooperativeMatrixPropertiesNV: ProcGetPhysicalDeviceCooperativeMatrixPropertiesNV +GetPhysicalDeviceDisplayPlaneProperties2KHR: ProcGetPhysicalDeviceDisplayPlaneProperties2KHR +GetPhysicalDeviceDisplayPlanePropertiesKHR: ProcGetPhysicalDeviceDisplayPlanePropertiesKHR +GetPhysicalDeviceDisplayProperties2KHR: ProcGetPhysicalDeviceDisplayProperties2KHR +GetPhysicalDeviceDisplayPropertiesKHR: ProcGetPhysicalDeviceDisplayPropertiesKHR +GetPhysicalDeviceExternalBufferProperties: ProcGetPhysicalDeviceExternalBufferProperties +GetPhysicalDeviceExternalBufferPropertiesKHR: ProcGetPhysicalDeviceExternalBufferPropertiesKHR +GetPhysicalDeviceExternalFenceProperties: ProcGetPhysicalDeviceExternalFenceProperties +GetPhysicalDeviceExternalFencePropertiesKHR: ProcGetPhysicalDeviceExternalFencePropertiesKHR +GetPhysicalDeviceExternalImageFormatPropertiesNV: ProcGetPhysicalDeviceExternalImageFormatPropertiesNV +GetPhysicalDeviceExternalSemaphoreProperties: ProcGetPhysicalDeviceExternalSemaphoreProperties +GetPhysicalDeviceExternalSemaphorePropertiesKHR: ProcGetPhysicalDeviceExternalSemaphorePropertiesKHR +GetPhysicalDeviceFeatures: ProcGetPhysicalDeviceFeatures +GetPhysicalDeviceFeatures2: ProcGetPhysicalDeviceFeatures2 +GetPhysicalDeviceFeatures2KHR: ProcGetPhysicalDeviceFeatures2KHR +GetPhysicalDeviceFormatProperties: ProcGetPhysicalDeviceFormatProperties +GetPhysicalDeviceFormatProperties2: ProcGetPhysicalDeviceFormatProperties2 +GetPhysicalDeviceFormatProperties2KHR: ProcGetPhysicalDeviceFormatProperties2KHR +GetPhysicalDeviceFragmentShadingRatesKHR: ProcGetPhysicalDeviceFragmentShadingRatesKHR +GetPhysicalDeviceImageFormatProperties: ProcGetPhysicalDeviceImageFormatProperties +GetPhysicalDeviceImageFormatProperties2: ProcGetPhysicalDeviceImageFormatProperties2 +GetPhysicalDeviceImageFormatProperties2KHR: ProcGetPhysicalDeviceImageFormatProperties2KHR +GetPhysicalDeviceMemoryProperties: ProcGetPhysicalDeviceMemoryProperties +GetPhysicalDeviceMemoryProperties2: ProcGetPhysicalDeviceMemoryProperties2 +GetPhysicalDeviceMemoryProperties2KHR: ProcGetPhysicalDeviceMemoryProperties2KHR +GetPhysicalDeviceMultisamplePropertiesEXT: ProcGetPhysicalDeviceMultisamplePropertiesEXT +GetPhysicalDevicePresentRectanglesKHR: ProcGetPhysicalDevicePresentRectanglesKHR +GetPhysicalDeviceProperties: ProcGetPhysicalDeviceProperties +GetPhysicalDeviceProperties2: ProcGetPhysicalDeviceProperties2 +GetPhysicalDeviceProperties2KHR: ProcGetPhysicalDeviceProperties2KHR +GetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR: ProcGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR +GetPhysicalDeviceQueueFamilyProperties: ProcGetPhysicalDeviceQueueFamilyProperties +GetPhysicalDeviceQueueFamilyProperties2: ProcGetPhysicalDeviceQueueFamilyProperties2 +GetPhysicalDeviceQueueFamilyProperties2KHR: ProcGetPhysicalDeviceQueueFamilyProperties2KHR +GetPhysicalDeviceSparseImageFormatProperties: ProcGetPhysicalDeviceSparseImageFormatProperties +GetPhysicalDeviceSparseImageFormatProperties2: ProcGetPhysicalDeviceSparseImageFormatProperties2 +GetPhysicalDeviceSparseImageFormatProperties2KHR: ProcGetPhysicalDeviceSparseImageFormatProperties2KHR +GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV: ProcGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV +GetPhysicalDeviceSurfaceCapabilities2EXT: ProcGetPhysicalDeviceSurfaceCapabilities2EXT +GetPhysicalDeviceSurfaceCapabilities2KHR: ProcGetPhysicalDeviceSurfaceCapabilities2KHR +GetPhysicalDeviceSurfaceCapabilitiesKHR: ProcGetPhysicalDeviceSurfaceCapabilitiesKHR +GetPhysicalDeviceSurfaceFormats2KHR: ProcGetPhysicalDeviceSurfaceFormats2KHR +GetPhysicalDeviceSurfaceFormatsKHR: ProcGetPhysicalDeviceSurfaceFormatsKHR +GetPhysicalDeviceSurfacePresentModes2EXT: ProcGetPhysicalDeviceSurfacePresentModes2EXT +GetPhysicalDeviceSurfacePresentModesKHR: ProcGetPhysicalDeviceSurfacePresentModesKHR +GetPhysicalDeviceSurfaceSupportKHR: ProcGetPhysicalDeviceSurfaceSupportKHR +GetPhysicalDeviceToolProperties: ProcGetPhysicalDeviceToolProperties +GetPhysicalDeviceToolPropertiesEXT: ProcGetPhysicalDeviceToolPropertiesEXT +GetPhysicalDeviceWin32PresentationSupportKHR: ProcGetPhysicalDeviceWin32PresentationSupportKHR +GetWinrtDisplayNV: ProcGetWinrtDisplayNV +ReleaseDisplayEXT: ProcReleaseDisplayEXT +SubmitDebugUtilsMessageEXT: ProcSubmitDebugUtilsMessageEXT - // Device Procedures - set_proc_address(&GetDeviceProcAddr, "vkGetDeviceProcAddr") - set_proc_address(&DestroyDevice, "vkDestroyDevice") - set_proc_address(&GetDeviceQueue, "vkGetDeviceQueue") - set_proc_address(&QueueSubmit, "vkQueueSubmit") - set_proc_address(&QueueWaitIdle, "vkQueueWaitIdle") - set_proc_address(&DeviceWaitIdle, "vkDeviceWaitIdle") - set_proc_address(&AllocateMemory, "vkAllocateMemory") - set_proc_address(&FreeMemory, "vkFreeMemory") - set_proc_address(&MapMemory, "vkMapMemory") - set_proc_address(&UnmapMemory, "vkUnmapMemory") - set_proc_address(&FlushMappedMemoryRanges, "vkFlushMappedMemoryRanges") - set_proc_address(&InvalidateMappedMemoryRanges, "vkInvalidateMappedMemoryRanges") - set_proc_address(&GetDeviceMemoryCommitment, "vkGetDeviceMemoryCommitment") - set_proc_address(&BindBufferMemory, "vkBindBufferMemory") - set_proc_address(&BindImageMemory, "vkBindImageMemory") - set_proc_address(&GetBufferMemoryRequirements, "vkGetBufferMemoryRequirements") - set_proc_address(&GetImageMemoryRequirements, "vkGetImageMemoryRequirements") - set_proc_address(&GetImageSparseMemoryRequirements, "vkGetImageSparseMemoryRequirements") - set_proc_address(&QueueBindSparse, "vkQueueBindSparse") - set_proc_address(&CreateFence, "vkCreateFence") - set_proc_address(&DestroyFence, "vkDestroyFence") - set_proc_address(&ResetFences, "vkResetFences") - set_proc_address(&GetFenceStatus, "vkGetFenceStatus") - set_proc_address(&WaitForFences, "vkWaitForFences") - set_proc_address(&CreateSemaphore, "vkCreateSemaphore") - set_proc_address(&DestroySemaphore, "vkDestroySemaphore") - set_proc_address(&CreateEvent, "vkCreateEvent") - set_proc_address(&DestroyEvent, "vkDestroyEvent") - set_proc_address(&GetEventStatus, "vkGetEventStatus") - set_proc_address(&SetEvent, "vkSetEvent") - set_proc_address(&ResetEvent, "vkResetEvent") - set_proc_address(&CreateQueryPool, "vkCreateQueryPool") - set_proc_address(&DestroyQueryPool, "vkDestroyQueryPool") - set_proc_address(&GetQueryPoolResults, "vkGetQueryPoolResults") - set_proc_address(&CreateBuffer, "vkCreateBuffer") - set_proc_address(&DestroyBuffer, "vkDestroyBuffer") - set_proc_address(&CreateBufferView, "vkCreateBufferView") - set_proc_address(&DestroyBufferView, "vkDestroyBufferView") - set_proc_address(&CreateImage, "vkCreateImage") - set_proc_address(&DestroyImage, "vkDestroyImage") - set_proc_address(&GetImageSubresourceLayout, "vkGetImageSubresourceLayout") - set_proc_address(&CreateImageView, "vkCreateImageView") - set_proc_address(&DestroyImageView, "vkDestroyImageView") - set_proc_address(&CreateShaderModule, "vkCreateShaderModule") - set_proc_address(&DestroyShaderModule, "vkDestroyShaderModule") - set_proc_address(&CreatePipelineCache, "vkCreatePipelineCache") - set_proc_address(&DestroyPipelineCache, "vkDestroyPipelineCache") - set_proc_address(&GetPipelineCacheData, "vkGetPipelineCacheData") - set_proc_address(&MergePipelineCaches, "vkMergePipelineCaches") - set_proc_address(&CreateGraphicsPipelines, "vkCreateGraphicsPipelines") - set_proc_address(&CreateComputePipelines, "vkCreateComputePipelines") - set_proc_address(&DestroyPipeline, "vkDestroyPipeline") - set_proc_address(&CreatePipelineLayout, "vkCreatePipelineLayout") - set_proc_address(&DestroyPipelineLayout, "vkDestroyPipelineLayout") - set_proc_address(&CreateSampler, "vkCreateSampler") - set_proc_address(&DestroySampler, "vkDestroySampler") - set_proc_address(&CreateDescriptorSetLayout, "vkCreateDescriptorSetLayout") - set_proc_address(&DestroyDescriptorSetLayout, "vkDestroyDescriptorSetLayout") - set_proc_address(&CreateDescriptorPool, "vkCreateDescriptorPool") - set_proc_address(&DestroyDescriptorPool, "vkDestroyDescriptorPool") - set_proc_address(&ResetDescriptorPool, "vkResetDescriptorPool") - set_proc_address(&AllocateDescriptorSets, "vkAllocateDescriptorSets") - set_proc_address(&FreeDescriptorSets, "vkFreeDescriptorSets") - set_proc_address(&UpdateDescriptorSets, "vkUpdateDescriptorSets") - set_proc_address(&CreateFramebuffer, "vkCreateFramebuffer") - set_proc_address(&DestroyFramebuffer, "vkDestroyFramebuffer") - set_proc_address(&CreateRenderPass, "vkCreateRenderPass") - set_proc_address(&DestroyRenderPass, "vkDestroyRenderPass") - set_proc_address(&GetRenderAreaGranularity, "vkGetRenderAreaGranularity") - set_proc_address(&CreateCommandPool, "vkCreateCommandPool") - set_proc_address(&DestroyCommandPool, "vkDestroyCommandPool") - set_proc_address(&ResetCommandPool, "vkResetCommandPool") - set_proc_address(&AllocateCommandBuffers, "vkAllocateCommandBuffers") - set_proc_address(&FreeCommandBuffers, "vkFreeCommandBuffers") - set_proc_address(&BeginCommandBuffer, "vkBeginCommandBuffer") - set_proc_address(&EndCommandBuffer, "vkEndCommandBuffer") - set_proc_address(&ResetCommandBuffer, "vkResetCommandBuffer") - set_proc_address(&CmdBindPipeline, "vkCmdBindPipeline") - set_proc_address(&CmdSetViewport, "vkCmdSetViewport") - set_proc_address(&CmdSetScissor, "vkCmdSetScissor") - set_proc_address(&CmdSetLineWidth, "vkCmdSetLineWidth") - set_proc_address(&CmdSetDepthBias, "vkCmdSetDepthBias") - set_proc_address(&CmdSetBlendConstants, "vkCmdSetBlendConstants") - set_proc_address(&CmdSetDepthBounds, "vkCmdSetDepthBounds") - set_proc_address(&CmdSetStencilCompareMask, "vkCmdSetStencilCompareMask") - set_proc_address(&CmdSetStencilWriteMask, "vkCmdSetStencilWriteMask") - set_proc_address(&CmdSetStencilReference, "vkCmdSetStencilReference") - set_proc_address(&CmdBindDescriptorSets, "vkCmdBindDescriptorSets") - set_proc_address(&CmdBindIndexBuffer, "vkCmdBindIndexBuffer") - set_proc_address(&CmdBindVertexBuffers, "vkCmdBindVertexBuffers") - set_proc_address(&CmdDraw, "vkCmdDraw") - set_proc_address(&CmdDrawIndexed, "vkCmdDrawIndexed") - set_proc_address(&CmdDrawIndirect, "vkCmdDrawIndirect") - set_proc_address(&CmdDrawIndexedIndirect, "vkCmdDrawIndexedIndirect") - set_proc_address(&CmdDispatch, "vkCmdDispatch") - set_proc_address(&CmdDispatchIndirect, "vkCmdDispatchIndirect") - set_proc_address(&CmdCopyBuffer, "vkCmdCopyBuffer") - set_proc_address(&CmdCopyImage, "vkCmdCopyImage") - set_proc_address(&CmdBlitImage, "vkCmdBlitImage") - set_proc_address(&CmdCopyBufferToImage, "vkCmdCopyBufferToImage") - set_proc_address(&CmdCopyImageToBuffer, "vkCmdCopyImageToBuffer") - set_proc_address(&CmdUpdateBuffer, "vkCmdUpdateBuffer") - set_proc_address(&CmdFillBuffer, "vkCmdFillBuffer") - set_proc_address(&CmdClearColorImage, "vkCmdClearColorImage") - set_proc_address(&CmdClearDepthStencilImage, "vkCmdClearDepthStencilImage") - set_proc_address(&CmdClearAttachments, "vkCmdClearAttachments") - set_proc_address(&CmdResolveImage, "vkCmdResolveImage") - set_proc_address(&CmdSetEvent, "vkCmdSetEvent") - set_proc_address(&CmdResetEvent, "vkCmdResetEvent") - set_proc_address(&CmdWaitEvents, "vkCmdWaitEvents") - set_proc_address(&CmdPipelineBarrier, "vkCmdPipelineBarrier") - set_proc_address(&CmdBeginQuery, "vkCmdBeginQuery") - set_proc_address(&CmdEndQuery, "vkCmdEndQuery") - set_proc_address(&CmdResetQueryPool, "vkCmdResetQueryPool") - set_proc_address(&CmdWriteTimestamp, "vkCmdWriteTimestamp") - set_proc_address(&CmdCopyQueryPoolResults, "vkCmdCopyQueryPoolResults") - set_proc_address(&CmdPushConstants, "vkCmdPushConstants") - set_proc_address(&CmdBeginRenderPass, "vkCmdBeginRenderPass") - set_proc_address(&CmdNextSubpass, "vkCmdNextSubpass") - set_proc_address(&CmdEndRenderPass, "vkCmdEndRenderPass") - set_proc_address(&CmdExecuteCommands, "vkCmdExecuteCommands") - set_proc_address(&BindBufferMemory2, "vkBindBufferMemory2") - set_proc_address(&BindImageMemory2, "vkBindImageMemory2") - set_proc_address(&GetDeviceGroupPeerMemoryFeatures, "vkGetDeviceGroupPeerMemoryFeatures") - set_proc_address(&CmdSetDeviceMask, "vkCmdSetDeviceMask") - set_proc_address(&CmdDispatchBase, "vkCmdDispatchBase") - set_proc_address(&GetImageMemoryRequirements2, "vkGetImageMemoryRequirements2") - set_proc_address(&GetBufferMemoryRequirements2, "vkGetBufferMemoryRequirements2") - set_proc_address(&GetImageSparseMemoryRequirements2, "vkGetImageSparseMemoryRequirements2") - set_proc_address(&TrimCommandPool, "vkTrimCommandPool") - set_proc_address(&GetDeviceQueue2, "vkGetDeviceQueue2") - set_proc_address(&CreateSamplerYcbcrConversion, "vkCreateSamplerYcbcrConversion") - set_proc_address(&DestroySamplerYcbcrConversion, "vkDestroySamplerYcbcrConversion") - set_proc_address(&CreateDescriptorUpdateTemplate, "vkCreateDescriptorUpdateTemplate") - set_proc_address(&DestroyDescriptorUpdateTemplate, "vkDestroyDescriptorUpdateTemplate") - set_proc_address(&UpdateDescriptorSetWithTemplate, "vkUpdateDescriptorSetWithTemplate") - set_proc_address(&GetDescriptorSetLayoutSupport, "vkGetDescriptorSetLayoutSupport") - set_proc_address(&CmdDrawIndirectCount, "vkCmdDrawIndirectCount") - set_proc_address(&CmdDrawIndexedIndirectCount, "vkCmdDrawIndexedIndirectCount") - set_proc_address(&CreateRenderPass2, "vkCreateRenderPass2") - set_proc_address(&CmdBeginRenderPass2, "vkCmdBeginRenderPass2") - set_proc_address(&CmdNextSubpass2, "vkCmdNextSubpass2") - set_proc_address(&CmdEndRenderPass2, "vkCmdEndRenderPass2") - set_proc_address(&ResetQueryPool, "vkResetQueryPool") - set_proc_address(&GetSemaphoreCounterValue, "vkGetSemaphoreCounterValue") - set_proc_address(&WaitSemaphores, "vkWaitSemaphores") - set_proc_address(&SignalSemaphore, "vkSignalSemaphore") - set_proc_address(&GetBufferDeviceAddress, "vkGetBufferDeviceAddress") - set_proc_address(&GetBufferOpaqueCaptureAddress, "vkGetBufferOpaqueCaptureAddress") - set_proc_address(&GetDeviceMemoryOpaqueCaptureAddress, "vkGetDeviceMemoryOpaqueCaptureAddress") - set_proc_address(&CreateSwapchainKHR, "vkCreateSwapchainKHR") - set_proc_address(&DestroySwapchainKHR, "vkDestroySwapchainKHR") - set_proc_address(&GetSwapchainImagesKHR, "vkGetSwapchainImagesKHR") - set_proc_address(&AcquireNextImageKHR, "vkAcquireNextImageKHR") - set_proc_address(&QueuePresentKHR, "vkQueuePresentKHR") - set_proc_address(&GetDeviceGroupPresentCapabilitiesKHR, "vkGetDeviceGroupPresentCapabilitiesKHR") - set_proc_address(&GetDeviceGroupSurfacePresentModesKHR, "vkGetDeviceGroupSurfacePresentModesKHR") - set_proc_address(&AcquireNextImage2KHR, "vkAcquireNextImage2KHR") - set_proc_address(&CreateSharedSwapchainsKHR, "vkCreateSharedSwapchainsKHR") - set_proc_address(&GetDeviceGroupPeerMemoryFeaturesKHR, "vkGetDeviceGroupPeerMemoryFeaturesKHR") - set_proc_address(&CmdSetDeviceMaskKHR, "vkCmdSetDeviceMaskKHR") - set_proc_address(&CmdDispatchBaseKHR, "vkCmdDispatchBaseKHR") - set_proc_address(&TrimCommandPoolKHR, "vkTrimCommandPoolKHR") - set_proc_address(&GetMemoryFdKHR, "vkGetMemoryFdKHR") - set_proc_address(&GetMemoryFdPropertiesKHR, "vkGetMemoryFdPropertiesKHR") - set_proc_address(&ImportSemaphoreFdKHR, "vkImportSemaphoreFdKHR") - set_proc_address(&GetSemaphoreFdKHR, "vkGetSemaphoreFdKHR") - set_proc_address(&CmdPushDescriptorSetKHR, "vkCmdPushDescriptorSetKHR") - set_proc_address(&CmdPushDescriptorSetWithTemplateKHR, "vkCmdPushDescriptorSetWithTemplateKHR") - set_proc_address(&CreateDescriptorUpdateTemplateKHR, "vkCreateDescriptorUpdateTemplateKHR") - set_proc_address(&DestroyDescriptorUpdateTemplateKHR, "vkDestroyDescriptorUpdateTemplateKHR") - set_proc_address(&UpdateDescriptorSetWithTemplateKHR, "vkUpdateDescriptorSetWithTemplateKHR") - set_proc_address(&CreateRenderPass2KHR, "vkCreateRenderPass2KHR") - set_proc_address(&CmdBeginRenderPass2KHR, "vkCmdBeginRenderPass2KHR") - set_proc_address(&CmdNextSubpass2KHR, "vkCmdNextSubpass2KHR") - set_proc_address(&CmdEndRenderPass2KHR, "vkCmdEndRenderPass2KHR") - set_proc_address(&GetSwapchainStatusKHR, "vkGetSwapchainStatusKHR") - set_proc_address(&ImportFenceFdKHR, "vkImportFenceFdKHR") - set_proc_address(&GetFenceFdKHR, "vkGetFenceFdKHR") - set_proc_address(&AcquireProfilingLockKHR, "vkAcquireProfilingLockKHR") - set_proc_address(&ReleaseProfilingLockKHR, "vkReleaseProfilingLockKHR") - set_proc_address(&GetImageMemoryRequirements2KHR, "vkGetImageMemoryRequirements2KHR") - set_proc_address(&GetBufferMemoryRequirements2KHR, "vkGetBufferMemoryRequirements2KHR") - set_proc_address(&GetImageSparseMemoryRequirements2KHR, "vkGetImageSparseMemoryRequirements2KHR") - set_proc_address(&CreateSamplerYcbcrConversionKHR, "vkCreateSamplerYcbcrConversionKHR") - set_proc_address(&DestroySamplerYcbcrConversionKHR, "vkDestroySamplerYcbcrConversionKHR") - set_proc_address(&BindBufferMemory2KHR, "vkBindBufferMemory2KHR") - set_proc_address(&BindImageMemory2KHR, "vkBindImageMemory2KHR") - set_proc_address(&GetDescriptorSetLayoutSupportKHR, "vkGetDescriptorSetLayoutSupportKHR") - set_proc_address(&CmdDrawIndirectCountKHR, "vkCmdDrawIndirectCountKHR") - set_proc_address(&CmdDrawIndexedIndirectCountKHR, "vkCmdDrawIndexedIndirectCountKHR") - set_proc_address(&GetSemaphoreCounterValueKHR, "vkGetSemaphoreCounterValueKHR") - set_proc_address(&WaitSemaphoresKHR, "vkWaitSemaphoresKHR") - set_proc_address(&SignalSemaphoreKHR, "vkSignalSemaphoreKHR") - set_proc_address(&CmdSetFragmentShadingRateKHR, "vkCmdSetFragmentShadingRateKHR") - set_proc_address(&WaitForPresentKHR, "vkWaitForPresentKHR") - set_proc_address(&GetBufferDeviceAddressKHR, "vkGetBufferDeviceAddressKHR") - set_proc_address(&GetBufferOpaqueCaptureAddressKHR, "vkGetBufferOpaqueCaptureAddressKHR") - set_proc_address(&GetDeviceMemoryOpaqueCaptureAddressKHR, "vkGetDeviceMemoryOpaqueCaptureAddressKHR") - set_proc_address(&CreateDeferredOperationKHR, "vkCreateDeferredOperationKHR") - set_proc_address(&DestroyDeferredOperationKHR, "vkDestroyDeferredOperationKHR") - set_proc_address(&GetDeferredOperationMaxConcurrencyKHR, "vkGetDeferredOperationMaxConcurrencyKHR") - set_proc_address(&GetDeferredOperationResultKHR, "vkGetDeferredOperationResultKHR") - set_proc_address(&DeferredOperationJoinKHR, "vkDeferredOperationJoinKHR") - set_proc_address(&GetPipelineExecutablePropertiesKHR, "vkGetPipelineExecutablePropertiesKHR") - set_proc_address(&GetPipelineExecutableStatisticsKHR, "vkGetPipelineExecutableStatisticsKHR") - set_proc_address(&GetPipelineExecutableInternalRepresentationsKHR, "vkGetPipelineExecutableInternalRepresentationsKHR") - set_proc_address(&CmdSetEvent2KHR, "vkCmdSetEvent2KHR") - set_proc_address(&CmdResetEvent2KHR, "vkCmdResetEvent2KHR") - set_proc_address(&CmdWaitEvents2KHR, "vkCmdWaitEvents2KHR") - set_proc_address(&CmdPipelineBarrier2KHR, "vkCmdPipelineBarrier2KHR") - set_proc_address(&CmdWriteTimestamp2KHR, "vkCmdWriteTimestamp2KHR") - set_proc_address(&QueueSubmit2KHR, "vkQueueSubmit2KHR") - set_proc_address(&CmdWriteBufferMarker2AMD, "vkCmdWriteBufferMarker2AMD") - set_proc_address(&GetQueueCheckpointData2NV, "vkGetQueueCheckpointData2NV") - set_proc_address(&CmdCopyBuffer2KHR, "vkCmdCopyBuffer2KHR") - set_proc_address(&CmdCopyImage2KHR, "vkCmdCopyImage2KHR") - set_proc_address(&CmdCopyBufferToImage2KHR, "vkCmdCopyBufferToImage2KHR") - set_proc_address(&CmdCopyImageToBuffer2KHR, "vkCmdCopyImageToBuffer2KHR") - set_proc_address(&CmdBlitImage2KHR, "vkCmdBlitImage2KHR") - set_proc_address(&CmdResolveImage2KHR, "vkCmdResolveImage2KHR") - set_proc_address(&DebugMarkerSetObjectTagEXT, "vkDebugMarkerSetObjectTagEXT") - set_proc_address(&DebugMarkerSetObjectNameEXT, "vkDebugMarkerSetObjectNameEXT") - set_proc_address(&CmdDebugMarkerBeginEXT, "vkCmdDebugMarkerBeginEXT") - set_proc_address(&CmdDebugMarkerEndEXT, "vkCmdDebugMarkerEndEXT") - set_proc_address(&CmdDebugMarkerInsertEXT, "vkCmdDebugMarkerInsertEXT") - set_proc_address(&CmdBindTransformFeedbackBuffersEXT, "vkCmdBindTransformFeedbackBuffersEXT") - set_proc_address(&CmdBeginTransformFeedbackEXT, "vkCmdBeginTransformFeedbackEXT") - set_proc_address(&CmdEndTransformFeedbackEXT, "vkCmdEndTransformFeedbackEXT") - set_proc_address(&CmdBeginQueryIndexedEXT, "vkCmdBeginQueryIndexedEXT") - set_proc_address(&CmdEndQueryIndexedEXT, "vkCmdEndQueryIndexedEXT") - set_proc_address(&CmdDrawIndirectByteCountEXT, "vkCmdDrawIndirectByteCountEXT") - set_proc_address(&CreateCuModuleNVX, "vkCreateCuModuleNVX") - set_proc_address(&CreateCuFunctionNVX, "vkCreateCuFunctionNVX") - set_proc_address(&DestroyCuModuleNVX, "vkDestroyCuModuleNVX") - set_proc_address(&DestroyCuFunctionNVX, "vkDestroyCuFunctionNVX") - set_proc_address(&CmdCuLaunchKernelNVX, "vkCmdCuLaunchKernelNVX") - set_proc_address(&GetImageViewHandleNVX, "vkGetImageViewHandleNVX") - set_proc_address(&GetImageViewAddressNVX, "vkGetImageViewAddressNVX") - set_proc_address(&CmdDrawIndirectCountAMD, "vkCmdDrawIndirectCountAMD") - set_proc_address(&CmdDrawIndexedIndirectCountAMD, "vkCmdDrawIndexedIndirectCountAMD") - set_proc_address(&GetShaderInfoAMD, "vkGetShaderInfoAMD") - set_proc_address(&CmdBeginConditionalRenderingEXT, "vkCmdBeginConditionalRenderingEXT") - set_proc_address(&CmdEndConditionalRenderingEXT, "vkCmdEndConditionalRenderingEXT") - set_proc_address(&CmdSetViewportWScalingNV, "vkCmdSetViewportWScalingNV") - set_proc_address(&DisplayPowerControlEXT, "vkDisplayPowerControlEXT") - set_proc_address(&RegisterDeviceEventEXT, "vkRegisterDeviceEventEXT") - set_proc_address(&RegisterDisplayEventEXT, "vkRegisterDisplayEventEXT") - set_proc_address(&GetSwapchainCounterEXT, "vkGetSwapchainCounterEXT") - set_proc_address(&GetRefreshCycleDurationGOOGLE, "vkGetRefreshCycleDurationGOOGLE") - set_proc_address(&GetPastPresentationTimingGOOGLE, "vkGetPastPresentationTimingGOOGLE") - set_proc_address(&CmdSetDiscardRectangleEXT, "vkCmdSetDiscardRectangleEXT") - set_proc_address(&SetHdrMetadataEXT, "vkSetHdrMetadataEXT") - set_proc_address(&SetDebugUtilsObjectNameEXT, "vkSetDebugUtilsObjectNameEXT") - set_proc_address(&SetDebugUtilsObjectTagEXT, "vkSetDebugUtilsObjectTagEXT") - set_proc_address(&QueueBeginDebugUtilsLabelEXT, "vkQueueBeginDebugUtilsLabelEXT") - set_proc_address(&QueueEndDebugUtilsLabelEXT, "vkQueueEndDebugUtilsLabelEXT") - set_proc_address(&QueueInsertDebugUtilsLabelEXT, "vkQueueInsertDebugUtilsLabelEXT") - set_proc_address(&CmdBeginDebugUtilsLabelEXT, "vkCmdBeginDebugUtilsLabelEXT") - set_proc_address(&CmdEndDebugUtilsLabelEXT, "vkCmdEndDebugUtilsLabelEXT") - set_proc_address(&CmdInsertDebugUtilsLabelEXT, "vkCmdInsertDebugUtilsLabelEXT") - set_proc_address(&CmdSetSampleLocationsEXT, "vkCmdSetSampleLocationsEXT") - set_proc_address(&GetImageDrmFormatModifierPropertiesEXT, "vkGetImageDrmFormatModifierPropertiesEXT") - set_proc_address(&CreateValidationCacheEXT, "vkCreateValidationCacheEXT") - set_proc_address(&DestroyValidationCacheEXT, "vkDestroyValidationCacheEXT") - set_proc_address(&MergeValidationCachesEXT, "vkMergeValidationCachesEXT") - set_proc_address(&GetValidationCacheDataEXT, "vkGetValidationCacheDataEXT") - set_proc_address(&CmdBindShadingRateImageNV, "vkCmdBindShadingRateImageNV") - set_proc_address(&CmdSetViewportShadingRatePaletteNV, "vkCmdSetViewportShadingRatePaletteNV") - set_proc_address(&CmdSetCoarseSampleOrderNV, "vkCmdSetCoarseSampleOrderNV") - set_proc_address(&CreateAccelerationStructureNV, "vkCreateAccelerationStructureNV") - set_proc_address(&DestroyAccelerationStructureNV, "vkDestroyAccelerationStructureNV") - set_proc_address(&GetAccelerationStructureMemoryRequirementsNV, "vkGetAccelerationStructureMemoryRequirementsNV") - set_proc_address(&BindAccelerationStructureMemoryNV, "vkBindAccelerationStructureMemoryNV") - set_proc_address(&CmdBuildAccelerationStructureNV, "vkCmdBuildAccelerationStructureNV") - set_proc_address(&CmdCopyAccelerationStructureNV, "vkCmdCopyAccelerationStructureNV") - set_proc_address(&CmdTraceRaysNV, "vkCmdTraceRaysNV") - set_proc_address(&CreateRayTracingPipelinesNV, "vkCreateRayTracingPipelinesNV") - set_proc_address(&GetRayTracingShaderGroupHandlesKHR, "vkGetRayTracingShaderGroupHandlesKHR") - set_proc_address(&GetRayTracingShaderGroupHandlesNV, "vkGetRayTracingShaderGroupHandlesNV") - set_proc_address(&GetAccelerationStructureHandleNV, "vkGetAccelerationStructureHandleNV") - set_proc_address(&CmdWriteAccelerationStructuresPropertiesNV, "vkCmdWriteAccelerationStructuresPropertiesNV") - set_proc_address(&CompileDeferredNV, "vkCompileDeferredNV") - set_proc_address(&GetMemoryHostPointerPropertiesEXT, "vkGetMemoryHostPointerPropertiesEXT") - set_proc_address(&CmdWriteBufferMarkerAMD, "vkCmdWriteBufferMarkerAMD") - set_proc_address(&GetCalibratedTimestampsEXT, "vkGetCalibratedTimestampsEXT") - set_proc_address(&CmdDrawMeshTasksNV, "vkCmdDrawMeshTasksNV") - set_proc_address(&CmdDrawMeshTasksIndirectNV, "vkCmdDrawMeshTasksIndirectNV") - set_proc_address(&CmdDrawMeshTasksIndirectCountNV, "vkCmdDrawMeshTasksIndirectCountNV") - set_proc_address(&CmdSetExclusiveScissorNV, "vkCmdSetExclusiveScissorNV") - set_proc_address(&CmdSetCheckpointNV, "vkCmdSetCheckpointNV") - set_proc_address(&GetQueueCheckpointDataNV, "vkGetQueueCheckpointDataNV") - set_proc_address(&InitializePerformanceApiINTEL, "vkInitializePerformanceApiINTEL") - set_proc_address(&UninitializePerformanceApiINTEL, "vkUninitializePerformanceApiINTEL") - set_proc_address(&CmdSetPerformanceMarkerINTEL, "vkCmdSetPerformanceMarkerINTEL") - set_proc_address(&CmdSetPerformanceStreamMarkerINTEL, "vkCmdSetPerformanceStreamMarkerINTEL") - set_proc_address(&CmdSetPerformanceOverrideINTEL, "vkCmdSetPerformanceOverrideINTEL") - set_proc_address(&AcquirePerformanceConfigurationINTEL, "vkAcquirePerformanceConfigurationINTEL") - set_proc_address(&ReleasePerformanceConfigurationINTEL, "vkReleasePerformanceConfigurationINTEL") - set_proc_address(&QueueSetPerformanceConfigurationINTEL, "vkQueueSetPerformanceConfigurationINTEL") - set_proc_address(&GetPerformanceParameterINTEL, "vkGetPerformanceParameterINTEL") - set_proc_address(&SetLocalDimmingAMD, "vkSetLocalDimmingAMD") - set_proc_address(&GetBufferDeviceAddressEXT, "vkGetBufferDeviceAddressEXT") - set_proc_address(&CmdSetLineStippleEXT, "vkCmdSetLineStippleEXT") - set_proc_address(&ResetQueryPoolEXT, "vkResetQueryPoolEXT") - set_proc_address(&CmdSetCullModeEXT, "vkCmdSetCullModeEXT") - set_proc_address(&CmdSetFrontFaceEXT, "vkCmdSetFrontFaceEXT") - set_proc_address(&CmdSetPrimitiveTopologyEXT, "vkCmdSetPrimitiveTopologyEXT") - set_proc_address(&CmdSetViewportWithCountEXT, "vkCmdSetViewportWithCountEXT") - set_proc_address(&CmdSetScissorWithCountEXT, "vkCmdSetScissorWithCountEXT") - set_proc_address(&CmdBindVertexBuffers2EXT, "vkCmdBindVertexBuffers2EXT") - set_proc_address(&CmdSetDepthTestEnableEXT, "vkCmdSetDepthTestEnableEXT") - set_proc_address(&CmdSetDepthWriteEnableEXT, "vkCmdSetDepthWriteEnableEXT") - set_proc_address(&CmdSetDepthCompareOpEXT, "vkCmdSetDepthCompareOpEXT") - set_proc_address(&CmdSetDepthBoundsTestEnableEXT, "vkCmdSetDepthBoundsTestEnableEXT") - set_proc_address(&CmdSetStencilTestEnableEXT, "vkCmdSetStencilTestEnableEXT") - set_proc_address(&CmdSetStencilOpEXT, "vkCmdSetStencilOpEXT") - set_proc_address(&GetGeneratedCommandsMemoryRequirementsNV, "vkGetGeneratedCommandsMemoryRequirementsNV") - set_proc_address(&CmdPreprocessGeneratedCommandsNV, "vkCmdPreprocessGeneratedCommandsNV") - set_proc_address(&CmdExecuteGeneratedCommandsNV, "vkCmdExecuteGeneratedCommandsNV") - set_proc_address(&CmdBindPipelineShaderGroupNV, "vkCmdBindPipelineShaderGroupNV") - set_proc_address(&CreateIndirectCommandsLayoutNV, "vkCreateIndirectCommandsLayoutNV") - set_proc_address(&DestroyIndirectCommandsLayoutNV, "vkDestroyIndirectCommandsLayoutNV") - set_proc_address(&CreatePrivateDataSlotEXT, "vkCreatePrivateDataSlotEXT") - set_proc_address(&DestroyPrivateDataSlotEXT, "vkDestroyPrivateDataSlotEXT") - set_proc_address(&SetPrivateDataEXT, "vkSetPrivateDataEXT") - set_proc_address(&GetPrivateDataEXT, "vkGetPrivateDataEXT") - set_proc_address(&CmdSetFragmentShadingRateEnumNV, "vkCmdSetFragmentShadingRateEnumNV") - set_proc_address(&CmdSetVertexInputEXT, "vkCmdSetVertexInputEXT") - set_proc_address(&GetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI, "vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI") - set_proc_address(&CmdSubpassShadingHUAWEI, "vkCmdSubpassShadingHUAWEI") - set_proc_address(&CmdBindInvocationMaskHUAWEI, "vkCmdBindInvocationMaskHUAWEI") - set_proc_address(&GetMemoryRemoteAddressNV, "vkGetMemoryRemoteAddressNV") - set_proc_address(&CmdSetPatchControlPointsEXT, "vkCmdSetPatchControlPointsEXT") - set_proc_address(&CmdSetRasterizerDiscardEnableEXT, "vkCmdSetRasterizerDiscardEnableEXT") - set_proc_address(&CmdSetDepthBiasEnableEXT, "vkCmdSetDepthBiasEnableEXT") - set_proc_address(&CmdSetLogicOpEXT, "vkCmdSetLogicOpEXT") - set_proc_address(&CmdSetPrimitiveRestartEnableEXT, "vkCmdSetPrimitiveRestartEnableEXT") - set_proc_address(&CmdDrawMultiEXT, "vkCmdDrawMultiEXT") - set_proc_address(&CmdDrawMultiIndexedEXT, "vkCmdDrawMultiIndexedEXT") - set_proc_address(&SetDeviceMemoryPriorityEXT, "vkSetDeviceMemoryPriorityEXT") - set_proc_address(&CreateAccelerationStructureKHR, "vkCreateAccelerationStructureKHR") - set_proc_address(&DestroyAccelerationStructureKHR, "vkDestroyAccelerationStructureKHR") - set_proc_address(&CmdBuildAccelerationStructuresKHR, "vkCmdBuildAccelerationStructuresKHR") - set_proc_address(&CmdBuildAccelerationStructuresIndirectKHR, "vkCmdBuildAccelerationStructuresIndirectKHR") - set_proc_address(&BuildAccelerationStructuresKHR, "vkBuildAccelerationStructuresKHR") - set_proc_address(&CopyAccelerationStructureKHR, "vkCopyAccelerationStructureKHR") - set_proc_address(&CopyAccelerationStructureToMemoryKHR, "vkCopyAccelerationStructureToMemoryKHR") - set_proc_address(&CopyMemoryToAccelerationStructureKHR, "vkCopyMemoryToAccelerationStructureKHR") - set_proc_address(&WriteAccelerationStructuresPropertiesKHR, "vkWriteAccelerationStructuresPropertiesKHR") - set_proc_address(&CmdCopyAccelerationStructureKHR, "vkCmdCopyAccelerationStructureKHR") - set_proc_address(&CmdCopyAccelerationStructureToMemoryKHR, "vkCmdCopyAccelerationStructureToMemoryKHR") - set_proc_address(&CmdCopyMemoryToAccelerationStructureKHR, "vkCmdCopyMemoryToAccelerationStructureKHR") - set_proc_address(&GetAccelerationStructureDeviceAddressKHR, "vkGetAccelerationStructureDeviceAddressKHR") - set_proc_address(&CmdWriteAccelerationStructuresPropertiesKHR, "vkCmdWriteAccelerationStructuresPropertiesKHR") - set_proc_address(&GetDeviceAccelerationStructureCompatibilityKHR, "vkGetDeviceAccelerationStructureCompatibilityKHR") - set_proc_address(&GetAccelerationStructureBuildSizesKHR, "vkGetAccelerationStructureBuildSizesKHR") - set_proc_address(&CmdTraceRaysKHR, "vkCmdTraceRaysKHR") - set_proc_address(&CreateRayTracingPipelinesKHR, "vkCreateRayTracingPipelinesKHR") - set_proc_address(&GetRayTracingCaptureReplayShaderGroupHandlesKHR, "vkGetRayTracingCaptureReplayShaderGroupHandlesKHR") - set_proc_address(&CmdTraceRaysIndirectKHR, "vkCmdTraceRaysIndirectKHR") - set_proc_address(&GetRayTracingShaderGroupStackSizeKHR, "vkGetRayTracingShaderGroupStackSizeKHR") - set_proc_address(&CmdSetRayTracingPipelineStackSizeKHR, "vkCmdSetRayTracingPipelineStackSizeKHR") - set_proc_address(&GetMemoryWin32HandleKHR, "vkGetMemoryWin32HandleKHR") - set_proc_address(&GetMemoryWin32HandlePropertiesKHR, "vkGetMemoryWin32HandlePropertiesKHR") - set_proc_address(&ImportSemaphoreWin32HandleKHR, "vkImportSemaphoreWin32HandleKHR") - set_proc_address(&GetSemaphoreWin32HandleKHR, "vkGetSemaphoreWin32HandleKHR") - set_proc_address(&ImportFenceWin32HandleKHR, "vkImportFenceWin32HandleKHR") - set_proc_address(&GetFenceWin32HandleKHR, "vkGetFenceWin32HandleKHR") - set_proc_address(&GetMemoryWin32HandleNV, "vkGetMemoryWin32HandleNV") - set_proc_address(&AcquireFullScreenExclusiveModeEXT, "vkAcquireFullScreenExclusiveModeEXT") - set_proc_address(&ReleaseFullScreenExclusiveModeEXT, "vkReleaseFullScreenExclusiveModeEXT") - set_proc_address(&GetDeviceGroupSurfacePresentModes2EXT, "vkGetDeviceGroupSurfacePresentModes2EXT") +// Device Procedures +AcquireFullScreenExclusiveModeEXT: ProcAcquireFullScreenExclusiveModeEXT +AcquireNextImage2KHR: ProcAcquireNextImage2KHR +AcquireNextImageKHR: ProcAcquireNextImageKHR +AcquirePerformanceConfigurationINTEL: ProcAcquirePerformanceConfigurationINTEL +AcquireProfilingLockKHR: ProcAcquireProfilingLockKHR +AllocateCommandBuffers: ProcAllocateCommandBuffers +AllocateDescriptorSets: ProcAllocateDescriptorSets +AllocateMemory: ProcAllocateMemory +BeginCommandBuffer: ProcBeginCommandBuffer +BindAccelerationStructureMemoryNV: ProcBindAccelerationStructureMemoryNV +BindBufferMemory: ProcBindBufferMemory +BindBufferMemory2: ProcBindBufferMemory2 +BindBufferMemory2KHR: ProcBindBufferMemory2KHR +BindImageMemory: ProcBindImageMemory +BindImageMemory2: ProcBindImageMemory2 +BindImageMemory2KHR: ProcBindImageMemory2KHR +BuildAccelerationStructuresKHR: ProcBuildAccelerationStructuresKHR +CmdBeginConditionalRenderingEXT: ProcCmdBeginConditionalRenderingEXT +CmdBeginDebugUtilsLabelEXT: ProcCmdBeginDebugUtilsLabelEXT +CmdBeginQuery: ProcCmdBeginQuery +CmdBeginQueryIndexedEXT: ProcCmdBeginQueryIndexedEXT +CmdBeginRenderPass: ProcCmdBeginRenderPass +CmdBeginRenderPass2: ProcCmdBeginRenderPass2 +CmdBeginRenderPass2KHR: ProcCmdBeginRenderPass2KHR +CmdBeginRendering: ProcCmdBeginRendering +CmdBeginRenderingKHR: ProcCmdBeginRenderingKHR +CmdBeginTransformFeedbackEXT: ProcCmdBeginTransformFeedbackEXT +CmdBindDescriptorSets: ProcCmdBindDescriptorSets +CmdBindIndexBuffer: ProcCmdBindIndexBuffer +CmdBindInvocationMaskHUAWEI: ProcCmdBindInvocationMaskHUAWEI +CmdBindPipeline: ProcCmdBindPipeline +CmdBindPipelineShaderGroupNV: ProcCmdBindPipelineShaderGroupNV +CmdBindShadingRateImageNV: ProcCmdBindShadingRateImageNV +CmdBindTransformFeedbackBuffersEXT: ProcCmdBindTransformFeedbackBuffersEXT +CmdBindVertexBuffers: ProcCmdBindVertexBuffers +CmdBindVertexBuffers2: ProcCmdBindVertexBuffers2 +CmdBindVertexBuffers2EXT: ProcCmdBindVertexBuffers2EXT +CmdBlitImage: ProcCmdBlitImage +CmdBlitImage2: ProcCmdBlitImage2 +CmdBlitImage2KHR: ProcCmdBlitImage2KHR +CmdBuildAccelerationStructureNV: ProcCmdBuildAccelerationStructureNV +CmdBuildAccelerationStructuresIndirectKHR: ProcCmdBuildAccelerationStructuresIndirectKHR +CmdBuildAccelerationStructuresKHR: ProcCmdBuildAccelerationStructuresKHR +CmdClearAttachments: ProcCmdClearAttachments +CmdClearColorImage: ProcCmdClearColorImage +CmdClearDepthStencilImage: ProcCmdClearDepthStencilImage +CmdCopyAccelerationStructureKHR: ProcCmdCopyAccelerationStructureKHR +CmdCopyAccelerationStructureNV: ProcCmdCopyAccelerationStructureNV +CmdCopyAccelerationStructureToMemoryKHR: ProcCmdCopyAccelerationStructureToMemoryKHR +CmdCopyBuffer: ProcCmdCopyBuffer +CmdCopyBuffer2: ProcCmdCopyBuffer2 +CmdCopyBuffer2KHR: ProcCmdCopyBuffer2KHR +CmdCopyBufferToImage: ProcCmdCopyBufferToImage +CmdCopyBufferToImage2: ProcCmdCopyBufferToImage2 +CmdCopyBufferToImage2KHR: ProcCmdCopyBufferToImage2KHR +CmdCopyImage: ProcCmdCopyImage +CmdCopyImage2: ProcCmdCopyImage2 +CmdCopyImage2KHR: ProcCmdCopyImage2KHR +CmdCopyImageToBuffer: ProcCmdCopyImageToBuffer +CmdCopyImageToBuffer2: ProcCmdCopyImageToBuffer2 +CmdCopyImageToBuffer2KHR: ProcCmdCopyImageToBuffer2KHR +CmdCopyMemoryToAccelerationStructureKHR: ProcCmdCopyMemoryToAccelerationStructureKHR +CmdCopyQueryPoolResults: ProcCmdCopyQueryPoolResults +CmdCuLaunchKernelNVX: ProcCmdCuLaunchKernelNVX +CmdDebugMarkerBeginEXT: ProcCmdDebugMarkerBeginEXT +CmdDebugMarkerEndEXT: ProcCmdDebugMarkerEndEXT +CmdDebugMarkerInsertEXT: ProcCmdDebugMarkerInsertEXT +CmdDispatch: ProcCmdDispatch +CmdDispatchBase: ProcCmdDispatchBase +CmdDispatchBaseKHR: ProcCmdDispatchBaseKHR +CmdDispatchIndirect: ProcCmdDispatchIndirect +CmdDraw: ProcCmdDraw +CmdDrawIndexed: ProcCmdDrawIndexed +CmdDrawIndexedIndirect: ProcCmdDrawIndexedIndirect +CmdDrawIndexedIndirectCount: ProcCmdDrawIndexedIndirectCount +CmdDrawIndexedIndirectCountAMD: ProcCmdDrawIndexedIndirectCountAMD +CmdDrawIndexedIndirectCountKHR: ProcCmdDrawIndexedIndirectCountKHR +CmdDrawIndirect: ProcCmdDrawIndirect +CmdDrawIndirectByteCountEXT: ProcCmdDrawIndirectByteCountEXT +CmdDrawIndirectCount: ProcCmdDrawIndirectCount +CmdDrawIndirectCountAMD: ProcCmdDrawIndirectCountAMD +CmdDrawIndirectCountKHR: ProcCmdDrawIndirectCountKHR +CmdDrawMeshTasksIndirectCountNV: ProcCmdDrawMeshTasksIndirectCountNV +CmdDrawMeshTasksIndirectNV: ProcCmdDrawMeshTasksIndirectNV +CmdDrawMeshTasksNV: ProcCmdDrawMeshTasksNV +CmdDrawMultiEXT: ProcCmdDrawMultiEXT +CmdDrawMultiIndexedEXT: ProcCmdDrawMultiIndexedEXT +CmdEndConditionalRenderingEXT: ProcCmdEndConditionalRenderingEXT +CmdEndDebugUtilsLabelEXT: ProcCmdEndDebugUtilsLabelEXT +CmdEndQuery: ProcCmdEndQuery +CmdEndQueryIndexedEXT: ProcCmdEndQueryIndexedEXT +CmdEndRenderPass: ProcCmdEndRenderPass +CmdEndRenderPass2: ProcCmdEndRenderPass2 +CmdEndRenderPass2KHR: ProcCmdEndRenderPass2KHR +CmdEndRendering: ProcCmdEndRendering +CmdEndRenderingKHR: ProcCmdEndRenderingKHR +CmdEndTransformFeedbackEXT: ProcCmdEndTransformFeedbackEXT +CmdExecuteCommands: ProcCmdExecuteCommands +CmdExecuteGeneratedCommandsNV: ProcCmdExecuteGeneratedCommandsNV +CmdFillBuffer: ProcCmdFillBuffer +CmdInsertDebugUtilsLabelEXT: ProcCmdInsertDebugUtilsLabelEXT +CmdNextSubpass: ProcCmdNextSubpass +CmdNextSubpass2: ProcCmdNextSubpass2 +CmdNextSubpass2KHR: ProcCmdNextSubpass2KHR +CmdPipelineBarrier: ProcCmdPipelineBarrier +CmdPipelineBarrier2: ProcCmdPipelineBarrier2 +CmdPipelineBarrier2KHR: ProcCmdPipelineBarrier2KHR +CmdPreprocessGeneratedCommandsNV: ProcCmdPreprocessGeneratedCommandsNV +CmdPushConstants: ProcCmdPushConstants +CmdPushDescriptorSetKHR: ProcCmdPushDescriptorSetKHR +CmdPushDescriptorSetWithTemplateKHR: ProcCmdPushDescriptorSetWithTemplateKHR +CmdResetEvent: ProcCmdResetEvent +CmdResetEvent2: ProcCmdResetEvent2 +CmdResetEvent2KHR: ProcCmdResetEvent2KHR +CmdResetQueryPool: ProcCmdResetQueryPool +CmdResolveImage: ProcCmdResolveImage +CmdResolveImage2: ProcCmdResolveImage2 +CmdResolveImage2KHR: ProcCmdResolveImage2KHR +CmdSetBlendConstants: ProcCmdSetBlendConstants +CmdSetCheckpointNV: ProcCmdSetCheckpointNV +CmdSetCoarseSampleOrderNV: ProcCmdSetCoarseSampleOrderNV +CmdSetCullMode: ProcCmdSetCullMode +CmdSetCullModeEXT: ProcCmdSetCullModeEXT +CmdSetDepthBias: ProcCmdSetDepthBias +CmdSetDepthBiasEnable: ProcCmdSetDepthBiasEnable +CmdSetDepthBiasEnableEXT: ProcCmdSetDepthBiasEnableEXT +CmdSetDepthBounds: ProcCmdSetDepthBounds +CmdSetDepthBoundsTestEnable: ProcCmdSetDepthBoundsTestEnable +CmdSetDepthBoundsTestEnableEXT: ProcCmdSetDepthBoundsTestEnableEXT +CmdSetDepthCompareOp: ProcCmdSetDepthCompareOp +CmdSetDepthCompareOpEXT: ProcCmdSetDepthCompareOpEXT +CmdSetDepthTestEnable: ProcCmdSetDepthTestEnable +CmdSetDepthTestEnableEXT: ProcCmdSetDepthTestEnableEXT +CmdSetDepthWriteEnable: ProcCmdSetDepthWriteEnable +CmdSetDepthWriteEnableEXT: ProcCmdSetDepthWriteEnableEXT +CmdSetDeviceMask: ProcCmdSetDeviceMask +CmdSetDeviceMaskKHR: ProcCmdSetDeviceMaskKHR +CmdSetDiscardRectangleEXT: ProcCmdSetDiscardRectangleEXT +CmdSetEvent: ProcCmdSetEvent +CmdSetEvent2: ProcCmdSetEvent2 +CmdSetEvent2KHR: ProcCmdSetEvent2KHR +CmdSetExclusiveScissorNV: ProcCmdSetExclusiveScissorNV +CmdSetFragmentShadingRateEnumNV: ProcCmdSetFragmentShadingRateEnumNV +CmdSetFragmentShadingRateKHR: ProcCmdSetFragmentShadingRateKHR +CmdSetFrontFace: ProcCmdSetFrontFace +CmdSetFrontFaceEXT: ProcCmdSetFrontFaceEXT +CmdSetLineStippleEXT: ProcCmdSetLineStippleEXT +CmdSetLineWidth: ProcCmdSetLineWidth +CmdSetLogicOpEXT: ProcCmdSetLogicOpEXT +CmdSetPatchControlPointsEXT: ProcCmdSetPatchControlPointsEXT +CmdSetPerformanceMarkerINTEL: ProcCmdSetPerformanceMarkerINTEL +CmdSetPerformanceOverrideINTEL: ProcCmdSetPerformanceOverrideINTEL +CmdSetPerformanceStreamMarkerINTEL: ProcCmdSetPerformanceStreamMarkerINTEL +CmdSetPrimitiveRestartEnable: ProcCmdSetPrimitiveRestartEnable +CmdSetPrimitiveRestartEnableEXT: ProcCmdSetPrimitiveRestartEnableEXT +CmdSetPrimitiveTopology: ProcCmdSetPrimitiveTopology +CmdSetPrimitiveTopologyEXT: ProcCmdSetPrimitiveTopologyEXT +CmdSetRasterizerDiscardEnable: ProcCmdSetRasterizerDiscardEnable +CmdSetRasterizerDiscardEnableEXT: ProcCmdSetRasterizerDiscardEnableEXT +CmdSetRayTracingPipelineStackSizeKHR: ProcCmdSetRayTracingPipelineStackSizeKHR +CmdSetSampleLocationsEXT: ProcCmdSetSampleLocationsEXT +CmdSetScissor: ProcCmdSetScissor +CmdSetScissorWithCount: ProcCmdSetScissorWithCount +CmdSetScissorWithCountEXT: ProcCmdSetScissorWithCountEXT +CmdSetStencilCompareMask: ProcCmdSetStencilCompareMask +CmdSetStencilOp: ProcCmdSetStencilOp +CmdSetStencilOpEXT: ProcCmdSetStencilOpEXT +CmdSetStencilReference: ProcCmdSetStencilReference +CmdSetStencilTestEnable: ProcCmdSetStencilTestEnable +CmdSetStencilTestEnableEXT: ProcCmdSetStencilTestEnableEXT +CmdSetStencilWriteMask: ProcCmdSetStencilWriteMask +CmdSetVertexInputEXT: ProcCmdSetVertexInputEXT +CmdSetViewport: ProcCmdSetViewport +CmdSetViewportShadingRatePaletteNV: ProcCmdSetViewportShadingRatePaletteNV +CmdSetViewportWScalingNV: ProcCmdSetViewportWScalingNV +CmdSetViewportWithCount: ProcCmdSetViewportWithCount +CmdSetViewportWithCountEXT: ProcCmdSetViewportWithCountEXT +CmdSubpassShadingHUAWEI: ProcCmdSubpassShadingHUAWEI +CmdTraceRaysIndirectKHR: ProcCmdTraceRaysIndirectKHR +CmdTraceRaysKHR: ProcCmdTraceRaysKHR +CmdTraceRaysNV: ProcCmdTraceRaysNV +CmdUpdateBuffer: ProcCmdUpdateBuffer +CmdWaitEvents: ProcCmdWaitEvents +CmdWaitEvents2: ProcCmdWaitEvents2 +CmdWaitEvents2KHR: ProcCmdWaitEvents2KHR +CmdWriteAccelerationStructuresPropertiesKHR: ProcCmdWriteAccelerationStructuresPropertiesKHR +CmdWriteAccelerationStructuresPropertiesNV: ProcCmdWriteAccelerationStructuresPropertiesNV +CmdWriteBufferMarker2AMD: ProcCmdWriteBufferMarker2AMD +CmdWriteBufferMarkerAMD: ProcCmdWriteBufferMarkerAMD +CmdWriteTimestamp: ProcCmdWriteTimestamp +CmdWriteTimestamp2: ProcCmdWriteTimestamp2 +CmdWriteTimestamp2KHR: ProcCmdWriteTimestamp2KHR +CompileDeferredNV: ProcCompileDeferredNV +CopyAccelerationStructureKHR: ProcCopyAccelerationStructureKHR +CopyAccelerationStructureToMemoryKHR: ProcCopyAccelerationStructureToMemoryKHR +CopyMemoryToAccelerationStructureKHR: ProcCopyMemoryToAccelerationStructureKHR +CreateAccelerationStructureKHR: ProcCreateAccelerationStructureKHR +CreateAccelerationStructureNV: ProcCreateAccelerationStructureNV +CreateBuffer: ProcCreateBuffer +CreateBufferView: ProcCreateBufferView +CreateCommandPool: ProcCreateCommandPool +CreateComputePipelines: ProcCreateComputePipelines +CreateCuFunctionNVX: ProcCreateCuFunctionNVX +CreateCuModuleNVX: ProcCreateCuModuleNVX +CreateDeferredOperationKHR: ProcCreateDeferredOperationKHR +CreateDescriptorPool: ProcCreateDescriptorPool +CreateDescriptorSetLayout: ProcCreateDescriptorSetLayout +CreateDescriptorUpdateTemplate: ProcCreateDescriptorUpdateTemplate +CreateDescriptorUpdateTemplateKHR: ProcCreateDescriptorUpdateTemplateKHR +CreateEvent: ProcCreateEvent +CreateFence: ProcCreateFence +CreateFramebuffer: ProcCreateFramebuffer +CreateGraphicsPipelines: ProcCreateGraphicsPipelines +CreateImage: ProcCreateImage +CreateImageView: ProcCreateImageView +CreateIndirectCommandsLayoutNV: ProcCreateIndirectCommandsLayoutNV +CreatePipelineCache: ProcCreatePipelineCache +CreatePipelineLayout: ProcCreatePipelineLayout +CreatePrivateDataSlot: ProcCreatePrivateDataSlot +CreatePrivateDataSlotEXT: ProcCreatePrivateDataSlotEXT +CreateQueryPool: ProcCreateQueryPool +CreateRayTracingPipelinesKHR: ProcCreateRayTracingPipelinesKHR +CreateRayTracingPipelinesNV: ProcCreateRayTracingPipelinesNV +CreateRenderPass: ProcCreateRenderPass +CreateRenderPass2: ProcCreateRenderPass2 +CreateRenderPass2KHR: ProcCreateRenderPass2KHR +CreateSampler: ProcCreateSampler +CreateSamplerYcbcrConversion: ProcCreateSamplerYcbcrConversion +CreateSamplerYcbcrConversionKHR: ProcCreateSamplerYcbcrConversionKHR +CreateSemaphore: ProcCreateSemaphore +CreateShaderModule: ProcCreateShaderModule +CreateSharedSwapchainsKHR: ProcCreateSharedSwapchainsKHR +CreateSwapchainKHR: ProcCreateSwapchainKHR +CreateValidationCacheEXT: ProcCreateValidationCacheEXT +DebugMarkerSetObjectNameEXT: ProcDebugMarkerSetObjectNameEXT +DebugMarkerSetObjectTagEXT: ProcDebugMarkerSetObjectTagEXT +DeferredOperationJoinKHR: ProcDeferredOperationJoinKHR +DestroyAccelerationStructureKHR: ProcDestroyAccelerationStructureKHR +DestroyAccelerationStructureNV: ProcDestroyAccelerationStructureNV +DestroyBuffer: ProcDestroyBuffer +DestroyBufferView: ProcDestroyBufferView +DestroyCommandPool: ProcDestroyCommandPool +DestroyCuFunctionNVX: ProcDestroyCuFunctionNVX +DestroyCuModuleNVX: ProcDestroyCuModuleNVX +DestroyDeferredOperationKHR: ProcDestroyDeferredOperationKHR +DestroyDescriptorPool: ProcDestroyDescriptorPool +DestroyDescriptorSetLayout: ProcDestroyDescriptorSetLayout +DestroyDescriptorUpdateTemplate: ProcDestroyDescriptorUpdateTemplate +DestroyDescriptorUpdateTemplateKHR: ProcDestroyDescriptorUpdateTemplateKHR +DestroyDevice: ProcDestroyDevice +DestroyEvent: ProcDestroyEvent +DestroyFence: ProcDestroyFence +DestroyFramebuffer: ProcDestroyFramebuffer +DestroyImage: ProcDestroyImage +DestroyImageView: ProcDestroyImageView +DestroyIndirectCommandsLayoutNV: ProcDestroyIndirectCommandsLayoutNV +DestroyPipeline: ProcDestroyPipeline +DestroyPipelineCache: ProcDestroyPipelineCache +DestroyPipelineLayout: ProcDestroyPipelineLayout +DestroyPrivateDataSlot: ProcDestroyPrivateDataSlot +DestroyPrivateDataSlotEXT: ProcDestroyPrivateDataSlotEXT +DestroyQueryPool: ProcDestroyQueryPool +DestroyRenderPass: ProcDestroyRenderPass +DestroySampler: ProcDestroySampler +DestroySamplerYcbcrConversion: ProcDestroySamplerYcbcrConversion +DestroySamplerYcbcrConversionKHR: ProcDestroySamplerYcbcrConversionKHR +DestroySemaphore: ProcDestroySemaphore +DestroyShaderModule: ProcDestroyShaderModule +DestroySwapchainKHR: ProcDestroySwapchainKHR +DestroyValidationCacheEXT: ProcDestroyValidationCacheEXT +DeviceWaitIdle: ProcDeviceWaitIdle +DisplayPowerControlEXT: ProcDisplayPowerControlEXT +EndCommandBuffer: ProcEndCommandBuffer +FlushMappedMemoryRanges: ProcFlushMappedMemoryRanges +FreeCommandBuffers: ProcFreeCommandBuffers +FreeDescriptorSets: ProcFreeDescriptorSets +FreeMemory: ProcFreeMemory +GetAccelerationStructureBuildSizesKHR: ProcGetAccelerationStructureBuildSizesKHR +GetAccelerationStructureDeviceAddressKHR: ProcGetAccelerationStructureDeviceAddressKHR +GetAccelerationStructureHandleNV: ProcGetAccelerationStructureHandleNV +GetAccelerationStructureMemoryRequirementsNV: ProcGetAccelerationStructureMemoryRequirementsNV +GetBufferDeviceAddress: ProcGetBufferDeviceAddress +GetBufferDeviceAddressEXT: ProcGetBufferDeviceAddressEXT +GetBufferDeviceAddressKHR: ProcGetBufferDeviceAddressKHR +GetBufferMemoryRequirements: ProcGetBufferMemoryRequirements +GetBufferMemoryRequirements2: ProcGetBufferMemoryRequirements2 +GetBufferMemoryRequirements2KHR: ProcGetBufferMemoryRequirements2KHR +GetBufferOpaqueCaptureAddress: ProcGetBufferOpaqueCaptureAddress +GetBufferOpaqueCaptureAddressKHR: ProcGetBufferOpaqueCaptureAddressKHR +GetCalibratedTimestampsEXT: ProcGetCalibratedTimestampsEXT +GetDeferredOperationMaxConcurrencyKHR: ProcGetDeferredOperationMaxConcurrencyKHR +GetDeferredOperationResultKHR: ProcGetDeferredOperationResultKHR +GetDescriptorSetHostMappingVALVE: ProcGetDescriptorSetHostMappingVALVE +GetDescriptorSetLayoutHostMappingInfoVALVE: ProcGetDescriptorSetLayoutHostMappingInfoVALVE +GetDescriptorSetLayoutSupport: ProcGetDescriptorSetLayoutSupport +GetDescriptorSetLayoutSupportKHR: ProcGetDescriptorSetLayoutSupportKHR +GetDeviceAccelerationStructureCompatibilityKHR: ProcGetDeviceAccelerationStructureCompatibilityKHR +GetDeviceBufferMemoryRequirements: ProcGetDeviceBufferMemoryRequirements +GetDeviceBufferMemoryRequirementsKHR: ProcGetDeviceBufferMemoryRequirementsKHR +GetDeviceGroupPeerMemoryFeatures: ProcGetDeviceGroupPeerMemoryFeatures +GetDeviceGroupPeerMemoryFeaturesKHR: ProcGetDeviceGroupPeerMemoryFeaturesKHR +GetDeviceGroupPresentCapabilitiesKHR: ProcGetDeviceGroupPresentCapabilitiesKHR +GetDeviceGroupSurfacePresentModes2EXT: ProcGetDeviceGroupSurfacePresentModes2EXT +GetDeviceGroupSurfacePresentModesKHR: ProcGetDeviceGroupSurfacePresentModesKHR +GetDeviceImageMemoryRequirements: ProcGetDeviceImageMemoryRequirements +GetDeviceImageMemoryRequirementsKHR: ProcGetDeviceImageMemoryRequirementsKHR +GetDeviceImageSparseMemoryRequirements: ProcGetDeviceImageSparseMemoryRequirements +GetDeviceImageSparseMemoryRequirementsKHR: ProcGetDeviceImageSparseMemoryRequirementsKHR +GetDeviceMemoryCommitment: ProcGetDeviceMemoryCommitment +GetDeviceMemoryOpaqueCaptureAddress: ProcGetDeviceMemoryOpaqueCaptureAddress +GetDeviceMemoryOpaqueCaptureAddressKHR: ProcGetDeviceMemoryOpaqueCaptureAddressKHR +GetDeviceProcAddr: ProcGetDeviceProcAddr +GetDeviceQueue: ProcGetDeviceQueue +GetDeviceQueue2: ProcGetDeviceQueue2 +GetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI: ProcGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI +GetEventStatus: ProcGetEventStatus +GetFenceFdKHR: ProcGetFenceFdKHR +GetFenceStatus: ProcGetFenceStatus +GetFenceWin32HandleKHR: ProcGetFenceWin32HandleKHR +GetGeneratedCommandsMemoryRequirementsNV: ProcGetGeneratedCommandsMemoryRequirementsNV +GetImageDrmFormatModifierPropertiesEXT: ProcGetImageDrmFormatModifierPropertiesEXT +GetImageMemoryRequirements: ProcGetImageMemoryRequirements +GetImageMemoryRequirements2: ProcGetImageMemoryRequirements2 +GetImageMemoryRequirements2KHR: ProcGetImageMemoryRequirements2KHR +GetImageSparseMemoryRequirements: ProcGetImageSparseMemoryRequirements +GetImageSparseMemoryRequirements2: ProcGetImageSparseMemoryRequirements2 +GetImageSparseMemoryRequirements2KHR: ProcGetImageSparseMemoryRequirements2KHR +GetImageSubresourceLayout: ProcGetImageSubresourceLayout +GetImageViewAddressNVX: ProcGetImageViewAddressNVX +GetImageViewHandleNVX: ProcGetImageViewHandleNVX +GetMemoryFdKHR: ProcGetMemoryFdKHR +GetMemoryFdPropertiesKHR: ProcGetMemoryFdPropertiesKHR +GetMemoryHostPointerPropertiesEXT: ProcGetMemoryHostPointerPropertiesEXT +GetMemoryRemoteAddressNV: ProcGetMemoryRemoteAddressNV +GetMemoryWin32HandleKHR: ProcGetMemoryWin32HandleKHR +GetMemoryWin32HandleNV: ProcGetMemoryWin32HandleNV +GetMemoryWin32HandlePropertiesKHR: ProcGetMemoryWin32HandlePropertiesKHR +GetPastPresentationTimingGOOGLE: ProcGetPastPresentationTimingGOOGLE +GetPerformanceParameterINTEL: ProcGetPerformanceParameterINTEL +GetPipelineCacheData: ProcGetPipelineCacheData +GetPipelineExecutableInternalRepresentationsKHR: ProcGetPipelineExecutableInternalRepresentationsKHR +GetPipelineExecutablePropertiesKHR: ProcGetPipelineExecutablePropertiesKHR +GetPipelineExecutableStatisticsKHR: ProcGetPipelineExecutableStatisticsKHR +GetPrivateData: ProcGetPrivateData +GetPrivateDataEXT: ProcGetPrivateDataEXT +GetQueryPoolResults: ProcGetQueryPoolResults +GetQueueCheckpointData2NV: ProcGetQueueCheckpointData2NV +GetQueueCheckpointDataNV: ProcGetQueueCheckpointDataNV +GetRayTracingCaptureReplayShaderGroupHandlesKHR: ProcGetRayTracingCaptureReplayShaderGroupHandlesKHR +GetRayTracingShaderGroupHandlesKHR: ProcGetRayTracingShaderGroupHandlesKHR +GetRayTracingShaderGroupHandlesNV: ProcGetRayTracingShaderGroupHandlesNV +GetRayTracingShaderGroupStackSizeKHR: ProcGetRayTracingShaderGroupStackSizeKHR +GetRefreshCycleDurationGOOGLE: ProcGetRefreshCycleDurationGOOGLE +GetRenderAreaGranularity: ProcGetRenderAreaGranularity +GetSemaphoreCounterValue: ProcGetSemaphoreCounterValue +GetSemaphoreCounterValueKHR: ProcGetSemaphoreCounterValueKHR +GetSemaphoreFdKHR: ProcGetSemaphoreFdKHR +GetSemaphoreWin32HandleKHR: ProcGetSemaphoreWin32HandleKHR +GetShaderInfoAMD: ProcGetShaderInfoAMD +GetSwapchainCounterEXT: ProcGetSwapchainCounterEXT +GetSwapchainImagesKHR: ProcGetSwapchainImagesKHR +GetSwapchainStatusKHR: ProcGetSwapchainStatusKHR +GetValidationCacheDataEXT: ProcGetValidationCacheDataEXT +ImportFenceFdKHR: ProcImportFenceFdKHR +ImportFenceWin32HandleKHR: ProcImportFenceWin32HandleKHR +ImportSemaphoreFdKHR: ProcImportSemaphoreFdKHR +ImportSemaphoreWin32HandleKHR: ProcImportSemaphoreWin32HandleKHR +InitializePerformanceApiINTEL: ProcInitializePerformanceApiINTEL +InvalidateMappedMemoryRanges: ProcInvalidateMappedMemoryRanges +MapMemory: ProcMapMemory +MergePipelineCaches: ProcMergePipelineCaches +MergeValidationCachesEXT: ProcMergeValidationCachesEXT +QueueBeginDebugUtilsLabelEXT: ProcQueueBeginDebugUtilsLabelEXT +QueueBindSparse: ProcQueueBindSparse +QueueEndDebugUtilsLabelEXT: ProcQueueEndDebugUtilsLabelEXT +QueueInsertDebugUtilsLabelEXT: ProcQueueInsertDebugUtilsLabelEXT +QueuePresentKHR: ProcQueuePresentKHR +QueueSetPerformanceConfigurationINTEL: ProcQueueSetPerformanceConfigurationINTEL +QueueSubmit: ProcQueueSubmit +QueueSubmit2: ProcQueueSubmit2 +QueueSubmit2KHR: ProcQueueSubmit2KHR +QueueWaitIdle: ProcQueueWaitIdle +RegisterDeviceEventEXT: ProcRegisterDeviceEventEXT +RegisterDisplayEventEXT: ProcRegisterDisplayEventEXT +ReleaseFullScreenExclusiveModeEXT: ProcReleaseFullScreenExclusiveModeEXT +ReleasePerformanceConfigurationINTEL: ProcReleasePerformanceConfigurationINTEL +ReleaseProfilingLockKHR: ProcReleaseProfilingLockKHR +ResetCommandBuffer: ProcResetCommandBuffer +ResetCommandPool: ProcResetCommandPool +ResetDescriptorPool: ProcResetDescriptorPool +ResetEvent: ProcResetEvent +ResetFences: ProcResetFences +ResetQueryPool: ProcResetQueryPool +ResetQueryPoolEXT: ProcResetQueryPoolEXT +SetDebugUtilsObjectNameEXT: ProcSetDebugUtilsObjectNameEXT +SetDebugUtilsObjectTagEXT: ProcSetDebugUtilsObjectTagEXT +SetDeviceMemoryPriorityEXT: ProcSetDeviceMemoryPriorityEXT +SetEvent: ProcSetEvent +SetHdrMetadataEXT: ProcSetHdrMetadataEXT +SetLocalDimmingAMD: ProcSetLocalDimmingAMD +SetPrivateData: ProcSetPrivateData +SetPrivateDataEXT: ProcSetPrivateDataEXT +SignalSemaphore: ProcSignalSemaphore +SignalSemaphoreKHR: ProcSignalSemaphoreKHR +TrimCommandPool: ProcTrimCommandPool +TrimCommandPoolKHR: ProcTrimCommandPoolKHR +UninitializePerformanceApiINTEL: ProcUninitializePerformanceApiINTEL +UnmapMemory: ProcUnmapMemory +UpdateDescriptorSetWithTemplate: ProcUpdateDescriptorSetWithTemplate +UpdateDescriptorSetWithTemplateKHR: ProcUpdateDescriptorSetWithTemplateKHR +UpdateDescriptorSets: ProcUpdateDescriptorSets +WaitForFences: ProcWaitForFences +WaitForPresentKHR: ProcWaitForPresentKHR +WaitSemaphores: ProcWaitSemaphores +WaitSemaphoresKHR: ProcWaitSemaphoresKHR +WriteAccelerationStructuresPropertiesKHR: ProcWriteAccelerationStructuresPropertiesKHR +load_proc_addresses_custom :: proc(set_proc_address: SetProcAddressType) { // Loader Procedures set_proc_address(&CreateInstance, "vkCreateInstance") + set_proc_address(&DebugUtilsMessengerCallbackEXT, "vkDebugUtilsMessengerCallbackEXT") + set_proc_address(&DeviceMemoryReportCallbackEXT, "vkDeviceMemoryReportCallbackEXT") set_proc_address(&EnumerateInstanceExtensionProperties, "vkEnumerateInstanceExtensionProperties") set_proc_address(&EnumerateInstanceLayerProperties, "vkEnumerateInstanceLayerProperties") set_proc_address(&EnumerateInstanceVersion, "vkEnumerateInstanceVersion") - set_proc_address(&DebugUtilsMessengerCallbackEXT, "vkDebugUtilsMessengerCallbackEXT") - set_proc_address(&DeviceMemoryReportCallbackEXT, "vkDeviceMemoryReportCallbackEXT") + + // Instance Procedures + set_proc_address(&AcquireDrmDisplayEXT, "vkAcquireDrmDisplayEXT") + set_proc_address(&AcquireWinrtDisplayNV, "vkAcquireWinrtDisplayNV") + set_proc_address(&CreateDebugReportCallbackEXT, "vkCreateDebugReportCallbackEXT") + set_proc_address(&CreateDebugUtilsMessengerEXT, "vkCreateDebugUtilsMessengerEXT") + set_proc_address(&CreateDevice, "vkCreateDevice") + set_proc_address(&CreateDisplayModeKHR, "vkCreateDisplayModeKHR") + set_proc_address(&CreateDisplayPlaneSurfaceKHR, "vkCreateDisplayPlaneSurfaceKHR") + set_proc_address(&CreateHeadlessSurfaceEXT, "vkCreateHeadlessSurfaceEXT") + set_proc_address(&CreateIOSSurfaceMVK, "vkCreateIOSSurfaceMVK") + set_proc_address(&CreateMacOSSurfaceMVK, "vkCreateMacOSSurfaceMVK") + set_proc_address(&CreateMetalSurfaceEXT, "vkCreateMetalSurfaceEXT") + set_proc_address(&CreateWin32SurfaceKHR, "vkCreateWin32SurfaceKHR") + set_proc_address(&DebugReportMessageEXT, "vkDebugReportMessageEXT") + set_proc_address(&DestroyDebugReportCallbackEXT, "vkDestroyDebugReportCallbackEXT") + set_proc_address(&DestroyDebugUtilsMessengerEXT, "vkDestroyDebugUtilsMessengerEXT") + set_proc_address(&DestroyInstance, "vkDestroyInstance") + set_proc_address(&DestroySurfaceKHR, "vkDestroySurfaceKHR") + set_proc_address(&EnumerateDeviceExtensionProperties, "vkEnumerateDeviceExtensionProperties") + set_proc_address(&EnumerateDeviceLayerProperties, "vkEnumerateDeviceLayerProperties") + set_proc_address(&EnumeratePhysicalDeviceGroups, "vkEnumeratePhysicalDeviceGroups") + set_proc_address(&EnumeratePhysicalDeviceGroupsKHR, "vkEnumeratePhysicalDeviceGroupsKHR") + set_proc_address(&EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR, "vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR") + set_proc_address(&EnumeratePhysicalDevices, "vkEnumeratePhysicalDevices") + set_proc_address(&GetDisplayModeProperties2KHR, "vkGetDisplayModeProperties2KHR") + set_proc_address(&GetDisplayModePropertiesKHR, "vkGetDisplayModePropertiesKHR") + set_proc_address(&GetDisplayPlaneCapabilities2KHR, "vkGetDisplayPlaneCapabilities2KHR") + set_proc_address(&GetDisplayPlaneCapabilitiesKHR, "vkGetDisplayPlaneCapabilitiesKHR") + set_proc_address(&GetDisplayPlaneSupportedDisplaysKHR, "vkGetDisplayPlaneSupportedDisplaysKHR") + set_proc_address(&GetDrmDisplayEXT, "vkGetDrmDisplayEXT") + set_proc_address(&GetInstanceProcAddr, "vkGetInstanceProcAddr") + set_proc_address(&GetPhysicalDeviceCalibrateableTimeDomainsEXT, "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT") + set_proc_address(&GetPhysicalDeviceCooperativeMatrixPropertiesNV, "vkGetPhysicalDeviceCooperativeMatrixPropertiesNV") + set_proc_address(&GetPhysicalDeviceDisplayPlaneProperties2KHR, "vkGetPhysicalDeviceDisplayPlaneProperties2KHR") + set_proc_address(&GetPhysicalDeviceDisplayPlanePropertiesKHR, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR") + set_proc_address(&GetPhysicalDeviceDisplayProperties2KHR, "vkGetPhysicalDeviceDisplayProperties2KHR") + set_proc_address(&GetPhysicalDeviceDisplayPropertiesKHR, "vkGetPhysicalDeviceDisplayPropertiesKHR") + set_proc_address(&GetPhysicalDeviceExternalBufferProperties, "vkGetPhysicalDeviceExternalBufferProperties") + set_proc_address(&GetPhysicalDeviceExternalBufferPropertiesKHR, "vkGetPhysicalDeviceExternalBufferPropertiesKHR") + set_proc_address(&GetPhysicalDeviceExternalFenceProperties, "vkGetPhysicalDeviceExternalFenceProperties") + set_proc_address(&GetPhysicalDeviceExternalFencePropertiesKHR, "vkGetPhysicalDeviceExternalFencePropertiesKHR") + set_proc_address(&GetPhysicalDeviceExternalImageFormatPropertiesNV, "vkGetPhysicalDeviceExternalImageFormatPropertiesNV") + set_proc_address(&GetPhysicalDeviceExternalSemaphoreProperties, "vkGetPhysicalDeviceExternalSemaphoreProperties") + set_proc_address(&GetPhysicalDeviceExternalSemaphorePropertiesKHR, "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR") + set_proc_address(&GetPhysicalDeviceFeatures, "vkGetPhysicalDeviceFeatures") + set_proc_address(&GetPhysicalDeviceFeatures2, "vkGetPhysicalDeviceFeatures2") + set_proc_address(&GetPhysicalDeviceFeatures2KHR, "vkGetPhysicalDeviceFeatures2KHR") + set_proc_address(&GetPhysicalDeviceFormatProperties, "vkGetPhysicalDeviceFormatProperties") + set_proc_address(&GetPhysicalDeviceFormatProperties2, "vkGetPhysicalDeviceFormatProperties2") + set_proc_address(&GetPhysicalDeviceFormatProperties2KHR, "vkGetPhysicalDeviceFormatProperties2KHR") + set_proc_address(&GetPhysicalDeviceFragmentShadingRatesKHR, "vkGetPhysicalDeviceFragmentShadingRatesKHR") + set_proc_address(&GetPhysicalDeviceImageFormatProperties, "vkGetPhysicalDeviceImageFormatProperties") + set_proc_address(&GetPhysicalDeviceImageFormatProperties2, "vkGetPhysicalDeviceImageFormatProperties2") + set_proc_address(&GetPhysicalDeviceImageFormatProperties2KHR, "vkGetPhysicalDeviceImageFormatProperties2KHR") + set_proc_address(&GetPhysicalDeviceMemoryProperties, "vkGetPhysicalDeviceMemoryProperties") + set_proc_address(&GetPhysicalDeviceMemoryProperties2, "vkGetPhysicalDeviceMemoryProperties2") + set_proc_address(&GetPhysicalDeviceMemoryProperties2KHR, "vkGetPhysicalDeviceMemoryProperties2KHR") + set_proc_address(&GetPhysicalDeviceMultisamplePropertiesEXT, "vkGetPhysicalDeviceMultisamplePropertiesEXT") + set_proc_address(&GetPhysicalDevicePresentRectanglesKHR, "vkGetPhysicalDevicePresentRectanglesKHR") + set_proc_address(&GetPhysicalDeviceProperties, "vkGetPhysicalDeviceProperties") + set_proc_address(&GetPhysicalDeviceProperties2, "vkGetPhysicalDeviceProperties2") + set_proc_address(&GetPhysicalDeviceProperties2KHR, "vkGetPhysicalDeviceProperties2KHR") + set_proc_address(&GetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR, "vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR") + set_proc_address(&GetPhysicalDeviceQueueFamilyProperties, "vkGetPhysicalDeviceQueueFamilyProperties") + set_proc_address(&GetPhysicalDeviceQueueFamilyProperties2, "vkGetPhysicalDeviceQueueFamilyProperties2") + set_proc_address(&GetPhysicalDeviceQueueFamilyProperties2KHR, "vkGetPhysicalDeviceQueueFamilyProperties2KHR") + set_proc_address(&GetPhysicalDeviceSparseImageFormatProperties, "vkGetPhysicalDeviceSparseImageFormatProperties") + set_proc_address(&GetPhysicalDeviceSparseImageFormatProperties2, "vkGetPhysicalDeviceSparseImageFormatProperties2") + set_proc_address(&GetPhysicalDeviceSparseImageFormatProperties2KHR, "vkGetPhysicalDeviceSparseImageFormatProperties2KHR") + set_proc_address(&GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV, "vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV") + set_proc_address(&GetPhysicalDeviceSurfaceCapabilities2EXT, "vkGetPhysicalDeviceSurfaceCapabilities2EXT") + set_proc_address(&GetPhysicalDeviceSurfaceCapabilities2KHR, "vkGetPhysicalDeviceSurfaceCapabilities2KHR") + set_proc_address(&GetPhysicalDeviceSurfaceCapabilitiesKHR, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR") + set_proc_address(&GetPhysicalDeviceSurfaceFormats2KHR, "vkGetPhysicalDeviceSurfaceFormats2KHR") + set_proc_address(&GetPhysicalDeviceSurfaceFormatsKHR, "vkGetPhysicalDeviceSurfaceFormatsKHR") + set_proc_address(&GetPhysicalDeviceSurfacePresentModes2EXT, "vkGetPhysicalDeviceSurfacePresentModes2EXT") + set_proc_address(&GetPhysicalDeviceSurfacePresentModesKHR, "vkGetPhysicalDeviceSurfacePresentModesKHR") + set_proc_address(&GetPhysicalDeviceSurfaceSupportKHR, "vkGetPhysicalDeviceSurfaceSupportKHR") + set_proc_address(&GetPhysicalDeviceToolProperties, "vkGetPhysicalDeviceToolProperties") + set_proc_address(&GetPhysicalDeviceToolPropertiesEXT, "vkGetPhysicalDeviceToolPropertiesEXT") + set_proc_address(&GetPhysicalDeviceWin32PresentationSupportKHR, "vkGetPhysicalDeviceWin32PresentationSupportKHR") + set_proc_address(&GetWinrtDisplayNV, "vkGetWinrtDisplayNV") + set_proc_address(&ReleaseDisplayEXT, "vkReleaseDisplayEXT") + set_proc_address(&SubmitDebugUtilsMessageEXT, "vkSubmitDebugUtilsMessageEXT") + + // Device Procedures + set_proc_address(&AcquireFullScreenExclusiveModeEXT, "vkAcquireFullScreenExclusiveModeEXT") + set_proc_address(&AcquireNextImage2KHR, "vkAcquireNextImage2KHR") + set_proc_address(&AcquireNextImageKHR, "vkAcquireNextImageKHR") + set_proc_address(&AcquirePerformanceConfigurationINTEL, "vkAcquirePerformanceConfigurationINTEL") + set_proc_address(&AcquireProfilingLockKHR, "vkAcquireProfilingLockKHR") + set_proc_address(&AllocateCommandBuffers, "vkAllocateCommandBuffers") + set_proc_address(&AllocateDescriptorSets, "vkAllocateDescriptorSets") + set_proc_address(&AllocateMemory, "vkAllocateMemory") + set_proc_address(&BeginCommandBuffer, "vkBeginCommandBuffer") + set_proc_address(&BindAccelerationStructureMemoryNV, "vkBindAccelerationStructureMemoryNV") + set_proc_address(&BindBufferMemory, "vkBindBufferMemory") + set_proc_address(&BindBufferMemory2, "vkBindBufferMemory2") + set_proc_address(&BindBufferMemory2KHR, "vkBindBufferMemory2KHR") + set_proc_address(&BindImageMemory, "vkBindImageMemory") + set_proc_address(&BindImageMemory2, "vkBindImageMemory2") + set_proc_address(&BindImageMemory2KHR, "vkBindImageMemory2KHR") + set_proc_address(&BuildAccelerationStructuresKHR, "vkBuildAccelerationStructuresKHR") + set_proc_address(&CmdBeginConditionalRenderingEXT, "vkCmdBeginConditionalRenderingEXT") + set_proc_address(&CmdBeginDebugUtilsLabelEXT, "vkCmdBeginDebugUtilsLabelEXT") + set_proc_address(&CmdBeginQuery, "vkCmdBeginQuery") + set_proc_address(&CmdBeginQueryIndexedEXT, "vkCmdBeginQueryIndexedEXT") + set_proc_address(&CmdBeginRenderPass, "vkCmdBeginRenderPass") + set_proc_address(&CmdBeginRenderPass2, "vkCmdBeginRenderPass2") + set_proc_address(&CmdBeginRenderPass2KHR, "vkCmdBeginRenderPass2KHR") + set_proc_address(&CmdBeginRendering, "vkCmdBeginRendering") + set_proc_address(&CmdBeginRenderingKHR, "vkCmdBeginRenderingKHR") + set_proc_address(&CmdBeginTransformFeedbackEXT, "vkCmdBeginTransformFeedbackEXT") + set_proc_address(&CmdBindDescriptorSets, "vkCmdBindDescriptorSets") + set_proc_address(&CmdBindIndexBuffer, "vkCmdBindIndexBuffer") + set_proc_address(&CmdBindInvocationMaskHUAWEI, "vkCmdBindInvocationMaskHUAWEI") + set_proc_address(&CmdBindPipeline, "vkCmdBindPipeline") + set_proc_address(&CmdBindPipelineShaderGroupNV, "vkCmdBindPipelineShaderGroupNV") + set_proc_address(&CmdBindShadingRateImageNV, "vkCmdBindShadingRateImageNV") + set_proc_address(&CmdBindTransformFeedbackBuffersEXT, "vkCmdBindTransformFeedbackBuffersEXT") + set_proc_address(&CmdBindVertexBuffers, "vkCmdBindVertexBuffers") + set_proc_address(&CmdBindVertexBuffers2, "vkCmdBindVertexBuffers2") + set_proc_address(&CmdBindVertexBuffers2EXT, "vkCmdBindVertexBuffers2EXT") + set_proc_address(&CmdBlitImage, "vkCmdBlitImage") + set_proc_address(&CmdBlitImage2, "vkCmdBlitImage2") + set_proc_address(&CmdBlitImage2KHR, "vkCmdBlitImage2KHR") + set_proc_address(&CmdBuildAccelerationStructureNV, "vkCmdBuildAccelerationStructureNV") + set_proc_address(&CmdBuildAccelerationStructuresIndirectKHR, "vkCmdBuildAccelerationStructuresIndirectKHR") + set_proc_address(&CmdBuildAccelerationStructuresKHR, "vkCmdBuildAccelerationStructuresKHR") + set_proc_address(&CmdClearAttachments, "vkCmdClearAttachments") + set_proc_address(&CmdClearColorImage, "vkCmdClearColorImage") + set_proc_address(&CmdClearDepthStencilImage, "vkCmdClearDepthStencilImage") + set_proc_address(&CmdCopyAccelerationStructureKHR, "vkCmdCopyAccelerationStructureKHR") + set_proc_address(&CmdCopyAccelerationStructureNV, "vkCmdCopyAccelerationStructureNV") + set_proc_address(&CmdCopyAccelerationStructureToMemoryKHR, "vkCmdCopyAccelerationStructureToMemoryKHR") + set_proc_address(&CmdCopyBuffer, "vkCmdCopyBuffer") + set_proc_address(&CmdCopyBuffer2, "vkCmdCopyBuffer2") + set_proc_address(&CmdCopyBuffer2KHR, "vkCmdCopyBuffer2KHR") + set_proc_address(&CmdCopyBufferToImage, "vkCmdCopyBufferToImage") + set_proc_address(&CmdCopyBufferToImage2, "vkCmdCopyBufferToImage2") + set_proc_address(&CmdCopyBufferToImage2KHR, "vkCmdCopyBufferToImage2KHR") + set_proc_address(&CmdCopyImage, "vkCmdCopyImage") + set_proc_address(&CmdCopyImage2, "vkCmdCopyImage2") + set_proc_address(&CmdCopyImage2KHR, "vkCmdCopyImage2KHR") + set_proc_address(&CmdCopyImageToBuffer, "vkCmdCopyImageToBuffer") + set_proc_address(&CmdCopyImageToBuffer2, "vkCmdCopyImageToBuffer2") + set_proc_address(&CmdCopyImageToBuffer2KHR, "vkCmdCopyImageToBuffer2KHR") + set_proc_address(&CmdCopyMemoryToAccelerationStructureKHR, "vkCmdCopyMemoryToAccelerationStructureKHR") + set_proc_address(&CmdCopyQueryPoolResults, "vkCmdCopyQueryPoolResults") + set_proc_address(&CmdCuLaunchKernelNVX, "vkCmdCuLaunchKernelNVX") + set_proc_address(&CmdDebugMarkerBeginEXT, "vkCmdDebugMarkerBeginEXT") + set_proc_address(&CmdDebugMarkerEndEXT, "vkCmdDebugMarkerEndEXT") + set_proc_address(&CmdDebugMarkerInsertEXT, "vkCmdDebugMarkerInsertEXT") + set_proc_address(&CmdDispatch, "vkCmdDispatch") + set_proc_address(&CmdDispatchBase, "vkCmdDispatchBase") + set_proc_address(&CmdDispatchBaseKHR, "vkCmdDispatchBaseKHR") + set_proc_address(&CmdDispatchIndirect, "vkCmdDispatchIndirect") + set_proc_address(&CmdDraw, "vkCmdDraw") + set_proc_address(&CmdDrawIndexed, "vkCmdDrawIndexed") + set_proc_address(&CmdDrawIndexedIndirect, "vkCmdDrawIndexedIndirect") + set_proc_address(&CmdDrawIndexedIndirectCount, "vkCmdDrawIndexedIndirectCount") + set_proc_address(&CmdDrawIndexedIndirectCountAMD, "vkCmdDrawIndexedIndirectCountAMD") + set_proc_address(&CmdDrawIndexedIndirectCountKHR, "vkCmdDrawIndexedIndirectCountKHR") + set_proc_address(&CmdDrawIndirect, "vkCmdDrawIndirect") + set_proc_address(&CmdDrawIndirectByteCountEXT, "vkCmdDrawIndirectByteCountEXT") + set_proc_address(&CmdDrawIndirectCount, "vkCmdDrawIndirectCount") + set_proc_address(&CmdDrawIndirectCountAMD, "vkCmdDrawIndirectCountAMD") + set_proc_address(&CmdDrawIndirectCountKHR, "vkCmdDrawIndirectCountKHR") + set_proc_address(&CmdDrawMeshTasksIndirectCountNV, "vkCmdDrawMeshTasksIndirectCountNV") + set_proc_address(&CmdDrawMeshTasksIndirectNV, "vkCmdDrawMeshTasksIndirectNV") + set_proc_address(&CmdDrawMeshTasksNV, "vkCmdDrawMeshTasksNV") + set_proc_address(&CmdDrawMultiEXT, "vkCmdDrawMultiEXT") + set_proc_address(&CmdDrawMultiIndexedEXT, "vkCmdDrawMultiIndexedEXT") + set_proc_address(&CmdEndConditionalRenderingEXT, "vkCmdEndConditionalRenderingEXT") + set_proc_address(&CmdEndDebugUtilsLabelEXT, "vkCmdEndDebugUtilsLabelEXT") + set_proc_address(&CmdEndQuery, "vkCmdEndQuery") + set_proc_address(&CmdEndQueryIndexedEXT, "vkCmdEndQueryIndexedEXT") + set_proc_address(&CmdEndRenderPass, "vkCmdEndRenderPass") + set_proc_address(&CmdEndRenderPass2, "vkCmdEndRenderPass2") + set_proc_address(&CmdEndRenderPass2KHR, "vkCmdEndRenderPass2KHR") + set_proc_address(&CmdEndRendering, "vkCmdEndRendering") + set_proc_address(&CmdEndRenderingKHR, "vkCmdEndRenderingKHR") + set_proc_address(&CmdEndTransformFeedbackEXT, "vkCmdEndTransformFeedbackEXT") + set_proc_address(&CmdExecuteCommands, "vkCmdExecuteCommands") + set_proc_address(&CmdExecuteGeneratedCommandsNV, "vkCmdExecuteGeneratedCommandsNV") + set_proc_address(&CmdFillBuffer, "vkCmdFillBuffer") + set_proc_address(&CmdInsertDebugUtilsLabelEXT, "vkCmdInsertDebugUtilsLabelEXT") + set_proc_address(&CmdNextSubpass, "vkCmdNextSubpass") + set_proc_address(&CmdNextSubpass2, "vkCmdNextSubpass2") + set_proc_address(&CmdNextSubpass2KHR, "vkCmdNextSubpass2KHR") + set_proc_address(&CmdPipelineBarrier, "vkCmdPipelineBarrier") + set_proc_address(&CmdPipelineBarrier2, "vkCmdPipelineBarrier2") + set_proc_address(&CmdPipelineBarrier2KHR, "vkCmdPipelineBarrier2KHR") + set_proc_address(&CmdPreprocessGeneratedCommandsNV, "vkCmdPreprocessGeneratedCommandsNV") + set_proc_address(&CmdPushConstants, "vkCmdPushConstants") + set_proc_address(&CmdPushDescriptorSetKHR, "vkCmdPushDescriptorSetKHR") + set_proc_address(&CmdPushDescriptorSetWithTemplateKHR, "vkCmdPushDescriptorSetWithTemplateKHR") + set_proc_address(&CmdResetEvent, "vkCmdResetEvent") + set_proc_address(&CmdResetEvent2, "vkCmdResetEvent2") + set_proc_address(&CmdResetEvent2KHR, "vkCmdResetEvent2KHR") + set_proc_address(&CmdResetQueryPool, "vkCmdResetQueryPool") + set_proc_address(&CmdResolveImage, "vkCmdResolveImage") + set_proc_address(&CmdResolveImage2, "vkCmdResolveImage2") + set_proc_address(&CmdResolveImage2KHR, "vkCmdResolveImage2KHR") + set_proc_address(&CmdSetBlendConstants, "vkCmdSetBlendConstants") + set_proc_address(&CmdSetCheckpointNV, "vkCmdSetCheckpointNV") + set_proc_address(&CmdSetCoarseSampleOrderNV, "vkCmdSetCoarseSampleOrderNV") + set_proc_address(&CmdSetCullMode, "vkCmdSetCullMode") + set_proc_address(&CmdSetCullModeEXT, "vkCmdSetCullModeEXT") + set_proc_address(&CmdSetDepthBias, "vkCmdSetDepthBias") + set_proc_address(&CmdSetDepthBiasEnable, "vkCmdSetDepthBiasEnable") + set_proc_address(&CmdSetDepthBiasEnableEXT, "vkCmdSetDepthBiasEnableEXT") + set_proc_address(&CmdSetDepthBounds, "vkCmdSetDepthBounds") + set_proc_address(&CmdSetDepthBoundsTestEnable, "vkCmdSetDepthBoundsTestEnable") + set_proc_address(&CmdSetDepthBoundsTestEnableEXT, "vkCmdSetDepthBoundsTestEnableEXT") + set_proc_address(&CmdSetDepthCompareOp, "vkCmdSetDepthCompareOp") + set_proc_address(&CmdSetDepthCompareOpEXT, "vkCmdSetDepthCompareOpEXT") + set_proc_address(&CmdSetDepthTestEnable, "vkCmdSetDepthTestEnable") + set_proc_address(&CmdSetDepthTestEnableEXT, "vkCmdSetDepthTestEnableEXT") + set_proc_address(&CmdSetDepthWriteEnable, "vkCmdSetDepthWriteEnable") + set_proc_address(&CmdSetDepthWriteEnableEXT, "vkCmdSetDepthWriteEnableEXT") + set_proc_address(&CmdSetDeviceMask, "vkCmdSetDeviceMask") + set_proc_address(&CmdSetDeviceMaskKHR, "vkCmdSetDeviceMaskKHR") + set_proc_address(&CmdSetDiscardRectangleEXT, "vkCmdSetDiscardRectangleEXT") + set_proc_address(&CmdSetEvent, "vkCmdSetEvent") + set_proc_address(&CmdSetEvent2, "vkCmdSetEvent2") + set_proc_address(&CmdSetEvent2KHR, "vkCmdSetEvent2KHR") + set_proc_address(&CmdSetExclusiveScissorNV, "vkCmdSetExclusiveScissorNV") + set_proc_address(&CmdSetFragmentShadingRateEnumNV, "vkCmdSetFragmentShadingRateEnumNV") + set_proc_address(&CmdSetFragmentShadingRateKHR, "vkCmdSetFragmentShadingRateKHR") + set_proc_address(&CmdSetFrontFace, "vkCmdSetFrontFace") + set_proc_address(&CmdSetFrontFaceEXT, "vkCmdSetFrontFaceEXT") + set_proc_address(&CmdSetLineStippleEXT, "vkCmdSetLineStippleEXT") + set_proc_address(&CmdSetLineWidth, "vkCmdSetLineWidth") + set_proc_address(&CmdSetLogicOpEXT, "vkCmdSetLogicOpEXT") + set_proc_address(&CmdSetPatchControlPointsEXT, "vkCmdSetPatchControlPointsEXT") + set_proc_address(&CmdSetPerformanceMarkerINTEL, "vkCmdSetPerformanceMarkerINTEL") + set_proc_address(&CmdSetPerformanceOverrideINTEL, "vkCmdSetPerformanceOverrideINTEL") + set_proc_address(&CmdSetPerformanceStreamMarkerINTEL, "vkCmdSetPerformanceStreamMarkerINTEL") + set_proc_address(&CmdSetPrimitiveRestartEnable, "vkCmdSetPrimitiveRestartEnable") + set_proc_address(&CmdSetPrimitiveRestartEnableEXT, "vkCmdSetPrimitiveRestartEnableEXT") + set_proc_address(&CmdSetPrimitiveTopology, "vkCmdSetPrimitiveTopology") + set_proc_address(&CmdSetPrimitiveTopologyEXT, "vkCmdSetPrimitiveTopologyEXT") + set_proc_address(&CmdSetRasterizerDiscardEnable, "vkCmdSetRasterizerDiscardEnable") + set_proc_address(&CmdSetRasterizerDiscardEnableEXT, "vkCmdSetRasterizerDiscardEnableEXT") + set_proc_address(&CmdSetRayTracingPipelineStackSizeKHR, "vkCmdSetRayTracingPipelineStackSizeKHR") + set_proc_address(&CmdSetSampleLocationsEXT, "vkCmdSetSampleLocationsEXT") + set_proc_address(&CmdSetScissor, "vkCmdSetScissor") + set_proc_address(&CmdSetScissorWithCount, "vkCmdSetScissorWithCount") + set_proc_address(&CmdSetScissorWithCountEXT, "vkCmdSetScissorWithCountEXT") + set_proc_address(&CmdSetStencilCompareMask, "vkCmdSetStencilCompareMask") + set_proc_address(&CmdSetStencilOp, "vkCmdSetStencilOp") + set_proc_address(&CmdSetStencilOpEXT, "vkCmdSetStencilOpEXT") + set_proc_address(&CmdSetStencilReference, "vkCmdSetStencilReference") + set_proc_address(&CmdSetStencilTestEnable, "vkCmdSetStencilTestEnable") + set_proc_address(&CmdSetStencilTestEnableEXT, "vkCmdSetStencilTestEnableEXT") + set_proc_address(&CmdSetStencilWriteMask, "vkCmdSetStencilWriteMask") + set_proc_address(&CmdSetVertexInputEXT, "vkCmdSetVertexInputEXT") + set_proc_address(&CmdSetViewport, "vkCmdSetViewport") + set_proc_address(&CmdSetViewportShadingRatePaletteNV, "vkCmdSetViewportShadingRatePaletteNV") + set_proc_address(&CmdSetViewportWScalingNV, "vkCmdSetViewportWScalingNV") + set_proc_address(&CmdSetViewportWithCount, "vkCmdSetViewportWithCount") + set_proc_address(&CmdSetViewportWithCountEXT, "vkCmdSetViewportWithCountEXT") + set_proc_address(&CmdSubpassShadingHUAWEI, "vkCmdSubpassShadingHUAWEI") + set_proc_address(&CmdTraceRaysIndirectKHR, "vkCmdTraceRaysIndirectKHR") + set_proc_address(&CmdTraceRaysKHR, "vkCmdTraceRaysKHR") + set_proc_address(&CmdTraceRaysNV, "vkCmdTraceRaysNV") + set_proc_address(&CmdUpdateBuffer, "vkCmdUpdateBuffer") + set_proc_address(&CmdWaitEvents, "vkCmdWaitEvents") + set_proc_address(&CmdWaitEvents2, "vkCmdWaitEvents2") + set_proc_address(&CmdWaitEvents2KHR, "vkCmdWaitEvents2KHR") + set_proc_address(&CmdWriteAccelerationStructuresPropertiesKHR, "vkCmdWriteAccelerationStructuresPropertiesKHR") + set_proc_address(&CmdWriteAccelerationStructuresPropertiesNV, "vkCmdWriteAccelerationStructuresPropertiesNV") + set_proc_address(&CmdWriteBufferMarker2AMD, "vkCmdWriteBufferMarker2AMD") + set_proc_address(&CmdWriteBufferMarkerAMD, "vkCmdWriteBufferMarkerAMD") + set_proc_address(&CmdWriteTimestamp, "vkCmdWriteTimestamp") + set_proc_address(&CmdWriteTimestamp2, "vkCmdWriteTimestamp2") + set_proc_address(&CmdWriteTimestamp2KHR, "vkCmdWriteTimestamp2KHR") + set_proc_address(&CompileDeferredNV, "vkCompileDeferredNV") + set_proc_address(&CopyAccelerationStructureKHR, "vkCopyAccelerationStructureKHR") + set_proc_address(&CopyAccelerationStructureToMemoryKHR, "vkCopyAccelerationStructureToMemoryKHR") + set_proc_address(&CopyMemoryToAccelerationStructureKHR, "vkCopyMemoryToAccelerationStructureKHR") + set_proc_address(&CreateAccelerationStructureKHR, "vkCreateAccelerationStructureKHR") + set_proc_address(&CreateAccelerationStructureNV, "vkCreateAccelerationStructureNV") + set_proc_address(&CreateBuffer, "vkCreateBuffer") + set_proc_address(&CreateBufferView, "vkCreateBufferView") + set_proc_address(&CreateCommandPool, "vkCreateCommandPool") + set_proc_address(&CreateComputePipelines, "vkCreateComputePipelines") + set_proc_address(&CreateCuFunctionNVX, "vkCreateCuFunctionNVX") + set_proc_address(&CreateCuModuleNVX, "vkCreateCuModuleNVX") + set_proc_address(&CreateDeferredOperationKHR, "vkCreateDeferredOperationKHR") + set_proc_address(&CreateDescriptorPool, "vkCreateDescriptorPool") + set_proc_address(&CreateDescriptorSetLayout, "vkCreateDescriptorSetLayout") + set_proc_address(&CreateDescriptorUpdateTemplate, "vkCreateDescriptorUpdateTemplate") + set_proc_address(&CreateDescriptorUpdateTemplateKHR, "vkCreateDescriptorUpdateTemplateKHR") + set_proc_address(&CreateEvent, "vkCreateEvent") + set_proc_address(&CreateFence, "vkCreateFence") + set_proc_address(&CreateFramebuffer, "vkCreateFramebuffer") + set_proc_address(&CreateGraphicsPipelines, "vkCreateGraphicsPipelines") + set_proc_address(&CreateImage, "vkCreateImage") + set_proc_address(&CreateImageView, "vkCreateImageView") + set_proc_address(&CreateIndirectCommandsLayoutNV, "vkCreateIndirectCommandsLayoutNV") + set_proc_address(&CreatePipelineCache, "vkCreatePipelineCache") + set_proc_address(&CreatePipelineLayout, "vkCreatePipelineLayout") + set_proc_address(&CreatePrivateDataSlot, "vkCreatePrivateDataSlot") + set_proc_address(&CreatePrivateDataSlotEXT, "vkCreatePrivateDataSlotEXT") + set_proc_address(&CreateQueryPool, "vkCreateQueryPool") + set_proc_address(&CreateRayTracingPipelinesKHR, "vkCreateRayTracingPipelinesKHR") + set_proc_address(&CreateRayTracingPipelinesNV, "vkCreateRayTracingPipelinesNV") + set_proc_address(&CreateRenderPass, "vkCreateRenderPass") + set_proc_address(&CreateRenderPass2, "vkCreateRenderPass2") + set_proc_address(&CreateRenderPass2KHR, "vkCreateRenderPass2KHR") + set_proc_address(&CreateSampler, "vkCreateSampler") + set_proc_address(&CreateSamplerYcbcrConversion, "vkCreateSamplerYcbcrConversion") + set_proc_address(&CreateSamplerYcbcrConversionKHR, "vkCreateSamplerYcbcrConversionKHR") + set_proc_address(&CreateSemaphore, "vkCreateSemaphore") + set_proc_address(&CreateShaderModule, "vkCreateShaderModule") + set_proc_address(&CreateSharedSwapchainsKHR, "vkCreateSharedSwapchainsKHR") + set_proc_address(&CreateSwapchainKHR, "vkCreateSwapchainKHR") + set_proc_address(&CreateValidationCacheEXT, "vkCreateValidationCacheEXT") + set_proc_address(&DebugMarkerSetObjectNameEXT, "vkDebugMarkerSetObjectNameEXT") + set_proc_address(&DebugMarkerSetObjectTagEXT, "vkDebugMarkerSetObjectTagEXT") + set_proc_address(&DeferredOperationJoinKHR, "vkDeferredOperationJoinKHR") + set_proc_address(&DestroyAccelerationStructureKHR, "vkDestroyAccelerationStructureKHR") + set_proc_address(&DestroyAccelerationStructureNV, "vkDestroyAccelerationStructureNV") + set_proc_address(&DestroyBuffer, "vkDestroyBuffer") + set_proc_address(&DestroyBufferView, "vkDestroyBufferView") + set_proc_address(&DestroyCommandPool, "vkDestroyCommandPool") + set_proc_address(&DestroyCuFunctionNVX, "vkDestroyCuFunctionNVX") + set_proc_address(&DestroyCuModuleNVX, "vkDestroyCuModuleNVX") + set_proc_address(&DestroyDeferredOperationKHR, "vkDestroyDeferredOperationKHR") + set_proc_address(&DestroyDescriptorPool, "vkDestroyDescriptorPool") + set_proc_address(&DestroyDescriptorSetLayout, "vkDestroyDescriptorSetLayout") + set_proc_address(&DestroyDescriptorUpdateTemplate, "vkDestroyDescriptorUpdateTemplate") + set_proc_address(&DestroyDescriptorUpdateTemplateKHR, "vkDestroyDescriptorUpdateTemplateKHR") + set_proc_address(&DestroyDevice, "vkDestroyDevice") + set_proc_address(&DestroyEvent, "vkDestroyEvent") + set_proc_address(&DestroyFence, "vkDestroyFence") + set_proc_address(&DestroyFramebuffer, "vkDestroyFramebuffer") + set_proc_address(&DestroyImage, "vkDestroyImage") + set_proc_address(&DestroyImageView, "vkDestroyImageView") + set_proc_address(&DestroyIndirectCommandsLayoutNV, "vkDestroyIndirectCommandsLayoutNV") + set_proc_address(&DestroyPipeline, "vkDestroyPipeline") + set_proc_address(&DestroyPipelineCache, "vkDestroyPipelineCache") + set_proc_address(&DestroyPipelineLayout, "vkDestroyPipelineLayout") + set_proc_address(&DestroyPrivateDataSlot, "vkDestroyPrivateDataSlot") + set_proc_address(&DestroyPrivateDataSlotEXT, "vkDestroyPrivateDataSlotEXT") + set_proc_address(&DestroyQueryPool, "vkDestroyQueryPool") + set_proc_address(&DestroyRenderPass, "vkDestroyRenderPass") + set_proc_address(&DestroySampler, "vkDestroySampler") + set_proc_address(&DestroySamplerYcbcrConversion, "vkDestroySamplerYcbcrConversion") + set_proc_address(&DestroySamplerYcbcrConversionKHR, "vkDestroySamplerYcbcrConversionKHR") + set_proc_address(&DestroySemaphore, "vkDestroySemaphore") + set_proc_address(&DestroyShaderModule, "vkDestroyShaderModule") + set_proc_address(&DestroySwapchainKHR, "vkDestroySwapchainKHR") + set_proc_address(&DestroyValidationCacheEXT, "vkDestroyValidationCacheEXT") + set_proc_address(&DeviceWaitIdle, "vkDeviceWaitIdle") + set_proc_address(&DisplayPowerControlEXT, "vkDisplayPowerControlEXT") + set_proc_address(&EndCommandBuffer, "vkEndCommandBuffer") + set_proc_address(&FlushMappedMemoryRanges, "vkFlushMappedMemoryRanges") + set_proc_address(&FreeCommandBuffers, "vkFreeCommandBuffers") + set_proc_address(&FreeDescriptorSets, "vkFreeDescriptorSets") + set_proc_address(&FreeMemory, "vkFreeMemory") + set_proc_address(&GetAccelerationStructureBuildSizesKHR, "vkGetAccelerationStructureBuildSizesKHR") + set_proc_address(&GetAccelerationStructureDeviceAddressKHR, "vkGetAccelerationStructureDeviceAddressKHR") + set_proc_address(&GetAccelerationStructureHandleNV, "vkGetAccelerationStructureHandleNV") + set_proc_address(&GetAccelerationStructureMemoryRequirementsNV, "vkGetAccelerationStructureMemoryRequirementsNV") + set_proc_address(&GetBufferDeviceAddress, "vkGetBufferDeviceAddress") + set_proc_address(&GetBufferDeviceAddressEXT, "vkGetBufferDeviceAddressEXT") + set_proc_address(&GetBufferDeviceAddressKHR, "vkGetBufferDeviceAddressKHR") + set_proc_address(&GetBufferMemoryRequirements, "vkGetBufferMemoryRequirements") + set_proc_address(&GetBufferMemoryRequirements2, "vkGetBufferMemoryRequirements2") + set_proc_address(&GetBufferMemoryRequirements2KHR, "vkGetBufferMemoryRequirements2KHR") + set_proc_address(&GetBufferOpaqueCaptureAddress, "vkGetBufferOpaqueCaptureAddress") + set_proc_address(&GetBufferOpaqueCaptureAddressKHR, "vkGetBufferOpaqueCaptureAddressKHR") + set_proc_address(&GetCalibratedTimestampsEXT, "vkGetCalibratedTimestampsEXT") + set_proc_address(&GetDeferredOperationMaxConcurrencyKHR, "vkGetDeferredOperationMaxConcurrencyKHR") + set_proc_address(&GetDeferredOperationResultKHR, "vkGetDeferredOperationResultKHR") + set_proc_address(&GetDescriptorSetHostMappingVALVE, "vkGetDescriptorSetHostMappingVALVE") + set_proc_address(&GetDescriptorSetLayoutHostMappingInfoVALVE, "vkGetDescriptorSetLayoutHostMappingInfoVALVE") + set_proc_address(&GetDescriptorSetLayoutSupport, "vkGetDescriptorSetLayoutSupport") + set_proc_address(&GetDescriptorSetLayoutSupportKHR, "vkGetDescriptorSetLayoutSupportKHR") + set_proc_address(&GetDeviceAccelerationStructureCompatibilityKHR, "vkGetDeviceAccelerationStructureCompatibilityKHR") + set_proc_address(&GetDeviceBufferMemoryRequirements, "vkGetDeviceBufferMemoryRequirements") + set_proc_address(&GetDeviceBufferMemoryRequirementsKHR, "vkGetDeviceBufferMemoryRequirementsKHR") + set_proc_address(&GetDeviceGroupPeerMemoryFeatures, "vkGetDeviceGroupPeerMemoryFeatures") + set_proc_address(&GetDeviceGroupPeerMemoryFeaturesKHR, "vkGetDeviceGroupPeerMemoryFeaturesKHR") + set_proc_address(&GetDeviceGroupPresentCapabilitiesKHR, "vkGetDeviceGroupPresentCapabilitiesKHR") + set_proc_address(&GetDeviceGroupSurfacePresentModes2EXT, "vkGetDeviceGroupSurfacePresentModes2EXT") + set_proc_address(&GetDeviceGroupSurfacePresentModesKHR, "vkGetDeviceGroupSurfacePresentModesKHR") + set_proc_address(&GetDeviceImageMemoryRequirements, "vkGetDeviceImageMemoryRequirements") + set_proc_address(&GetDeviceImageMemoryRequirementsKHR, "vkGetDeviceImageMemoryRequirementsKHR") + set_proc_address(&GetDeviceImageSparseMemoryRequirements, "vkGetDeviceImageSparseMemoryRequirements") + set_proc_address(&GetDeviceImageSparseMemoryRequirementsKHR, "vkGetDeviceImageSparseMemoryRequirementsKHR") + set_proc_address(&GetDeviceMemoryCommitment, "vkGetDeviceMemoryCommitment") + set_proc_address(&GetDeviceMemoryOpaqueCaptureAddress, "vkGetDeviceMemoryOpaqueCaptureAddress") + set_proc_address(&GetDeviceMemoryOpaqueCaptureAddressKHR, "vkGetDeviceMemoryOpaqueCaptureAddressKHR") + set_proc_address(&GetDeviceProcAddr, "vkGetDeviceProcAddr") + set_proc_address(&GetDeviceQueue, "vkGetDeviceQueue") + set_proc_address(&GetDeviceQueue2, "vkGetDeviceQueue2") + set_proc_address(&GetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI, "vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI") + set_proc_address(&GetEventStatus, "vkGetEventStatus") + set_proc_address(&GetFenceFdKHR, "vkGetFenceFdKHR") + set_proc_address(&GetFenceStatus, "vkGetFenceStatus") + set_proc_address(&GetFenceWin32HandleKHR, "vkGetFenceWin32HandleKHR") + set_proc_address(&GetGeneratedCommandsMemoryRequirementsNV, "vkGetGeneratedCommandsMemoryRequirementsNV") + set_proc_address(&GetImageDrmFormatModifierPropertiesEXT, "vkGetImageDrmFormatModifierPropertiesEXT") + set_proc_address(&GetImageMemoryRequirements, "vkGetImageMemoryRequirements") + set_proc_address(&GetImageMemoryRequirements2, "vkGetImageMemoryRequirements2") + set_proc_address(&GetImageMemoryRequirements2KHR, "vkGetImageMemoryRequirements2KHR") + set_proc_address(&GetImageSparseMemoryRequirements, "vkGetImageSparseMemoryRequirements") + set_proc_address(&GetImageSparseMemoryRequirements2, "vkGetImageSparseMemoryRequirements2") + set_proc_address(&GetImageSparseMemoryRequirements2KHR, "vkGetImageSparseMemoryRequirements2KHR") + set_proc_address(&GetImageSubresourceLayout, "vkGetImageSubresourceLayout") + set_proc_address(&GetImageViewAddressNVX, "vkGetImageViewAddressNVX") + set_proc_address(&GetImageViewHandleNVX, "vkGetImageViewHandleNVX") + set_proc_address(&GetMemoryFdKHR, "vkGetMemoryFdKHR") + set_proc_address(&GetMemoryFdPropertiesKHR, "vkGetMemoryFdPropertiesKHR") + set_proc_address(&GetMemoryHostPointerPropertiesEXT, "vkGetMemoryHostPointerPropertiesEXT") + set_proc_address(&GetMemoryRemoteAddressNV, "vkGetMemoryRemoteAddressNV") + set_proc_address(&GetMemoryWin32HandleKHR, "vkGetMemoryWin32HandleKHR") + set_proc_address(&GetMemoryWin32HandleNV, "vkGetMemoryWin32HandleNV") + set_proc_address(&GetMemoryWin32HandlePropertiesKHR, "vkGetMemoryWin32HandlePropertiesKHR") + set_proc_address(&GetPastPresentationTimingGOOGLE, "vkGetPastPresentationTimingGOOGLE") + set_proc_address(&GetPerformanceParameterINTEL, "vkGetPerformanceParameterINTEL") + set_proc_address(&GetPipelineCacheData, "vkGetPipelineCacheData") + set_proc_address(&GetPipelineExecutableInternalRepresentationsKHR, "vkGetPipelineExecutableInternalRepresentationsKHR") + set_proc_address(&GetPipelineExecutablePropertiesKHR, "vkGetPipelineExecutablePropertiesKHR") + set_proc_address(&GetPipelineExecutableStatisticsKHR, "vkGetPipelineExecutableStatisticsKHR") + set_proc_address(&GetPrivateData, "vkGetPrivateData") + set_proc_address(&GetPrivateDataEXT, "vkGetPrivateDataEXT") + set_proc_address(&GetQueryPoolResults, "vkGetQueryPoolResults") + set_proc_address(&GetQueueCheckpointData2NV, "vkGetQueueCheckpointData2NV") + set_proc_address(&GetQueueCheckpointDataNV, "vkGetQueueCheckpointDataNV") + set_proc_address(&GetRayTracingCaptureReplayShaderGroupHandlesKHR, "vkGetRayTracingCaptureReplayShaderGroupHandlesKHR") + set_proc_address(&GetRayTracingShaderGroupHandlesKHR, "vkGetRayTracingShaderGroupHandlesKHR") + set_proc_address(&GetRayTracingShaderGroupHandlesNV, "vkGetRayTracingShaderGroupHandlesNV") + set_proc_address(&GetRayTracingShaderGroupStackSizeKHR, "vkGetRayTracingShaderGroupStackSizeKHR") + set_proc_address(&GetRefreshCycleDurationGOOGLE, "vkGetRefreshCycleDurationGOOGLE") + set_proc_address(&GetRenderAreaGranularity, "vkGetRenderAreaGranularity") + set_proc_address(&GetSemaphoreCounterValue, "vkGetSemaphoreCounterValue") + set_proc_address(&GetSemaphoreCounterValueKHR, "vkGetSemaphoreCounterValueKHR") + set_proc_address(&GetSemaphoreFdKHR, "vkGetSemaphoreFdKHR") + set_proc_address(&GetSemaphoreWin32HandleKHR, "vkGetSemaphoreWin32HandleKHR") + set_proc_address(&GetShaderInfoAMD, "vkGetShaderInfoAMD") + set_proc_address(&GetSwapchainCounterEXT, "vkGetSwapchainCounterEXT") + set_proc_address(&GetSwapchainImagesKHR, "vkGetSwapchainImagesKHR") + set_proc_address(&GetSwapchainStatusKHR, "vkGetSwapchainStatusKHR") + set_proc_address(&GetValidationCacheDataEXT, "vkGetValidationCacheDataEXT") + set_proc_address(&ImportFenceFdKHR, "vkImportFenceFdKHR") + set_proc_address(&ImportFenceWin32HandleKHR, "vkImportFenceWin32HandleKHR") + set_proc_address(&ImportSemaphoreFdKHR, "vkImportSemaphoreFdKHR") + set_proc_address(&ImportSemaphoreWin32HandleKHR, "vkImportSemaphoreWin32HandleKHR") + set_proc_address(&InitializePerformanceApiINTEL, "vkInitializePerformanceApiINTEL") + set_proc_address(&InvalidateMappedMemoryRanges, "vkInvalidateMappedMemoryRanges") + set_proc_address(&MapMemory, "vkMapMemory") + set_proc_address(&MergePipelineCaches, "vkMergePipelineCaches") + set_proc_address(&MergeValidationCachesEXT, "vkMergeValidationCachesEXT") + set_proc_address(&QueueBeginDebugUtilsLabelEXT, "vkQueueBeginDebugUtilsLabelEXT") + set_proc_address(&QueueBindSparse, "vkQueueBindSparse") + set_proc_address(&QueueEndDebugUtilsLabelEXT, "vkQueueEndDebugUtilsLabelEXT") + set_proc_address(&QueueInsertDebugUtilsLabelEXT, "vkQueueInsertDebugUtilsLabelEXT") + set_proc_address(&QueuePresentKHR, "vkQueuePresentKHR") + set_proc_address(&QueueSetPerformanceConfigurationINTEL, "vkQueueSetPerformanceConfigurationINTEL") + set_proc_address(&QueueSubmit, "vkQueueSubmit") + set_proc_address(&QueueSubmit2, "vkQueueSubmit2") + set_proc_address(&QueueSubmit2KHR, "vkQueueSubmit2KHR") + set_proc_address(&QueueWaitIdle, "vkQueueWaitIdle") + set_proc_address(&RegisterDeviceEventEXT, "vkRegisterDeviceEventEXT") + set_proc_address(&RegisterDisplayEventEXT, "vkRegisterDisplayEventEXT") + set_proc_address(&ReleaseFullScreenExclusiveModeEXT, "vkReleaseFullScreenExclusiveModeEXT") + set_proc_address(&ReleasePerformanceConfigurationINTEL, "vkReleasePerformanceConfigurationINTEL") + set_proc_address(&ReleaseProfilingLockKHR, "vkReleaseProfilingLockKHR") + set_proc_address(&ResetCommandBuffer, "vkResetCommandBuffer") + set_proc_address(&ResetCommandPool, "vkResetCommandPool") + set_proc_address(&ResetDescriptorPool, "vkResetDescriptorPool") + set_proc_address(&ResetEvent, "vkResetEvent") + set_proc_address(&ResetFences, "vkResetFences") + set_proc_address(&ResetQueryPool, "vkResetQueryPool") + set_proc_address(&ResetQueryPoolEXT, "vkResetQueryPoolEXT") + set_proc_address(&SetDebugUtilsObjectNameEXT, "vkSetDebugUtilsObjectNameEXT") + set_proc_address(&SetDebugUtilsObjectTagEXT, "vkSetDebugUtilsObjectTagEXT") + set_proc_address(&SetDeviceMemoryPriorityEXT, "vkSetDeviceMemoryPriorityEXT") + set_proc_address(&SetEvent, "vkSetEvent") + set_proc_address(&SetHdrMetadataEXT, "vkSetHdrMetadataEXT") + set_proc_address(&SetLocalDimmingAMD, "vkSetLocalDimmingAMD") + set_proc_address(&SetPrivateData, "vkSetPrivateData") + set_proc_address(&SetPrivateDataEXT, "vkSetPrivateDataEXT") + set_proc_address(&SignalSemaphore, "vkSignalSemaphore") + set_proc_address(&SignalSemaphoreKHR, "vkSignalSemaphoreKHR") + set_proc_address(&TrimCommandPool, "vkTrimCommandPool") + set_proc_address(&TrimCommandPoolKHR, "vkTrimCommandPoolKHR") + set_proc_address(&UninitializePerformanceApiINTEL, "vkUninitializePerformanceApiINTEL") + set_proc_address(&UnmapMemory, "vkUnmapMemory") + set_proc_address(&UpdateDescriptorSetWithTemplate, "vkUpdateDescriptorSetWithTemplate") + set_proc_address(&UpdateDescriptorSetWithTemplateKHR, "vkUpdateDescriptorSetWithTemplateKHR") + set_proc_address(&UpdateDescriptorSets, "vkUpdateDescriptorSets") + set_proc_address(&WaitForFences, "vkWaitForFences") + set_proc_address(&WaitForPresentKHR, "vkWaitForPresentKHR") + set_proc_address(&WaitSemaphores, "vkWaitSemaphores") + set_proc_address(&WaitSemaphoresKHR, "vkWaitSemaphoresKHR") + set_proc_address(&WriteAccelerationStructuresPropertiesKHR, "vkWriteAccelerationStructuresPropertiesKHR") } +// Device Procedure VTable +Device_VTable :: struct { + AcquireFullScreenExclusiveModeEXT: ProcAcquireFullScreenExclusiveModeEXT, + AcquireNextImage2KHR: ProcAcquireNextImage2KHR, + AcquireNextImageKHR: ProcAcquireNextImageKHR, + AcquirePerformanceConfigurationINTEL: ProcAcquirePerformanceConfigurationINTEL, + AcquireProfilingLockKHR: ProcAcquireProfilingLockKHR, + AllocateCommandBuffers: ProcAllocateCommandBuffers, + AllocateDescriptorSets: ProcAllocateDescriptorSets, + AllocateMemory: ProcAllocateMemory, + BeginCommandBuffer: ProcBeginCommandBuffer, + BindAccelerationStructureMemoryNV: ProcBindAccelerationStructureMemoryNV, + BindBufferMemory: ProcBindBufferMemory, + BindBufferMemory2: ProcBindBufferMemory2, + BindBufferMemory2KHR: ProcBindBufferMemory2KHR, + BindImageMemory: ProcBindImageMemory, + BindImageMemory2: ProcBindImageMemory2, + BindImageMemory2KHR: ProcBindImageMemory2KHR, + BuildAccelerationStructuresKHR: ProcBuildAccelerationStructuresKHR, + CmdBeginConditionalRenderingEXT: ProcCmdBeginConditionalRenderingEXT, + CmdBeginDebugUtilsLabelEXT: ProcCmdBeginDebugUtilsLabelEXT, + CmdBeginQuery: ProcCmdBeginQuery, + CmdBeginQueryIndexedEXT: ProcCmdBeginQueryIndexedEXT, + CmdBeginRenderPass: ProcCmdBeginRenderPass, + CmdBeginRenderPass2: ProcCmdBeginRenderPass2, + CmdBeginRenderPass2KHR: ProcCmdBeginRenderPass2KHR, + CmdBeginRendering: ProcCmdBeginRendering, + CmdBeginRenderingKHR: ProcCmdBeginRenderingKHR, + CmdBeginTransformFeedbackEXT: ProcCmdBeginTransformFeedbackEXT, + CmdBindDescriptorSets: ProcCmdBindDescriptorSets, + CmdBindIndexBuffer: ProcCmdBindIndexBuffer, + CmdBindInvocationMaskHUAWEI: ProcCmdBindInvocationMaskHUAWEI, + CmdBindPipeline: ProcCmdBindPipeline, + CmdBindPipelineShaderGroupNV: ProcCmdBindPipelineShaderGroupNV, + CmdBindShadingRateImageNV: ProcCmdBindShadingRateImageNV, + CmdBindTransformFeedbackBuffersEXT: ProcCmdBindTransformFeedbackBuffersEXT, + CmdBindVertexBuffers: ProcCmdBindVertexBuffers, + CmdBindVertexBuffers2: ProcCmdBindVertexBuffers2, + CmdBindVertexBuffers2EXT: ProcCmdBindVertexBuffers2EXT, + CmdBlitImage: ProcCmdBlitImage, + CmdBlitImage2: ProcCmdBlitImage2, + CmdBlitImage2KHR: ProcCmdBlitImage2KHR, + CmdBuildAccelerationStructureNV: ProcCmdBuildAccelerationStructureNV, + CmdBuildAccelerationStructuresIndirectKHR: ProcCmdBuildAccelerationStructuresIndirectKHR, + CmdBuildAccelerationStructuresKHR: ProcCmdBuildAccelerationStructuresKHR, + CmdClearAttachments: ProcCmdClearAttachments, + CmdClearColorImage: ProcCmdClearColorImage, + CmdClearDepthStencilImage: ProcCmdClearDepthStencilImage, + CmdCopyAccelerationStructureKHR: ProcCmdCopyAccelerationStructureKHR, + CmdCopyAccelerationStructureNV: ProcCmdCopyAccelerationStructureNV, + CmdCopyAccelerationStructureToMemoryKHR: ProcCmdCopyAccelerationStructureToMemoryKHR, + CmdCopyBuffer: ProcCmdCopyBuffer, + CmdCopyBuffer2: ProcCmdCopyBuffer2, + CmdCopyBuffer2KHR: ProcCmdCopyBuffer2KHR, + CmdCopyBufferToImage: ProcCmdCopyBufferToImage, + CmdCopyBufferToImage2: ProcCmdCopyBufferToImage2, + CmdCopyBufferToImage2KHR: ProcCmdCopyBufferToImage2KHR, + CmdCopyImage: ProcCmdCopyImage, + CmdCopyImage2: ProcCmdCopyImage2, + CmdCopyImage2KHR: ProcCmdCopyImage2KHR, + CmdCopyImageToBuffer: ProcCmdCopyImageToBuffer, + CmdCopyImageToBuffer2: ProcCmdCopyImageToBuffer2, + CmdCopyImageToBuffer2KHR: ProcCmdCopyImageToBuffer2KHR, + CmdCopyMemoryToAccelerationStructureKHR: ProcCmdCopyMemoryToAccelerationStructureKHR, + CmdCopyQueryPoolResults: ProcCmdCopyQueryPoolResults, + CmdCuLaunchKernelNVX: ProcCmdCuLaunchKernelNVX, + CmdDebugMarkerBeginEXT: ProcCmdDebugMarkerBeginEXT, + CmdDebugMarkerEndEXT: ProcCmdDebugMarkerEndEXT, + CmdDebugMarkerInsertEXT: ProcCmdDebugMarkerInsertEXT, + CmdDispatch: ProcCmdDispatch, + CmdDispatchBase: ProcCmdDispatchBase, + CmdDispatchBaseKHR: ProcCmdDispatchBaseKHR, + CmdDispatchIndirect: ProcCmdDispatchIndirect, + CmdDraw: ProcCmdDraw, + CmdDrawIndexed: ProcCmdDrawIndexed, + CmdDrawIndexedIndirect: ProcCmdDrawIndexedIndirect, + CmdDrawIndexedIndirectCount: ProcCmdDrawIndexedIndirectCount, + CmdDrawIndexedIndirectCountAMD: ProcCmdDrawIndexedIndirectCountAMD, + CmdDrawIndexedIndirectCountKHR: ProcCmdDrawIndexedIndirectCountKHR, + CmdDrawIndirect: ProcCmdDrawIndirect, + CmdDrawIndirectByteCountEXT: ProcCmdDrawIndirectByteCountEXT, + CmdDrawIndirectCount: ProcCmdDrawIndirectCount, + CmdDrawIndirectCountAMD: ProcCmdDrawIndirectCountAMD, + CmdDrawIndirectCountKHR: ProcCmdDrawIndirectCountKHR, + CmdDrawMeshTasksIndirectCountNV: ProcCmdDrawMeshTasksIndirectCountNV, + CmdDrawMeshTasksIndirectNV: ProcCmdDrawMeshTasksIndirectNV, + CmdDrawMeshTasksNV: ProcCmdDrawMeshTasksNV, + CmdDrawMultiEXT: ProcCmdDrawMultiEXT, + CmdDrawMultiIndexedEXT: ProcCmdDrawMultiIndexedEXT, + CmdEndConditionalRenderingEXT: ProcCmdEndConditionalRenderingEXT, + CmdEndDebugUtilsLabelEXT: ProcCmdEndDebugUtilsLabelEXT, + CmdEndQuery: ProcCmdEndQuery, + CmdEndQueryIndexedEXT: ProcCmdEndQueryIndexedEXT, + CmdEndRenderPass: ProcCmdEndRenderPass, + CmdEndRenderPass2: ProcCmdEndRenderPass2, + CmdEndRenderPass2KHR: ProcCmdEndRenderPass2KHR, + CmdEndRendering: ProcCmdEndRendering, + CmdEndRenderingKHR: ProcCmdEndRenderingKHR, + CmdEndTransformFeedbackEXT: ProcCmdEndTransformFeedbackEXT, + CmdExecuteCommands: ProcCmdExecuteCommands, + CmdExecuteGeneratedCommandsNV: ProcCmdExecuteGeneratedCommandsNV, + CmdFillBuffer: ProcCmdFillBuffer, + CmdInsertDebugUtilsLabelEXT: ProcCmdInsertDebugUtilsLabelEXT, + CmdNextSubpass: ProcCmdNextSubpass, + CmdNextSubpass2: ProcCmdNextSubpass2, + CmdNextSubpass2KHR: ProcCmdNextSubpass2KHR, + CmdPipelineBarrier: ProcCmdPipelineBarrier, + CmdPipelineBarrier2: ProcCmdPipelineBarrier2, + CmdPipelineBarrier2KHR: ProcCmdPipelineBarrier2KHR, + CmdPreprocessGeneratedCommandsNV: ProcCmdPreprocessGeneratedCommandsNV, + CmdPushConstants: ProcCmdPushConstants, + CmdPushDescriptorSetKHR: ProcCmdPushDescriptorSetKHR, + CmdPushDescriptorSetWithTemplateKHR: ProcCmdPushDescriptorSetWithTemplateKHR, + CmdResetEvent: ProcCmdResetEvent, + CmdResetEvent2: ProcCmdResetEvent2, + CmdResetEvent2KHR: ProcCmdResetEvent2KHR, + CmdResetQueryPool: ProcCmdResetQueryPool, + CmdResolveImage: ProcCmdResolveImage, + CmdResolveImage2: ProcCmdResolveImage2, + CmdResolveImage2KHR: ProcCmdResolveImage2KHR, + CmdSetBlendConstants: ProcCmdSetBlendConstants, + CmdSetCheckpointNV: ProcCmdSetCheckpointNV, + CmdSetCoarseSampleOrderNV: ProcCmdSetCoarseSampleOrderNV, + CmdSetCullMode: ProcCmdSetCullMode, + CmdSetCullModeEXT: ProcCmdSetCullModeEXT, + CmdSetDepthBias: ProcCmdSetDepthBias, + CmdSetDepthBiasEnable: ProcCmdSetDepthBiasEnable, + CmdSetDepthBiasEnableEXT: ProcCmdSetDepthBiasEnableEXT, + CmdSetDepthBounds: ProcCmdSetDepthBounds, + CmdSetDepthBoundsTestEnable: ProcCmdSetDepthBoundsTestEnable, + CmdSetDepthBoundsTestEnableEXT: ProcCmdSetDepthBoundsTestEnableEXT, + CmdSetDepthCompareOp: ProcCmdSetDepthCompareOp, + CmdSetDepthCompareOpEXT: ProcCmdSetDepthCompareOpEXT, + CmdSetDepthTestEnable: ProcCmdSetDepthTestEnable, + CmdSetDepthTestEnableEXT: ProcCmdSetDepthTestEnableEXT, + CmdSetDepthWriteEnable: ProcCmdSetDepthWriteEnable, + CmdSetDepthWriteEnableEXT: ProcCmdSetDepthWriteEnableEXT, + CmdSetDeviceMask: ProcCmdSetDeviceMask, + CmdSetDeviceMaskKHR: ProcCmdSetDeviceMaskKHR, + CmdSetDiscardRectangleEXT: ProcCmdSetDiscardRectangleEXT, + CmdSetEvent: ProcCmdSetEvent, + CmdSetEvent2: ProcCmdSetEvent2, + CmdSetEvent2KHR: ProcCmdSetEvent2KHR, + CmdSetExclusiveScissorNV: ProcCmdSetExclusiveScissorNV, + CmdSetFragmentShadingRateEnumNV: ProcCmdSetFragmentShadingRateEnumNV, + CmdSetFragmentShadingRateKHR: ProcCmdSetFragmentShadingRateKHR, + CmdSetFrontFace: ProcCmdSetFrontFace, + CmdSetFrontFaceEXT: ProcCmdSetFrontFaceEXT, + CmdSetLineStippleEXT: ProcCmdSetLineStippleEXT, + CmdSetLineWidth: ProcCmdSetLineWidth, + CmdSetLogicOpEXT: ProcCmdSetLogicOpEXT, + CmdSetPatchControlPointsEXT: ProcCmdSetPatchControlPointsEXT, + CmdSetPerformanceMarkerINTEL: ProcCmdSetPerformanceMarkerINTEL, + CmdSetPerformanceOverrideINTEL: ProcCmdSetPerformanceOverrideINTEL, + CmdSetPerformanceStreamMarkerINTEL: ProcCmdSetPerformanceStreamMarkerINTEL, + CmdSetPrimitiveRestartEnable: ProcCmdSetPrimitiveRestartEnable, + CmdSetPrimitiveRestartEnableEXT: ProcCmdSetPrimitiveRestartEnableEXT, + CmdSetPrimitiveTopology: ProcCmdSetPrimitiveTopology, + CmdSetPrimitiveTopologyEXT: ProcCmdSetPrimitiveTopologyEXT, + CmdSetRasterizerDiscardEnable: ProcCmdSetRasterizerDiscardEnable, + CmdSetRasterizerDiscardEnableEXT: ProcCmdSetRasterizerDiscardEnableEXT, + CmdSetRayTracingPipelineStackSizeKHR: ProcCmdSetRayTracingPipelineStackSizeKHR, + CmdSetSampleLocationsEXT: ProcCmdSetSampleLocationsEXT, + CmdSetScissor: ProcCmdSetScissor, + CmdSetScissorWithCount: ProcCmdSetScissorWithCount, + CmdSetScissorWithCountEXT: ProcCmdSetScissorWithCountEXT, + CmdSetStencilCompareMask: ProcCmdSetStencilCompareMask, + CmdSetStencilOp: ProcCmdSetStencilOp, + CmdSetStencilOpEXT: ProcCmdSetStencilOpEXT, + CmdSetStencilReference: ProcCmdSetStencilReference, + CmdSetStencilTestEnable: ProcCmdSetStencilTestEnable, + CmdSetStencilTestEnableEXT: ProcCmdSetStencilTestEnableEXT, + CmdSetStencilWriteMask: ProcCmdSetStencilWriteMask, + CmdSetVertexInputEXT: ProcCmdSetVertexInputEXT, + CmdSetViewport: ProcCmdSetViewport, + CmdSetViewportShadingRatePaletteNV: ProcCmdSetViewportShadingRatePaletteNV, + CmdSetViewportWScalingNV: ProcCmdSetViewportWScalingNV, + CmdSetViewportWithCount: ProcCmdSetViewportWithCount, + CmdSetViewportWithCountEXT: ProcCmdSetViewportWithCountEXT, + CmdSubpassShadingHUAWEI: ProcCmdSubpassShadingHUAWEI, + CmdTraceRaysIndirectKHR: ProcCmdTraceRaysIndirectKHR, + CmdTraceRaysKHR: ProcCmdTraceRaysKHR, + CmdTraceRaysNV: ProcCmdTraceRaysNV, + CmdUpdateBuffer: ProcCmdUpdateBuffer, + CmdWaitEvents: ProcCmdWaitEvents, + CmdWaitEvents2: ProcCmdWaitEvents2, + CmdWaitEvents2KHR: ProcCmdWaitEvents2KHR, + CmdWriteAccelerationStructuresPropertiesKHR: ProcCmdWriteAccelerationStructuresPropertiesKHR, + CmdWriteAccelerationStructuresPropertiesNV: ProcCmdWriteAccelerationStructuresPropertiesNV, + CmdWriteBufferMarker2AMD: ProcCmdWriteBufferMarker2AMD, + CmdWriteBufferMarkerAMD: ProcCmdWriteBufferMarkerAMD, + CmdWriteTimestamp: ProcCmdWriteTimestamp, + CmdWriteTimestamp2: ProcCmdWriteTimestamp2, + CmdWriteTimestamp2KHR: ProcCmdWriteTimestamp2KHR, + CompileDeferredNV: ProcCompileDeferredNV, + CopyAccelerationStructureKHR: ProcCopyAccelerationStructureKHR, + CopyAccelerationStructureToMemoryKHR: ProcCopyAccelerationStructureToMemoryKHR, + CopyMemoryToAccelerationStructureKHR: ProcCopyMemoryToAccelerationStructureKHR, + CreateAccelerationStructureKHR: ProcCreateAccelerationStructureKHR, + CreateAccelerationStructureNV: ProcCreateAccelerationStructureNV, + CreateBuffer: ProcCreateBuffer, + CreateBufferView: ProcCreateBufferView, + CreateCommandPool: ProcCreateCommandPool, + CreateComputePipelines: ProcCreateComputePipelines, + CreateCuFunctionNVX: ProcCreateCuFunctionNVX, + CreateCuModuleNVX: ProcCreateCuModuleNVX, + CreateDeferredOperationKHR: ProcCreateDeferredOperationKHR, + CreateDescriptorPool: ProcCreateDescriptorPool, + CreateDescriptorSetLayout: ProcCreateDescriptorSetLayout, + CreateDescriptorUpdateTemplate: ProcCreateDescriptorUpdateTemplate, + CreateDescriptorUpdateTemplateKHR: ProcCreateDescriptorUpdateTemplateKHR, + CreateEvent: ProcCreateEvent, + CreateFence: ProcCreateFence, + CreateFramebuffer: ProcCreateFramebuffer, + CreateGraphicsPipelines: ProcCreateGraphicsPipelines, + CreateImage: ProcCreateImage, + CreateImageView: ProcCreateImageView, + CreateIndirectCommandsLayoutNV: ProcCreateIndirectCommandsLayoutNV, + CreatePipelineCache: ProcCreatePipelineCache, + CreatePipelineLayout: ProcCreatePipelineLayout, + CreatePrivateDataSlot: ProcCreatePrivateDataSlot, + CreatePrivateDataSlotEXT: ProcCreatePrivateDataSlotEXT, + CreateQueryPool: ProcCreateQueryPool, + CreateRayTracingPipelinesKHR: ProcCreateRayTracingPipelinesKHR, + CreateRayTracingPipelinesNV: ProcCreateRayTracingPipelinesNV, + CreateRenderPass: ProcCreateRenderPass, + CreateRenderPass2: ProcCreateRenderPass2, + CreateRenderPass2KHR: ProcCreateRenderPass2KHR, + CreateSampler: ProcCreateSampler, + CreateSamplerYcbcrConversion: ProcCreateSamplerYcbcrConversion, + CreateSamplerYcbcrConversionKHR: ProcCreateSamplerYcbcrConversionKHR, + CreateSemaphore: ProcCreateSemaphore, + CreateShaderModule: ProcCreateShaderModule, + CreateSharedSwapchainsKHR: ProcCreateSharedSwapchainsKHR, + CreateSwapchainKHR: ProcCreateSwapchainKHR, + CreateValidationCacheEXT: ProcCreateValidationCacheEXT, + DebugMarkerSetObjectNameEXT: ProcDebugMarkerSetObjectNameEXT, + DebugMarkerSetObjectTagEXT: ProcDebugMarkerSetObjectTagEXT, + DeferredOperationJoinKHR: ProcDeferredOperationJoinKHR, + DestroyAccelerationStructureKHR: ProcDestroyAccelerationStructureKHR, + DestroyAccelerationStructureNV: ProcDestroyAccelerationStructureNV, + DestroyBuffer: ProcDestroyBuffer, + DestroyBufferView: ProcDestroyBufferView, + DestroyCommandPool: ProcDestroyCommandPool, + DestroyCuFunctionNVX: ProcDestroyCuFunctionNVX, + DestroyCuModuleNVX: ProcDestroyCuModuleNVX, + DestroyDeferredOperationKHR: ProcDestroyDeferredOperationKHR, + DestroyDescriptorPool: ProcDestroyDescriptorPool, + DestroyDescriptorSetLayout: ProcDestroyDescriptorSetLayout, + DestroyDescriptorUpdateTemplate: ProcDestroyDescriptorUpdateTemplate, + DestroyDescriptorUpdateTemplateKHR: ProcDestroyDescriptorUpdateTemplateKHR, + DestroyDevice: ProcDestroyDevice, + DestroyEvent: ProcDestroyEvent, + DestroyFence: ProcDestroyFence, + DestroyFramebuffer: ProcDestroyFramebuffer, + DestroyImage: ProcDestroyImage, + DestroyImageView: ProcDestroyImageView, + DestroyIndirectCommandsLayoutNV: ProcDestroyIndirectCommandsLayoutNV, + DestroyPipeline: ProcDestroyPipeline, + DestroyPipelineCache: ProcDestroyPipelineCache, + DestroyPipelineLayout: ProcDestroyPipelineLayout, + DestroyPrivateDataSlot: ProcDestroyPrivateDataSlot, + DestroyPrivateDataSlotEXT: ProcDestroyPrivateDataSlotEXT, + DestroyQueryPool: ProcDestroyQueryPool, + DestroyRenderPass: ProcDestroyRenderPass, + DestroySampler: ProcDestroySampler, + DestroySamplerYcbcrConversion: ProcDestroySamplerYcbcrConversion, + DestroySamplerYcbcrConversionKHR: ProcDestroySamplerYcbcrConversionKHR, + DestroySemaphore: ProcDestroySemaphore, + DestroyShaderModule: ProcDestroyShaderModule, + DestroySwapchainKHR: ProcDestroySwapchainKHR, + DestroyValidationCacheEXT: ProcDestroyValidationCacheEXT, + DeviceWaitIdle: ProcDeviceWaitIdle, + DisplayPowerControlEXT: ProcDisplayPowerControlEXT, + EndCommandBuffer: ProcEndCommandBuffer, + FlushMappedMemoryRanges: ProcFlushMappedMemoryRanges, + FreeCommandBuffers: ProcFreeCommandBuffers, + FreeDescriptorSets: ProcFreeDescriptorSets, + FreeMemory: ProcFreeMemory, + GetAccelerationStructureBuildSizesKHR: ProcGetAccelerationStructureBuildSizesKHR, + GetAccelerationStructureDeviceAddressKHR: ProcGetAccelerationStructureDeviceAddressKHR, + GetAccelerationStructureHandleNV: ProcGetAccelerationStructureHandleNV, + GetAccelerationStructureMemoryRequirementsNV: ProcGetAccelerationStructureMemoryRequirementsNV, + GetBufferDeviceAddress: ProcGetBufferDeviceAddress, + GetBufferDeviceAddressEXT: ProcGetBufferDeviceAddressEXT, + GetBufferDeviceAddressKHR: ProcGetBufferDeviceAddressKHR, + GetBufferMemoryRequirements: ProcGetBufferMemoryRequirements, + GetBufferMemoryRequirements2: ProcGetBufferMemoryRequirements2, + GetBufferMemoryRequirements2KHR: ProcGetBufferMemoryRequirements2KHR, + GetBufferOpaqueCaptureAddress: ProcGetBufferOpaqueCaptureAddress, + GetBufferOpaqueCaptureAddressKHR: ProcGetBufferOpaqueCaptureAddressKHR, + GetCalibratedTimestampsEXT: ProcGetCalibratedTimestampsEXT, + GetDeferredOperationMaxConcurrencyKHR: ProcGetDeferredOperationMaxConcurrencyKHR, + GetDeferredOperationResultKHR: ProcGetDeferredOperationResultKHR, + GetDescriptorSetHostMappingVALVE: ProcGetDescriptorSetHostMappingVALVE, + GetDescriptorSetLayoutHostMappingInfoVALVE: ProcGetDescriptorSetLayoutHostMappingInfoVALVE, + GetDescriptorSetLayoutSupport: ProcGetDescriptorSetLayoutSupport, + GetDescriptorSetLayoutSupportKHR: ProcGetDescriptorSetLayoutSupportKHR, + GetDeviceAccelerationStructureCompatibilityKHR: ProcGetDeviceAccelerationStructureCompatibilityKHR, + GetDeviceBufferMemoryRequirements: ProcGetDeviceBufferMemoryRequirements, + GetDeviceBufferMemoryRequirementsKHR: ProcGetDeviceBufferMemoryRequirementsKHR, + GetDeviceGroupPeerMemoryFeatures: ProcGetDeviceGroupPeerMemoryFeatures, + GetDeviceGroupPeerMemoryFeaturesKHR: ProcGetDeviceGroupPeerMemoryFeaturesKHR, + GetDeviceGroupPresentCapabilitiesKHR: ProcGetDeviceGroupPresentCapabilitiesKHR, + GetDeviceGroupSurfacePresentModes2EXT: ProcGetDeviceGroupSurfacePresentModes2EXT, + GetDeviceGroupSurfacePresentModesKHR: ProcGetDeviceGroupSurfacePresentModesKHR, + GetDeviceImageMemoryRequirements: ProcGetDeviceImageMemoryRequirements, + GetDeviceImageMemoryRequirementsKHR: ProcGetDeviceImageMemoryRequirementsKHR, + GetDeviceImageSparseMemoryRequirements: ProcGetDeviceImageSparseMemoryRequirements, + GetDeviceImageSparseMemoryRequirementsKHR: ProcGetDeviceImageSparseMemoryRequirementsKHR, + GetDeviceMemoryCommitment: ProcGetDeviceMemoryCommitment, + GetDeviceMemoryOpaqueCaptureAddress: ProcGetDeviceMemoryOpaqueCaptureAddress, + GetDeviceMemoryOpaqueCaptureAddressKHR: ProcGetDeviceMemoryOpaqueCaptureAddressKHR, + GetDeviceProcAddr: ProcGetDeviceProcAddr, + GetDeviceQueue: ProcGetDeviceQueue, + GetDeviceQueue2: ProcGetDeviceQueue2, + GetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI: ProcGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI, + GetEventStatus: ProcGetEventStatus, + GetFenceFdKHR: ProcGetFenceFdKHR, + GetFenceStatus: ProcGetFenceStatus, + GetFenceWin32HandleKHR: ProcGetFenceWin32HandleKHR, + GetGeneratedCommandsMemoryRequirementsNV: ProcGetGeneratedCommandsMemoryRequirementsNV, + GetImageDrmFormatModifierPropertiesEXT: ProcGetImageDrmFormatModifierPropertiesEXT, + GetImageMemoryRequirements: ProcGetImageMemoryRequirements, + GetImageMemoryRequirements2: ProcGetImageMemoryRequirements2, + GetImageMemoryRequirements2KHR: ProcGetImageMemoryRequirements2KHR, + GetImageSparseMemoryRequirements: ProcGetImageSparseMemoryRequirements, + GetImageSparseMemoryRequirements2: ProcGetImageSparseMemoryRequirements2, + GetImageSparseMemoryRequirements2KHR: ProcGetImageSparseMemoryRequirements2KHR, + GetImageSubresourceLayout: ProcGetImageSubresourceLayout, + GetImageViewAddressNVX: ProcGetImageViewAddressNVX, + GetImageViewHandleNVX: ProcGetImageViewHandleNVX, + GetMemoryFdKHR: ProcGetMemoryFdKHR, + GetMemoryFdPropertiesKHR: ProcGetMemoryFdPropertiesKHR, + GetMemoryHostPointerPropertiesEXT: ProcGetMemoryHostPointerPropertiesEXT, + GetMemoryRemoteAddressNV: ProcGetMemoryRemoteAddressNV, + GetMemoryWin32HandleKHR: ProcGetMemoryWin32HandleKHR, + GetMemoryWin32HandleNV: ProcGetMemoryWin32HandleNV, + GetMemoryWin32HandlePropertiesKHR: ProcGetMemoryWin32HandlePropertiesKHR, + GetPastPresentationTimingGOOGLE: ProcGetPastPresentationTimingGOOGLE, + GetPerformanceParameterINTEL: ProcGetPerformanceParameterINTEL, + GetPipelineCacheData: ProcGetPipelineCacheData, + GetPipelineExecutableInternalRepresentationsKHR: ProcGetPipelineExecutableInternalRepresentationsKHR, + GetPipelineExecutablePropertiesKHR: ProcGetPipelineExecutablePropertiesKHR, + GetPipelineExecutableStatisticsKHR: ProcGetPipelineExecutableStatisticsKHR, + GetPrivateData: ProcGetPrivateData, + GetPrivateDataEXT: ProcGetPrivateDataEXT, + GetQueryPoolResults: ProcGetQueryPoolResults, + GetQueueCheckpointData2NV: ProcGetQueueCheckpointData2NV, + GetQueueCheckpointDataNV: ProcGetQueueCheckpointDataNV, + GetRayTracingCaptureReplayShaderGroupHandlesKHR: ProcGetRayTracingCaptureReplayShaderGroupHandlesKHR, + GetRayTracingShaderGroupHandlesKHR: ProcGetRayTracingShaderGroupHandlesKHR, + GetRayTracingShaderGroupHandlesNV: ProcGetRayTracingShaderGroupHandlesNV, + GetRayTracingShaderGroupStackSizeKHR: ProcGetRayTracingShaderGroupStackSizeKHR, + GetRefreshCycleDurationGOOGLE: ProcGetRefreshCycleDurationGOOGLE, + GetRenderAreaGranularity: ProcGetRenderAreaGranularity, + GetSemaphoreCounterValue: ProcGetSemaphoreCounterValue, + GetSemaphoreCounterValueKHR: ProcGetSemaphoreCounterValueKHR, + GetSemaphoreFdKHR: ProcGetSemaphoreFdKHR, + GetSemaphoreWin32HandleKHR: ProcGetSemaphoreWin32HandleKHR, + GetShaderInfoAMD: ProcGetShaderInfoAMD, + GetSwapchainCounterEXT: ProcGetSwapchainCounterEXT, + GetSwapchainImagesKHR: ProcGetSwapchainImagesKHR, + GetSwapchainStatusKHR: ProcGetSwapchainStatusKHR, + GetValidationCacheDataEXT: ProcGetValidationCacheDataEXT, + ImportFenceFdKHR: ProcImportFenceFdKHR, + ImportFenceWin32HandleKHR: ProcImportFenceWin32HandleKHR, + ImportSemaphoreFdKHR: ProcImportSemaphoreFdKHR, + ImportSemaphoreWin32HandleKHR: ProcImportSemaphoreWin32HandleKHR, + InitializePerformanceApiINTEL: ProcInitializePerformanceApiINTEL, + InvalidateMappedMemoryRanges: ProcInvalidateMappedMemoryRanges, + MapMemory: ProcMapMemory, + MergePipelineCaches: ProcMergePipelineCaches, + MergeValidationCachesEXT: ProcMergeValidationCachesEXT, + QueueBeginDebugUtilsLabelEXT: ProcQueueBeginDebugUtilsLabelEXT, + QueueBindSparse: ProcQueueBindSparse, + QueueEndDebugUtilsLabelEXT: ProcQueueEndDebugUtilsLabelEXT, + QueueInsertDebugUtilsLabelEXT: ProcQueueInsertDebugUtilsLabelEXT, + QueuePresentKHR: ProcQueuePresentKHR, + QueueSetPerformanceConfigurationINTEL: ProcQueueSetPerformanceConfigurationINTEL, + QueueSubmit: ProcQueueSubmit, + QueueSubmit2: ProcQueueSubmit2, + QueueSubmit2KHR: ProcQueueSubmit2KHR, + QueueWaitIdle: ProcQueueWaitIdle, + RegisterDeviceEventEXT: ProcRegisterDeviceEventEXT, + RegisterDisplayEventEXT: ProcRegisterDisplayEventEXT, + ReleaseFullScreenExclusiveModeEXT: ProcReleaseFullScreenExclusiveModeEXT, + ReleasePerformanceConfigurationINTEL: ProcReleasePerformanceConfigurationINTEL, + ReleaseProfilingLockKHR: ProcReleaseProfilingLockKHR, + ResetCommandBuffer: ProcResetCommandBuffer, + ResetCommandPool: ProcResetCommandPool, + ResetDescriptorPool: ProcResetDescriptorPool, + ResetEvent: ProcResetEvent, + ResetFences: ProcResetFences, + ResetQueryPool: ProcResetQueryPool, + ResetQueryPoolEXT: ProcResetQueryPoolEXT, + SetDebugUtilsObjectNameEXT: ProcSetDebugUtilsObjectNameEXT, + SetDebugUtilsObjectTagEXT: ProcSetDebugUtilsObjectTagEXT, + SetDeviceMemoryPriorityEXT: ProcSetDeviceMemoryPriorityEXT, + SetEvent: ProcSetEvent, + SetHdrMetadataEXT: ProcSetHdrMetadataEXT, + SetLocalDimmingAMD: ProcSetLocalDimmingAMD, + SetPrivateData: ProcSetPrivateData, + SetPrivateDataEXT: ProcSetPrivateDataEXT, + SignalSemaphore: ProcSignalSemaphore, + SignalSemaphoreKHR: ProcSignalSemaphoreKHR, + TrimCommandPool: ProcTrimCommandPool, + TrimCommandPoolKHR: ProcTrimCommandPoolKHR, + UninitializePerformanceApiINTEL: ProcUninitializePerformanceApiINTEL, + UnmapMemory: ProcUnmapMemory, + UpdateDescriptorSetWithTemplate: ProcUpdateDescriptorSetWithTemplate, + UpdateDescriptorSetWithTemplateKHR: ProcUpdateDescriptorSetWithTemplateKHR, + UpdateDescriptorSets: ProcUpdateDescriptorSets, + WaitForFences: ProcWaitForFences, + WaitForPresentKHR: ProcWaitForPresentKHR, + WaitSemaphores: ProcWaitSemaphores, + WaitSemaphoresKHR: ProcWaitSemaphoresKHR, + WriteAccelerationStructuresPropertiesKHR: ProcWriteAccelerationStructuresPropertiesKHR, +} + +load_proc_addresses_device_vtable :: proc(device: Device, vtable: ^Device_VTable) { + vtable.AcquireFullScreenExclusiveModeEXT = auto_cast GetDeviceProcAddr(device, "vkAcquireFullScreenExclusiveModeEXT") + vtable.AcquireNextImage2KHR = auto_cast GetDeviceProcAddr(device, "vkAcquireNextImage2KHR") + vtable.AcquireNextImageKHR = auto_cast GetDeviceProcAddr(device, "vkAcquireNextImageKHR") + vtable.AcquirePerformanceConfigurationINTEL = auto_cast GetDeviceProcAddr(device, "vkAcquirePerformanceConfigurationINTEL") + vtable.AcquireProfilingLockKHR = auto_cast GetDeviceProcAddr(device, "vkAcquireProfilingLockKHR") + vtable.AllocateCommandBuffers = auto_cast GetDeviceProcAddr(device, "vkAllocateCommandBuffers") + vtable.AllocateDescriptorSets = auto_cast GetDeviceProcAddr(device, "vkAllocateDescriptorSets") + vtable.AllocateMemory = auto_cast GetDeviceProcAddr(device, "vkAllocateMemory") + vtable.BeginCommandBuffer = auto_cast GetDeviceProcAddr(device, "vkBeginCommandBuffer") + vtable.BindAccelerationStructureMemoryNV = auto_cast GetDeviceProcAddr(device, "vkBindAccelerationStructureMemoryNV") + vtable.BindBufferMemory = auto_cast GetDeviceProcAddr(device, "vkBindBufferMemory") + vtable.BindBufferMemory2 = auto_cast GetDeviceProcAddr(device, "vkBindBufferMemory2") + vtable.BindBufferMemory2KHR = auto_cast GetDeviceProcAddr(device, "vkBindBufferMemory2KHR") + vtable.BindImageMemory = auto_cast GetDeviceProcAddr(device, "vkBindImageMemory") + vtable.BindImageMemory2 = auto_cast GetDeviceProcAddr(device, "vkBindImageMemory2") + vtable.BindImageMemory2KHR = auto_cast GetDeviceProcAddr(device, "vkBindImageMemory2KHR") + vtable.BuildAccelerationStructuresKHR = auto_cast GetDeviceProcAddr(device, "vkBuildAccelerationStructuresKHR") + vtable.CmdBeginConditionalRenderingEXT = auto_cast GetDeviceProcAddr(device, "vkCmdBeginConditionalRenderingEXT") + vtable.CmdBeginDebugUtilsLabelEXT = auto_cast GetDeviceProcAddr(device, "vkCmdBeginDebugUtilsLabelEXT") + vtable.CmdBeginQuery = auto_cast GetDeviceProcAddr(device, "vkCmdBeginQuery") + vtable.CmdBeginQueryIndexedEXT = auto_cast GetDeviceProcAddr(device, "vkCmdBeginQueryIndexedEXT") + vtable.CmdBeginRenderPass = auto_cast GetDeviceProcAddr(device, "vkCmdBeginRenderPass") + vtable.CmdBeginRenderPass2 = auto_cast GetDeviceProcAddr(device, "vkCmdBeginRenderPass2") + vtable.CmdBeginRenderPass2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdBeginRenderPass2KHR") + vtable.CmdBeginRendering = auto_cast GetDeviceProcAddr(device, "vkCmdBeginRendering") + vtable.CmdBeginRenderingKHR = auto_cast GetDeviceProcAddr(device, "vkCmdBeginRenderingKHR") + vtable.CmdBeginTransformFeedbackEXT = auto_cast GetDeviceProcAddr(device, "vkCmdBeginTransformFeedbackEXT") + vtable.CmdBindDescriptorSets = auto_cast GetDeviceProcAddr(device, "vkCmdBindDescriptorSets") + vtable.CmdBindIndexBuffer = auto_cast GetDeviceProcAddr(device, "vkCmdBindIndexBuffer") + vtable.CmdBindInvocationMaskHUAWEI = auto_cast GetDeviceProcAddr(device, "vkCmdBindInvocationMaskHUAWEI") + vtable.CmdBindPipeline = auto_cast GetDeviceProcAddr(device, "vkCmdBindPipeline") + vtable.CmdBindPipelineShaderGroupNV = auto_cast GetDeviceProcAddr(device, "vkCmdBindPipelineShaderGroupNV") + vtable.CmdBindShadingRateImageNV = auto_cast GetDeviceProcAddr(device, "vkCmdBindShadingRateImageNV") + vtable.CmdBindTransformFeedbackBuffersEXT = auto_cast GetDeviceProcAddr(device, "vkCmdBindTransformFeedbackBuffersEXT") + vtable.CmdBindVertexBuffers = auto_cast GetDeviceProcAddr(device, "vkCmdBindVertexBuffers") + vtable.CmdBindVertexBuffers2 = auto_cast GetDeviceProcAddr(device, "vkCmdBindVertexBuffers2") + vtable.CmdBindVertexBuffers2EXT = auto_cast GetDeviceProcAddr(device, "vkCmdBindVertexBuffers2EXT") + vtable.CmdBlitImage = auto_cast GetDeviceProcAddr(device, "vkCmdBlitImage") + vtable.CmdBlitImage2 = auto_cast GetDeviceProcAddr(device, "vkCmdBlitImage2") + vtable.CmdBlitImage2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdBlitImage2KHR") + vtable.CmdBuildAccelerationStructureNV = auto_cast GetDeviceProcAddr(device, "vkCmdBuildAccelerationStructureNV") + vtable.CmdBuildAccelerationStructuresIndirectKHR = auto_cast GetDeviceProcAddr(device, "vkCmdBuildAccelerationStructuresIndirectKHR") + vtable.CmdBuildAccelerationStructuresKHR = auto_cast GetDeviceProcAddr(device, "vkCmdBuildAccelerationStructuresKHR") + vtable.CmdClearAttachments = auto_cast GetDeviceProcAddr(device, "vkCmdClearAttachments") + vtable.CmdClearColorImage = auto_cast GetDeviceProcAddr(device, "vkCmdClearColorImage") + vtable.CmdClearDepthStencilImage = auto_cast GetDeviceProcAddr(device, "vkCmdClearDepthStencilImage") + vtable.CmdCopyAccelerationStructureKHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyAccelerationStructureKHR") + vtable.CmdCopyAccelerationStructureNV = auto_cast GetDeviceProcAddr(device, "vkCmdCopyAccelerationStructureNV") + vtable.CmdCopyAccelerationStructureToMemoryKHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyAccelerationStructureToMemoryKHR") + vtable.CmdCopyBuffer = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBuffer") + vtable.CmdCopyBuffer2 = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBuffer2") + vtable.CmdCopyBuffer2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBuffer2KHR") + vtable.CmdCopyBufferToImage = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBufferToImage") + vtable.CmdCopyBufferToImage2 = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBufferToImage2") + vtable.CmdCopyBufferToImage2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBufferToImage2KHR") + vtable.CmdCopyImage = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImage") + vtable.CmdCopyImage2 = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImage2") + vtable.CmdCopyImage2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImage2KHR") + vtable.CmdCopyImageToBuffer = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImageToBuffer") + vtable.CmdCopyImageToBuffer2 = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImageToBuffer2") + vtable.CmdCopyImageToBuffer2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImageToBuffer2KHR") + vtable.CmdCopyMemoryToAccelerationStructureKHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyMemoryToAccelerationStructureKHR") + vtable.CmdCopyQueryPoolResults = auto_cast GetDeviceProcAddr(device, "vkCmdCopyQueryPoolResults") + vtable.CmdCuLaunchKernelNVX = auto_cast GetDeviceProcAddr(device, "vkCmdCuLaunchKernelNVX") + vtable.CmdDebugMarkerBeginEXT = auto_cast GetDeviceProcAddr(device, "vkCmdDebugMarkerBeginEXT") + vtable.CmdDebugMarkerEndEXT = auto_cast GetDeviceProcAddr(device, "vkCmdDebugMarkerEndEXT") + vtable.CmdDebugMarkerInsertEXT = auto_cast GetDeviceProcAddr(device, "vkCmdDebugMarkerInsertEXT") + vtable.CmdDispatch = auto_cast GetDeviceProcAddr(device, "vkCmdDispatch") + vtable.CmdDispatchBase = auto_cast GetDeviceProcAddr(device, "vkCmdDispatchBase") + vtable.CmdDispatchBaseKHR = auto_cast GetDeviceProcAddr(device, "vkCmdDispatchBaseKHR") + vtable.CmdDispatchIndirect = auto_cast GetDeviceProcAddr(device, "vkCmdDispatchIndirect") + vtable.CmdDraw = auto_cast GetDeviceProcAddr(device, "vkCmdDraw") + vtable.CmdDrawIndexed = auto_cast GetDeviceProcAddr(device, "vkCmdDrawIndexed") + vtable.CmdDrawIndexedIndirect = auto_cast GetDeviceProcAddr(device, "vkCmdDrawIndexedIndirect") + vtable.CmdDrawIndexedIndirectCount = auto_cast GetDeviceProcAddr(device, "vkCmdDrawIndexedIndirectCount") + vtable.CmdDrawIndexedIndirectCountAMD = auto_cast GetDeviceProcAddr(device, "vkCmdDrawIndexedIndirectCountAMD") + vtable.CmdDrawIndexedIndirectCountKHR = auto_cast GetDeviceProcAddr(device, "vkCmdDrawIndexedIndirectCountKHR") + vtable.CmdDrawIndirect = auto_cast GetDeviceProcAddr(device, "vkCmdDrawIndirect") + vtable.CmdDrawIndirectByteCountEXT = auto_cast GetDeviceProcAddr(device, "vkCmdDrawIndirectByteCountEXT") + vtable.CmdDrawIndirectCount = auto_cast GetDeviceProcAddr(device, "vkCmdDrawIndirectCount") + vtable.CmdDrawIndirectCountAMD = auto_cast GetDeviceProcAddr(device, "vkCmdDrawIndirectCountAMD") + vtable.CmdDrawIndirectCountKHR = auto_cast GetDeviceProcAddr(device, "vkCmdDrawIndirectCountKHR") + vtable.CmdDrawMeshTasksIndirectCountNV = auto_cast GetDeviceProcAddr(device, "vkCmdDrawMeshTasksIndirectCountNV") + vtable.CmdDrawMeshTasksIndirectNV = auto_cast GetDeviceProcAddr(device, "vkCmdDrawMeshTasksIndirectNV") + vtable.CmdDrawMeshTasksNV = auto_cast GetDeviceProcAddr(device, "vkCmdDrawMeshTasksNV") + vtable.CmdDrawMultiEXT = auto_cast GetDeviceProcAddr(device, "vkCmdDrawMultiEXT") + vtable.CmdDrawMultiIndexedEXT = auto_cast GetDeviceProcAddr(device, "vkCmdDrawMultiIndexedEXT") + vtable.CmdEndConditionalRenderingEXT = auto_cast GetDeviceProcAddr(device, "vkCmdEndConditionalRenderingEXT") + vtable.CmdEndDebugUtilsLabelEXT = auto_cast GetDeviceProcAddr(device, "vkCmdEndDebugUtilsLabelEXT") + vtable.CmdEndQuery = auto_cast GetDeviceProcAddr(device, "vkCmdEndQuery") + vtable.CmdEndQueryIndexedEXT = auto_cast GetDeviceProcAddr(device, "vkCmdEndQueryIndexedEXT") + vtable.CmdEndRenderPass = auto_cast GetDeviceProcAddr(device, "vkCmdEndRenderPass") + vtable.CmdEndRenderPass2 = auto_cast GetDeviceProcAddr(device, "vkCmdEndRenderPass2") + vtable.CmdEndRenderPass2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdEndRenderPass2KHR") + vtable.CmdEndRendering = auto_cast GetDeviceProcAddr(device, "vkCmdEndRendering") + vtable.CmdEndRenderingKHR = auto_cast GetDeviceProcAddr(device, "vkCmdEndRenderingKHR") + vtable.CmdEndTransformFeedbackEXT = auto_cast GetDeviceProcAddr(device, "vkCmdEndTransformFeedbackEXT") + vtable.CmdExecuteCommands = auto_cast GetDeviceProcAddr(device, "vkCmdExecuteCommands") + vtable.CmdExecuteGeneratedCommandsNV = auto_cast GetDeviceProcAddr(device, "vkCmdExecuteGeneratedCommandsNV") + vtable.CmdFillBuffer = auto_cast GetDeviceProcAddr(device, "vkCmdFillBuffer") + vtable.CmdInsertDebugUtilsLabelEXT = auto_cast GetDeviceProcAddr(device, "vkCmdInsertDebugUtilsLabelEXT") + vtable.CmdNextSubpass = auto_cast GetDeviceProcAddr(device, "vkCmdNextSubpass") + vtable.CmdNextSubpass2 = auto_cast GetDeviceProcAddr(device, "vkCmdNextSubpass2") + vtable.CmdNextSubpass2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdNextSubpass2KHR") + vtable.CmdPipelineBarrier = auto_cast GetDeviceProcAddr(device, "vkCmdPipelineBarrier") + vtable.CmdPipelineBarrier2 = auto_cast GetDeviceProcAddr(device, "vkCmdPipelineBarrier2") + vtable.CmdPipelineBarrier2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdPipelineBarrier2KHR") + vtable.CmdPreprocessGeneratedCommandsNV = auto_cast GetDeviceProcAddr(device, "vkCmdPreprocessGeneratedCommandsNV") + vtable.CmdPushConstants = auto_cast GetDeviceProcAddr(device, "vkCmdPushConstants") + vtable.CmdPushDescriptorSetKHR = auto_cast GetDeviceProcAddr(device, "vkCmdPushDescriptorSetKHR") + vtable.CmdPushDescriptorSetWithTemplateKHR = auto_cast GetDeviceProcAddr(device, "vkCmdPushDescriptorSetWithTemplateKHR") + vtable.CmdResetEvent = auto_cast GetDeviceProcAddr(device, "vkCmdResetEvent") + vtable.CmdResetEvent2 = auto_cast GetDeviceProcAddr(device, "vkCmdResetEvent2") + vtable.CmdResetEvent2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdResetEvent2KHR") + vtable.CmdResetQueryPool = auto_cast GetDeviceProcAddr(device, "vkCmdResetQueryPool") + vtable.CmdResolveImage = auto_cast GetDeviceProcAddr(device, "vkCmdResolveImage") + vtable.CmdResolveImage2 = auto_cast GetDeviceProcAddr(device, "vkCmdResolveImage2") + vtable.CmdResolveImage2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdResolveImage2KHR") + vtable.CmdSetBlendConstants = auto_cast GetDeviceProcAddr(device, "vkCmdSetBlendConstants") + vtable.CmdSetCheckpointNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetCheckpointNV") + vtable.CmdSetCoarseSampleOrderNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetCoarseSampleOrderNV") + vtable.CmdSetCullMode = auto_cast GetDeviceProcAddr(device, "vkCmdSetCullMode") + vtable.CmdSetCullModeEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetCullModeEXT") + vtable.CmdSetDepthBias = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBias") + vtable.CmdSetDepthBiasEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBiasEnable") + vtable.CmdSetDepthBiasEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBiasEnableEXT") + vtable.CmdSetDepthBounds = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBounds") + vtable.CmdSetDepthBoundsTestEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBoundsTestEnable") + vtable.CmdSetDepthBoundsTestEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBoundsTestEnableEXT") + vtable.CmdSetDepthCompareOp = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthCompareOp") + vtable.CmdSetDepthCompareOpEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthCompareOpEXT") + vtable.CmdSetDepthTestEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthTestEnable") + vtable.CmdSetDepthTestEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthTestEnableEXT") + vtable.CmdSetDepthWriteEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthWriteEnable") + vtable.CmdSetDepthWriteEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthWriteEnableEXT") + vtable.CmdSetDeviceMask = auto_cast GetDeviceProcAddr(device, "vkCmdSetDeviceMask") + vtable.CmdSetDeviceMaskKHR = auto_cast GetDeviceProcAddr(device, "vkCmdSetDeviceMaskKHR") + vtable.CmdSetDiscardRectangleEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDiscardRectangleEXT") + vtable.CmdSetEvent = auto_cast GetDeviceProcAddr(device, "vkCmdSetEvent") + vtable.CmdSetEvent2 = auto_cast GetDeviceProcAddr(device, "vkCmdSetEvent2") + vtable.CmdSetEvent2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdSetEvent2KHR") + vtable.CmdSetExclusiveScissorNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetExclusiveScissorNV") + vtable.CmdSetFragmentShadingRateEnumNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetFragmentShadingRateEnumNV") + vtable.CmdSetFragmentShadingRateKHR = auto_cast GetDeviceProcAddr(device, "vkCmdSetFragmentShadingRateKHR") + vtable.CmdSetFrontFace = auto_cast GetDeviceProcAddr(device, "vkCmdSetFrontFace") + vtable.CmdSetFrontFaceEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetFrontFaceEXT") + vtable.CmdSetLineStippleEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetLineStippleEXT") + vtable.CmdSetLineWidth = auto_cast GetDeviceProcAddr(device, "vkCmdSetLineWidth") + vtable.CmdSetLogicOpEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetLogicOpEXT") + vtable.CmdSetPatchControlPointsEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetPatchControlPointsEXT") + vtable.CmdSetPerformanceMarkerINTEL = auto_cast GetDeviceProcAddr(device, "vkCmdSetPerformanceMarkerINTEL") + vtable.CmdSetPerformanceOverrideINTEL = auto_cast GetDeviceProcAddr(device, "vkCmdSetPerformanceOverrideINTEL") + vtable.CmdSetPerformanceStreamMarkerINTEL = auto_cast GetDeviceProcAddr(device, "vkCmdSetPerformanceStreamMarkerINTEL") + vtable.CmdSetPrimitiveRestartEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetPrimitiveRestartEnable") + vtable.CmdSetPrimitiveRestartEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetPrimitiveRestartEnableEXT") + vtable.CmdSetPrimitiveTopology = auto_cast GetDeviceProcAddr(device, "vkCmdSetPrimitiveTopology") + vtable.CmdSetPrimitiveTopologyEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetPrimitiveTopologyEXT") + vtable.CmdSetRasterizerDiscardEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetRasterizerDiscardEnable") + vtable.CmdSetRasterizerDiscardEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetRasterizerDiscardEnableEXT") + vtable.CmdSetRayTracingPipelineStackSizeKHR = auto_cast GetDeviceProcAddr(device, "vkCmdSetRayTracingPipelineStackSizeKHR") + vtable.CmdSetSampleLocationsEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetSampleLocationsEXT") + vtable.CmdSetScissor = auto_cast GetDeviceProcAddr(device, "vkCmdSetScissor") + vtable.CmdSetScissorWithCount = auto_cast GetDeviceProcAddr(device, "vkCmdSetScissorWithCount") + vtable.CmdSetScissorWithCountEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetScissorWithCountEXT") + vtable.CmdSetStencilCompareMask = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilCompareMask") + vtable.CmdSetStencilOp = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilOp") + vtable.CmdSetStencilOpEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilOpEXT") + vtable.CmdSetStencilReference = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilReference") + vtable.CmdSetStencilTestEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilTestEnable") + vtable.CmdSetStencilTestEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilTestEnableEXT") + vtable.CmdSetStencilWriteMask = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilWriteMask") + vtable.CmdSetVertexInputEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetVertexInputEXT") + vtable.CmdSetViewport = auto_cast GetDeviceProcAddr(device, "vkCmdSetViewport") + vtable.CmdSetViewportShadingRatePaletteNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetViewportShadingRatePaletteNV") + vtable.CmdSetViewportWScalingNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetViewportWScalingNV") + vtable.CmdSetViewportWithCount = auto_cast GetDeviceProcAddr(device, "vkCmdSetViewportWithCount") + vtable.CmdSetViewportWithCountEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetViewportWithCountEXT") + vtable.CmdSubpassShadingHUAWEI = auto_cast GetDeviceProcAddr(device, "vkCmdSubpassShadingHUAWEI") + vtable.CmdTraceRaysIndirectKHR = auto_cast GetDeviceProcAddr(device, "vkCmdTraceRaysIndirectKHR") + vtable.CmdTraceRaysKHR = auto_cast GetDeviceProcAddr(device, "vkCmdTraceRaysKHR") + vtable.CmdTraceRaysNV = auto_cast GetDeviceProcAddr(device, "vkCmdTraceRaysNV") + vtable.CmdUpdateBuffer = auto_cast GetDeviceProcAddr(device, "vkCmdUpdateBuffer") + vtable.CmdWaitEvents = auto_cast GetDeviceProcAddr(device, "vkCmdWaitEvents") + vtable.CmdWaitEvents2 = auto_cast GetDeviceProcAddr(device, "vkCmdWaitEvents2") + vtable.CmdWaitEvents2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdWaitEvents2KHR") + vtable.CmdWriteAccelerationStructuresPropertiesKHR = auto_cast GetDeviceProcAddr(device, "vkCmdWriteAccelerationStructuresPropertiesKHR") + vtable.CmdWriteAccelerationStructuresPropertiesNV = auto_cast GetDeviceProcAddr(device, "vkCmdWriteAccelerationStructuresPropertiesNV") + vtable.CmdWriteBufferMarker2AMD = auto_cast GetDeviceProcAddr(device, "vkCmdWriteBufferMarker2AMD") + vtable.CmdWriteBufferMarkerAMD = auto_cast GetDeviceProcAddr(device, "vkCmdWriteBufferMarkerAMD") + vtable.CmdWriteTimestamp = auto_cast GetDeviceProcAddr(device, "vkCmdWriteTimestamp") + vtable.CmdWriteTimestamp2 = auto_cast GetDeviceProcAddr(device, "vkCmdWriteTimestamp2") + vtable.CmdWriteTimestamp2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdWriteTimestamp2KHR") + vtable.CompileDeferredNV = auto_cast GetDeviceProcAddr(device, "vkCompileDeferredNV") + vtable.CopyAccelerationStructureKHR = auto_cast GetDeviceProcAddr(device, "vkCopyAccelerationStructureKHR") + vtable.CopyAccelerationStructureToMemoryKHR = auto_cast GetDeviceProcAddr(device, "vkCopyAccelerationStructureToMemoryKHR") + vtable.CopyMemoryToAccelerationStructureKHR = auto_cast GetDeviceProcAddr(device, "vkCopyMemoryToAccelerationStructureKHR") + vtable.CreateAccelerationStructureKHR = auto_cast GetDeviceProcAddr(device, "vkCreateAccelerationStructureKHR") + vtable.CreateAccelerationStructureNV = auto_cast GetDeviceProcAddr(device, "vkCreateAccelerationStructureNV") + vtable.CreateBuffer = auto_cast GetDeviceProcAddr(device, "vkCreateBuffer") + vtable.CreateBufferView = auto_cast GetDeviceProcAddr(device, "vkCreateBufferView") + vtable.CreateCommandPool = auto_cast GetDeviceProcAddr(device, "vkCreateCommandPool") + vtable.CreateComputePipelines = auto_cast GetDeviceProcAddr(device, "vkCreateComputePipelines") + vtable.CreateCuFunctionNVX = auto_cast GetDeviceProcAddr(device, "vkCreateCuFunctionNVX") + vtable.CreateCuModuleNVX = auto_cast GetDeviceProcAddr(device, "vkCreateCuModuleNVX") + vtable.CreateDeferredOperationKHR = auto_cast GetDeviceProcAddr(device, "vkCreateDeferredOperationKHR") + vtable.CreateDescriptorPool = auto_cast GetDeviceProcAddr(device, "vkCreateDescriptorPool") + vtable.CreateDescriptorSetLayout = auto_cast GetDeviceProcAddr(device, "vkCreateDescriptorSetLayout") + vtable.CreateDescriptorUpdateTemplate = auto_cast GetDeviceProcAddr(device, "vkCreateDescriptorUpdateTemplate") + vtable.CreateDescriptorUpdateTemplateKHR = auto_cast GetDeviceProcAddr(device, "vkCreateDescriptorUpdateTemplateKHR") + vtable.CreateEvent = auto_cast GetDeviceProcAddr(device, "vkCreateEvent") + vtable.CreateFence = auto_cast GetDeviceProcAddr(device, "vkCreateFence") + vtable.CreateFramebuffer = auto_cast GetDeviceProcAddr(device, "vkCreateFramebuffer") + vtable.CreateGraphicsPipelines = auto_cast GetDeviceProcAddr(device, "vkCreateGraphicsPipelines") + vtable.CreateImage = auto_cast GetDeviceProcAddr(device, "vkCreateImage") + vtable.CreateImageView = auto_cast GetDeviceProcAddr(device, "vkCreateImageView") + vtable.CreateIndirectCommandsLayoutNV = auto_cast GetDeviceProcAddr(device, "vkCreateIndirectCommandsLayoutNV") + vtable.CreatePipelineCache = auto_cast GetDeviceProcAddr(device, "vkCreatePipelineCache") + vtable.CreatePipelineLayout = auto_cast GetDeviceProcAddr(device, "vkCreatePipelineLayout") + vtable.CreatePrivateDataSlot = auto_cast GetDeviceProcAddr(device, "vkCreatePrivateDataSlot") + vtable.CreatePrivateDataSlotEXT = auto_cast GetDeviceProcAddr(device, "vkCreatePrivateDataSlotEXT") + vtable.CreateQueryPool = auto_cast GetDeviceProcAddr(device, "vkCreateQueryPool") + vtable.CreateRayTracingPipelinesKHR = auto_cast GetDeviceProcAddr(device, "vkCreateRayTracingPipelinesKHR") + vtable.CreateRayTracingPipelinesNV = auto_cast GetDeviceProcAddr(device, "vkCreateRayTracingPipelinesNV") + vtable.CreateRenderPass = auto_cast GetDeviceProcAddr(device, "vkCreateRenderPass") + vtable.CreateRenderPass2 = auto_cast GetDeviceProcAddr(device, "vkCreateRenderPass2") + vtable.CreateRenderPass2KHR = auto_cast GetDeviceProcAddr(device, "vkCreateRenderPass2KHR") + vtable.CreateSampler = auto_cast GetDeviceProcAddr(device, "vkCreateSampler") + vtable.CreateSamplerYcbcrConversion = auto_cast GetDeviceProcAddr(device, "vkCreateSamplerYcbcrConversion") + vtable.CreateSamplerYcbcrConversionKHR = auto_cast GetDeviceProcAddr(device, "vkCreateSamplerYcbcrConversionKHR") + vtable.CreateSemaphore = auto_cast GetDeviceProcAddr(device, "vkCreateSemaphore") + vtable.CreateShaderModule = auto_cast GetDeviceProcAddr(device, "vkCreateShaderModule") + vtable.CreateSharedSwapchainsKHR = auto_cast GetDeviceProcAddr(device, "vkCreateSharedSwapchainsKHR") + vtable.CreateSwapchainKHR = auto_cast GetDeviceProcAddr(device, "vkCreateSwapchainKHR") + vtable.CreateValidationCacheEXT = auto_cast GetDeviceProcAddr(device, "vkCreateValidationCacheEXT") + vtable.DebugMarkerSetObjectNameEXT = auto_cast GetDeviceProcAddr(device, "vkDebugMarkerSetObjectNameEXT") + vtable.DebugMarkerSetObjectTagEXT = auto_cast GetDeviceProcAddr(device, "vkDebugMarkerSetObjectTagEXT") + vtable.DeferredOperationJoinKHR = auto_cast GetDeviceProcAddr(device, "vkDeferredOperationJoinKHR") + vtable.DestroyAccelerationStructureKHR = auto_cast GetDeviceProcAddr(device, "vkDestroyAccelerationStructureKHR") + vtable.DestroyAccelerationStructureNV = auto_cast GetDeviceProcAddr(device, "vkDestroyAccelerationStructureNV") + vtable.DestroyBuffer = auto_cast GetDeviceProcAddr(device, "vkDestroyBuffer") + vtable.DestroyBufferView = auto_cast GetDeviceProcAddr(device, "vkDestroyBufferView") + vtable.DestroyCommandPool = auto_cast GetDeviceProcAddr(device, "vkDestroyCommandPool") + vtable.DestroyCuFunctionNVX = auto_cast GetDeviceProcAddr(device, "vkDestroyCuFunctionNVX") + vtable.DestroyCuModuleNVX = auto_cast GetDeviceProcAddr(device, "vkDestroyCuModuleNVX") + vtable.DestroyDeferredOperationKHR = auto_cast GetDeviceProcAddr(device, "vkDestroyDeferredOperationKHR") + vtable.DestroyDescriptorPool = auto_cast GetDeviceProcAddr(device, "vkDestroyDescriptorPool") + vtable.DestroyDescriptorSetLayout = auto_cast GetDeviceProcAddr(device, "vkDestroyDescriptorSetLayout") + vtable.DestroyDescriptorUpdateTemplate = auto_cast GetDeviceProcAddr(device, "vkDestroyDescriptorUpdateTemplate") + vtable.DestroyDescriptorUpdateTemplateKHR = auto_cast GetDeviceProcAddr(device, "vkDestroyDescriptorUpdateTemplateKHR") + vtable.DestroyDevice = auto_cast GetDeviceProcAddr(device, "vkDestroyDevice") + vtable.DestroyEvent = auto_cast GetDeviceProcAddr(device, "vkDestroyEvent") + vtable.DestroyFence = auto_cast GetDeviceProcAddr(device, "vkDestroyFence") + vtable.DestroyFramebuffer = auto_cast GetDeviceProcAddr(device, "vkDestroyFramebuffer") + vtable.DestroyImage = auto_cast GetDeviceProcAddr(device, "vkDestroyImage") + vtable.DestroyImageView = auto_cast GetDeviceProcAddr(device, "vkDestroyImageView") + vtable.DestroyIndirectCommandsLayoutNV = auto_cast GetDeviceProcAddr(device, "vkDestroyIndirectCommandsLayoutNV") + vtable.DestroyPipeline = auto_cast GetDeviceProcAddr(device, "vkDestroyPipeline") + vtable.DestroyPipelineCache = auto_cast GetDeviceProcAddr(device, "vkDestroyPipelineCache") + vtable.DestroyPipelineLayout = auto_cast GetDeviceProcAddr(device, "vkDestroyPipelineLayout") + vtable.DestroyPrivateDataSlot = auto_cast GetDeviceProcAddr(device, "vkDestroyPrivateDataSlot") + vtable.DestroyPrivateDataSlotEXT = auto_cast GetDeviceProcAddr(device, "vkDestroyPrivateDataSlotEXT") + vtable.DestroyQueryPool = auto_cast GetDeviceProcAddr(device, "vkDestroyQueryPool") + vtable.DestroyRenderPass = auto_cast GetDeviceProcAddr(device, "vkDestroyRenderPass") + vtable.DestroySampler = auto_cast GetDeviceProcAddr(device, "vkDestroySampler") + vtable.DestroySamplerYcbcrConversion = auto_cast GetDeviceProcAddr(device, "vkDestroySamplerYcbcrConversion") + vtable.DestroySamplerYcbcrConversionKHR = auto_cast GetDeviceProcAddr(device, "vkDestroySamplerYcbcrConversionKHR") + vtable.DestroySemaphore = auto_cast GetDeviceProcAddr(device, "vkDestroySemaphore") + vtable.DestroyShaderModule = auto_cast GetDeviceProcAddr(device, "vkDestroyShaderModule") + vtable.DestroySwapchainKHR = auto_cast GetDeviceProcAddr(device, "vkDestroySwapchainKHR") + vtable.DestroyValidationCacheEXT = auto_cast GetDeviceProcAddr(device, "vkDestroyValidationCacheEXT") + vtable.DeviceWaitIdle = auto_cast GetDeviceProcAddr(device, "vkDeviceWaitIdle") + vtable.DisplayPowerControlEXT = auto_cast GetDeviceProcAddr(device, "vkDisplayPowerControlEXT") + vtable.EndCommandBuffer = auto_cast GetDeviceProcAddr(device, "vkEndCommandBuffer") + vtable.FlushMappedMemoryRanges = auto_cast GetDeviceProcAddr(device, "vkFlushMappedMemoryRanges") + vtable.FreeCommandBuffers = auto_cast GetDeviceProcAddr(device, "vkFreeCommandBuffers") + vtable.FreeDescriptorSets = auto_cast GetDeviceProcAddr(device, "vkFreeDescriptorSets") + vtable.FreeMemory = auto_cast GetDeviceProcAddr(device, "vkFreeMemory") + vtable.GetAccelerationStructureBuildSizesKHR = auto_cast GetDeviceProcAddr(device, "vkGetAccelerationStructureBuildSizesKHR") + vtable.GetAccelerationStructureDeviceAddressKHR = auto_cast GetDeviceProcAddr(device, "vkGetAccelerationStructureDeviceAddressKHR") + vtable.GetAccelerationStructureHandleNV = auto_cast GetDeviceProcAddr(device, "vkGetAccelerationStructureHandleNV") + vtable.GetAccelerationStructureMemoryRequirementsNV = auto_cast GetDeviceProcAddr(device, "vkGetAccelerationStructureMemoryRequirementsNV") + vtable.GetBufferDeviceAddress = auto_cast GetDeviceProcAddr(device, "vkGetBufferDeviceAddress") + vtable.GetBufferDeviceAddressEXT = auto_cast GetDeviceProcAddr(device, "vkGetBufferDeviceAddressEXT") + vtable.GetBufferDeviceAddressKHR = auto_cast GetDeviceProcAddr(device, "vkGetBufferDeviceAddressKHR") + vtable.GetBufferMemoryRequirements = auto_cast GetDeviceProcAddr(device, "vkGetBufferMemoryRequirements") + vtable.GetBufferMemoryRequirements2 = auto_cast GetDeviceProcAddr(device, "vkGetBufferMemoryRequirements2") + vtable.GetBufferMemoryRequirements2KHR = auto_cast GetDeviceProcAddr(device, "vkGetBufferMemoryRequirements2KHR") + vtable.GetBufferOpaqueCaptureAddress = auto_cast GetDeviceProcAddr(device, "vkGetBufferOpaqueCaptureAddress") + vtable.GetBufferOpaqueCaptureAddressKHR = auto_cast GetDeviceProcAddr(device, "vkGetBufferOpaqueCaptureAddressKHR") + vtable.GetCalibratedTimestampsEXT = auto_cast GetDeviceProcAddr(device, "vkGetCalibratedTimestampsEXT") + vtable.GetDeferredOperationMaxConcurrencyKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeferredOperationMaxConcurrencyKHR") + vtable.GetDeferredOperationResultKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeferredOperationResultKHR") + vtable.GetDescriptorSetHostMappingVALVE = auto_cast GetDeviceProcAddr(device, "vkGetDescriptorSetHostMappingVALVE") + vtable.GetDescriptorSetLayoutHostMappingInfoVALVE = auto_cast GetDeviceProcAddr(device, "vkGetDescriptorSetLayoutHostMappingInfoVALVE") + vtable.GetDescriptorSetLayoutSupport = auto_cast GetDeviceProcAddr(device, "vkGetDescriptorSetLayoutSupport") + vtable.GetDescriptorSetLayoutSupportKHR = auto_cast GetDeviceProcAddr(device, "vkGetDescriptorSetLayoutSupportKHR") + vtable.GetDeviceAccelerationStructureCompatibilityKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceAccelerationStructureCompatibilityKHR") + vtable.GetDeviceBufferMemoryRequirements = auto_cast GetDeviceProcAddr(device, "vkGetDeviceBufferMemoryRequirements") + vtable.GetDeviceBufferMemoryRequirementsKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceBufferMemoryRequirementsKHR") + vtable.GetDeviceGroupPeerMemoryFeatures = auto_cast GetDeviceProcAddr(device, "vkGetDeviceGroupPeerMemoryFeatures") + vtable.GetDeviceGroupPeerMemoryFeaturesKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceGroupPeerMemoryFeaturesKHR") + vtable.GetDeviceGroupPresentCapabilitiesKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceGroupPresentCapabilitiesKHR") + vtable.GetDeviceGroupSurfacePresentModes2EXT = auto_cast GetDeviceProcAddr(device, "vkGetDeviceGroupSurfacePresentModes2EXT") + vtable.GetDeviceGroupSurfacePresentModesKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceGroupSurfacePresentModesKHR") + vtable.GetDeviceImageMemoryRequirements = auto_cast GetDeviceProcAddr(device, "vkGetDeviceImageMemoryRequirements") + vtable.GetDeviceImageMemoryRequirementsKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceImageMemoryRequirementsKHR") + vtable.GetDeviceImageSparseMemoryRequirements = auto_cast GetDeviceProcAddr(device, "vkGetDeviceImageSparseMemoryRequirements") + vtable.GetDeviceImageSparseMemoryRequirementsKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceImageSparseMemoryRequirementsKHR") + vtable.GetDeviceMemoryCommitment = auto_cast GetDeviceProcAddr(device, "vkGetDeviceMemoryCommitment") + vtable.GetDeviceMemoryOpaqueCaptureAddress = auto_cast GetDeviceProcAddr(device, "vkGetDeviceMemoryOpaqueCaptureAddress") + vtable.GetDeviceMemoryOpaqueCaptureAddressKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceMemoryOpaqueCaptureAddressKHR") + vtable.GetDeviceProcAddr = auto_cast GetDeviceProcAddr(device, "vkGetDeviceProcAddr") + vtable.GetDeviceQueue = auto_cast GetDeviceProcAddr(device, "vkGetDeviceQueue") + vtable.GetDeviceQueue2 = auto_cast GetDeviceProcAddr(device, "vkGetDeviceQueue2") + vtable.GetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI = auto_cast GetDeviceProcAddr(device, "vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI") + vtable.GetEventStatus = auto_cast GetDeviceProcAddr(device, "vkGetEventStatus") + vtable.GetFenceFdKHR = auto_cast GetDeviceProcAddr(device, "vkGetFenceFdKHR") + vtable.GetFenceStatus = auto_cast GetDeviceProcAddr(device, "vkGetFenceStatus") + vtable.GetFenceWin32HandleKHR = auto_cast GetDeviceProcAddr(device, "vkGetFenceWin32HandleKHR") + vtable.GetGeneratedCommandsMemoryRequirementsNV = auto_cast GetDeviceProcAddr(device, "vkGetGeneratedCommandsMemoryRequirementsNV") + vtable.GetImageDrmFormatModifierPropertiesEXT = auto_cast GetDeviceProcAddr(device, "vkGetImageDrmFormatModifierPropertiesEXT") + vtable.GetImageMemoryRequirements = auto_cast GetDeviceProcAddr(device, "vkGetImageMemoryRequirements") + vtable.GetImageMemoryRequirements2 = auto_cast GetDeviceProcAddr(device, "vkGetImageMemoryRequirements2") + vtable.GetImageMemoryRequirements2KHR = auto_cast GetDeviceProcAddr(device, "vkGetImageMemoryRequirements2KHR") + vtable.GetImageSparseMemoryRequirements = auto_cast GetDeviceProcAddr(device, "vkGetImageSparseMemoryRequirements") + vtable.GetImageSparseMemoryRequirements2 = auto_cast GetDeviceProcAddr(device, "vkGetImageSparseMemoryRequirements2") + vtable.GetImageSparseMemoryRequirements2KHR = auto_cast GetDeviceProcAddr(device, "vkGetImageSparseMemoryRequirements2KHR") + vtable.GetImageSubresourceLayout = auto_cast GetDeviceProcAddr(device, "vkGetImageSubresourceLayout") + vtable.GetImageViewAddressNVX = auto_cast GetDeviceProcAddr(device, "vkGetImageViewAddressNVX") + vtable.GetImageViewHandleNVX = auto_cast GetDeviceProcAddr(device, "vkGetImageViewHandleNVX") + vtable.GetMemoryFdKHR = auto_cast GetDeviceProcAddr(device, "vkGetMemoryFdKHR") + vtable.GetMemoryFdPropertiesKHR = auto_cast GetDeviceProcAddr(device, "vkGetMemoryFdPropertiesKHR") + vtable.GetMemoryHostPointerPropertiesEXT = auto_cast GetDeviceProcAddr(device, "vkGetMemoryHostPointerPropertiesEXT") + vtable.GetMemoryRemoteAddressNV = auto_cast GetDeviceProcAddr(device, "vkGetMemoryRemoteAddressNV") + vtable.GetMemoryWin32HandleKHR = auto_cast GetDeviceProcAddr(device, "vkGetMemoryWin32HandleKHR") + vtable.GetMemoryWin32HandleNV = auto_cast GetDeviceProcAddr(device, "vkGetMemoryWin32HandleNV") + vtable.GetMemoryWin32HandlePropertiesKHR = auto_cast GetDeviceProcAddr(device, "vkGetMemoryWin32HandlePropertiesKHR") + vtable.GetPastPresentationTimingGOOGLE = auto_cast GetDeviceProcAddr(device, "vkGetPastPresentationTimingGOOGLE") + vtable.GetPerformanceParameterINTEL = auto_cast GetDeviceProcAddr(device, "vkGetPerformanceParameterINTEL") + vtable.GetPipelineCacheData = auto_cast GetDeviceProcAddr(device, "vkGetPipelineCacheData") + vtable.GetPipelineExecutableInternalRepresentationsKHR = auto_cast GetDeviceProcAddr(device, "vkGetPipelineExecutableInternalRepresentationsKHR") + vtable.GetPipelineExecutablePropertiesKHR = auto_cast GetDeviceProcAddr(device, "vkGetPipelineExecutablePropertiesKHR") + vtable.GetPipelineExecutableStatisticsKHR = auto_cast GetDeviceProcAddr(device, "vkGetPipelineExecutableStatisticsKHR") + vtable.GetPrivateData = auto_cast GetDeviceProcAddr(device, "vkGetPrivateData") + vtable.GetPrivateDataEXT = auto_cast GetDeviceProcAddr(device, "vkGetPrivateDataEXT") + vtable.GetQueryPoolResults = auto_cast GetDeviceProcAddr(device, "vkGetQueryPoolResults") + vtable.GetQueueCheckpointData2NV = auto_cast GetDeviceProcAddr(device, "vkGetQueueCheckpointData2NV") + vtable.GetQueueCheckpointDataNV = auto_cast GetDeviceProcAddr(device, "vkGetQueueCheckpointDataNV") + vtable.GetRayTracingCaptureReplayShaderGroupHandlesKHR = auto_cast GetDeviceProcAddr(device, "vkGetRayTracingCaptureReplayShaderGroupHandlesKHR") + vtable.GetRayTracingShaderGroupHandlesKHR = auto_cast GetDeviceProcAddr(device, "vkGetRayTracingShaderGroupHandlesKHR") + vtable.GetRayTracingShaderGroupHandlesNV = auto_cast GetDeviceProcAddr(device, "vkGetRayTracingShaderGroupHandlesNV") + vtable.GetRayTracingShaderGroupStackSizeKHR = auto_cast GetDeviceProcAddr(device, "vkGetRayTracingShaderGroupStackSizeKHR") + vtable.GetRefreshCycleDurationGOOGLE = auto_cast GetDeviceProcAddr(device, "vkGetRefreshCycleDurationGOOGLE") + vtable.GetRenderAreaGranularity = auto_cast GetDeviceProcAddr(device, "vkGetRenderAreaGranularity") + vtable.GetSemaphoreCounterValue = auto_cast GetDeviceProcAddr(device, "vkGetSemaphoreCounterValue") + vtable.GetSemaphoreCounterValueKHR = auto_cast GetDeviceProcAddr(device, "vkGetSemaphoreCounterValueKHR") + vtable.GetSemaphoreFdKHR = auto_cast GetDeviceProcAddr(device, "vkGetSemaphoreFdKHR") + vtable.GetSemaphoreWin32HandleKHR = auto_cast GetDeviceProcAddr(device, "vkGetSemaphoreWin32HandleKHR") + vtable.GetShaderInfoAMD = auto_cast GetDeviceProcAddr(device, "vkGetShaderInfoAMD") + vtable.GetSwapchainCounterEXT = auto_cast GetDeviceProcAddr(device, "vkGetSwapchainCounterEXT") + vtable.GetSwapchainImagesKHR = auto_cast GetDeviceProcAddr(device, "vkGetSwapchainImagesKHR") + vtable.GetSwapchainStatusKHR = auto_cast GetDeviceProcAddr(device, "vkGetSwapchainStatusKHR") + vtable.GetValidationCacheDataEXT = auto_cast GetDeviceProcAddr(device, "vkGetValidationCacheDataEXT") + vtable.ImportFenceFdKHR = auto_cast GetDeviceProcAddr(device, "vkImportFenceFdKHR") + vtable.ImportFenceWin32HandleKHR = auto_cast GetDeviceProcAddr(device, "vkImportFenceWin32HandleKHR") + vtable.ImportSemaphoreFdKHR = auto_cast GetDeviceProcAddr(device, "vkImportSemaphoreFdKHR") + vtable.ImportSemaphoreWin32HandleKHR = auto_cast GetDeviceProcAddr(device, "vkImportSemaphoreWin32HandleKHR") + vtable.InitializePerformanceApiINTEL = auto_cast GetDeviceProcAddr(device, "vkInitializePerformanceApiINTEL") + vtable.InvalidateMappedMemoryRanges = auto_cast GetDeviceProcAddr(device, "vkInvalidateMappedMemoryRanges") + vtable.MapMemory = auto_cast GetDeviceProcAddr(device, "vkMapMemory") + vtable.MergePipelineCaches = auto_cast GetDeviceProcAddr(device, "vkMergePipelineCaches") + vtable.MergeValidationCachesEXT = auto_cast GetDeviceProcAddr(device, "vkMergeValidationCachesEXT") + vtable.QueueBeginDebugUtilsLabelEXT = auto_cast GetDeviceProcAddr(device, "vkQueueBeginDebugUtilsLabelEXT") + vtable.QueueBindSparse = auto_cast GetDeviceProcAddr(device, "vkQueueBindSparse") + vtable.QueueEndDebugUtilsLabelEXT = auto_cast GetDeviceProcAddr(device, "vkQueueEndDebugUtilsLabelEXT") + vtable.QueueInsertDebugUtilsLabelEXT = auto_cast GetDeviceProcAddr(device, "vkQueueInsertDebugUtilsLabelEXT") + vtable.QueuePresentKHR = auto_cast GetDeviceProcAddr(device, "vkQueuePresentKHR") + vtable.QueueSetPerformanceConfigurationINTEL = auto_cast GetDeviceProcAddr(device, "vkQueueSetPerformanceConfigurationINTEL") + vtable.QueueSubmit = auto_cast GetDeviceProcAddr(device, "vkQueueSubmit") + vtable.QueueSubmit2 = auto_cast GetDeviceProcAddr(device, "vkQueueSubmit2") + vtable.QueueSubmit2KHR = auto_cast GetDeviceProcAddr(device, "vkQueueSubmit2KHR") + vtable.QueueWaitIdle = auto_cast GetDeviceProcAddr(device, "vkQueueWaitIdle") + vtable.RegisterDeviceEventEXT = auto_cast GetDeviceProcAddr(device, "vkRegisterDeviceEventEXT") + vtable.RegisterDisplayEventEXT = auto_cast GetDeviceProcAddr(device, "vkRegisterDisplayEventEXT") + vtable.ReleaseFullScreenExclusiveModeEXT = auto_cast GetDeviceProcAddr(device, "vkReleaseFullScreenExclusiveModeEXT") + vtable.ReleasePerformanceConfigurationINTEL = auto_cast GetDeviceProcAddr(device, "vkReleasePerformanceConfigurationINTEL") + vtable.ReleaseProfilingLockKHR = auto_cast GetDeviceProcAddr(device, "vkReleaseProfilingLockKHR") + vtable.ResetCommandBuffer = auto_cast GetDeviceProcAddr(device, "vkResetCommandBuffer") + vtable.ResetCommandPool = auto_cast GetDeviceProcAddr(device, "vkResetCommandPool") + vtable.ResetDescriptorPool = auto_cast GetDeviceProcAddr(device, "vkResetDescriptorPool") + vtable.ResetEvent = auto_cast GetDeviceProcAddr(device, "vkResetEvent") + vtable.ResetFences = auto_cast GetDeviceProcAddr(device, "vkResetFences") + vtable.ResetQueryPool = auto_cast GetDeviceProcAddr(device, "vkResetQueryPool") + vtable.ResetQueryPoolEXT = auto_cast GetDeviceProcAddr(device, "vkResetQueryPoolEXT") + vtable.SetDebugUtilsObjectNameEXT = auto_cast GetDeviceProcAddr(device, "vkSetDebugUtilsObjectNameEXT") + vtable.SetDebugUtilsObjectTagEXT = auto_cast GetDeviceProcAddr(device, "vkSetDebugUtilsObjectTagEXT") + vtable.SetDeviceMemoryPriorityEXT = auto_cast GetDeviceProcAddr(device, "vkSetDeviceMemoryPriorityEXT") + vtable.SetEvent = auto_cast GetDeviceProcAddr(device, "vkSetEvent") + vtable.SetHdrMetadataEXT = auto_cast GetDeviceProcAddr(device, "vkSetHdrMetadataEXT") + vtable.SetLocalDimmingAMD = auto_cast GetDeviceProcAddr(device, "vkSetLocalDimmingAMD") + vtable.SetPrivateData = auto_cast GetDeviceProcAddr(device, "vkSetPrivateData") + vtable.SetPrivateDataEXT = auto_cast GetDeviceProcAddr(device, "vkSetPrivateDataEXT") + vtable.SignalSemaphore = auto_cast GetDeviceProcAddr(device, "vkSignalSemaphore") + vtable.SignalSemaphoreKHR = auto_cast GetDeviceProcAddr(device, "vkSignalSemaphoreKHR") + vtable.TrimCommandPool = auto_cast GetDeviceProcAddr(device, "vkTrimCommandPool") + vtable.TrimCommandPoolKHR = auto_cast GetDeviceProcAddr(device, "vkTrimCommandPoolKHR") + vtable.UninitializePerformanceApiINTEL = auto_cast GetDeviceProcAddr(device, "vkUninitializePerformanceApiINTEL") + vtable.UnmapMemory = auto_cast GetDeviceProcAddr(device, "vkUnmapMemory") + vtable.UpdateDescriptorSetWithTemplate = auto_cast GetDeviceProcAddr(device, "vkUpdateDescriptorSetWithTemplate") + vtable.UpdateDescriptorSetWithTemplateKHR = auto_cast GetDeviceProcAddr(device, "vkUpdateDescriptorSetWithTemplateKHR") + vtable.UpdateDescriptorSets = auto_cast GetDeviceProcAddr(device, "vkUpdateDescriptorSets") + vtable.WaitForFences = auto_cast GetDeviceProcAddr(device, "vkWaitForFences") + vtable.WaitForPresentKHR = auto_cast GetDeviceProcAddr(device, "vkWaitForPresentKHR") + vtable.WaitSemaphores = auto_cast GetDeviceProcAddr(device, "vkWaitSemaphores") + vtable.WaitSemaphoresKHR = auto_cast GetDeviceProcAddr(device, "vkWaitSemaphoresKHR") + vtable.WriteAccelerationStructuresPropertiesKHR = auto_cast GetDeviceProcAddr(device, "vkWriteAccelerationStructuresPropertiesKHR") +} + +load_proc_addresses_device :: proc(device: Device) { + AcquireFullScreenExclusiveModeEXT = auto_cast GetDeviceProcAddr(device, "vkAcquireFullScreenExclusiveModeEXT") + AcquireNextImage2KHR = auto_cast GetDeviceProcAddr(device, "vkAcquireNextImage2KHR") + AcquireNextImageKHR = auto_cast GetDeviceProcAddr(device, "vkAcquireNextImageKHR") + AcquirePerformanceConfigurationINTEL = auto_cast GetDeviceProcAddr(device, "vkAcquirePerformanceConfigurationINTEL") + AcquireProfilingLockKHR = auto_cast GetDeviceProcAddr(device, "vkAcquireProfilingLockKHR") + AllocateCommandBuffers = auto_cast GetDeviceProcAddr(device, "vkAllocateCommandBuffers") + AllocateDescriptorSets = auto_cast GetDeviceProcAddr(device, "vkAllocateDescriptorSets") + AllocateMemory = auto_cast GetDeviceProcAddr(device, "vkAllocateMemory") + BeginCommandBuffer = auto_cast GetDeviceProcAddr(device, "vkBeginCommandBuffer") + BindAccelerationStructureMemoryNV = auto_cast GetDeviceProcAddr(device, "vkBindAccelerationStructureMemoryNV") + BindBufferMemory = auto_cast GetDeviceProcAddr(device, "vkBindBufferMemory") + BindBufferMemory2 = auto_cast GetDeviceProcAddr(device, "vkBindBufferMemory2") + BindBufferMemory2KHR = auto_cast GetDeviceProcAddr(device, "vkBindBufferMemory2KHR") + BindImageMemory = auto_cast GetDeviceProcAddr(device, "vkBindImageMemory") + BindImageMemory2 = auto_cast GetDeviceProcAddr(device, "vkBindImageMemory2") + BindImageMemory2KHR = auto_cast GetDeviceProcAddr(device, "vkBindImageMemory2KHR") + BuildAccelerationStructuresKHR = auto_cast GetDeviceProcAddr(device, "vkBuildAccelerationStructuresKHR") + CmdBeginConditionalRenderingEXT = auto_cast GetDeviceProcAddr(device, "vkCmdBeginConditionalRenderingEXT") + CmdBeginDebugUtilsLabelEXT = auto_cast GetDeviceProcAddr(device, "vkCmdBeginDebugUtilsLabelEXT") + CmdBeginQuery = auto_cast GetDeviceProcAddr(device, "vkCmdBeginQuery") + CmdBeginQueryIndexedEXT = auto_cast GetDeviceProcAddr(device, "vkCmdBeginQueryIndexedEXT") + CmdBeginRenderPass = auto_cast GetDeviceProcAddr(device, "vkCmdBeginRenderPass") + CmdBeginRenderPass2 = auto_cast GetDeviceProcAddr(device, "vkCmdBeginRenderPass2") + CmdBeginRenderPass2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdBeginRenderPass2KHR") + CmdBeginRendering = auto_cast GetDeviceProcAddr(device, "vkCmdBeginRendering") + CmdBeginRenderingKHR = auto_cast GetDeviceProcAddr(device, "vkCmdBeginRenderingKHR") + CmdBeginTransformFeedbackEXT = auto_cast GetDeviceProcAddr(device, "vkCmdBeginTransformFeedbackEXT") + CmdBindDescriptorSets = auto_cast GetDeviceProcAddr(device, "vkCmdBindDescriptorSets") + CmdBindIndexBuffer = auto_cast GetDeviceProcAddr(device, "vkCmdBindIndexBuffer") + CmdBindInvocationMaskHUAWEI = auto_cast GetDeviceProcAddr(device, "vkCmdBindInvocationMaskHUAWEI") + CmdBindPipeline = auto_cast GetDeviceProcAddr(device, "vkCmdBindPipeline") + CmdBindPipelineShaderGroupNV = auto_cast GetDeviceProcAddr(device, "vkCmdBindPipelineShaderGroupNV") + CmdBindShadingRateImageNV = auto_cast GetDeviceProcAddr(device, "vkCmdBindShadingRateImageNV") + CmdBindTransformFeedbackBuffersEXT = auto_cast GetDeviceProcAddr(device, "vkCmdBindTransformFeedbackBuffersEXT") + CmdBindVertexBuffers = auto_cast GetDeviceProcAddr(device, "vkCmdBindVertexBuffers") + CmdBindVertexBuffers2 = auto_cast GetDeviceProcAddr(device, "vkCmdBindVertexBuffers2") + CmdBindVertexBuffers2EXT = auto_cast GetDeviceProcAddr(device, "vkCmdBindVertexBuffers2EXT") + CmdBlitImage = auto_cast GetDeviceProcAddr(device, "vkCmdBlitImage") + CmdBlitImage2 = auto_cast GetDeviceProcAddr(device, "vkCmdBlitImage2") + CmdBlitImage2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdBlitImage2KHR") + CmdBuildAccelerationStructureNV = auto_cast GetDeviceProcAddr(device, "vkCmdBuildAccelerationStructureNV") + CmdBuildAccelerationStructuresIndirectKHR = auto_cast GetDeviceProcAddr(device, "vkCmdBuildAccelerationStructuresIndirectKHR") + CmdBuildAccelerationStructuresKHR = auto_cast GetDeviceProcAddr(device, "vkCmdBuildAccelerationStructuresKHR") + CmdClearAttachments = auto_cast GetDeviceProcAddr(device, "vkCmdClearAttachments") + CmdClearColorImage = auto_cast GetDeviceProcAddr(device, "vkCmdClearColorImage") + CmdClearDepthStencilImage = auto_cast GetDeviceProcAddr(device, "vkCmdClearDepthStencilImage") + CmdCopyAccelerationStructureKHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyAccelerationStructureKHR") + CmdCopyAccelerationStructureNV = auto_cast GetDeviceProcAddr(device, "vkCmdCopyAccelerationStructureNV") + CmdCopyAccelerationStructureToMemoryKHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyAccelerationStructureToMemoryKHR") + CmdCopyBuffer = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBuffer") + CmdCopyBuffer2 = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBuffer2") + CmdCopyBuffer2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBuffer2KHR") + CmdCopyBufferToImage = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBufferToImage") + CmdCopyBufferToImage2 = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBufferToImage2") + CmdCopyBufferToImage2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyBufferToImage2KHR") + CmdCopyImage = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImage") + CmdCopyImage2 = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImage2") + CmdCopyImage2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImage2KHR") + CmdCopyImageToBuffer = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImageToBuffer") + CmdCopyImageToBuffer2 = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImageToBuffer2") + CmdCopyImageToBuffer2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyImageToBuffer2KHR") + CmdCopyMemoryToAccelerationStructureKHR = auto_cast GetDeviceProcAddr(device, "vkCmdCopyMemoryToAccelerationStructureKHR") + CmdCopyQueryPoolResults = auto_cast GetDeviceProcAddr(device, "vkCmdCopyQueryPoolResults") + CmdCuLaunchKernelNVX = auto_cast GetDeviceProcAddr(device, "vkCmdCuLaunchKernelNVX") + CmdDebugMarkerBeginEXT = auto_cast GetDeviceProcAddr(device, "vkCmdDebugMarkerBeginEXT") + CmdDebugMarkerEndEXT = auto_cast GetDeviceProcAddr(device, "vkCmdDebugMarkerEndEXT") + CmdDebugMarkerInsertEXT = auto_cast GetDeviceProcAddr(device, "vkCmdDebugMarkerInsertEXT") + CmdDispatch = auto_cast GetDeviceProcAddr(device, "vkCmdDispatch") + CmdDispatchBase = auto_cast GetDeviceProcAddr(device, "vkCmdDispatchBase") + CmdDispatchBaseKHR = auto_cast GetDeviceProcAddr(device, "vkCmdDispatchBaseKHR") + CmdDispatchIndirect = auto_cast GetDeviceProcAddr(device, "vkCmdDispatchIndirect") + CmdDraw = auto_cast GetDeviceProcAddr(device, "vkCmdDraw") + CmdDrawIndexed = auto_cast GetDeviceProcAddr(device, "vkCmdDrawIndexed") + CmdDrawIndexedIndirect = auto_cast GetDeviceProcAddr(device, "vkCmdDrawIndexedIndirect") + CmdDrawIndexedIndirectCount = auto_cast GetDeviceProcAddr(device, "vkCmdDrawIndexedIndirectCount") + CmdDrawIndexedIndirectCountAMD = auto_cast GetDeviceProcAddr(device, "vkCmdDrawIndexedIndirectCountAMD") + CmdDrawIndexedIndirectCountKHR = auto_cast GetDeviceProcAddr(device, "vkCmdDrawIndexedIndirectCountKHR") + CmdDrawIndirect = auto_cast GetDeviceProcAddr(device, "vkCmdDrawIndirect") + CmdDrawIndirectByteCountEXT = auto_cast GetDeviceProcAddr(device, "vkCmdDrawIndirectByteCountEXT") + CmdDrawIndirectCount = auto_cast GetDeviceProcAddr(device, "vkCmdDrawIndirectCount") + CmdDrawIndirectCountAMD = auto_cast GetDeviceProcAddr(device, "vkCmdDrawIndirectCountAMD") + CmdDrawIndirectCountKHR = auto_cast GetDeviceProcAddr(device, "vkCmdDrawIndirectCountKHR") + CmdDrawMeshTasksIndirectCountNV = auto_cast GetDeviceProcAddr(device, "vkCmdDrawMeshTasksIndirectCountNV") + CmdDrawMeshTasksIndirectNV = auto_cast GetDeviceProcAddr(device, "vkCmdDrawMeshTasksIndirectNV") + CmdDrawMeshTasksNV = auto_cast GetDeviceProcAddr(device, "vkCmdDrawMeshTasksNV") + CmdDrawMultiEXT = auto_cast GetDeviceProcAddr(device, "vkCmdDrawMultiEXT") + CmdDrawMultiIndexedEXT = auto_cast GetDeviceProcAddr(device, "vkCmdDrawMultiIndexedEXT") + CmdEndConditionalRenderingEXT = auto_cast GetDeviceProcAddr(device, "vkCmdEndConditionalRenderingEXT") + CmdEndDebugUtilsLabelEXT = auto_cast GetDeviceProcAddr(device, "vkCmdEndDebugUtilsLabelEXT") + CmdEndQuery = auto_cast GetDeviceProcAddr(device, "vkCmdEndQuery") + CmdEndQueryIndexedEXT = auto_cast GetDeviceProcAddr(device, "vkCmdEndQueryIndexedEXT") + CmdEndRenderPass = auto_cast GetDeviceProcAddr(device, "vkCmdEndRenderPass") + CmdEndRenderPass2 = auto_cast GetDeviceProcAddr(device, "vkCmdEndRenderPass2") + CmdEndRenderPass2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdEndRenderPass2KHR") + CmdEndRendering = auto_cast GetDeviceProcAddr(device, "vkCmdEndRendering") + CmdEndRenderingKHR = auto_cast GetDeviceProcAddr(device, "vkCmdEndRenderingKHR") + CmdEndTransformFeedbackEXT = auto_cast GetDeviceProcAddr(device, "vkCmdEndTransformFeedbackEXT") + CmdExecuteCommands = auto_cast GetDeviceProcAddr(device, "vkCmdExecuteCommands") + CmdExecuteGeneratedCommandsNV = auto_cast GetDeviceProcAddr(device, "vkCmdExecuteGeneratedCommandsNV") + CmdFillBuffer = auto_cast GetDeviceProcAddr(device, "vkCmdFillBuffer") + CmdInsertDebugUtilsLabelEXT = auto_cast GetDeviceProcAddr(device, "vkCmdInsertDebugUtilsLabelEXT") + CmdNextSubpass = auto_cast GetDeviceProcAddr(device, "vkCmdNextSubpass") + CmdNextSubpass2 = auto_cast GetDeviceProcAddr(device, "vkCmdNextSubpass2") + CmdNextSubpass2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdNextSubpass2KHR") + CmdPipelineBarrier = auto_cast GetDeviceProcAddr(device, "vkCmdPipelineBarrier") + CmdPipelineBarrier2 = auto_cast GetDeviceProcAddr(device, "vkCmdPipelineBarrier2") + CmdPipelineBarrier2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdPipelineBarrier2KHR") + CmdPreprocessGeneratedCommandsNV = auto_cast GetDeviceProcAddr(device, "vkCmdPreprocessGeneratedCommandsNV") + CmdPushConstants = auto_cast GetDeviceProcAddr(device, "vkCmdPushConstants") + CmdPushDescriptorSetKHR = auto_cast GetDeviceProcAddr(device, "vkCmdPushDescriptorSetKHR") + CmdPushDescriptorSetWithTemplateKHR = auto_cast GetDeviceProcAddr(device, "vkCmdPushDescriptorSetWithTemplateKHR") + CmdResetEvent = auto_cast GetDeviceProcAddr(device, "vkCmdResetEvent") + CmdResetEvent2 = auto_cast GetDeviceProcAddr(device, "vkCmdResetEvent2") + CmdResetEvent2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdResetEvent2KHR") + CmdResetQueryPool = auto_cast GetDeviceProcAddr(device, "vkCmdResetQueryPool") + CmdResolveImage = auto_cast GetDeviceProcAddr(device, "vkCmdResolveImage") + CmdResolveImage2 = auto_cast GetDeviceProcAddr(device, "vkCmdResolveImage2") + CmdResolveImage2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdResolveImage2KHR") + CmdSetBlendConstants = auto_cast GetDeviceProcAddr(device, "vkCmdSetBlendConstants") + CmdSetCheckpointNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetCheckpointNV") + CmdSetCoarseSampleOrderNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetCoarseSampleOrderNV") + CmdSetCullMode = auto_cast GetDeviceProcAddr(device, "vkCmdSetCullMode") + CmdSetCullModeEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetCullModeEXT") + CmdSetDepthBias = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBias") + CmdSetDepthBiasEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBiasEnable") + CmdSetDepthBiasEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBiasEnableEXT") + CmdSetDepthBounds = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBounds") + CmdSetDepthBoundsTestEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBoundsTestEnable") + CmdSetDepthBoundsTestEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthBoundsTestEnableEXT") + CmdSetDepthCompareOp = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthCompareOp") + CmdSetDepthCompareOpEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthCompareOpEXT") + CmdSetDepthTestEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthTestEnable") + CmdSetDepthTestEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthTestEnableEXT") + CmdSetDepthWriteEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthWriteEnable") + CmdSetDepthWriteEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDepthWriteEnableEXT") + CmdSetDeviceMask = auto_cast GetDeviceProcAddr(device, "vkCmdSetDeviceMask") + CmdSetDeviceMaskKHR = auto_cast GetDeviceProcAddr(device, "vkCmdSetDeviceMaskKHR") + CmdSetDiscardRectangleEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetDiscardRectangleEXT") + CmdSetEvent = auto_cast GetDeviceProcAddr(device, "vkCmdSetEvent") + CmdSetEvent2 = auto_cast GetDeviceProcAddr(device, "vkCmdSetEvent2") + CmdSetEvent2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdSetEvent2KHR") + CmdSetExclusiveScissorNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetExclusiveScissorNV") + CmdSetFragmentShadingRateEnumNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetFragmentShadingRateEnumNV") + CmdSetFragmentShadingRateKHR = auto_cast GetDeviceProcAddr(device, "vkCmdSetFragmentShadingRateKHR") + CmdSetFrontFace = auto_cast GetDeviceProcAddr(device, "vkCmdSetFrontFace") + CmdSetFrontFaceEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetFrontFaceEXT") + CmdSetLineStippleEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetLineStippleEXT") + CmdSetLineWidth = auto_cast GetDeviceProcAddr(device, "vkCmdSetLineWidth") + CmdSetLogicOpEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetLogicOpEXT") + CmdSetPatchControlPointsEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetPatchControlPointsEXT") + CmdSetPerformanceMarkerINTEL = auto_cast GetDeviceProcAddr(device, "vkCmdSetPerformanceMarkerINTEL") + CmdSetPerformanceOverrideINTEL = auto_cast GetDeviceProcAddr(device, "vkCmdSetPerformanceOverrideINTEL") + CmdSetPerformanceStreamMarkerINTEL = auto_cast GetDeviceProcAddr(device, "vkCmdSetPerformanceStreamMarkerINTEL") + CmdSetPrimitiveRestartEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetPrimitiveRestartEnable") + CmdSetPrimitiveRestartEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetPrimitiveRestartEnableEXT") + CmdSetPrimitiveTopology = auto_cast GetDeviceProcAddr(device, "vkCmdSetPrimitiveTopology") + CmdSetPrimitiveTopologyEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetPrimitiveTopologyEXT") + CmdSetRasterizerDiscardEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetRasterizerDiscardEnable") + CmdSetRasterizerDiscardEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetRasterizerDiscardEnableEXT") + CmdSetRayTracingPipelineStackSizeKHR = auto_cast GetDeviceProcAddr(device, "vkCmdSetRayTracingPipelineStackSizeKHR") + CmdSetSampleLocationsEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetSampleLocationsEXT") + CmdSetScissor = auto_cast GetDeviceProcAddr(device, "vkCmdSetScissor") + CmdSetScissorWithCount = auto_cast GetDeviceProcAddr(device, "vkCmdSetScissorWithCount") + CmdSetScissorWithCountEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetScissorWithCountEXT") + CmdSetStencilCompareMask = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilCompareMask") + CmdSetStencilOp = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilOp") + CmdSetStencilOpEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilOpEXT") + CmdSetStencilReference = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilReference") + CmdSetStencilTestEnable = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilTestEnable") + CmdSetStencilTestEnableEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilTestEnableEXT") + CmdSetStencilWriteMask = auto_cast GetDeviceProcAddr(device, "vkCmdSetStencilWriteMask") + CmdSetVertexInputEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetVertexInputEXT") + CmdSetViewport = auto_cast GetDeviceProcAddr(device, "vkCmdSetViewport") + CmdSetViewportShadingRatePaletteNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetViewportShadingRatePaletteNV") + CmdSetViewportWScalingNV = auto_cast GetDeviceProcAddr(device, "vkCmdSetViewportWScalingNV") + CmdSetViewportWithCount = auto_cast GetDeviceProcAddr(device, "vkCmdSetViewportWithCount") + CmdSetViewportWithCountEXT = auto_cast GetDeviceProcAddr(device, "vkCmdSetViewportWithCountEXT") + CmdSubpassShadingHUAWEI = auto_cast GetDeviceProcAddr(device, "vkCmdSubpassShadingHUAWEI") + CmdTraceRaysIndirectKHR = auto_cast GetDeviceProcAddr(device, "vkCmdTraceRaysIndirectKHR") + CmdTraceRaysKHR = auto_cast GetDeviceProcAddr(device, "vkCmdTraceRaysKHR") + CmdTraceRaysNV = auto_cast GetDeviceProcAddr(device, "vkCmdTraceRaysNV") + CmdUpdateBuffer = auto_cast GetDeviceProcAddr(device, "vkCmdUpdateBuffer") + CmdWaitEvents = auto_cast GetDeviceProcAddr(device, "vkCmdWaitEvents") + CmdWaitEvents2 = auto_cast GetDeviceProcAddr(device, "vkCmdWaitEvents2") + CmdWaitEvents2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdWaitEvents2KHR") + CmdWriteAccelerationStructuresPropertiesKHR = auto_cast GetDeviceProcAddr(device, "vkCmdWriteAccelerationStructuresPropertiesKHR") + CmdWriteAccelerationStructuresPropertiesNV = auto_cast GetDeviceProcAddr(device, "vkCmdWriteAccelerationStructuresPropertiesNV") + CmdWriteBufferMarker2AMD = auto_cast GetDeviceProcAddr(device, "vkCmdWriteBufferMarker2AMD") + CmdWriteBufferMarkerAMD = auto_cast GetDeviceProcAddr(device, "vkCmdWriteBufferMarkerAMD") + CmdWriteTimestamp = auto_cast GetDeviceProcAddr(device, "vkCmdWriteTimestamp") + CmdWriteTimestamp2 = auto_cast GetDeviceProcAddr(device, "vkCmdWriteTimestamp2") + CmdWriteTimestamp2KHR = auto_cast GetDeviceProcAddr(device, "vkCmdWriteTimestamp2KHR") + CompileDeferredNV = auto_cast GetDeviceProcAddr(device, "vkCompileDeferredNV") + CopyAccelerationStructureKHR = auto_cast GetDeviceProcAddr(device, "vkCopyAccelerationStructureKHR") + CopyAccelerationStructureToMemoryKHR = auto_cast GetDeviceProcAddr(device, "vkCopyAccelerationStructureToMemoryKHR") + CopyMemoryToAccelerationStructureKHR = auto_cast GetDeviceProcAddr(device, "vkCopyMemoryToAccelerationStructureKHR") + CreateAccelerationStructureKHR = auto_cast GetDeviceProcAddr(device, "vkCreateAccelerationStructureKHR") + CreateAccelerationStructureNV = auto_cast GetDeviceProcAddr(device, "vkCreateAccelerationStructureNV") + CreateBuffer = auto_cast GetDeviceProcAddr(device, "vkCreateBuffer") + CreateBufferView = auto_cast GetDeviceProcAddr(device, "vkCreateBufferView") + CreateCommandPool = auto_cast GetDeviceProcAddr(device, "vkCreateCommandPool") + CreateComputePipelines = auto_cast GetDeviceProcAddr(device, "vkCreateComputePipelines") + CreateCuFunctionNVX = auto_cast GetDeviceProcAddr(device, "vkCreateCuFunctionNVX") + CreateCuModuleNVX = auto_cast GetDeviceProcAddr(device, "vkCreateCuModuleNVX") + CreateDeferredOperationKHR = auto_cast GetDeviceProcAddr(device, "vkCreateDeferredOperationKHR") + CreateDescriptorPool = auto_cast GetDeviceProcAddr(device, "vkCreateDescriptorPool") + CreateDescriptorSetLayout = auto_cast GetDeviceProcAddr(device, "vkCreateDescriptorSetLayout") + CreateDescriptorUpdateTemplate = auto_cast GetDeviceProcAddr(device, "vkCreateDescriptorUpdateTemplate") + CreateDescriptorUpdateTemplateKHR = auto_cast GetDeviceProcAddr(device, "vkCreateDescriptorUpdateTemplateKHR") + CreateEvent = auto_cast GetDeviceProcAddr(device, "vkCreateEvent") + CreateFence = auto_cast GetDeviceProcAddr(device, "vkCreateFence") + CreateFramebuffer = auto_cast GetDeviceProcAddr(device, "vkCreateFramebuffer") + CreateGraphicsPipelines = auto_cast GetDeviceProcAddr(device, "vkCreateGraphicsPipelines") + CreateImage = auto_cast GetDeviceProcAddr(device, "vkCreateImage") + CreateImageView = auto_cast GetDeviceProcAddr(device, "vkCreateImageView") + CreateIndirectCommandsLayoutNV = auto_cast GetDeviceProcAddr(device, "vkCreateIndirectCommandsLayoutNV") + CreatePipelineCache = auto_cast GetDeviceProcAddr(device, "vkCreatePipelineCache") + CreatePipelineLayout = auto_cast GetDeviceProcAddr(device, "vkCreatePipelineLayout") + CreatePrivateDataSlot = auto_cast GetDeviceProcAddr(device, "vkCreatePrivateDataSlot") + CreatePrivateDataSlotEXT = auto_cast GetDeviceProcAddr(device, "vkCreatePrivateDataSlotEXT") + CreateQueryPool = auto_cast GetDeviceProcAddr(device, "vkCreateQueryPool") + CreateRayTracingPipelinesKHR = auto_cast GetDeviceProcAddr(device, "vkCreateRayTracingPipelinesKHR") + CreateRayTracingPipelinesNV = auto_cast GetDeviceProcAddr(device, "vkCreateRayTracingPipelinesNV") + CreateRenderPass = auto_cast GetDeviceProcAddr(device, "vkCreateRenderPass") + CreateRenderPass2 = auto_cast GetDeviceProcAddr(device, "vkCreateRenderPass2") + CreateRenderPass2KHR = auto_cast GetDeviceProcAddr(device, "vkCreateRenderPass2KHR") + CreateSampler = auto_cast GetDeviceProcAddr(device, "vkCreateSampler") + CreateSamplerYcbcrConversion = auto_cast GetDeviceProcAddr(device, "vkCreateSamplerYcbcrConversion") + CreateSamplerYcbcrConversionKHR = auto_cast GetDeviceProcAddr(device, "vkCreateSamplerYcbcrConversionKHR") + CreateSemaphore = auto_cast GetDeviceProcAddr(device, "vkCreateSemaphore") + CreateShaderModule = auto_cast GetDeviceProcAddr(device, "vkCreateShaderModule") + CreateSharedSwapchainsKHR = auto_cast GetDeviceProcAddr(device, "vkCreateSharedSwapchainsKHR") + CreateSwapchainKHR = auto_cast GetDeviceProcAddr(device, "vkCreateSwapchainKHR") + CreateValidationCacheEXT = auto_cast GetDeviceProcAddr(device, "vkCreateValidationCacheEXT") + DebugMarkerSetObjectNameEXT = auto_cast GetDeviceProcAddr(device, "vkDebugMarkerSetObjectNameEXT") + DebugMarkerSetObjectTagEXT = auto_cast GetDeviceProcAddr(device, "vkDebugMarkerSetObjectTagEXT") + DeferredOperationJoinKHR = auto_cast GetDeviceProcAddr(device, "vkDeferredOperationJoinKHR") + DestroyAccelerationStructureKHR = auto_cast GetDeviceProcAddr(device, "vkDestroyAccelerationStructureKHR") + DestroyAccelerationStructureNV = auto_cast GetDeviceProcAddr(device, "vkDestroyAccelerationStructureNV") + DestroyBuffer = auto_cast GetDeviceProcAddr(device, "vkDestroyBuffer") + DestroyBufferView = auto_cast GetDeviceProcAddr(device, "vkDestroyBufferView") + DestroyCommandPool = auto_cast GetDeviceProcAddr(device, "vkDestroyCommandPool") + DestroyCuFunctionNVX = auto_cast GetDeviceProcAddr(device, "vkDestroyCuFunctionNVX") + DestroyCuModuleNVX = auto_cast GetDeviceProcAddr(device, "vkDestroyCuModuleNVX") + DestroyDeferredOperationKHR = auto_cast GetDeviceProcAddr(device, "vkDestroyDeferredOperationKHR") + DestroyDescriptorPool = auto_cast GetDeviceProcAddr(device, "vkDestroyDescriptorPool") + DestroyDescriptorSetLayout = auto_cast GetDeviceProcAddr(device, "vkDestroyDescriptorSetLayout") + DestroyDescriptorUpdateTemplate = auto_cast GetDeviceProcAddr(device, "vkDestroyDescriptorUpdateTemplate") + DestroyDescriptorUpdateTemplateKHR = auto_cast GetDeviceProcAddr(device, "vkDestroyDescriptorUpdateTemplateKHR") + DestroyDevice = auto_cast GetDeviceProcAddr(device, "vkDestroyDevice") + DestroyEvent = auto_cast GetDeviceProcAddr(device, "vkDestroyEvent") + DestroyFence = auto_cast GetDeviceProcAddr(device, "vkDestroyFence") + DestroyFramebuffer = auto_cast GetDeviceProcAddr(device, "vkDestroyFramebuffer") + DestroyImage = auto_cast GetDeviceProcAddr(device, "vkDestroyImage") + DestroyImageView = auto_cast GetDeviceProcAddr(device, "vkDestroyImageView") + DestroyIndirectCommandsLayoutNV = auto_cast GetDeviceProcAddr(device, "vkDestroyIndirectCommandsLayoutNV") + DestroyPipeline = auto_cast GetDeviceProcAddr(device, "vkDestroyPipeline") + DestroyPipelineCache = auto_cast GetDeviceProcAddr(device, "vkDestroyPipelineCache") + DestroyPipelineLayout = auto_cast GetDeviceProcAddr(device, "vkDestroyPipelineLayout") + DestroyPrivateDataSlot = auto_cast GetDeviceProcAddr(device, "vkDestroyPrivateDataSlot") + DestroyPrivateDataSlotEXT = auto_cast GetDeviceProcAddr(device, "vkDestroyPrivateDataSlotEXT") + DestroyQueryPool = auto_cast GetDeviceProcAddr(device, "vkDestroyQueryPool") + DestroyRenderPass = auto_cast GetDeviceProcAddr(device, "vkDestroyRenderPass") + DestroySampler = auto_cast GetDeviceProcAddr(device, "vkDestroySampler") + DestroySamplerYcbcrConversion = auto_cast GetDeviceProcAddr(device, "vkDestroySamplerYcbcrConversion") + DestroySamplerYcbcrConversionKHR = auto_cast GetDeviceProcAddr(device, "vkDestroySamplerYcbcrConversionKHR") + DestroySemaphore = auto_cast GetDeviceProcAddr(device, "vkDestroySemaphore") + DestroyShaderModule = auto_cast GetDeviceProcAddr(device, "vkDestroyShaderModule") + DestroySwapchainKHR = auto_cast GetDeviceProcAddr(device, "vkDestroySwapchainKHR") + DestroyValidationCacheEXT = auto_cast GetDeviceProcAddr(device, "vkDestroyValidationCacheEXT") + DeviceWaitIdle = auto_cast GetDeviceProcAddr(device, "vkDeviceWaitIdle") + DisplayPowerControlEXT = auto_cast GetDeviceProcAddr(device, "vkDisplayPowerControlEXT") + EndCommandBuffer = auto_cast GetDeviceProcAddr(device, "vkEndCommandBuffer") + FlushMappedMemoryRanges = auto_cast GetDeviceProcAddr(device, "vkFlushMappedMemoryRanges") + FreeCommandBuffers = auto_cast GetDeviceProcAddr(device, "vkFreeCommandBuffers") + FreeDescriptorSets = auto_cast GetDeviceProcAddr(device, "vkFreeDescriptorSets") + FreeMemory = auto_cast GetDeviceProcAddr(device, "vkFreeMemory") + GetAccelerationStructureBuildSizesKHR = auto_cast GetDeviceProcAddr(device, "vkGetAccelerationStructureBuildSizesKHR") + GetAccelerationStructureDeviceAddressKHR = auto_cast GetDeviceProcAddr(device, "vkGetAccelerationStructureDeviceAddressKHR") + GetAccelerationStructureHandleNV = auto_cast GetDeviceProcAddr(device, "vkGetAccelerationStructureHandleNV") + GetAccelerationStructureMemoryRequirementsNV = auto_cast GetDeviceProcAddr(device, "vkGetAccelerationStructureMemoryRequirementsNV") + GetBufferDeviceAddress = auto_cast GetDeviceProcAddr(device, "vkGetBufferDeviceAddress") + GetBufferDeviceAddressEXT = auto_cast GetDeviceProcAddr(device, "vkGetBufferDeviceAddressEXT") + GetBufferDeviceAddressKHR = auto_cast GetDeviceProcAddr(device, "vkGetBufferDeviceAddressKHR") + GetBufferMemoryRequirements = auto_cast GetDeviceProcAddr(device, "vkGetBufferMemoryRequirements") + GetBufferMemoryRequirements2 = auto_cast GetDeviceProcAddr(device, "vkGetBufferMemoryRequirements2") + GetBufferMemoryRequirements2KHR = auto_cast GetDeviceProcAddr(device, "vkGetBufferMemoryRequirements2KHR") + GetBufferOpaqueCaptureAddress = auto_cast GetDeviceProcAddr(device, "vkGetBufferOpaqueCaptureAddress") + GetBufferOpaqueCaptureAddressKHR = auto_cast GetDeviceProcAddr(device, "vkGetBufferOpaqueCaptureAddressKHR") + GetCalibratedTimestampsEXT = auto_cast GetDeviceProcAddr(device, "vkGetCalibratedTimestampsEXT") + GetDeferredOperationMaxConcurrencyKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeferredOperationMaxConcurrencyKHR") + GetDeferredOperationResultKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeferredOperationResultKHR") + GetDescriptorSetHostMappingVALVE = auto_cast GetDeviceProcAddr(device, "vkGetDescriptorSetHostMappingVALVE") + GetDescriptorSetLayoutHostMappingInfoVALVE = auto_cast GetDeviceProcAddr(device, "vkGetDescriptorSetLayoutHostMappingInfoVALVE") + GetDescriptorSetLayoutSupport = auto_cast GetDeviceProcAddr(device, "vkGetDescriptorSetLayoutSupport") + GetDescriptorSetLayoutSupportKHR = auto_cast GetDeviceProcAddr(device, "vkGetDescriptorSetLayoutSupportKHR") + GetDeviceAccelerationStructureCompatibilityKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceAccelerationStructureCompatibilityKHR") + GetDeviceBufferMemoryRequirements = auto_cast GetDeviceProcAddr(device, "vkGetDeviceBufferMemoryRequirements") + GetDeviceBufferMemoryRequirementsKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceBufferMemoryRequirementsKHR") + GetDeviceGroupPeerMemoryFeatures = auto_cast GetDeviceProcAddr(device, "vkGetDeviceGroupPeerMemoryFeatures") + GetDeviceGroupPeerMemoryFeaturesKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceGroupPeerMemoryFeaturesKHR") + GetDeviceGroupPresentCapabilitiesKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceGroupPresentCapabilitiesKHR") + GetDeviceGroupSurfacePresentModes2EXT = auto_cast GetDeviceProcAddr(device, "vkGetDeviceGroupSurfacePresentModes2EXT") + GetDeviceGroupSurfacePresentModesKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceGroupSurfacePresentModesKHR") + GetDeviceImageMemoryRequirements = auto_cast GetDeviceProcAddr(device, "vkGetDeviceImageMemoryRequirements") + GetDeviceImageMemoryRequirementsKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceImageMemoryRequirementsKHR") + GetDeviceImageSparseMemoryRequirements = auto_cast GetDeviceProcAddr(device, "vkGetDeviceImageSparseMemoryRequirements") + GetDeviceImageSparseMemoryRequirementsKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceImageSparseMemoryRequirementsKHR") + GetDeviceMemoryCommitment = auto_cast GetDeviceProcAddr(device, "vkGetDeviceMemoryCommitment") + GetDeviceMemoryOpaqueCaptureAddress = auto_cast GetDeviceProcAddr(device, "vkGetDeviceMemoryOpaqueCaptureAddress") + GetDeviceMemoryOpaqueCaptureAddressKHR = auto_cast GetDeviceProcAddr(device, "vkGetDeviceMemoryOpaqueCaptureAddressKHR") + GetDeviceProcAddr = auto_cast GetDeviceProcAddr(device, "vkGetDeviceProcAddr") + GetDeviceQueue = auto_cast GetDeviceProcAddr(device, "vkGetDeviceQueue") + GetDeviceQueue2 = auto_cast GetDeviceProcAddr(device, "vkGetDeviceQueue2") + GetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI = auto_cast GetDeviceProcAddr(device, "vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI") + GetEventStatus = auto_cast GetDeviceProcAddr(device, "vkGetEventStatus") + GetFenceFdKHR = auto_cast GetDeviceProcAddr(device, "vkGetFenceFdKHR") + GetFenceStatus = auto_cast GetDeviceProcAddr(device, "vkGetFenceStatus") + GetFenceWin32HandleKHR = auto_cast GetDeviceProcAddr(device, "vkGetFenceWin32HandleKHR") + GetGeneratedCommandsMemoryRequirementsNV = auto_cast GetDeviceProcAddr(device, "vkGetGeneratedCommandsMemoryRequirementsNV") + GetImageDrmFormatModifierPropertiesEXT = auto_cast GetDeviceProcAddr(device, "vkGetImageDrmFormatModifierPropertiesEXT") + GetImageMemoryRequirements = auto_cast GetDeviceProcAddr(device, "vkGetImageMemoryRequirements") + GetImageMemoryRequirements2 = auto_cast GetDeviceProcAddr(device, "vkGetImageMemoryRequirements2") + GetImageMemoryRequirements2KHR = auto_cast GetDeviceProcAddr(device, "vkGetImageMemoryRequirements2KHR") + GetImageSparseMemoryRequirements = auto_cast GetDeviceProcAddr(device, "vkGetImageSparseMemoryRequirements") + GetImageSparseMemoryRequirements2 = auto_cast GetDeviceProcAddr(device, "vkGetImageSparseMemoryRequirements2") + GetImageSparseMemoryRequirements2KHR = auto_cast GetDeviceProcAddr(device, "vkGetImageSparseMemoryRequirements2KHR") + GetImageSubresourceLayout = auto_cast GetDeviceProcAddr(device, "vkGetImageSubresourceLayout") + GetImageViewAddressNVX = auto_cast GetDeviceProcAddr(device, "vkGetImageViewAddressNVX") + GetImageViewHandleNVX = auto_cast GetDeviceProcAddr(device, "vkGetImageViewHandleNVX") + GetMemoryFdKHR = auto_cast GetDeviceProcAddr(device, "vkGetMemoryFdKHR") + GetMemoryFdPropertiesKHR = auto_cast GetDeviceProcAddr(device, "vkGetMemoryFdPropertiesKHR") + GetMemoryHostPointerPropertiesEXT = auto_cast GetDeviceProcAddr(device, "vkGetMemoryHostPointerPropertiesEXT") + GetMemoryRemoteAddressNV = auto_cast GetDeviceProcAddr(device, "vkGetMemoryRemoteAddressNV") + GetMemoryWin32HandleKHR = auto_cast GetDeviceProcAddr(device, "vkGetMemoryWin32HandleKHR") + GetMemoryWin32HandleNV = auto_cast GetDeviceProcAddr(device, "vkGetMemoryWin32HandleNV") + GetMemoryWin32HandlePropertiesKHR = auto_cast GetDeviceProcAddr(device, "vkGetMemoryWin32HandlePropertiesKHR") + GetPastPresentationTimingGOOGLE = auto_cast GetDeviceProcAddr(device, "vkGetPastPresentationTimingGOOGLE") + GetPerformanceParameterINTEL = auto_cast GetDeviceProcAddr(device, "vkGetPerformanceParameterINTEL") + GetPipelineCacheData = auto_cast GetDeviceProcAddr(device, "vkGetPipelineCacheData") + GetPipelineExecutableInternalRepresentationsKHR = auto_cast GetDeviceProcAddr(device, "vkGetPipelineExecutableInternalRepresentationsKHR") + GetPipelineExecutablePropertiesKHR = auto_cast GetDeviceProcAddr(device, "vkGetPipelineExecutablePropertiesKHR") + GetPipelineExecutableStatisticsKHR = auto_cast GetDeviceProcAddr(device, "vkGetPipelineExecutableStatisticsKHR") + GetPrivateData = auto_cast GetDeviceProcAddr(device, "vkGetPrivateData") + GetPrivateDataEXT = auto_cast GetDeviceProcAddr(device, "vkGetPrivateDataEXT") + GetQueryPoolResults = auto_cast GetDeviceProcAddr(device, "vkGetQueryPoolResults") + GetQueueCheckpointData2NV = auto_cast GetDeviceProcAddr(device, "vkGetQueueCheckpointData2NV") + GetQueueCheckpointDataNV = auto_cast GetDeviceProcAddr(device, "vkGetQueueCheckpointDataNV") + GetRayTracingCaptureReplayShaderGroupHandlesKHR = auto_cast GetDeviceProcAddr(device, "vkGetRayTracingCaptureReplayShaderGroupHandlesKHR") + GetRayTracingShaderGroupHandlesKHR = auto_cast GetDeviceProcAddr(device, "vkGetRayTracingShaderGroupHandlesKHR") + GetRayTracingShaderGroupHandlesNV = auto_cast GetDeviceProcAddr(device, "vkGetRayTracingShaderGroupHandlesNV") + GetRayTracingShaderGroupStackSizeKHR = auto_cast GetDeviceProcAddr(device, "vkGetRayTracingShaderGroupStackSizeKHR") + GetRefreshCycleDurationGOOGLE = auto_cast GetDeviceProcAddr(device, "vkGetRefreshCycleDurationGOOGLE") + GetRenderAreaGranularity = auto_cast GetDeviceProcAddr(device, "vkGetRenderAreaGranularity") + GetSemaphoreCounterValue = auto_cast GetDeviceProcAddr(device, "vkGetSemaphoreCounterValue") + GetSemaphoreCounterValueKHR = auto_cast GetDeviceProcAddr(device, "vkGetSemaphoreCounterValueKHR") + GetSemaphoreFdKHR = auto_cast GetDeviceProcAddr(device, "vkGetSemaphoreFdKHR") + GetSemaphoreWin32HandleKHR = auto_cast GetDeviceProcAddr(device, "vkGetSemaphoreWin32HandleKHR") + GetShaderInfoAMD = auto_cast GetDeviceProcAddr(device, "vkGetShaderInfoAMD") + GetSwapchainCounterEXT = auto_cast GetDeviceProcAddr(device, "vkGetSwapchainCounterEXT") + GetSwapchainImagesKHR = auto_cast GetDeviceProcAddr(device, "vkGetSwapchainImagesKHR") + GetSwapchainStatusKHR = auto_cast GetDeviceProcAddr(device, "vkGetSwapchainStatusKHR") + GetValidationCacheDataEXT = auto_cast GetDeviceProcAddr(device, "vkGetValidationCacheDataEXT") + ImportFenceFdKHR = auto_cast GetDeviceProcAddr(device, "vkImportFenceFdKHR") + ImportFenceWin32HandleKHR = auto_cast GetDeviceProcAddr(device, "vkImportFenceWin32HandleKHR") + ImportSemaphoreFdKHR = auto_cast GetDeviceProcAddr(device, "vkImportSemaphoreFdKHR") + ImportSemaphoreWin32HandleKHR = auto_cast GetDeviceProcAddr(device, "vkImportSemaphoreWin32HandleKHR") + InitializePerformanceApiINTEL = auto_cast GetDeviceProcAddr(device, "vkInitializePerformanceApiINTEL") + InvalidateMappedMemoryRanges = auto_cast GetDeviceProcAddr(device, "vkInvalidateMappedMemoryRanges") + MapMemory = auto_cast GetDeviceProcAddr(device, "vkMapMemory") + MergePipelineCaches = auto_cast GetDeviceProcAddr(device, "vkMergePipelineCaches") + MergeValidationCachesEXT = auto_cast GetDeviceProcAddr(device, "vkMergeValidationCachesEXT") + QueueBeginDebugUtilsLabelEXT = auto_cast GetDeviceProcAddr(device, "vkQueueBeginDebugUtilsLabelEXT") + QueueBindSparse = auto_cast GetDeviceProcAddr(device, "vkQueueBindSparse") + QueueEndDebugUtilsLabelEXT = auto_cast GetDeviceProcAddr(device, "vkQueueEndDebugUtilsLabelEXT") + QueueInsertDebugUtilsLabelEXT = auto_cast GetDeviceProcAddr(device, "vkQueueInsertDebugUtilsLabelEXT") + QueuePresentKHR = auto_cast GetDeviceProcAddr(device, "vkQueuePresentKHR") + QueueSetPerformanceConfigurationINTEL = auto_cast GetDeviceProcAddr(device, "vkQueueSetPerformanceConfigurationINTEL") + QueueSubmit = auto_cast GetDeviceProcAddr(device, "vkQueueSubmit") + QueueSubmit2 = auto_cast GetDeviceProcAddr(device, "vkQueueSubmit2") + QueueSubmit2KHR = auto_cast GetDeviceProcAddr(device, "vkQueueSubmit2KHR") + QueueWaitIdle = auto_cast GetDeviceProcAddr(device, "vkQueueWaitIdle") + RegisterDeviceEventEXT = auto_cast GetDeviceProcAddr(device, "vkRegisterDeviceEventEXT") + RegisterDisplayEventEXT = auto_cast GetDeviceProcAddr(device, "vkRegisterDisplayEventEXT") + ReleaseFullScreenExclusiveModeEXT = auto_cast GetDeviceProcAddr(device, "vkReleaseFullScreenExclusiveModeEXT") + ReleasePerformanceConfigurationINTEL = auto_cast GetDeviceProcAddr(device, "vkReleasePerformanceConfigurationINTEL") + ReleaseProfilingLockKHR = auto_cast GetDeviceProcAddr(device, "vkReleaseProfilingLockKHR") + ResetCommandBuffer = auto_cast GetDeviceProcAddr(device, "vkResetCommandBuffer") + ResetCommandPool = auto_cast GetDeviceProcAddr(device, "vkResetCommandPool") + ResetDescriptorPool = auto_cast GetDeviceProcAddr(device, "vkResetDescriptorPool") + ResetEvent = auto_cast GetDeviceProcAddr(device, "vkResetEvent") + ResetFences = auto_cast GetDeviceProcAddr(device, "vkResetFences") + ResetQueryPool = auto_cast GetDeviceProcAddr(device, "vkResetQueryPool") + ResetQueryPoolEXT = auto_cast GetDeviceProcAddr(device, "vkResetQueryPoolEXT") + SetDebugUtilsObjectNameEXT = auto_cast GetDeviceProcAddr(device, "vkSetDebugUtilsObjectNameEXT") + SetDebugUtilsObjectTagEXT = auto_cast GetDeviceProcAddr(device, "vkSetDebugUtilsObjectTagEXT") + SetDeviceMemoryPriorityEXT = auto_cast GetDeviceProcAddr(device, "vkSetDeviceMemoryPriorityEXT") + SetEvent = auto_cast GetDeviceProcAddr(device, "vkSetEvent") + SetHdrMetadataEXT = auto_cast GetDeviceProcAddr(device, "vkSetHdrMetadataEXT") + SetLocalDimmingAMD = auto_cast GetDeviceProcAddr(device, "vkSetLocalDimmingAMD") + SetPrivateData = auto_cast GetDeviceProcAddr(device, "vkSetPrivateData") + SetPrivateDataEXT = auto_cast GetDeviceProcAddr(device, "vkSetPrivateDataEXT") + SignalSemaphore = auto_cast GetDeviceProcAddr(device, "vkSignalSemaphore") + SignalSemaphoreKHR = auto_cast GetDeviceProcAddr(device, "vkSignalSemaphoreKHR") + TrimCommandPool = auto_cast GetDeviceProcAddr(device, "vkTrimCommandPool") + TrimCommandPoolKHR = auto_cast GetDeviceProcAddr(device, "vkTrimCommandPoolKHR") + UninitializePerformanceApiINTEL = auto_cast GetDeviceProcAddr(device, "vkUninitializePerformanceApiINTEL") + UnmapMemory = auto_cast GetDeviceProcAddr(device, "vkUnmapMemory") + UpdateDescriptorSetWithTemplate = auto_cast GetDeviceProcAddr(device, "vkUpdateDescriptorSetWithTemplate") + UpdateDescriptorSetWithTemplateKHR = auto_cast GetDeviceProcAddr(device, "vkUpdateDescriptorSetWithTemplateKHR") + UpdateDescriptorSets = auto_cast GetDeviceProcAddr(device, "vkUpdateDescriptorSets") + WaitForFences = auto_cast GetDeviceProcAddr(device, "vkWaitForFences") + WaitForPresentKHR = auto_cast GetDeviceProcAddr(device, "vkWaitForPresentKHR") + WaitSemaphores = auto_cast GetDeviceProcAddr(device, "vkWaitSemaphores") + WaitSemaphoresKHR = auto_cast GetDeviceProcAddr(device, "vkWaitSemaphoresKHR") + WriteAccelerationStructuresPropertiesKHR = auto_cast GetDeviceProcAddr(device, "vkWriteAccelerationStructuresPropertiesKHR") +} + +load_proc_addresses_instance :: proc(instance: Instance) { + AcquireDrmDisplayEXT = auto_cast GetInstanceProcAddr(instance, "vkAcquireDrmDisplayEXT") + AcquireWinrtDisplayNV = auto_cast GetInstanceProcAddr(instance, "vkAcquireWinrtDisplayNV") + CreateDebugReportCallbackEXT = auto_cast GetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT") + CreateDebugUtilsMessengerEXT = auto_cast GetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT") + CreateDevice = auto_cast GetInstanceProcAddr(instance, "vkCreateDevice") + CreateDisplayModeKHR = auto_cast GetInstanceProcAddr(instance, "vkCreateDisplayModeKHR") + CreateDisplayPlaneSurfaceKHR = auto_cast GetInstanceProcAddr(instance, "vkCreateDisplayPlaneSurfaceKHR") + CreateHeadlessSurfaceEXT = auto_cast GetInstanceProcAddr(instance, "vkCreateHeadlessSurfaceEXT") + CreateIOSSurfaceMVK = auto_cast GetInstanceProcAddr(instance, "vkCreateIOSSurfaceMVK") + CreateMacOSSurfaceMVK = auto_cast GetInstanceProcAddr(instance, "vkCreateMacOSSurfaceMVK") + CreateMetalSurfaceEXT = auto_cast GetInstanceProcAddr(instance, "vkCreateMetalSurfaceEXT") + CreateWin32SurfaceKHR = auto_cast GetInstanceProcAddr(instance, "vkCreateWin32SurfaceKHR") + DebugReportMessageEXT = auto_cast GetInstanceProcAddr(instance, "vkDebugReportMessageEXT") + DestroyDebugReportCallbackEXT = auto_cast GetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT") + DestroyDebugUtilsMessengerEXT = auto_cast GetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT") + DestroyInstance = auto_cast GetInstanceProcAddr(instance, "vkDestroyInstance") + DestroySurfaceKHR = auto_cast GetInstanceProcAddr(instance, "vkDestroySurfaceKHR") + EnumerateDeviceExtensionProperties = auto_cast GetInstanceProcAddr(instance, "vkEnumerateDeviceExtensionProperties") + EnumerateDeviceLayerProperties = auto_cast GetInstanceProcAddr(instance, "vkEnumerateDeviceLayerProperties") + EnumeratePhysicalDeviceGroups = auto_cast GetInstanceProcAddr(instance, "vkEnumeratePhysicalDeviceGroups") + EnumeratePhysicalDeviceGroupsKHR = auto_cast GetInstanceProcAddr(instance, "vkEnumeratePhysicalDeviceGroupsKHR") + EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR = auto_cast GetInstanceProcAddr(instance, "vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR") + EnumeratePhysicalDevices = auto_cast GetInstanceProcAddr(instance, "vkEnumeratePhysicalDevices") + GetDisplayModeProperties2KHR = auto_cast GetInstanceProcAddr(instance, "vkGetDisplayModeProperties2KHR") + GetDisplayModePropertiesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDisplayModePropertiesKHR") + GetDisplayPlaneCapabilities2KHR = auto_cast GetInstanceProcAddr(instance, "vkGetDisplayPlaneCapabilities2KHR") + GetDisplayPlaneCapabilitiesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDisplayPlaneCapabilitiesKHR") + GetDisplayPlaneSupportedDisplaysKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDisplayPlaneSupportedDisplaysKHR") + GetDrmDisplayEXT = auto_cast GetInstanceProcAddr(instance, "vkGetDrmDisplayEXT") + GetInstanceProcAddr = auto_cast GetInstanceProcAddr(instance, "vkGetInstanceProcAddr") + GetPhysicalDeviceCalibrateableTimeDomainsEXT = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT") + GetPhysicalDeviceCooperativeMatrixPropertiesNV = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceCooperativeMatrixPropertiesNV") + GetPhysicalDeviceDisplayPlaneProperties2KHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPlaneProperties2KHR") + GetPhysicalDeviceDisplayPlanePropertiesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR") + GetPhysicalDeviceDisplayProperties2KHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayProperties2KHR") + GetPhysicalDeviceDisplayPropertiesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPropertiesKHR") + GetPhysicalDeviceExternalBufferProperties = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalBufferProperties") + GetPhysicalDeviceExternalBufferPropertiesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalBufferPropertiesKHR") + GetPhysicalDeviceExternalFenceProperties = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalFenceProperties") + GetPhysicalDeviceExternalFencePropertiesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalFencePropertiesKHR") + GetPhysicalDeviceExternalImageFormatPropertiesNV = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalImageFormatPropertiesNV") + GetPhysicalDeviceExternalSemaphoreProperties = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalSemaphoreProperties") + GetPhysicalDeviceExternalSemaphorePropertiesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR") + GetPhysicalDeviceFeatures = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures") + GetPhysicalDeviceFeatures2 = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures2") + GetPhysicalDeviceFeatures2KHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures2KHR") + GetPhysicalDeviceFormatProperties = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceFormatProperties") + GetPhysicalDeviceFormatProperties2 = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceFormatProperties2") + GetPhysicalDeviceFormatProperties2KHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceFormatProperties2KHR") + GetPhysicalDeviceFragmentShadingRatesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceFragmentShadingRatesKHR") + GetPhysicalDeviceImageFormatProperties = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceImageFormatProperties") + GetPhysicalDeviceImageFormatProperties2 = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceImageFormatProperties2") + GetPhysicalDeviceImageFormatProperties2KHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceImageFormatProperties2KHR") + GetPhysicalDeviceMemoryProperties = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceMemoryProperties") + GetPhysicalDeviceMemoryProperties2 = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceMemoryProperties2") + GetPhysicalDeviceMemoryProperties2KHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceMemoryProperties2KHR") + GetPhysicalDeviceMultisamplePropertiesEXT = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceMultisamplePropertiesEXT") + GetPhysicalDevicePresentRectanglesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDevicePresentRectanglesKHR") + GetPhysicalDeviceProperties = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties") + GetPhysicalDeviceProperties2 = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2") + GetPhysicalDeviceProperties2KHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2KHR") + GetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR") + GetPhysicalDeviceQueueFamilyProperties = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceQueueFamilyProperties") + GetPhysicalDeviceQueueFamilyProperties2 = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceQueueFamilyProperties2") + GetPhysicalDeviceQueueFamilyProperties2KHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceQueueFamilyProperties2KHR") + GetPhysicalDeviceSparseImageFormatProperties = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceSparseImageFormatProperties") + GetPhysicalDeviceSparseImageFormatProperties2 = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceSparseImageFormatProperties2") + GetPhysicalDeviceSparseImageFormatProperties2KHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceSparseImageFormatProperties2KHR") + GetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV") + GetPhysicalDeviceSurfaceCapabilities2EXT = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceCapabilities2EXT") + GetPhysicalDeviceSurfaceCapabilities2KHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceCapabilities2KHR") + GetPhysicalDeviceSurfaceCapabilitiesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR") + GetPhysicalDeviceSurfaceFormats2KHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceFormats2KHR") + GetPhysicalDeviceSurfaceFormatsKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceFormatsKHR") + GetPhysicalDeviceSurfacePresentModes2EXT = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfacePresentModes2EXT") + GetPhysicalDeviceSurfacePresentModesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfacePresentModesKHR") + GetPhysicalDeviceSurfaceSupportKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceSurfaceSupportKHR") + GetPhysicalDeviceToolProperties = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceToolProperties") + GetPhysicalDeviceToolPropertiesEXT = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceToolPropertiesEXT") + GetPhysicalDeviceWin32PresentationSupportKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR") + GetWinrtDisplayNV = auto_cast GetInstanceProcAddr(instance, "vkGetWinrtDisplayNV") + ReleaseDisplayEXT = auto_cast GetInstanceProcAddr(instance, "vkReleaseDisplayEXT") + SubmitDebugUtilsMessageEXT = auto_cast GetInstanceProcAddr(instance, "vkSubmitDebugUtilsMessageEXT") + + // Device Procedures (may call into dispatch) + AcquireFullScreenExclusiveModeEXT = auto_cast GetInstanceProcAddr(instance, "vkAcquireFullScreenExclusiveModeEXT") + AcquireNextImage2KHR = auto_cast GetInstanceProcAddr(instance, "vkAcquireNextImage2KHR") + AcquireNextImageKHR = auto_cast GetInstanceProcAddr(instance, "vkAcquireNextImageKHR") + AcquirePerformanceConfigurationINTEL = auto_cast GetInstanceProcAddr(instance, "vkAcquirePerformanceConfigurationINTEL") + AcquireProfilingLockKHR = auto_cast GetInstanceProcAddr(instance, "vkAcquireProfilingLockKHR") + AllocateCommandBuffers = auto_cast GetInstanceProcAddr(instance, "vkAllocateCommandBuffers") + AllocateDescriptorSets = auto_cast GetInstanceProcAddr(instance, "vkAllocateDescriptorSets") + AllocateMemory = auto_cast GetInstanceProcAddr(instance, "vkAllocateMemory") + BeginCommandBuffer = auto_cast GetInstanceProcAddr(instance, "vkBeginCommandBuffer") + BindAccelerationStructureMemoryNV = auto_cast GetInstanceProcAddr(instance, "vkBindAccelerationStructureMemoryNV") + BindBufferMemory = auto_cast GetInstanceProcAddr(instance, "vkBindBufferMemory") + BindBufferMemory2 = auto_cast GetInstanceProcAddr(instance, "vkBindBufferMemory2") + BindBufferMemory2KHR = auto_cast GetInstanceProcAddr(instance, "vkBindBufferMemory2KHR") + BindImageMemory = auto_cast GetInstanceProcAddr(instance, "vkBindImageMemory") + BindImageMemory2 = auto_cast GetInstanceProcAddr(instance, "vkBindImageMemory2") + BindImageMemory2KHR = auto_cast GetInstanceProcAddr(instance, "vkBindImageMemory2KHR") + BuildAccelerationStructuresKHR = auto_cast GetInstanceProcAddr(instance, "vkBuildAccelerationStructuresKHR") + CmdBeginConditionalRenderingEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdBeginConditionalRenderingEXT") + CmdBeginDebugUtilsLabelEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdBeginDebugUtilsLabelEXT") + CmdBeginQuery = auto_cast GetInstanceProcAddr(instance, "vkCmdBeginQuery") + CmdBeginQueryIndexedEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdBeginQueryIndexedEXT") + CmdBeginRenderPass = auto_cast GetInstanceProcAddr(instance, "vkCmdBeginRenderPass") + CmdBeginRenderPass2 = auto_cast GetInstanceProcAddr(instance, "vkCmdBeginRenderPass2") + CmdBeginRenderPass2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdBeginRenderPass2KHR") + CmdBeginRendering = auto_cast GetInstanceProcAddr(instance, "vkCmdBeginRendering") + CmdBeginRenderingKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdBeginRenderingKHR") + CmdBeginTransformFeedbackEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdBeginTransformFeedbackEXT") + CmdBindDescriptorSets = auto_cast GetInstanceProcAddr(instance, "vkCmdBindDescriptorSets") + CmdBindIndexBuffer = auto_cast GetInstanceProcAddr(instance, "vkCmdBindIndexBuffer") + CmdBindInvocationMaskHUAWEI = auto_cast GetInstanceProcAddr(instance, "vkCmdBindInvocationMaskHUAWEI") + CmdBindPipeline = auto_cast GetInstanceProcAddr(instance, "vkCmdBindPipeline") + CmdBindPipelineShaderGroupNV = auto_cast GetInstanceProcAddr(instance, "vkCmdBindPipelineShaderGroupNV") + CmdBindShadingRateImageNV = auto_cast GetInstanceProcAddr(instance, "vkCmdBindShadingRateImageNV") + CmdBindTransformFeedbackBuffersEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdBindTransformFeedbackBuffersEXT") + CmdBindVertexBuffers = auto_cast GetInstanceProcAddr(instance, "vkCmdBindVertexBuffers") + CmdBindVertexBuffers2 = auto_cast GetInstanceProcAddr(instance, "vkCmdBindVertexBuffers2") + CmdBindVertexBuffers2EXT = auto_cast GetInstanceProcAddr(instance, "vkCmdBindVertexBuffers2EXT") + CmdBlitImage = auto_cast GetInstanceProcAddr(instance, "vkCmdBlitImage") + CmdBlitImage2 = auto_cast GetInstanceProcAddr(instance, "vkCmdBlitImage2") + CmdBlitImage2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdBlitImage2KHR") + CmdBuildAccelerationStructureNV = auto_cast GetInstanceProcAddr(instance, "vkCmdBuildAccelerationStructureNV") + CmdBuildAccelerationStructuresIndirectKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdBuildAccelerationStructuresIndirectKHR") + CmdBuildAccelerationStructuresKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdBuildAccelerationStructuresKHR") + CmdClearAttachments = auto_cast GetInstanceProcAddr(instance, "vkCmdClearAttachments") + CmdClearColorImage = auto_cast GetInstanceProcAddr(instance, "vkCmdClearColorImage") + CmdClearDepthStencilImage = auto_cast GetInstanceProcAddr(instance, "vkCmdClearDepthStencilImage") + CmdCopyAccelerationStructureKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyAccelerationStructureKHR") + CmdCopyAccelerationStructureNV = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyAccelerationStructureNV") + CmdCopyAccelerationStructureToMemoryKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyAccelerationStructureToMemoryKHR") + CmdCopyBuffer = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyBuffer") + CmdCopyBuffer2 = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyBuffer2") + CmdCopyBuffer2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyBuffer2KHR") + CmdCopyBufferToImage = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyBufferToImage") + CmdCopyBufferToImage2 = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyBufferToImage2") + CmdCopyBufferToImage2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyBufferToImage2KHR") + CmdCopyImage = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyImage") + CmdCopyImage2 = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyImage2") + CmdCopyImage2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyImage2KHR") + CmdCopyImageToBuffer = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyImageToBuffer") + CmdCopyImageToBuffer2 = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyImageToBuffer2") + CmdCopyImageToBuffer2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyImageToBuffer2KHR") + CmdCopyMemoryToAccelerationStructureKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyMemoryToAccelerationStructureKHR") + CmdCopyQueryPoolResults = auto_cast GetInstanceProcAddr(instance, "vkCmdCopyQueryPoolResults") + CmdCuLaunchKernelNVX = auto_cast GetInstanceProcAddr(instance, "vkCmdCuLaunchKernelNVX") + CmdDebugMarkerBeginEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdDebugMarkerBeginEXT") + CmdDebugMarkerEndEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdDebugMarkerEndEXT") + CmdDebugMarkerInsertEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdDebugMarkerInsertEXT") + CmdDispatch = auto_cast GetInstanceProcAddr(instance, "vkCmdDispatch") + CmdDispatchBase = auto_cast GetInstanceProcAddr(instance, "vkCmdDispatchBase") + CmdDispatchBaseKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdDispatchBaseKHR") + CmdDispatchIndirect = auto_cast GetInstanceProcAddr(instance, "vkCmdDispatchIndirect") + CmdDraw = auto_cast GetInstanceProcAddr(instance, "vkCmdDraw") + CmdDrawIndexed = auto_cast GetInstanceProcAddr(instance, "vkCmdDrawIndexed") + CmdDrawIndexedIndirect = auto_cast GetInstanceProcAddr(instance, "vkCmdDrawIndexedIndirect") + CmdDrawIndexedIndirectCount = auto_cast GetInstanceProcAddr(instance, "vkCmdDrawIndexedIndirectCount") + CmdDrawIndexedIndirectCountAMD = auto_cast GetInstanceProcAddr(instance, "vkCmdDrawIndexedIndirectCountAMD") + CmdDrawIndexedIndirectCountKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdDrawIndexedIndirectCountKHR") + CmdDrawIndirect = auto_cast GetInstanceProcAddr(instance, "vkCmdDrawIndirect") + CmdDrawIndirectByteCountEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdDrawIndirectByteCountEXT") + CmdDrawIndirectCount = auto_cast GetInstanceProcAddr(instance, "vkCmdDrawIndirectCount") + CmdDrawIndirectCountAMD = auto_cast GetInstanceProcAddr(instance, "vkCmdDrawIndirectCountAMD") + CmdDrawIndirectCountKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdDrawIndirectCountKHR") + CmdDrawMeshTasksIndirectCountNV = auto_cast GetInstanceProcAddr(instance, "vkCmdDrawMeshTasksIndirectCountNV") + CmdDrawMeshTasksIndirectNV = auto_cast GetInstanceProcAddr(instance, "vkCmdDrawMeshTasksIndirectNV") + CmdDrawMeshTasksNV = auto_cast GetInstanceProcAddr(instance, "vkCmdDrawMeshTasksNV") + CmdDrawMultiEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdDrawMultiEXT") + CmdDrawMultiIndexedEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdDrawMultiIndexedEXT") + CmdEndConditionalRenderingEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdEndConditionalRenderingEXT") + CmdEndDebugUtilsLabelEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdEndDebugUtilsLabelEXT") + CmdEndQuery = auto_cast GetInstanceProcAddr(instance, "vkCmdEndQuery") + CmdEndQueryIndexedEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdEndQueryIndexedEXT") + CmdEndRenderPass = auto_cast GetInstanceProcAddr(instance, "vkCmdEndRenderPass") + CmdEndRenderPass2 = auto_cast GetInstanceProcAddr(instance, "vkCmdEndRenderPass2") + CmdEndRenderPass2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdEndRenderPass2KHR") + CmdEndRendering = auto_cast GetInstanceProcAddr(instance, "vkCmdEndRendering") + CmdEndRenderingKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdEndRenderingKHR") + CmdEndTransformFeedbackEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdEndTransformFeedbackEXT") + CmdExecuteCommands = auto_cast GetInstanceProcAddr(instance, "vkCmdExecuteCommands") + CmdExecuteGeneratedCommandsNV = auto_cast GetInstanceProcAddr(instance, "vkCmdExecuteGeneratedCommandsNV") + CmdFillBuffer = auto_cast GetInstanceProcAddr(instance, "vkCmdFillBuffer") + CmdInsertDebugUtilsLabelEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdInsertDebugUtilsLabelEXT") + CmdNextSubpass = auto_cast GetInstanceProcAddr(instance, "vkCmdNextSubpass") + CmdNextSubpass2 = auto_cast GetInstanceProcAddr(instance, "vkCmdNextSubpass2") + CmdNextSubpass2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdNextSubpass2KHR") + CmdPipelineBarrier = auto_cast GetInstanceProcAddr(instance, "vkCmdPipelineBarrier") + CmdPipelineBarrier2 = auto_cast GetInstanceProcAddr(instance, "vkCmdPipelineBarrier2") + CmdPipelineBarrier2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdPipelineBarrier2KHR") + CmdPreprocessGeneratedCommandsNV = auto_cast GetInstanceProcAddr(instance, "vkCmdPreprocessGeneratedCommandsNV") + CmdPushConstants = auto_cast GetInstanceProcAddr(instance, "vkCmdPushConstants") + CmdPushDescriptorSetKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdPushDescriptorSetKHR") + CmdPushDescriptorSetWithTemplateKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdPushDescriptorSetWithTemplateKHR") + CmdResetEvent = auto_cast GetInstanceProcAddr(instance, "vkCmdResetEvent") + CmdResetEvent2 = auto_cast GetInstanceProcAddr(instance, "vkCmdResetEvent2") + CmdResetEvent2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdResetEvent2KHR") + CmdResetQueryPool = auto_cast GetInstanceProcAddr(instance, "vkCmdResetQueryPool") + CmdResolveImage = auto_cast GetInstanceProcAddr(instance, "vkCmdResolveImage") + CmdResolveImage2 = auto_cast GetInstanceProcAddr(instance, "vkCmdResolveImage2") + CmdResolveImage2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdResolveImage2KHR") + CmdSetBlendConstants = auto_cast GetInstanceProcAddr(instance, "vkCmdSetBlendConstants") + CmdSetCheckpointNV = auto_cast GetInstanceProcAddr(instance, "vkCmdSetCheckpointNV") + CmdSetCoarseSampleOrderNV = auto_cast GetInstanceProcAddr(instance, "vkCmdSetCoarseSampleOrderNV") + CmdSetCullMode = auto_cast GetInstanceProcAddr(instance, "vkCmdSetCullMode") + CmdSetCullModeEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetCullModeEXT") + CmdSetDepthBias = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthBias") + CmdSetDepthBiasEnable = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthBiasEnable") + CmdSetDepthBiasEnableEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthBiasEnableEXT") + CmdSetDepthBounds = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthBounds") + CmdSetDepthBoundsTestEnable = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthBoundsTestEnable") + CmdSetDepthBoundsTestEnableEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthBoundsTestEnableEXT") + CmdSetDepthCompareOp = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthCompareOp") + CmdSetDepthCompareOpEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthCompareOpEXT") + CmdSetDepthTestEnable = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthTestEnable") + CmdSetDepthTestEnableEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthTestEnableEXT") + CmdSetDepthWriteEnable = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthWriteEnable") + CmdSetDepthWriteEnableEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDepthWriteEnableEXT") + CmdSetDeviceMask = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDeviceMask") + CmdSetDeviceMaskKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDeviceMaskKHR") + CmdSetDiscardRectangleEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetDiscardRectangleEXT") + CmdSetEvent = auto_cast GetInstanceProcAddr(instance, "vkCmdSetEvent") + CmdSetEvent2 = auto_cast GetInstanceProcAddr(instance, "vkCmdSetEvent2") + CmdSetEvent2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdSetEvent2KHR") + CmdSetExclusiveScissorNV = auto_cast GetInstanceProcAddr(instance, "vkCmdSetExclusiveScissorNV") + CmdSetFragmentShadingRateEnumNV = auto_cast GetInstanceProcAddr(instance, "vkCmdSetFragmentShadingRateEnumNV") + CmdSetFragmentShadingRateKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdSetFragmentShadingRateKHR") + CmdSetFrontFace = auto_cast GetInstanceProcAddr(instance, "vkCmdSetFrontFace") + CmdSetFrontFaceEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetFrontFaceEXT") + CmdSetLineStippleEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetLineStippleEXT") + CmdSetLineWidth = auto_cast GetInstanceProcAddr(instance, "vkCmdSetLineWidth") + CmdSetLogicOpEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetLogicOpEXT") + CmdSetPatchControlPointsEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetPatchControlPointsEXT") + CmdSetPerformanceMarkerINTEL = auto_cast GetInstanceProcAddr(instance, "vkCmdSetPerformanceMarkerINTEL") + CmdSetPerformanceOverrideINTEL = auto_cast GetInstanceProcAddr(instance, "vkCmdSetPerformanceOverrideINTEL") + CmdSetPerformanceStreamMarkerINTEL = auto_cast GetInstanceProcAddr(instance, "vkCmdSetPerformanceStreamMarkerINTEL") + CmdSetPrimitiveRestartEnable = auto_cast GetInstanceProcAddr(instance, "vkCmdSetPrimitiveRestartEnable") + CmdSetPrimitiveRestartEnableEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetPrimitiveRestartEnableEXT") + CmdSetPrimitiveTopology = auto_cast GetInstanceProcAddr(instance, "vkCmdSetPrimitiveTopology") + CmdSetPrimitiveTopologyEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetPrimitiveTopologyEXT") + CmdSetRasterizerDiscardEnable = auto_cast GetInstanceProcAddr(instance, "vkCmdSetRasterizerDiscardEnable") + CmdSetRasterizerDiscardEnableEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetRasterizerDiscardEnableEXT") + CmdSetRayTracingPipelineStackSizeKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdSetRayTracingPipelineStackSizeKHR") + CmdSetSampleLocationsEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetSampleLocationsEXT") + CmdSetScissor = auto_cast GetInstanceProcAddr(instance, "vkCmdSetScissor") + CmdSetScissorWithCount = auto_cast GetInstanceProcAddr(instance, "vkCmdSetScissorWithCount") + CmdSetScissorWithCountEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetScissorWithCountEXT") + CmdSetStencilCompareMask = auto_cast GetInstanceProcAddr(instance, "vkCmdSetStencilCompareMask") + CmdSetStencilOp = auto_cast GetInstanceProcAddr(instance, "vkCmdSetStencilOp") + CmdSetStencilOpEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetStencilOpEXT") + CmdSetStencilReference = auto_cast GetInstanceProcAddr(instance, "vkCmdSetStencilReference") + CmdSetStencilTestEnable = auto_cast GetInstanceProcAddr(instance, "vkCmdSetStencilTestEnable") + CmdSetStencilTestEnableEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetStencilTestEnableEXT") + CmdSetStencilWriteMask = auto_cast GetInstanceProcAddr(instance, "vkCmdSetStencilWriteMask") + CmdSetVertexInputEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetVertexInputEXT") + CmdSetViewport = auto_cast GetInstanceProcAddr(instance, "vkCmdSetViewport") + CmdSetViewportShadingRatePaletteNV = auto_cast GetInstanceProcAddr(instance, "vkCmdSetViewportShadingRatePaletteNV") + CmdSetViewportWScalingNV = auto_cast GetInstanceProcAddr(instance, "vkCmdSetViewportWScalingNV") + CmdSetViewportWithCount = auto_cast GetInstanceProcAddr(instance, "vkCmdSetViewportWithCount") + CmdSetViewportWithCountEXT = auto_cast GetInstanceProcAddr(instance, "vkCmdSetViewportWithCountEXT") + CmdSubpassShadingHUAWEI = auto_cast GetInstanceProcAddr(instance, "vkCmdSubpassShadingHUAWEI") + CmdTraceRaysIndirectKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdTraceRaysIndirectKHR") + CmdTraceRaysKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdTraceRaysKHR") + CmdTraceRaysNV = auto_cast GetInstanceProcAddr(instance, "vkCmdTraceRaysNV") + CmdUpdateBuffer = auto_cast GetInstanceProcAddr(instance, "vkCmdUpdateBuffer") + CmdWaitEvents = auto_cast GetInstanceProcAddr(instance, "vkCmdWaitEvents") + CmdWaitEvents2 = auto_cast GetInstanceProcAddr(instance, "vkCmdWaitEvents2") + CmdWaitEvents2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdWaitEvents2KHR") + CmdWriteAccelerationStructuresPropertiesKHR = auto_cast GetInstanceProcAddr(instance, "vkCmdWriteAccelerationStructuresPropertiesKHR") + CmdWriteAccelerationStructuresPropertiesNV = auto_cast GetInstanceProcAddr(instance, "vkCmdWriteAccelerationStructuresPropertiesNV") + CmdWriteBufferMarker2AMD = auto_cast GetInstanceProcAddr(instance, "vkCmdWriteBufferMarker2AMD") + CmdWriteBufferMarkerAMD = auto_cast GetInstanceProcAddr(instance, "vkCmdWriteBufferMarkerAMD") + CmdWriteTimestamp = auto_cast GetInstanceProcAddr(instance, "vkCmdWriteTimestamp") + CmdWriteTimestamp2 = auto_cast GetInstanceProcAddr(instance, "vkCmdWriteTimestamp2") + CmdWriteTimestamp2KHR = auto_cast GetInstanceProcAddr(instance, "vkCmdWriteTimestamp2KHR") + CompileDeferredNV = auto_cast GetInstanceProcAddr(instance, "vkCompileDeferredNV") + CopyAccelerationStructureKHR = auto_cast GetInstanceProcAddr(instance, "vkCopyAccelerationStructureKHR") + CopyAccelerationStructureToMemoryKHR = auto_cast GetInstanceProcAddr(instance, "vkCopyAccelerationStructureToMemoryKHR") + CopyMemoryToAccelerationStructureKHR = auto_cast GetInstanceProcAddr(instance, "vkCopyMemoryToAccelerationStructureKHR") + CreateAccelerationStructureKHR = auto_cast GetInstanceProcAddr(instance, "vkCreateAccelerationStructureKHR") + CreateAccelerationStructureNV = auto_cast GetInstanceProcAddr(instance, "vkCreateAccelerationStructureNV") + CreateBuffer = auto_cast GetInstanceProcAddr(instance, "vkCreateBuffer") + CreateBufferView = auto_cast GetInstanceProcAddr(instance, "vkCreateBufferView") + CreateCommandPool = auto_cast GetInstanceProcAddr(instance, "vkCreateCommandPool") + CreateComputePipelines = auto_cast GetInstanceProcAddr(instance, "vkCreateComputePipelines") + CreateCuFunctionNVX = auto_cast GetInstanceProcAddr(instance, "vkCreateCuFunctionNVX") + CreateCuModuleNVX = auto_cast GetInstanceProcAddr(instance, "vkCreateCuModuleNVX") + CreateDeferredOperationKHR = auto_cast GetInstanceProcAddr(instance, "vkCreateDeferredOperationKHR") + CreateDescriptorPool = auto_cast GetInstanceProcAddr(instance, "vkCreateDescriptorPool") + CreateDescriptorSetLayout = auto_cast GetInstanceProcAddr(instance, "vkCreateDescriptorSetLayout") + CreateDescriptorUpdateTemplate = auto_cast GetInstanceProcAddr(instance, "vkCreateDescriptorUpdateTemplate") + CreateDescriptorUpdateTemplateKHR = auto_cast GetInstanceProcAddr(instance, "vkCreateDescriptorUpdateTemplateKHR") + CreateEvent = auto_cast GetInstanceProcAddr(instance, "vkCreateEvent") + CreateFence = auto_cast GetInstanceProcAddr(instance, "vkCreateFence") + CreateFramebuffer = auto_cast GetInstanceProcAddr(instance, "vkCreateFramebuffer") + CreateGraphicsPipelines = auto_cast GetInstanceProcAddr(instance, "vkCreateGraphicsPipelines") + CreateImage = auto_cast GetInstanceProcAddr(instance, "vkCreateImage") + CreateImageView = auto_cast GetInstanceProcAddr(instance, "vkCreateImageView") + CreateIndirectCommandsLayoutNV = auto_cast GetInstanceProcAddr(instance, "vkCreateIndirectCommandsLayoutNV") + CreatePipelineCache = auto_cast GetInstanceProcAddr(instance, "vkCreatePipelineCache") + CreatePipelineLayout = auto_cast GetInstanceProcAddr(instance, "vkCreatePipelineLayout") + CreatePrivateDataSlot = auto_cast GetInstanceProcAddr(instance, "vkCreatePrivateDataSlot") + CreatePrivateDataSlotEXT = auto_cast GetInstanceProcAddr(instance, "vkCreatePrivateDataSlotEXT") + CreateQueryPool = auto_cast GetInstanceProcAddr(instance, "vkCreateQueryPool") + CreateRayTracingPipelinesKHR = auto_cast GetInstanceProcAddr(instance, "vkCreateRayTracingPipelinesKHR") + CreateRayTracingPipelinesNV = auto_cast GetInstanceProcAddr(instance, "vkCreateRayTracingPipelinesNV") + CreateRenderPass = auto_cast GetInstanceProcAddr(instance, "vkCreateRenderPass") + CreateRenderPass2 = auto_cast GetInstanceProcAddr(instance, "vkCreateRenderPass2") + CreateRenderPass2KHR = auto_cast GetInstanceProcAddr(instance, "vkCreateRenderPass2KHR") + CreateSampler = auto_cast GetInstanceProcAddr(instance, "vkCreateSampler") + CreateSamplerYcbcrConversion = auto_cast GetInstanceProcAddr(instance, "vkCreateSamplerYcbcrConversion") + CreateSamplerYcbcrConversionKHR = auto_cast GetInstanceProcAddr(instance, "vkCreateSamplerYcbcrConversionKHR") + CreateSemaphore = auto_cast GetInstanceProcAddr(instance, "vkCreateSemaphore") + CreateShaderModule = auto_cast GetInstanceProcAddr(instance, "vkCreateShaderModule") + CreateSharedSwapchainsKHR = auto_cast GetInstanceProcAddr(instance, "vkCreateSharedSwapchainsKHR") + CreateSwapchainKHR = auto_cast GetInstanceProcAddr(instance, "vkCreateSwapchainKHR") + CreateValidationCacheEXT = auto_cast GetInstanceProcAddr(instance, "vkCreateValidationCacheEXT") + DebugMarkerSetObjectNameEXT = auto_cast GetInstanceProcAddr(instance, "vkDebugMarkerSetObjectNameEXT") + DebugMarkerSetObjectTagEXT = auto_cast GetInstanceProcAddr(instance, "vkDebugMarkerSetObjectTagEXT") + DeferredOperationJoinKHR = auto_cast GetInstanceProcAddr(instance, "vkDeferredOperationJoinKHR") + DestroyAccelerationStructureKHR = auto_cast GetInstanceProcAddr(instance, "vkDestroyAccelerationStructureKHR") + DestroyAccelerationStructureNV = auto_cast GetInstanceProcAddr(instance, "vkDestroyAccelerationStructureNV") + DestroyBuffer = auto_cast GetInstanceProcAddr(instance, "vkDestroyBuffer") + DestroyBufferView = auto_cast GetInstanceProcAddr(instance, "vkDestroyBufferView") + DestroyCommandPool = auto_cast GetInstanceProcAddr(instance, "vkDestroyCommandPool") + DestroyCuFunctionNVX = auto_cast GetInstanceProcAddr(instance, "vkDestroyCuFunctionNVX") + DestroyCuModuleNVX = auto_cast GetInstanceProcAddr(instance, "vkDestroyCuModuleNVX") + DestroyDeferredOperationKHR = auto_cast GetInstanceProcAddr(instance, "vkDestroyDeferredOperationKHR") + DestroyDescriptorPool = auto_cast GetInstanceProcAddr(instance, "vkDestroyDescriptorPool") + DestroyDescriptorSetLayout = auto_cast GetInstanceProcAddr(instance, "vkDestroyDescriptorSetLayout") + DestroyDescriptorUpdateTemplate = auto_cast GetInstanceProcAddr(instance, "vkDestroyDescriptorUpdateTemplate") + DestroyDescriptorUpdateTemplateKHR = auto_cast GetInstanceProcAddr(instance, "vkDestroyDescriptorUpdateTemplateKHR") + DestroyDevice = auto_cast GetInstanceProcAddr(instance, "vkDestroyDevice") + DestroyEvent = auto_cast GetInstanceProcAddr(instance, "vkDestroyEvent") + DestroyFence = auto_cast GetInstanceProcAddr(instance, "vkDestroyFence") + DestroyFramebuffer = auto_cast GetInstanceProcAddr(instance, "vkDestroyFramebuffer") + DestroyImage = auto_cast GetInstanceProcAddr(instance, "vkDestroyImage") + DestroyImageView = auto_cast GetInstanceProcAddr(instance, "vkDestroyImageView") + DestroyIndirectCommandsLayoutNV = auto_cast GetInstanceProcAddr(instance, "vkDestroyIndirectCommandsLayoutNV") + DestroyPipeline = auto_cast GetInstanceProcAddr(instance, "vkDestroyPipeline") + DestroyPipelineCache = auto_cast GetInstanceProcAddr(instance, "vkDestroyPipelineCache") + DestroyPipelineLayout = auto_cast GetInstanceProcAddr(instance, "vkDestroyPipelineLayout") + DestroyPrivateDataSlot = auto_cast GetInstanceProcAddr(instance, "vkDestroyPrivateDataSlot") + DestroyPrivateDataSlotEXT = auto_cast GetInstanceProcAddr(instance, "vkDestroyPrivateDataSlotEXT") + DestroyQueryPool = auto_cast GetInstanceProcAddr(instance, "vkDestroyQueryPool") + DestroyRenderPass = auto_cast GetInstanceProcAddr(instance, "vkDestroyRenderPass") + DestroySampler = auto_cast GetInstanceProcAddr(instance, "vkDestroySampler") + DestroySamplerYcbcrConversion = auto_cast GetInstanceProcAddr(instance, "vkDestroySamplerYcbcrConversion") + DestroySamplerYcbcrConversionKHR = auto_cast GetInstanceProcAddr(instance, "vkDestroySamplerYcbcrConversionKHR") + DestroySemaphore = auto_cast GetInstanceProcAddr(instance, "vkDestroySemaphore") + DestroyShaderModule = auto_cast GetInstanceProcAddr(instance, "vkDestroyShaderModule") + DestroySwapchainKHR = auto_cast GetInstanceProcAddr(instance, "vkDestroySwapchainKHR") + DestroyValidationCacheEXT = auto_cast GetInstanceProcAddr(instance, "vkDestroyValidationCacheEXT") + DeviceWaitIdle = auto_cast GetInstanceProcAddr(instance, "vkDeviceWaitIdle") + DisplayPowerControlEXT = auto_cast GetInstanceProcAddr(instance, "vkDisplayPowerControlEXT") + EndCommandBuffer = auto_cast GetInstanceProcAddr(instance, "vkEndCommandBuffer") + FlushMappedMemoryRanges = auto_cast GetInstanceProcAddr(instance, "vkFlushMappedMemoryRanges") + FreeCommandBuffers = auto_cast GetInstanceProcAddr(instance, "vkFreeCommandBuffers") + FreeDescriptorSets = auto_cast GetInstanceProcAddr(instance, "vkFreeDescriptorSets") + FreeMemory = auto_cast GetInstanceProcAddr(instance, "vkFreeMemory") + GetAccelerationStructureBuildSizesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetAccelerationStructureBuildSizesKHR") + GetAccelerationStructureDeviceAddressKHR = auto_cast GetInstanceProcAddr(instance, "vkGetAccelerationStructureDeviceAddressKHR") + GetAccelerationStructureHandleNV = auto_cast GetInstanceProcAddr(instance, "vkGetAccelerationStructureHandleNV") + GetAccelerationStructureMemoryRequirementsNV = auto_cast GetInstanceProcAddr(instance, "vkGetAccelerationStructureMemoryRequirementsNV") + GetBufferDeviceAddress = auto_cast GetInstanceProcAddr(instance, "vkGetBufferDeviceAddress") + GetBufferDeviceAddressEXT = auto_cast GetInstanceProcAddr(instance, "vkGetBufferDeviceAddressEXT") + GetBufferDeviceAddressKHR = auto_cast GetInstanceProcAddr(instance, "vkGetBufferDeviceAddressKHR") + GetBufferMemoryRequirements = auto_cast GetInstanceProcAddr(instance, "vkGetBufferMemoryRequirements") + GetBufferMemoryRequirements2 = auto_cast GetInstanceProcAddr(instance, "vkGetBufferMemoryRequirements2") + GetBufferMemoryRequirements2KHR = auto_cast GetInstanceProcAddr(instance, "vkGetBufferMemoryRequirements2KHR") + GetBufferOpaqueCaptureAddress = auto_cast GetInstanceProcAddr(instance, "vkGetBufferOpaqueCaptureAddress") + GetBufferOpaqueCaptureAddressKHR = auto_cast GetInstanceProcAddr(instance, "vkGetBufferOpaqueCaptureAddressKHR") + GetCalibratedTimestampsEXT = auto_cast GetInstanceProcAddr(instance, "vkGetCalibratedTimestampsEXT") + GetDeferredOperationMaxConcurrencyKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDeferredOperationMaxConcurrencyKHR") + GetDeferredOperationResultKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDeferredOperationResultKHR") + GetDescriptorSetHostMappingVALVE = auto_cast GetInstanceProcAddr(instance, "vkGetDescriptorSetHostMappingVALVE") + GetDescriptorSetLayoutHostMappingInfoVALVE = auto_cast GetInstanceProcAddr(instance, "vkGetDescriptorSetLayoutHostMappingInfoVALVE") + GetDescriptorSetLayoutSupport = auto_cast GetInstanceProcAddr(instance, "vkGetDescriptorSetLayoutSupport") + GetDescriptorSetLayoutSupportKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDescriptorSetLayoutSupportKHR") + GetDeviceAccelerationStructureCompatibilityKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceAccelerationStructureCompatibilityKHR") + GetDeviceBufferMemoryRequirements = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceBufferMemoryRequirements") + GetDeviceBufferMemoryRequirementsKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceBufferMemoryRequirementsKHR") + GetDeviceGroupPeerMemoryFeatures = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceGroupPeerMemoryFeatures") + GetDeviceGroupPeerMemoryFeaturesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceGroupPeerMemoryFeaturesKHR") + GetDeviceGroupPresentCapabilitiesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceGroupPresentCapabilitiesKHR") + GetDeviceGroupSurfacePresentModes2EXT = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceGroupSurfacePresentModes2EXT") + GetDeviceGroupSurfacePresentModesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceGroupSurfacePresentModesKHR") + GetDeviceImageMemoryRequirements = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceImageMemoryRequirements") + GetDeviceImageMemoryRequirementsKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceImageMemoryRequirementsKHR") + GetDeviceImageSparseMemoryRequirements = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceImageSparseMemoryRequirements") + GetDeviceImageSparseMemoryRequirementsKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceImageSparseMemoryRequirementsKHR") + GetDeviceMemoryCommitment = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceMemoryCommitment") + GetDeviceMemoryOpaqueCaptureAddress = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceMemoryOpaqueCaptureAddress") + GetDeviceMemoryOpaqueCaptureAddressKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceMemoryOpaqueCaptureAddressKHR") + GetDeviceProcAddr = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceProcAddr") + GetDeviceQueue = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceQueue") + GetDeviceQueue2 = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceQueue2") + GetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI = auto_cast GetInstanceProcAddr(instance, "vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI") + GetEventStatus = auto_cast GetInstanceProcAddr(instance, "vkGetEventStatus") + GetFenceFdKHR = auto_cast GetInstanceProcAddr(instance, "vkGetFenceFdKHR") + GetFenceStatus = auto_cast GetInstanceProcAddr(instance, "vkGetFenceStatus") + GetFenceWin32HandleKHR = auto_cast GetInstanceProcAddr(instance, "vkGetFenceWin32HandleKHR") + GetGeneratedCommandsMemoryRequirementsNV = auto_cast GetInstanceProcAddr(instance, "vkGetGeneratedCommandsMemoryRequirementsNV") + GetImageDrmFormatModifierPropertiesEXT = auto_cast GetInstanceProcAddr(instance, "vkGetImageDrmFormatModifierPropertiesEXT") + GetImageMemoryRequirements = auto_cast GetInstanceProcAddr(instance, "vkGetImageMemoryRequirements") + GetImageMemoryRequirements2 = auto_cast GetInstanceProcAddr(instance, "vkGetImageMemoryRequirements2") + GetImageMemoryRequirements2KHR = auto_cast GetInstanceProcAddr(instance, "vkGetImageMemoryRequirements2KHR") + GetImageSparseMemoryRequirements = auto_cast GetInstanceProcAddr(instance, "vkGetImageSparseMemoryRequirements") + GetImageSparseMemoryRequirements2 = auto_cast GetInstanceProcAddr(instance, "vkGetImageSparseMemoryRequirements2") + GetImageSparseMemoryRequirements2KHR = auto_cast GetInstanceProcAddr(instance, "vkGetImageSparseMemoryRequirements2KHR") + GetImageSubresourceLayout = auto_cast GetInstanceProcAddr(instance, "vkGetImageSubresourceLayout") + GetImageViewAddressNVX = auto_cast GetInstanceProcAddr(instance, "vkGetImageViewAddressNVX") + GetImageViewHandleNVX = auto_cast GetInstanceProcAddr(instance, "vkGetImageViewHandleNVX") + GetMemoryFdKHR = auto_cast GetInstanceProcAddr(instance, "vkGetMemoryFdKHR") + GetMemoryFdPropertiesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetMemoryFdPropertiesKHR") + GetMemoryHostPointerPropertiesEXT = auto_cast GetInstanceProcAddr(instance, "vkGetMemoryHostPointerPropertiesEXT") + GetMemoryRemoteAddressNV = auto_cast GetInstanceProcAddr(instance, "vkGetMemoryRemoteAddressNV") + GetMemoryWin32HandleKHR = auto_cast GetInstanceProcAddr(instance, "vkGetMemoryWin32HandleKHR") + GetMemoryWin32HandleNV = auto_cast GetInstanceProcAddr(instance, "vkGetMemoryWin32HandleNV") + GetMemoryWin32HandlePropertiesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetMemoryWin32HandlePropertiesKHR") + GetPastPresentationTimingGOOGLE = auto_cast GetInstanceProcAddr(instance, "vkGetPastPresentationTimingGOOGLE") + GetPerformanceParameterINTEL = auto_cast GetInstanceProcAddr(instance, "vkGetPerformanceParameterINTEL") + GetPipelineCacheData = auto_cast GetInstanceProcAddr(instance, "vkGetPipelineCacheData") + GetPipelineExecutableInternalRepresentationsKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPipelineExecutableInternalRepresentationsKHR") + GetPipelineExecutablePropertiesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPipelineExecutablePropertiesKHR") + GetPipelineExecutableStatisticsKHR = auto_cast GetInstanceProcAddr(instance, "vkGetPipelineExecutableStatisticsKHR") + GetPrivateData = auto_cast GetInstanceProcAddr(instance, "vkGetPrivateData") + GetPrivateDataEXT = auto_cast GetInstanceProcAddr(instance, "vkGetPrivateDataEXT") + GetQueryPoolResults = auto_cast GetInstanceProcAddr(instance, "vkGetQueryPoolResults") + GetQueueCheckpointData2NV = auto_cast GetInstanceProcAddr(instance, "vkGetQueueCheckpointData2NV") + GetQueueCheckpointDataNV = auto_cast GetInstanceProcAddr(instance, "vkGetQueueCheckpointDataNV") + GetRayTracingCaptureReplayShaderGroupHandlesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetRayTracingCaptureReplayShaderGroupHandlesKHR") + GetRayTracingShaderGroupHandlesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetRayTracingShaderGroupHandlesKHR") + GetRayTracingShaderGroupHandlesNV = auto_cast GetInstanceProcAddr(instance, "vkGetRayTracingShaderGroupHandlesNV") + GetRayTracingShaderGroupStackSizeKHR = auto_cast GetInstanceProcAddr(instance, "vkGetRayTracingShaderGroupStackSizeKHR") + GetRefreshCycleDurationGOOGLE = auto_cast GetInstanceProcAddr(instance, "vkGetRefreshCycleDurationGOOGLE") + GetRenderAreaGranularity = auto_cast GetInstanceProcAddr(instance, "vkGetRenderAreaGranularity") + GetSemaphoreCounterValue = auto_cast GetInstanceProcAddr(instance, "vkGetSemaphoreCounterValue") + GetSemaphoreCounterValueKHR = auto_cast GetInstanceProcAddr(instance, "vkGetSemaphoreCounterValueKHR") + GetSemaphoreFdKHR = auto_cast GetInstanceProcAddr(instance, "vkGetSemaphoreFdKHR") + GetSemaphoreWin32HandleKHR = auto_cast GetInstanceProcAddr(instance, "vkGetSemaphoreWin32HandleKHR") + GetShaderInfoAMD = auto_cast GetInstanceProcAddr(instance, "vkGetShaderInfoAMD") + GetSwapchainCounterEXT = auto_cast GetInstanceProcAddr(instance, "vkGetSwapchainCounterEXT") + GetSwapchainImagesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetSwapchainImagesKHR") + GetSwapchainStatusKHR = auto_cast GetInstanceProcAddr(instance, "vkGetSwapchainStatusKHR") + GetValidationCacheDataEXT = auto_cast GetInstanceProcAddr(instance, "vkGetValidationCacheDataEXT") + ImportFenceFdKHR = auto_cast GetInstanceProcAddr(instance, "vkImportFenceFdKHR") + ImportFenceWin32HandleKHR = auto_cast GetInstanceProcAddr(instance, "vkImportFenceWin32HandleKHR") + ImportSemaphoreFdKHR = auto_cast GetInstanceProcAddr(instance, "vkImportSemaphoreFdKHR") + ImportSemaphoreWin32HandleKHR = auto_cast GetInstanceProcAddr(instance, "vkImportSemaphoreWin32HandleKHR") + InitializePerformanceApiINTEL = auto_cast GetInstanceProcAddr(instance, "vkInitializePerformanceApiINTEL") + InvalidateMappedMemoryRanges = auto_cast GetInstanceProcAddr(instance, "vkInvalidateMappedMemoryRanges") + MapMemory = auto_cast GetInstanceProcAddr(instance, "vkMapMemory") + MergePipelineCaches = auto_cast GetInstanceProcAddr(instance, "vkMergePipelineCaches") + MergeValidationCachesEXT = auto_cast GetInstanceProcAddr(instance, "vkMergeValidationCachesEXT") + QueueBeginDebugUtilsLabelEXT = auto_cast GetInstanceProcAddr(instance, "vkQueueBeginDebugUtilsLabelEXT") + QueueBindSparse = auto_cast GetInstanceProcAddr(instance, "vkQueueBindSparse") + QueueEndDebugUtilsLabelEXT = auto_cast GetInstanceProcAddr(instance, "vkQueueEndDebugUtilsLabelEXT") + QueueInsertDebugUtilsLabelEXT = auto_cast GetInstanceProcAddr(instance, "vkQueueInsertDebugUtilsLabelEXT") + QueuePresentKHR = auto_cast GetInstanceProcAddr(instance, "vkQueuePresentKHR") + QueueSetPerformanceConfigurationINTEL = auto_cast GetInstanceProcAddr(instance, "vkQueueSetPerformanceConfigurationINTEL") + QueueSubmit = auto_cast GetInstanceProcAddr(instance, "vkQueueSubmit") + QueueSubmit2 = auto_cast GetInstanceProcAddr(instance, "vkQueueSubmit2") + QueueSubmit2KHR = auto_cast GetInstanceProcAddr(instance, "vkQueueSubmit2KHR") + QueueWaitIdle = auto_cast GetInstanceProcAddr(instance, "vkQueueWaitIdle") + RegisterDeviceEventEXT = auto_cast GetInstanceProcAddr(instance, "vkRegisterDeviceEventEXT") + RegisterDisplayEventEXT = auto_cast GetInstanceProcAddr(instance, "vkRegisterDisplayEventEXT") + ReleaseFullScreenExclusiveModeEXT = auto_cast GetInstanceProcAddr(instance, "vkReleaseFullScreenExclusiveModeEXT") + ReleasePerformanceConfigurationINTEL = auto_cast GetInstanceProcAddr(instance, "vkReleasePerformanceConfigurationINTEL") + ReleaseProfilingLockKHR = auto_cast GetInstanceProcAddr(instance, "vkReleaseProfilingLockKHR") + ResetCommandBuffer = auto_cast GetInstanceProcAddr(instance, "vkResetCommandBuffer") + ResetCommandPool = auto_cast GetInstanceProcAddr(instance, "vkResetCommandPool") + ResetDescriptorPool = auto_cast GetInstanceProcAddr(instance, "vkResetDescriptorPool") + ResetEvent = auto_cast GetInstanceProcAddr(instance, "vkResetEvent") + ResetFences = auto_cast GetInstanceProcAddr(instance, "vkResetFences") + ResetQueryPool = auto_cast GetInstanceProcAddr(instance, "vkResetQueryPool") + ResetQueryPoolEXT = auto_cast GetInstanceProcAddr(instance, "vkResetQueryPoolEXT") + SetDebugUtilsObjectNameEXT = auto_cast GetInstanceProcAddr(instance, "vkSetDebugUtilsObjectNameEXT") + SetDebugUtilsObjectTagEXT = auto_cast GetInstanceProcAddr(instance, "vkSetDebugUtilsObjectTagEXT") + SetDeviceMemoryPriorityEXT = auto_cast GetInstanceProcAddr(instance, "vkSetDeviceMemoryPriorityEXT") + SetEvent = auto_cast GetInstanceProcAddr(instance, "vkSetEvent") + SetHdrMetadataEXT = auto_cast GetInstanceProcAddr(instance, "vkSetHdrMetadataEXT") + SetLocalDimmingAMD = auto_cast GetInstanceProcAddr(instance, "vkSetLocalDimmingAMD") + SetPrivateData = auto_cast GetInstanceProcAddr(instance, "vkSetPrivateData") + SetPrivateDataEXT = auto_cast GetInstanceProcAddr(instance, "vkSetPrivateDataEXT") + SignalSemaphore = auto_cast GetInstanceProcAddr(instance, "vkSignalSemaphore") + SignalSemaphoreKHR = auto_cast GetInstanceProcAddr(instance, "vkSignalSemaphoreKHR") + TrimCommandPool = auto_cast GetInstanceProcAddr(instance, "vkTrimCommandPool") + TrimCommandPoolKHR = auto_cast GetInstanceProcAddr(instance, "vkTrimCommandPoolKHR") + UninitializePerformanceApiINTEL = auto_cast GetInstanceProcAddr(instance, "vkUninitializePerformanceApiINTEL") + UnmapMemory = auto_cast GetInstanceProcAddr(instance, "vkUnmapMemory") + UpdateDescriptorSetWithTemplate = auto_cast GetInstanceProcAddr(instance, "vkUpdateDescriptorSetWithTemplate") + UpdateDescriptorSetWithTemplateKHR = auto_cast GetInstanceProcAddr(instance, "vkUpdateDescriptorSetWithTemplateKHR") + UpdateDescriptorSets = auto_cast GetInstanceProcAddr(instance, "vkUpdateDescriptorSets") + WaitForFences = auto_cast GetInstanceProcAddr(instance, "vkWaitForFences") + WaitForPresentKHR = auto_cast GetInstanceProcAddr(instance, "vkWaitForPresentKHR") + WaitSemaphores = auto_cast GetInstanceProcAddr(instance, "vkWaitSemaphores") + WaitSemaphoresKHR = auto_cast GetInstanceProcAddr(instance, "vkWaitSemaphoresKHR") + WriteAccelerationStructuresPropertiesKHR = auto_cast GetInstanceProcAddr(instance, "vkWriteAccelerationStructuresPropertiesKHR") +} + +load_proc_addresses_global :: proc(vk_get_instance_proc_addr: rawptr) { + GetInstanceProcAddr = auto_cast vk_get_instance_proc_addr + + CreateInstance = auto_cast GetInstanceProcAddr(nil, "vkCreateInstance") + DebugUtilsMessengerCallbackEXT = auto_cast GetInstanceProcAddr(nil, "vkDebugUtilsMessengerCallbackEXT") + DeviceMemoryReportCallbackEXT = auto_cast GetInstanceProcAddr(nil, "vkDeviceMemoryReportCallbackEXT") + EnumerateInstanceExtensionProperties = auto_cast GetInstanceProcAddr(nil, "vkEnumerateInstanceExtensionProperties") + EnumerateInstanceLayerProperties = auto_cast GetInstanceProcAddr(nil, "vkEnumerateInstanceLayerProperties") + EnumerateInstanceVersion = auto_cast GetInstanceProcAddr(nil, "vkEnumerateInstanceVersion") +} + +load_proc_addresses :: proc{ + load_proc_addresses_global, + load_proc_addresses_instance, + load_proc_addresses_device, + load_proc_addresses_device_vtable, + load_proc_addresses_custom, +} diff --git a/vendor/vulkan/structs.odin b/vendor/vulkan/structs.odin index 4d90a53fa..3bc3e1935 100644 --- a/vendor/vulkan/structs.odin +++ b/vendor/vulkan/structs.odin @@ -5,7 +5,7 @@ package vulkan import "core:c" -when ODIN_OS == "windows" { +when ODIN_OS == .Windows { import win32 "core:sys/windows" HINSTANCE :: win32.HINSTANCE @@ -2170,6 +2170,537 @@ DeviceMemoryOpaqueCaptureAddressInfo :: struct { memory: DeviceMemory, } +PhysicalDeviceVulkan13Features :: struct { + sType: StructureType, + pNext: rawptr, + robustImageAccess: b32, + inlineUniformBlock: b32, + descriptorBindingInlineUniformBlockUpdateAfterBind: b32, + pipelineCreationCacheControl: b32, + privateData: b32, + shaderDemoteToHelperInvocation: b32, + shaderTerminateInvocation: b32, + subgroupSizeControl: b32, + computeFullSubgroups: b32, + synchronization2: b32, + textureCompressionASTC_HDR: b32, + shaderZeroInitializeWorkgroupMemory: b32, + dynamicRendering: b32, + shaderIntegerDotProduct: b32, + maintenance4: b32, +} + +PhysicalDeviceVulkan13Properties :: struct { + sType: StructureType, + pNext: rawptr, + minSubgroupSize: u32, + maxSubgroupSize: u32, + maxComputeWorkgroupSubgroups: u32, + requiredSubgroupSizeStages: ShaderStageFlags, + maxInlineUniformBlockSize: u32, + maxPerStageDescriptorInlineUniformBlocks: u32, + maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks: u32, + maxDescriptorSetInlineUniformBlocks: u32, + maxDescriptorSetUpdateAfterBindInlineUniformBlocks: u32, + maxInlineUniformTotalSize: u32, + integerDotProduct8BitUnsignedAccelerated: b32, + integerDotProduct8BitSignedAccelerated: b32, + integerDotProduct8BitMixedSignednessAccelerated: b32, + integerDotProduct4x8BitPackedUnsignedAccelerated: b32, + integerDotProduct4x8BitPackedSignedAccelerated: b32, + integerDotProduct4x8BitPackedMixedSignednessAccelerated: b32, + integerDotProduct16BitUnsignedAccelerated: b32, + integerDotProduct16BitSignedAccelerated: b32, + integerDotProduct16BitMixedSignednessAccelerated: b32, + integerDotProduct32BitUnsignedAccelerated: b32, + integerDotProduct32BitSignedAccelerated: b32, + integerDotProduct32BitMixedSignednessAccelerated: b32, + integerDotProduct64BitUnsignedAccelerated: b32, + integerDotProduct64BitSignedAccelerated: b32, + integerDotProduct64BitMixedSignednessAccelerated: b32, + integerDotProductAccumulatingSaturating8BitUnsignedAccelerated: b32, + integerDotProductAccumulatingSaturating8BitSignedAccelerated: b32, + integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated: b32, + integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated: b32, + integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated: b32, + integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated: b32, + integerDotProductAccumulatingSaturating16BitUnsignedAccelerated: b32, + integerDotProductAccumulatingSaturating16BitSignedAccelerated: b32, + integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated: b32, + integerDotProductAccumulatingSaturating32BitUnsignedAccelerated: b32, + integerDotProductAccumulatingSaturating32BitSignedAccelerated: b32, + integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated: b32, + integerDotProductAccumulatingSaturating64BitUnsignedAccelerated: b32, + integerDotProductAccumulatingSaturating64BitSignedAccelerated: b32, + integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated: b32, + storageTexelBufferOffsetAlignmentBytes: DeviceSize, + storageTexelBufferOffsetSingleTexelAlignment: b32, + uniformTexelBufferOffsetAlignmentBytes: DeviceSize, + uniformTexelBufferOffsetSingleTexelAlignment: b32, + maxBufferSize: DeviceSize, +} + +PipelineCreationFeedback :: struct { + flags: PipelineCreationFeedbackFlags, + duration: u64, +} + +PipelineCreationFeedbackCreateInfo :: struct { + sType: StructureType, + pNext: rawptr, + pPipelineCreationFeedback: ^PipelineCreationFeedback, + pipelineStageCreationFeedbackCount: u32, + pPipelineStageCreationFeedbacks: [^]PipelineCreationFeedback, +} + +PhysicalDeviceShaderTerminateInvocationFeatures :: struct { + sType: StructureType, + pNext: rawptr, + shaderTerminateInvocation: b32, +} + +PhysicalDeviceToolProperties :: struct { + sType: StructureType, + pNext: rawptr, + name: [MAX_EXTENSION_NAME_SIZE]byte, + version: [MAX_EXTENSION_NAME_SIZE]byte, + purposes: ToolPurposeFlags, + description: [MAX_DESCRIPTION_SIZE]byte, + layer: [MAX_EXTENSION_NAME_SIZE]byte, +} + +PhysicalDeviceShaderDemoteToHelperInvocationFeatures :: struct { + sType: StructureType, + pNext: rawptr, + shaderDemoteToHelperInvocation: b32, +} + +PhysicalDevicePrivateDataFeatures :: struct { + sType: StructureType, + pNext: rawptr, + privateData: b32, +} + +DevicePrivateDataCreateInfo :: struct { + sType: StructureType, + pNext: rawptr, + privateDataSlotRequestCount: u32, +} + +PrivateDataSlotCreateInfo :: struct { + sType: StructureType, + pNext: rawptr, + flags: PrivateDataSlotCreateFlags, +} + +PhysicalDevicePipelineCreationCacheControlFeatures :: struct { + sType: StructureType, + pNext: rawptr, + pipelineCreationCacheControl: b32, +} + +MemoryBarrier2 :: struct { + sType: StructureType, + pNext: rawptr, + srcStageMask: PipelineStageFlags2, + srcAccessMask: AccessFlags2, + dstStageMask: PipelineStageFlags2, + dstAccessMask: AccessFlags2, +} + +BufferMemoryBarrier2 :: struct { + sType: StructureType, + pNext: rawptr, + srcStageMask: PipelineStageFlags2, + srcAccessMask: AccessFlags2, + dstStageMask: PipelineStageFlags2, + dstAccessMask: AccessFlags2, + srcQueueFamilyIndex: u32, + dstQueueFamilyIndex: u32, + buffer: Buffer, + offset: DeviceSize, + size: DeviceSize, +} + +ImageMemoryBarrier2 :: struct { + sType: StructureType, + pNext: rawptr, + srcStageMask: PipelineStageFlags2, + srcAccessMask: AccessFlags2, + dstStageMask: PipelineStageFlags2, + dstAccessMask: AccessFlags2, + oldLayout: ImageLayout, + newLayout: ImageLayout, + srcQueueFamilyIndex: u32, + dstQueueFamilyIndex: u32, + image: Image, + subresourceRange: ImageSubresourceRange, +} + +DependencyInfo :: struct { + sType: StructureType, + pNext: rawptr, + dependencyFlags: DependencyFlags, + memoryBarrierCount: u32, + pMemoryBarriers: [^]MemoryBarrier2, + bufferMemoryBarrierCount: u32, + pBufferMemoryBarriers: [^]BufferMemoryBarrier2, + imageMemoryBarrierCount: u32, + pImageMemoryBarriers: [^]ImageMemoryBarrier2, +} + +SemaphoreSubmitInfo :: struct { + sType: StructureType, + pNext: rawptr, + semaphore: Semaphore, + value: u64, + stageMask: PipelineStageFlags2, + deviceIndex: u32, +} + +CommandBufferSubmitInfo :: struct { + sType: StructureType, + pNext: rawptr, + commandBuffer: CommandBuffer, + deviceMask: u32, +} + +SubmitInfo2 :: struct { + sType: StructureType, + pNext: rawptr, + flags: SubmitFlags, + waitSemaphoreInfoCount: u32, + pWaitSemaphoreInfos: [^]SemaphoreSubmitInfo, + commandBufferInfoCount: u32, + pCommandBufferInfos: [^]CommandBufferSubmitInfo, + signalSemaphoreInfoCount: u32, + pSignalSemaphoreInfos: [^]SemaphoreSubmitInfo, +} + +PhysicalDeviceSynchronization2Features :: struct { + sType: StructureType, + pNext: rawptr, + synchronization2: b32, +} + +PhysicalDeviceZeroInitializeWorkgroupMemoryFeatures :: struct { + sType: StructureType, + pNext: rawptr, + shaderZeroInitializeWorkgroupMemory: b32, +} + +PhysicalDeviceImageRobustnessFeatures :: struct { + sType: StructureType, + pNext: rawptr, + robustImageAccess: b32, +} + +BufferCopy2 :: struct { + sType: StructureType, + pNext: rawptr, + srcOffset: DeviceSize, + dstOffset: DeviceSize, + size: DeviceSize, +} + +CopyBufferInfo2 :: struct { + sType: StructureType, + pNext: rawptr, + srcBuffer: Buffer, + dstBuffer: Buffer, + regionCount: u32, + pRegions: [^]BufferCopy2, +} + +ImageCopy2 :: struct { + sType: StructureType, + pNext: rawptr, + srcSubresource: ImageSubresourceLayers, + srcOffset: Offset3D, + dstSubresource: ImageSubresourceLayers, + dstOffset: Offset3D, + extent: Extent3D, +} + +CopyImageInfo2 :: struct { + sType: StructureType, + pNext: rawptr, + srcImage: Image, + srcImageLayout: ImageLayout, + dstImage: Image, + dstImageLayout: ImageLayout, + regionCount: u32, + pRegions: [^]ImageCopy2, +} + +BufferImageCopy2 :: struct { + sType: StructureType, + pNext: rawptr, + bufferOffset: DeviceSize, + bufferRowLength: u32, + bufferImageHeight: u32, + imageSubresource: ImageSubresourceLayers, + imageOffset: Offset3D, + imageExtent: Extent3D, +} + +CopyBufferToImageInfo2 :: struct { + sType: StructureType, + pNext: rawptr, + srcBuffer: Buffer, + dstImage: Image, + dstImageLayout: ImageLayout, + regionCount: u32, + pRegions: [^]BufferImageCopy2, +} + +CopyImageToBufferInfo2 :: struct { + sType: StructureType, + pNext: rawptr, + srcImage: Image, + srcImageLayout: ImageLayout, + dstBuffer: Buffer, + regionCount: u32, + pRegions: [^]BufferImageCopy2, +} + +ImageBlit2 :: struct { + sType: StructureType, + pNext: rawptr, + srcSubresource: ImageSubresourceLayers, + srcOffsets: [2]Offset3D, + dstSubresource: ImageSubresourceLayers, + dstOffsets: [2]Offset3D, +} + +BlitImageInfo2 :: struct { + sType: StructureType, + pNext: rawptr, + srcImage: Image, + srcImageLayout: ImageLayout, + dstImage: Image, + dstImageLayout: ImageLayout, + regionCount: u32, + pRegions: [^]ImageBlit2, + filter: Filter, +} + +ImageResolve2 :: struct { + sType: StructureType, + pNext: rawptr, + srcSubresource: ImageSubresourceLayers, + srcOffset: Offset3D, + dstSubresource: ImageSubresourceLayers, + dstOffset: Offset3D, + extent: Extent3D, +} + +ResolveImageInfo2 :: struct { + sType: StructureType, + pNext: rawptr, + srcImage: Image, + srcImageLayout: ImageLayout, + dstImage: Image, + dstImageLayout: ImageLayout, + regionCount: u32, + pRegions: [^]ImageResolve2, +} + +PhysicalDeviceSubgroupSizeControlFeatures :: struct { + sType: StructureType, + pNext: rawptr, + subgroupSizeControl: b32, + computeFullSubgroups: b32, +} + +PhysicalDeviceSubgroupSizeControlProperties :: struct { + sType: StructureType, + pNext: rawptr, + minSubgroupSize: u32, + maxSubgroupSize: u32, + maxComputeWorkgroupSubgroups: u32, + requiredSubgroupSizeStages: ShaderStageFlags, +} + +PipelineShaderStageRequiredSubgroupSizeCreateInfo :: struct { + sType: StructureType, + pNext: rawptr, + requiredSubgroupSize: u32, +} + +PhysicalDeviceInlineUniformBlockFeatures :: struct { + sType: StructureType, + pNext: rawptr, + inlineUniformBlock: b32, + descriptorBindingInlineUniformBlockUpdateAfterBind: b32, +} + +PhysicalDeviceInlineUniformBlockProperties :: struct { + sType: StructureType, + pNext: rawptr, + maxInlineUniformBlockSize: u32, + maxPerStageDescriptorInlineUniformBlocks: u32, + maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks: u32, + maxDescriptorSetInlineUniformBlocks: u32, + maxDescriptorSetUpdateAfterBindInlineUniformBlocks: u32, +} + +WriteDescriptorSetInlineUniformBlock :: struct { + sType: StructureType, + pNext: rawptr, + dataSize: u32, + pData: rawptr, +} + +DescriptorPoolInlineUniformBlockCreateInfo :: struct { + sType: StructureType, + pNext: rawptr, + maxInlineUniformBlockBindings: u32, +} + +PhysicalDeviceTextureCompressionASTCHDRFeatures :: struct { + sType: StructureType, + pNext: rawptr, + textureCompressionASTC_HDR: b32, +} + +RenderingAttachmentInfo :: struct { + sType: StructureType, + pNext: rawptr, + imageView: ImageView, + imageLayout: ImageLayout, + resolveMode: ResolveModeFlags, + resolveImageView: ImageView, + resolveImageLayout: ImageLayout, + loadOp: AttachmentLoadOp, + storeOp: AttachmentStoreOp, + clearValue: ClearValue, +} + +RenderingInfo :: struct { + sType: StructureType, + pNext: rawptr, + flags: RenderingFlags, + renderArea: Rect2D, + layerCount: u32, + viewMask: u32, + colorAttachmentCount: u32, + pColorAttachments: [^]RenderingAttachmentInfo, + pDepthAttachment: ^RenderingAttachmentInfo, + pStencilAttachment: ^RenderingAttachmentInfo, +} + +PipelineRenderingCreateInfo :: struct { + sType: StructureType, + pNext: rawptr, + viewMask: u32, + colorAttachmentCount: u32, + pColorAttachmentFormats: [^]Format, + depthAttachmentFormat: Format, + stencilAttachmentFormat: Format, +} + +PhysicalDeviceDynamicRenderingFeatures :: struct { + sType: StructureType, + pNext: rawptr, + dynamicRendering: b32, +} + +CommandBufferInheritanceRenderingInfo :: struct { + sType: StructureType, + pNext: rawptr, + flags: RenderingFlags, + viewMask: u32, + colorAttachmentCount: u32, + pColorAttachmentFormats: [^]Format, + depthAttachmentFormat: Format, + stencilAttachmentFormat: Format, + rasterizationSamples: SampleCountFlags, +} + +PhysicalDeviceShaderIntegerDotProductFeatures :: struct { + sType: StructureType, + pNext: rawptr, + shaderIntegerDotProduct: b32, +} + +PhysicalDeviceShaderIntegerDotProductProperties :: struct { + sType: StructureType, + pNext: rawptr, + integerDotProduct8BitUnsignedAccelerated: b32, + integerDotProduct8BitSignedAccelerated: b32, + integerDotProduct8BitMixedSignednessAccelerated: b32, + integerDotProduct4x8BitPackedUnsignedAccelerated: b32, + integerDotProduct4x8BitPackedSignedAccelerated: b32, + integerDotProduct4x8BitPackedMixedSignednessAccelerated: b32, + integerDotProduct16BitUnsignedAccelerated: b32, + integerDotProduct16BitSignedAccelerated: b32, + integerDotProduct16BitMixedSignednessAccelerated: b32, + integerDotProduct32BitUnsignedAccelerated: b32, + integerDotProduct32BitSignedAccelerated: b32, + integerDotProduct32BitMixedSignednessAccelerated: b32, + integerDotProduct64BitUnsignedAccelerated: b32, + integerDotProduct64BitSignedAccelerated: b32, + integerDotProduct64BitMixedSignednessAccelerated: b32, + integerDotProductAccumulatingSaturating8BitUnsignedAccelerated: b32, + integerDotProductAccumulatingSaturating8BitSignedAccelerated: b32, + integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated: b32, + integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated: b32, + integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated: b32, + integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated: b32, + integerDotProductAccumulatingSaturating16BitUnsignedAccelerated: b32, + integerDotProductAccumulatingSaturating16BitSignedAccelerated: b32, + integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated: b32, + integerDotProductAccumulatingSaturating32BitUnsignedAccelerated: b32, + integerDotProductAccumulatingSaturating32BitSignedAccelerated: b32, + integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated: b32, + integerDotProductAccumulatingSaturating64BitUnsignedAccelerated: b32, + integerDotProductAccumulatingSaturating64BitSignedAccelerated: b32, + integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated: b32, +} + +PhysicalDeviceTexelBufferAlignmentProperties :: struct { + sType: StructureType, + pNext: rawptr, + storageTexelBufferOffsetAlignmentBytes: DeviceSize, + storageTexelBufferOffsetSingleTexelAlignment: b32, + uniformTexelBufferOffsetAlignmentBytes: DeviceSize, + uniformTexelBufferOffsetSingleTexelAlignment: b32, +} + +FormatProperties3 :: struct { + sType: StructureType, + pNext: rawptr, + linearTilingFeatures: FormatFeatureFlags2, + optimalTilingFeatures: FormatFeatureFlags2, + bufferFeatures: FormatFeatureFlags2, +} + +PhysicalDeviceMaintenance4Features :: struct { + sType: StructureType, + pNext: rawptr, + maintenance4: b32, +} + +PhysicalDeviceMaintenance4Properties :: struct { + sType: StructureType, + pNext: rawptr, + maxBufferSize: DeviceSize, +} + +DeviceBufferMemoryRequirements :: struct { + sType: StructureType, + pNext: rawptr, + pCreateInfo: ^BufferCreateInfo, +} + +DeviceImageMemoryRequirements :: struct { + sType: StructureType, + pNext: rawptr, + pCreateInfo: ^ImageCreateInfo, + planeAspect: ImageAspectFlags, +} + SurfaceCapabilitiesKHR :: struct { minImageCount: u32, maxImageCount: u32, @@ -2329,6 +2860,36 @@ DisplayPresentInfoKHR :: struct { persistent: b32, } +RenderingFragmentShadingRateAttachmentInfoKHR :: struct { + sType: StructureType, + pNext: rawptr, + imageView: ImageView, + imageLayout: ImageLayout, + shadingRateAttachmentTexelSize: Extent2D, +} + +RenderingFragmentDensityMapAttachmentInfoEXT :: struct { + sType: StructureType, + pNext: rawptr, + imageView: ImageView, + imageLayout: ImageLayout, +} + +AttachmentSampleCountInfoAMD :: struct { + sType: StructureType, + pNext: rawptr, + colorAttachmentCount: u32, + pColorAttachmentSamples: [^]SampleCountFlags, + depthStencilAttachmentSamples: SampleCountFlags, +} + +MultiviewPerViewAttributesInfoNVX :: struct { + sType: StructureType, + pNext: rawptr, + perViewAttributes: b32, + perViewAttributesPositionXOnly: b32, +} + ImportMemoryFdInfoKHR :: struct { sType: StructureType, pNext: rawptr, @@ -2528,10 +3089,23 @@ PhysicalDeviceShaderClockFeaturesKHR :: struct { shaderDeviceClock: b32, } -PhysicalDeviceShaderTerminateInvocationFeaturesKHR :: struct { - sType: StructureType, - pNext: rawptr, - shaderTerminateInvocation: b32, +DeviceQueueGlobalPriorityCreateInfoKHR :: struct { + sType: StructureType, + pNext: rawptr, + globalPriority: QueueGlobalPriorityKHR, +} + +PhysicalDeviceGlobalPriorityQueryFeaturesKHR :: struct { + sType: StructureType, + pNext: rawptr, + globalPriorityQuery: b32, +} + +QueueFamilyGlobalPriorityPropertiesKHR :: struct { + sType: StructureType, + pNext: rawptr, + priorityCount: u32, + priorities: [MAX_GLOBAL_PRIORITY_SIZE_KHR]QueueGlobalPriorityKHR, } FragmentShadingRateAttachmentInfoKHR :: struct { @@ -2651,47 +3225,6 @@ PipelineExecutableInternalRepresentationKHR :: struct { pData: rawptr, } -PhysicalDeviceShaderIntegerDotProductFeaturesKHR :: struct { - sType: StructureType, - pNext: rawptr, - shaderIntegerDotProduct: b32, -} - -PhysicalDeviceShaderIntegerDotProductPropertiesKHR :: struct { - sType: StructureType, - pNext: rawptr, - integerDotProduct8BitUnsignedAccelerated: b32, - integerDotProduct8BitSignedAccelerated: b32, - integerDotProduct8BitMixedSignednessAccelerated: b32, - integerDotProduct4x8BitPackedUnsignedAccelerated: b32, - integerDotProduct4x8BitPackedSignedAccelerated: b32, - integerDotProduct4x8BitPackedMixedSignednessAccelerated: b32, - integerDotProduct16BitUnsignedAccelerated: b32, - integerDotProduct16BitSignedAccelerated: b32, - integerDotProduct16BitMixedSignednessAccelerated: b32, - integerDotProduct32BitUnsignedAccelerated: b32, - integerDotProduct32BitSignedAccelerated: b32, - integerDotProduct32BitMixedSignednessAccelerated: b32, - integerDotProduct64BitUnsignedAccelerated: b32, - integerDotProduct64BitSignedAccelerated: b32, - integerDotProduct64BitMixedSignednessAccelerated: b32, - integerDotProductAccumulatingSaturating8BitUnsignedAccelerated: b32, - integerDotProductAccumulatingSaturating8BitSignedAccelerated: b32, - integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated: b32, - integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated: b32, - integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated: b32, - integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated: b32, - integerDotProductAccumulatingSaturating16BitUnsignedAccelerated: b32, - integerDotProductAccumulatingSaturating16BitSignedAccelerated: b32, - integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated: b32, - integerDotProductAccumulatingSaturating32BitUnsignedAccelerated: b32, - integerDotProductAccumulatingSaturating32BitSignedAccelerated: b32, - integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated: b32, - integerDotProductAccumulatingSaturating64BitUnsignedAccelerated: b32, - integerDotProductAccumulatingSaturating64BitSignedAccelerated: b32, - integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated: b32, -} - PipelineLibraryCreateInfoKHR :: struct { sType: StructureType, pNext: rawptr, @@ -2712,100 +3245,16 @@ PhysicalDevicePresentIdFeaturesKHR :: struct { presentId: b32, } -MemoryBarrier2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcStageMask: PipelineStageFlags2KHR, - srcAccessMask: AccessFlags2KHR, - dstStageMask: PipelineStageFlags2KHR, - dstAccessMask: AccessFlags2KHR, -} - -BufferMemoryBarrier2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcStageMask: PipelineStageFlags2KHR, - srcAccessMask: AccessFlags2KHR, - dstStageMask: PipelineStageFlags2KHR, - dstAccessMask: AccessFlags2KHR, - srcQueueFamilyIndex: u32, - dstQueueFamilyIndex: u32, - buffer: Buffer, - offset: DeviceSize, - size: DeviceSize, -} - -ImageMemoryBarrier2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcStageMask: PipelineStageFlags2KHR, - srcAccessMask: AccessFlags2KHR, - dstStageMask: PipelineStageFlags2KHR, - dstAccessMask: AccessFlags2KHR, - oldLayout: ImageLayout, - newLayout: ImageLayout, - srcQueueFamilyIndex: u32, - dstQueueFamilyIndex: u32, - image: Image, - subresourceRange: ImageSubresourceRange, -} - -DependencyInfoKHR :: struct { - sType: StructureType, - pNext: rawptr, - dependencyFlags: DependencyFlags, - memoryBarrierCount: u32, - pMemoryBarriers: [^]MemoryBarrier2KHR, - bufferMemoryBarrierCount: u32, - pBufferMemoryBarriers: [^]BufferMemoryBarrier2KHR, - imageMemoryBarrierCount: u32, - pImageMemoryBarriers: [^]ImageMemoryBarrier2KHR, -} - -SemaphoreSubmitInfoKHR :: struct { - sType: StructureType, - pNext: rawptr, - semaphore: Semaphore, - value: u64, - stageMask: PipelineStageFlags2KHR, - deviceIndex: u32, -} - -CommandBufferSubmitInfoKHR :: struct { - sType: StructureType, - pNext: rawptr, - commandBuffer: CommandBuffer, - deviceMask: u32, -} - -SubmitInfo2KHR :: struct { - sType: StructureType, - pNext: rawptr, - flags: SubmitFlagsKHR, - waitSemaphoreInfoCount: u32, - pWaitSemaphoreInfos: [^]SemaphoreSubmitInfoKHR, - commandBufferInfoCount: u32, - pCommandBufferInfos: [^]CommandBufferSubmitInfoKHR, - signalSemaphoreInfoCount: u32, - pSignalSemaphoreInfos: [^]SemaphoreSubmitInfoKHR, -} - -PhysicalDeviceSynchronization2FeaturesKHR :: struct { - sType: StructureType, - pNext: rawptr, - synchronization2: b32, -} - QueueFamilyCheckpointProperties2NV :: struct { sType: StructureType, pNext: rawptr, - checkpointExecutionStageMask: PipelineStageFlags2KHR, + checkpointExecutionStageMask: PipelineStageFlags2, } CheckpointData2NV :: struct { sType: StructureType, pNext: rawptr, - stage: PipelineStageFlags2KHR, + stage: PipelineStageFlags2, pCheckpointMarker: rawptr, } @@ -2815,12 +3264,6 @@ PhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR :: struct { shaderSubgroupUniformControlFlow: b32, } -PhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR :: struct { - sType: StructureType, - pNext: rawptr, - shaderZeroInitializeWorkgroupMemory: b32, -} - PhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR :: struct { sType: StructureType, pNext: rawptr, @@ -2830,117 +3273,6 @@ PhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR :: struct { workgroupMemoryExplicitLayout16BitAccess: b32, } -BufferCopy2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcOffset: DeviceSize, - dstOffset: DeviceSize, - size: DeviceSize, -} - -CopyBufferInfo2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcBuffer: Buffer, - dstBuffer: Buffer, - regionCount: u32, - pRegions: [^]BufferCopy2KHR, -} - -ImageCopy2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcSubresource: ImageSubresourceLayers, - srcOffset: Offset3D, - dstSubresource: ImageSubresourceLayers, - dstOffset: Offset3D, - extent: Extent3D, -} - -CopyImageInfo2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcImage: Image, - srcImageLayout: ImageLayout, - dstImage: Image, - dstImageLayout: ImageLayout, - regionCount: u32, - pRegions: [^]ImageCopy2KHR, -} - -BufferImageCopy2KHR :: struct { - sType: StructureType, - pNext: rawptr, - bufferOffset: DeviceSize, - bufferRowLength: u32, - bufferImageHeight: u32, - imageSubresource: ImageSubresourceLayers, - imageOffset: Offset3D, - imageExtent: Extent3D, -} - -CopyBufferToImageInfo2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcBuffer: Buffer, - dstImage: Image, - dstImageLayout: ImageLayout, - regionCount: u32, - pRegions: [^]BufferImageCopy2KHR, -} - -CopyImageToBufferInfo2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcImage: Image, - srcImageLayout: ImageLayout, - dstBuffer: Buffer, - regionCount: u32, - pRegions: [^]BufferImageCopy2KHR, -} - -ImageBlit2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcSubresource: ImageSubresourceLayers, - srcOffsets: [2]Offset3D, - dstSubresource: ImageSubresourceLayers, - dstOffsets: [2]Offset3D, -} - -BlitImageInfo2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcImage: Image, - srcImageLayout: ImageLayout, - dstImage: Image, - dstImageLayout: ImageLayout, - regionCount: u32, - pRegions: [^]ImageBlit2KHR, - filter: Filter, -} - -ImageResolve2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcSubresource: ImageSubresourceLayers, - srcOffset: Offset3D, - dstSubresource: ImageSubresourceLayers, - dstOffset: Offset3D, - extent: Extent3D, -} - -ResolveImageInfo2KHR :: struct { - sType: StructureType, - pNext: rawptr, - srcImage: Image, - srcImageLayout: ImageLayout, - dstImage: Image, - dstImageLayout: ImageLayout, - regionCount: u32, - pRegions: [^]ImageResolve2KHR, -} - DebugReportCallbackCreateInfoEXT :: struct { sType: StructureType, pNext: rawptr, @@ -3130,12 +3462,6 @@ ValidationFlagsEXT :: struct { pDisabledValidationChecks: [^]ValidationCheckEXT, } -PhysicalDeviceTextureCompressionASTCHDRFeaturesEXT :: struct { - sType: StructureType, - pNext: rawptr, - textureCompressionASTC_HDR: b32, -} - ImageViewASTCDecodeModeEXT :: struct { sType: StructureType, pNext: rawptr, @@ -3385,36 +3711,6 @@ DebugUtilsObjectTagInfoEXT :: struct { pTag: rawptr, } -PhysicalDeviceInlineUniformBlockFeaturesEXT :: struct { - sType: StructureType, - pNext: rawptr, - inlineUniformBlock: b32, - descriptorBindingInlineUniformBlockUpdateAfterBind: b32, -} - -PhysicalDeviceInlineUniformBlockPropertiesEXT :: struct { - sType: StructureType, - pNext: rawptr, - maxInlineUniformBlockSize: u32, - maxPerStageDescriptorInlineUniformBlocks: u32, - maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks: u32, - maxDescriptorSetInlineUniformBlocks: u32, - maxDescriptorSetUpdateAfterBindInlineUniformBlocks: u32, -} - -WriteDescriptorSetInlineUniformBlockEXT :: struct { - sType: StructureType, - pNext: rawptr, - dataSize: u32, - pData: rawptr, -} - -DescriptorPoolInlineUniformBlockCreateInfoEXT :: struct { - sType: StructureType, - pNext: rawptr, - maxInlineUniformBlockBindings: u32, -} - SampleLocationEXT :: struct { x: f32, y: f32, @@ -3570,6 +3866,19 @@ ImageDrmFormatModifierPropertiesEXT :: struct { drmFormatModifier: u64, } +DrmFormatModifierProperties2EXT :: struct { + drmFormatModifier: u64, + drmFormatModifierPlaneCount: u32, + drmFormatModifierTilingFeatures: FormatFeatureFlags2, +} + +DrmFormatModifierPropertiesList2EXT :: struct { + sType: StructureType, + pNext: rawptr, + drmFormatModifierCount: u32, + pDrmFormatModifierProperties: [^]DrmFormatModifierProperties2EXT, +} + ValidationCacheCreateInfoEXT :: struct { sType: StructureType, pNext: rawptr, @@ -3792,12 +4101,6 @@ FilterCubicImageViewImageFormatPropertiesEXT :: struct { filterCubicMinmax: b32, } -DeviceQueueGlobalPriorityCreateInfoEXT :: struct { - sType: StructureType, - pNext: rawptr, - globalPriority: QueueGlobalPriorityEXT, -} - ImportMemoryHostPointerInfoEXT :: struct { sType: StructureType, pNext: rawptr, @@ -3879,19 +4182,6 @@ PhysicalDeviceVertexAttributeDivisorFeaturesEXT :: struct { vertexAttributeInstanceRateZeroDivisor: b32, } -PipelineCreationFeedbackEXT :: struct { - flags: PipelineCreationFeedbackFlagsEXT, - duration: u64, -} - -PipelineCreationFeedbackCreateInfoEXT :: struct { - sType: StructureType, - pNext: rawptr, - pPipelineCreationFeedback: ^PipelineCreationFeedbackEXT, - pipelineStageCreationFeedbackCount: u32, - pPipelineStageCreationFeedbacks: [^]PipelineCreationFeedbackEXT, -} - PhysicalDeviceComputeShaderDerivativesFeaturesNV :: struct { sType: StructureType, pNext: rawptr, @@ -4067,28 +4357,6 @@ RenderPassFragmentDensityMapCreateInfoEXT :: struct { fragmentDensityMapAttachment: AttachmentReference, } -PhysicalDeviceSubgroupSizeControlFeaturesEXT :: struct { - sType: StructureType, - pNext: rawptr, - subgroupSizeControl: b32, - computeFullSubgroups: b32, -} - -PhysicalDeviceSubgroupSizeControlPropertiesEXT :: struct { - sType: StructureType, - pNext: rawptr, - minSubgroupSize: u32, - maxSubgroupSize: u32, - maxComputeWorkgroupSubgroups: u32, - requiredSubgroupSizeStages: ShaderStageFlags, -} - -PipelineShaderStageRequiredSubgroupSizeCreateInfoEXT :: struct { - sType: StructureType, - pNext: rawptr, - requiredSubgroupSize: u32, -} - PhysicalDeviceShaderCoreProperties2AMD :: struct { sType: StructureType, pNext: rawptr, @@ -4148,16 +4416,6 @@ BufferDeviceAddressCreateInfoEXT :: struct { deviceAddress: DeviceAddress, } -PhysicalDeviceToolPropertiesEXT :: struct { - sType: StructureType, - pNext: rawptr, - name: [MAX_EXTENSION_NAME_SIZE]byte, - version: [MAX_EXTENSION_NAME_SIZE]byte, - purposes: ToolPurposeFlagsEXT, - description: [MAX_DESCRIPTION_SIZE]byte, - layer: [MAX_EXTENSION_NAME_SIZE]byte, -} - ValidationFeaturesEXT :: struct { sType: StructureType, pNext: rawptr, @@ -4327,12 +4585,6 @@ PhysicalDeviceShaderAtomicFloat2FeaturesEXT :: struct { sparseImageFloat32AtomicMinMax: b32, } -PhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT :: struct { - sType: StructureType, - pNext: rawptr, - shaderDemoteToHelperInvocation: b32, -} - PhysicalDeviceDeviceGeneratedCommandsPropertiesNV :: struct { sType: StructureType, pNext: rawptr, @@ -4472,15 +4724,6 @@ PhysicalDeviceTexelBufferAlignmentFeaturesEXT :: struct { texelBufferAlignment: b32, } -PhysicalDeviceTexelBufferAlignmentPropertiesEXT :: struct { - sType: StructureType, - pNext: rawptr, - storageTexelBufferOffsetAlignmentBytes: DeviceSize, - storageTexelBufferOffsetSingleTexelAlignment: b32, - uniformTexelBufferOffsetAlignmentBytes: DeviceSize, - uniformTexelBufferOffsetSingleTexelAlignment: b32, -} - RenderPassTransformBeginInfoQCOM :: struct { sType: StructureType, pNext: rawptr, @@ -4555,30 +4798,6 @@ PhysicalDeviceCustomBorderColorFeaturesEXT :: struct { customBorderColorWithoutFormat: b32, } -PhysicalDevicePrivateDataFeaturesEXT :: struct { - sType: StructureType, - pNext: rawptr, - privateData: b32, -} - -DevicePrivateDataCreateInfoEXT :: struct { - sType: StructureType, - pNext: rawptr, - privateDataSlotRequestCount: u32, -} - -PrivateDataSlotCreateInfoEXT :: struct { - sType: StructureType, - pNext: rawptr, - flags: PrivateDataSlotCreateFlagsEXT, -} - -PhysicalDevicePipelineCreationCacheControlFeaturesEXT :: struct { - sType: StructureType, - pNext: rawptr, - pipelineCreationCacheControl: b32, -} - PhysicalDeviceDiagnosticsConfigFeaturesNV :: struct { sType: StructureType, pNext: rawptr, @@ -4591,6 +4810,25 @@ DeviceDiagnosticsConfigCreateInfoNV :: struct { flags: DeviceDiagnosticsConfigFlagsNV, } +PhysicalDeviceGraphicsPipelineLibraryFeaturesEXT :: struct { + sType: StructureType, + pNext: rawptr, + graphicsPipelineLibrary: b32, +} + +PhysicalDeviceGraphicsPipelineLibraryPropertiesEXT :: struct { + sType: StructureType, + pNext: rawptr, + graphicsPipelineLibraryFastLinking: b32, + graphicsPipelineLibraryIndependentInterpolationDecoration: b32, +} + +GraphicsPipelineLibraryCreateInfoEXT :: struct { + sType: StructureType, + pNext: rawptr, + flags: GraphicsPipelineLibraryFlagsEXT, +} + PhysicalDeviceFragmentShadingRateEnumsFeaturesNV :: struct { sType: StructureType, pNext: rawptr, @@ -4708,12 +4946,6 @@ CopyCommandTransformInfoQCOM :: struct { transform: SurfaceTransformFlagsKHR, } -PhysicalDeviceImageRobustnessFeaturesEXT :: struct { - sType: StructureType, - pNext: rawptr, - robustImageAccess: b32, -} - PhysicalDevice4444FormatsFeaturesEXT :: struct { sType: StructureType, pNext: rawptr, @@ -4721,6 +4953,20 @@ PhysicalDevice4444FormatsFeaturesEXT :: struct { formatA4B4G4R4: b32, } +PhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM :: struct { + sType: StructureType, + pNext: rawptr, + rasterizationOrderColorAttachmentAccess: b32, + rasterizationOrderDepthAttachmentAccess: b32, + rasterizationOrderStencilAttachmentAccess: b32, +} + +PhysicalDeviceRGBA10X6FormatsFeaturesEXT :: struct { + sType: StructureType, + pNext: rawptr, + formatRgba10x6WithoutYCbCrSampler: b32, +} + PhysicalDeviceMutableDescriptorTypeFeaturesVALVE :: struct { sType: StructureType, pNext: rawptr, @@ -4774,6 +5020,18 @@ PhysicalDeviceDrmPropertiesEXT :: struct { renderMinor: i64, } +PhysicalDeviceDepthClipControlFeaturesEXT :: struct { + sType: StructureType, + pNext: rawptr, + depthClipControl: b32, +} + +PipelineViewportDepthClipControlCreateInfoEXT :: struct { + sType: StructureType, + pNext: rawptr, + negativeOneToOne: b32, +} + PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT :: struct { sType: StructureType, pNext: rawptr, @@ -4840,17 +5098,24 @@ PipelineColorWriteCreateInfoEXT :: struct { pColorWriteEnables: [^]b32, } -PhysicalDeviceGlobalPriorityQueryFeaturesEXT :: struct { - sType: StructureType, - pNext: rawptr, - globalPriorityQuery: b32, +PhysicalDevicePrimitivesGeneratedQueryFeaturesEXT :: struct { + sType: StructureType, + pNext: rawptr, + primitivesGeneratedQuery: b32, + primitivesGeneratedQueryWithRasterizerDiscard: b32, + primitivesGeneratedQueryWithNonZeroStreams: b32, } -QueueFamilyGlobalPriorityPropertiesEXT :: struct { - sType: StructureType, - pNext: rawptr, - priorityCount: u32, - priorities: [MAX_GLOBAL_PRIORITY_SIZE_EXT]QueueGlobalPriorityEXT, +PhysicalDeviceImageViewMinLodFeaturesEXT :: struct { + sType: StructureType, + pNext: rawptr, + minLod: b32, +} + +ImageViewMinLodCreateInfoEXT :: struct { + sType: StructureType, + pNext: rawptr, + minLod: f32, } PhysicalDeviceMultiDrawFeaturesEXT :: struct { @@ -4876,12 +5141,78 @@ MultiDrawIndexedInfoEXT :: struct { vertexOffset: i32, } +PhysicalDeviceImage2DViewOf3DFeaturesEXT :: struct { + sType: StructureType, + pNext: rawptr, + image2DViewOf3D: b32, + sampler2DViewOf3D: b32, +} + +PhysicalDeviceBorderColorSwizzleFeaturesEXT :: struct { + sType: StructureType, + pNext: rawptr, + borderColorSwizzle: b32, + borderColorSwizzleFromImage: b32, +} + +SamplerBorderColorComponentMappingCreateInfoEXT :: struct { + sType: StructureType, + pNext: rawptr, + components: ComponentMapping, + srgb: b32, +} + PhysicalDevicePageableDeviceLocalMemoryFeaturesEXT :: struct { sType: StructureType, pNext: rawptr, pageableDeviceLocalMemory: b32, } +PhysicalDeviceDescriptorSetHostMappingFeaturesVALVE :: struct { + sType: StructureType, + pNext: rawptr, + descriptorSetHostMapping: b32, +} + +DescriptorSetBindingReferenceVALVE :: struct { + sType: StructureType, + pNext: rawptr, + descriptorSetLayout: DescriptorSetLayout, + binding: u32, +} + +DescriptorSetLayoutHostMappingInfoVALVE :: struct { + sType: StructureType, + pNext: rawptr, + descriptorOffset: int, + descriptorSize: u32, +} + +PhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM :: struct { + sType: StructureType, + pNext: rawptr, + fragmentDensityMapOffset: b32, +} + +PhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM :: struct { + sType: StructureType, + pNext: rawptr, + fragmentDensityOffsetGranularity: Extent2D, +} + +SubpassFragmentDensityMapOffsetEndInfoQCOM :: struct { + sType: StructureType, + pNext: rawptr, + fragmentDensityOffsetCount: u32, + pFragmentDensityOffsets: [^]Offset2D, +} + +PhysicalDeviceLinearColorAttachmentFeaturesNV :: struct { + sType: StructureType, + pNext: rawptr, + linearColorAttachment: b32, +} + DeviceOrHostAddressKHR :: struct #raw_union { deviceAddress: DeviceAddress, hostAddress: rawptr, @@ -5283,178 +5614,252 @@ IOSSurfaceCreateInfoMVK :: struct { } // Aliases -PhysicalDeviceVariablePointerFeatures :: PhysicalDeviceVariablePointersFeatures -PhysicalDeviceShaderDrawParameterFeatures :: PhysicalDeviceShaderDrawParametersFeatures -RenderPassMultiviewCreateInfoKHR :: RenderPassMultiviewCreateInfo -PhysicalDeviceMultiviewFeaturesKHR :: PhysicalDeviceMultiviewFeatures -PhysicalDeviceMultiviewPropertiesKHR :: PhysicalDeviceMultiviewProperties -PhysicalDeviceFeatures2KHR :: PhysicalDeviceFeatures2 -PhysicalDeviceProperties2KHR :: PhysicalDeviceProperties2 -FormatProperties2KHR :: FormatProperties2 -ImageFormatProperties2KHR :: ImageFormatProperties2 -PhysicalDeviceImageFormatInfo2KHR :: PhysicalDeviceImageFormatInfo2 -QueueFamilyProperties2KHR :: QueueFamilyProperties2 -PhysicalDeviceMemoryProperties2KHR :: PhysicalDeviceMemoryProperties2 -SparseImageFormatProperties2KHR :: SparseImageFormatProperties2 -PhysicalDeviceSparseImageFormatInfo2KHR :: PhysicalDeviceSparseImageFormatInfo2 -PeerMemoryFeatureFlagsKHR :: PeerMemoryFeatureFlags -PeerMemoryFeatureFlagKHR :: PeerMemoryFeatureFlag -MemoryAllocateFlagsKHR :: MemoryAllocateFlags -MemoryAllocateFlagKHR :: MemoryAllocateFlag -MemoryAllocateFlagsInfoKHR :: MemoryAllocateFlagsInfo -DeviceGroupRenderPassBeginInfoKHR :: DeviceGroupRenderPassBeginInfo -DeviceGroupCommandBufferBeginInfoKHR :: DeviceGroupCommandBufferBeginInfo -DeviceGroupSubmitInfoKHR :: DeviceGroupSubmitInfo -DeviceGroupBindSparseInfoKHR :: DeviceGroupBindSparseInfo -BindBufferMemoryDeviceGroupInfoKHR :: BindBufferMemoryDeviceGroupInfo -BindImageMemoryDeviceGroupInfoKHR :: BindImageMemoryDeviceGroupInfo -CommandPoolTrimFlagsKHR :: CommandPoolTrimFlags -PhysicalDeviceGroupPropertiesKHR :: PhysicalDeviceGroupProperties -DeviceGroupDeviceCreateInfoKHR :: DeviceGroupDeviceCreateInfo -ExternalMemoryHandleTypeFlagsKHR :: ExternalMemoryHandleTypeFlags -ExternalMemoryHandleTypeFlagKHR :: ExternalMemoryHandleTypeFlag -ExternalMemoryFeatureFlagsKHR :: ExternalMemoryFeatureFlags -ExternalMemoryFeatureFlagKHR :: ExternalMemoryFeatureFlag -ExternalMemoryPropertiesKHR :: ExternalMemoryProperties -PhysicalDeviceExternalImageFormatInfoKHR :: PhysicalDeviceExternalImageFormatInfo -ExternalImageFormatPropertiesKHR :: ExternalImageFormatProperties -PhysicalDeviceExternalBufferInfoKHR :: PhysicalDeviceExternalBufferInfo -ExternalBufferPropertiesKHR :: ExternalBufferProperties -PhysicalDeviceIDPropertiesKHR :: PhysicalDeviceIDProperties -ExternalMemoryImageCreateInfoKHR :: ExternalMemoryImageCreateInfo -ExternalMemoryBufferCreateInfoKHR :: ExternalMemoryBufferCreateInfo -ExportMemoryAllocateInfoKHR :: ExportMemoryAllocateInfo -ExternalSemaphoreHandleTypeFlagsKHR :: ExternalSemaphoreHandleTypeFlags -ExternalSemaphoreHandleTypeFlagKHR :: ExternalSemaphoreHandleTypeFlag -ExternalSemaphoreFeatureFlagsKHR :: ExternalSemaphoreFeatureFlags -ExternalSemaphoreFeatureFlagKHR :: ExternalSemaphoreFeatureFlag -PhysicalDeviceExternalSemaphoreInfoKHR :: PhysicalDeviceExternalSemaphoreInfo -ExternalSemaphorePropertiesKHR :: ExternalSemaphoreProperties -SemaphoreImportFlagsKHR :: SemaphoreImportFlags -SemaphoreImportFlagKHR :: SemaphoreImportFlag -ExportSemaphoreCreateInfoKHR :: ExportSemaphoreCreateInfo -PhysicalDeviceShaderFloat16Int8FeaturesKHR :: PhysicalDeviceShaderFloat16Int8Features -PhysicalDeviceFloat16Int8FeaturesKHR :: PhysicalDeviceShaderFloat16Int8Features -PhysicalDevice16BitStorageFeaturesKHR :: PhysicalDevice16BitStorageFeatures -DescriptorUpdateTemplateKHR :: DescriptorUpdateTemplate -DescriptorUpdateTemplateTypeKHR :: DescriptorUpdateTemplateType -DescriptorUpdateTemplateCreateFlagsKHR :: DescriptorUpdateTemplateCreateFlags -DescriptorUpdateTemplateEntryKHR :: DescriptorUpdateTemplateEntry -DescriptorUpdateTemplateCreateInfoKHR :: DescriptorUpdateTemplateCreateInfo -PhysicalDeviceImagelessFramebufferFeaturesKHR :: PhysicalDeviceImagelessFramebufferFeatures -FramebufferAttachmentsCreateInfoKHR :: FramebufferAttachmentsCreateInfo -FramebufferAttachmentImageInfoKHR :: FramebufferAttachmentImageInfo -RenderPassAttachmentBeginInfoKHR :: RenderPassAttachmentBeginInfo -RenderPassCreateInfo2KHR :: RenderPassCreateInfo2 -AttachmentDescription2KHR :: AttachmentDescription2 -AttachmentReference2KHR :: AttachmentReference2 -SubpassDescription2KHR :: SubpassDescription2 -SubpassDependency2KHR :: SubpassDependency2 -SubpassBeginInfoKHR :: SubpassBeginInfo -SubpassEndInfoKHR :: SubpassEndInfo -ExternalFenceHandleTypeFlagsKHR :: ExternalFenceHandleTypeFlags -ExternalFenceHandleTypeFlagKHR :: ExternalFenceHandleTypeFlag -ExternalFenceFeatureFlagsKHR :: ExternalFenceFeatureFlags -ExternalFenceFeatureFlagKHR :: ExternalFenceFeatureFlag -PhysicalDeviceExternalFenceInfoKHR :: PhysicalDeviceExternalFenceInfo -ExternalFencePropertiesKHR :: ExternalFenceProperties -FenceImportFlagsKHR :: FenceImportFlags -FenceImportFlagKHR :: FenceImportFlag -ExportFenceCreateInfoKHR :: ExportFenceCreateInfo -PointClippingBehaviorKHR :: PointClippingBehavior -TessellationDomainOriginKHR :: TessellationDomainOrigin -PhysicalDevicePointClippingPropertiesKHR :: PhysicalDevicePointClippingProperties -RenderPassInputAttachmentAspectCreateInfoKHR :: RenderPassInputAttachmentAspectCreateInfo -InputAttachmentAspectReferenceKHR :: InputAttachmentAspectReference -ImageViewUsageCreateInfoKHR :: ImageViewUsageCreateInfo -PipelineTessellationDomainOriginStateCreateInfoKHR :: PipelineTessellationDomainOriginStateCreateInfo -PhysicalDeviceVariablePointerFeaturesKHR :: PhysicalDeviceVariablePointersFeatures -PhysicalDeviceVariablePointersFeaturesKHR :: PhysicalDeviceVariablePointersFeatures -MemoryDedicatedRequirementsKHR :: MemoryDedicatedRequirements -MemoryDedicatedAllocateInfoKHR :: MemoryDedicatedAllocateInfo -BufferMemoryRequirementsInfo2KHR :: BufferMemoryRequirementsInfo2 -ImageMemoryRequirementsInfo2KHR :: ImageMemoryRequirementsInfo2 -ImageSparseMemoryRequirementsInfo2KHR :: ImageSparseMemoryRequirementsInfo2 -MemoryRequirements2KHR :: MemoryRequirements2 -SparseImageMemoryRequirements2KHR :: SparseImageMemoryRequirements2 -ImageFormatListCreateInfoKHR :: ImageFormatListCreateInfo -SamplerYcbcrConversionKHR :: SamplerYcbcrConversion -SamplerYcbcrModelConversionKHR :: SamplerYcbcrModelConversion -SamplerYcbcrRangeKHR :: SamplerYcbcrRange -ChromaLocationKHR :: ChromaLocation -SamplerYcbcrConversionCreateInfoKHR :: SamplerYcbcrConversionCreateInfo -SamplerYcbcrConversionInfoKHR :: SamplerYcbcrConversionInfo -BindImagePlaneMemoryInfoKHR :: BindImagePlaneMemoryInfo -ImagePlaneMemoryRequirementsInfoKHR :: ImagePlaneMemoryRequirementsInfo -PhysicalDeviceSamplerYcbcrConversionFeaturesKHR :: PhysicalDeviceSamplerYcbcrConversionFeatures -SamplerYcbcrConversionImageFormatPropertiesKHR :: SamplerYcbcrConversionImageFormatProperties -BindBufferMemoryInfoKHR :: BindBufferMemoryInfo -BindImageMemoryInfoKHR :: BindImageMemoryInfo -PhysicalDeviceMaintenance3PropertiesKHR :: PhysicalDeviceMaintenance3Properties -DescriptorSetLayoutSupportKHR :: DescriptorSetLayoutSupport -PhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR :: PhysicalDeviceShaderSubgroupExtendedTypesFeatures -PhysicalDevice8BitStorageFeaturesKHR :: PhysicalDevice8BitStorageFeatures -PhysicalDeviceShaderAtomicInt64FeaturesKHR :: PhysicalDeviceShaderAtomicInt64Features -DriverIdKHR :: DriverId -ConformanceVersionKHR :: ConformanceVersion -PhysicalDeviceDriverPropertiesKHR :: PhysicalDeviceDriverProperties -ShaderFloatControlsIndependenceKHR :: ShaderFloatControlsIndependence -PhysicalDeviceFloatControlsPropertiesKHR :: PhysicalDeviceFloatControlsProperties -ResolveModeFlagKHR :: ResolveModeFlag -ResolveModeFlagsKHR :: ResolveModeFlags -SubpassDescriptionDepthStencilResolveKHR :: SubpassDescriptionDepthStencilResolve -PhysicalDeviceDepthStencilResolvePropertiesKHR :: PhysicalDeviceDepthStencilResolveProperties -SemaphoreTypeKHR :: SemaphoreType -SemaphoreWaitFlagKHR :: SemaphoreWaitFlag -SemaphoreWaitFlagsKHR :: SemaphoreWaitFlags -PhysicalDeviceTimelineSemaphoreFeaturesKHR :: PhysicalDeviceTimelineSemaphoreFeatures -PhysicalDeviceTimelineSemaphorePropertiesKHR :: PhysicalDeviceTimelineSemaphoreProperties -SemaphoreTypeCreateInfoKHR :: SemaphoreTypeCreateInfo -TimelineSemaphoreSubmitInfoKHR :: TimelineSemaphoreSubmitInfo -SemaphoreWaitInfoKHR :: SemaphoreWaitInfo -SemaphoreSignalInfoKHR :: SemaphoreSignalInfo -PhysicalDeviceVulkanMemoryModelFeaturesKHR :: PhysicalDeviceVulkanMemoryModelFeatures -PhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR :: PhysicalDeviceSeparateDepthStencilLayoutsFeatures -AttachmentReferenceStencilLayoutKHR :: AttachmentReferenceStencilLayout -AttachmentDescriptionStencilLayoutKHR :: AttachmentDescriptionStencilLayout -PhysicalDeviceUniformBufferStandardLayoutFeaturesKHR :: PhysicalDeviceUniformBufferStandardLayoutFeatures -PhysicalDeviceBufferDeviceAddressFeaturesKHR :: PhysicalDeviceBufferDeviceAddressFeatures -BufferDeviceAddressInfoKHR :: BufferDeviceAddressInfo -BufferOpaqueCaptureAddressCreateInfoKHR :: BufferOpaqueCaptureAddressCreateInfo -MemoryOpaqueCaptureAddressAllocateInfoKHR :: MemoryOpaqueCaptureAddressAllocateInfo -DeviceMemoryOpaqueCaptureAddressInfoKHR :: DeviceMemoryOpaqueCaptureAddressInfo -PipelineStageFlags2KHR :: Flags64 -PipelineStageFlag2KHR :: Flags64 -AccessFlags2KHR :: Flags64 -AccessFlag2KHR :: Flags64 -SamplerReductionModeEXT :: SamplerReductionMode -SamplerReductionModeCreateInfoEXT :: SamplerReductionModeCreateInfo -PhysicalDeviceSamplerFilterMinmaxPropertiesEXT :: PhysicalDeviceSamplerFilterMinmaxProperties -DescriptorBindingFlagEXT :: DescriptorBindingFlag -DescriptorBindingFlagsEXT :: DescriptorBindingFlags -DescriptorSetLayoutBindingFlagsCreateInfoEXT :: DescriptorSetLayoutBindingFlagsCreateInfo -PhysicalDeviceDescriptorIndexingFeaturesEXT :: PhysicalDeviceDescriptorIndexingFeatures -PhysicalDeviceDescriptorIndexingPropertiesEXT :: PhysicalDeviceDescriptorIndexingProperties -DescriptorSetVariableDescriptorCountAllocateInfoEXT :: DescriptorSetVariableDescriptorCountAllocateInfo -DescriptorSetVariableDescriptorCountLayoutSupportEXT :: DescriptorSetVariableDescriptorCountLayoutSupport -RayTracingShaderGroupTypeNV :: RayTracingShaderGroupTypeKHR -GeometryTypeNV :: GeometryTypeKHR -AccelerationStructureTypeNV :: AccelerationStructureTypeKHR -CopyAccelerationStructureModeNV :: CopyAccelerationStructureModeKHR -GeometryFlagsNV :: GeometryFlagsKHR -GeometryFlagNV :: GeometryFlagKHR -GeometryInstanceFlagsNV :: GeometryInstanceFlagsKHR -GeometryInstanceFlagNV :: GeometryInstanceFlagKHR -BuildAccelerationStructureFlagsNV :: BuildAccelerationStructureFlagsKHR -BuildAccelerationStructureFlagNV :: BuildAccelerationStructureFlagKHR -TransformMatrixNV :: TransformMatrixKHR -AabbPositionsNV :: AabbPositionsKHR -AccelerationStructureInstanceNV :: AccelerationStructureInstanceKHR -QueryPoolCreateInfoINTEL :: QueryPoolPerformanceQueryCreateInfoINTEL -PhysicalDeviceScalarBlockLayoutFeaturesEXT :: PhysicalDeviceScalarBlockLayoutFeatures -PhysicalDeviceBufferAddressFeaturesEXT :: PhysicalDeviceBufferDeviceAddressFeaturesEXT -BufferDeviceAddressInfoEXT :: BufferDeviceAddressInfo -ImageStencilUsageCreateInfoEXT :: ImageStencilUsageCreateInfo -PhysicalDeviceHostQueryResetFeaturesEXT :: PhysicalDeviceHostQueryResetFeatures +PhysicalDeviceVariablePointerFeatures :: PhysicalDeviceVariablePointersFeatures +PhysicalDeviceShaderDrawParameterFeatures :: PhysicalDeviceShaderDrawParametersFeatures +PipelineStageFlags2 :: Flags64 +PipelineStageFlag2 :: Flags64 +AccessFlags2 :: Flags64 +AccessFlag2 :: Flags64 +FormatFeatureFlags2 :: Flags64 +FormatFeatureFlag2 :: Flags64 +RenderingFlagsKHR :: RenderingFlags +RenderingFlagKHR :: RenderingFlag +RenderingInfoKHR :: RenderingInfo +RenderingAttachmentInfoKHR :: RenderingAttachmentInfo +PipelineRenderingCreateInfoKHR :: PipelineRenderingCreateInfo +PhysicalDeviceDynamicRenderingFeaturesKHR :: PhysicalDeviceDynamicRenderingFeatures +CommandBufferInheritanceRenderingInfoKHR :: CommandBufferInheritanceRenderingInfo +AttachmentSampleCountInfoNV :: AttachmentSampleCountInfoAMD +RenderPassMultiviewCreateInfoKHR :: RenderPassMultiviewCreateInfo +PhysicalDeviceMultiviewFeaturesKHR :: PhysicalDeviceMultiviewFeatures +PhysicalDeviceMultiviewPropertiesKHR :: PhysicalDeviceMultiviewProperties +PhysicalDeviceFeatures2KHR :: PhysicalDeviceFeatures2 +PhysicalDeviceProperties2KHR :: PhysicalDeviceProperties2 +FormatProperties2KHR :: FormatProperties2 +ImageFormatProperties2KHR :: ImageFormatProperties2 +PhysicalDeviceImageFormatInfo2KHR :: PhysicalDeviceImageFormatInfo2 +QueueFamilyProperties2KHR :: QueueFamilyProperties2 +PhysicalDeviceMemoryProperties2KHR :: PhysicalDeviceMemoryProperties2 +SparseImageFormatProperties2KHR :: SparseImageFormatProperties2 +PhysicalDeviceSparseImageFormatInfo2KHR :: PhysicalDeviceSparseImageFormatInfo2 +PeerMemoryFeatureFlagsKHR :: PeerMemoryFeatureFlags +PeerMemoryFeatureFlagKHR :: PeerMemoryFeatureFlag +MemoryAllocateFlagsKHR :: MemoryAllocateFlags +MemoryAllocateFlagKHR :: MemoryAllocateFlag +MemoryAllocateFlagsInfoKHR :: MemoryAllocateFlagsInfo +DeviceGroupRenderPassBeginInfoKHR :: DeviceGroupRenderPassBeginInfo +DeviceGroupCommandBufferBeginInfoKHR :: DeviceGroupCommandBufferBeginInfo +DeviceGroupSubmitInfoKHR :: DeviceGroupSubmitInfo +DeviceGroupBindSparseInfoKHR :: DeviceGroupBindSparseInfo +BindBufferMemoryDeviceGroupInfoKHR :: BindBufferMemoryDeviceGroupInfo +BindImageMemoryDeviceGroupInfoKHR :: BindImageMemoryDeviceGroupInfo +CommandPoolTrimFlagsKHR :: CommandPoolTrimFlags +PhysicalDeviceGroupPropertiesKHR :: PhysicalDeviceGroupProperties +DeviceGroupDeviceCreateInfoKHR :: DeviceGroupDeviceCreateInfo +ExternalMemoryHandleTypeFlagsKHR :: ExternalMemoryHandleTypeFlags +ExternalMemoryHandleTypeFlagKHR :: ExternalMemoryHandleTypeFlag +ExternalMemoryFeatureFlagsKHR :: ExternalMemoryFeatureFlags +ExternalMemoryFeatureFlagKHR :: ExternalMemoryFeatureFlag +ExternalMemoryPropertiesKHR :: ExternalMemoryProperties +PhysicalDeviceExternalImageFormatInfoKHR :: PhysicalDeviceExternalImageFormatInfo +ExternalImageFormatPropertiesKHR :: ExternalImageFormatProperties +PhysicalDeviceExternalBufferInfoKHR :: PhysicalDeviceExternalBufferInfo +ExternalBufferPropertiesKHR :: ExternalBufferProperties +PhysicalDeviceIDPropertiesKHR :: PhysicalDeviceIDProperties +ExternalMemoryImageCreateInfoKHR :: ExternalMemoryImageCreateInfo +ExternalMemoryBufferCreateInfoKHR :: ExternalMemoryBufferCreateInfo +ExportMemoryAllocateInfoKHR :: ExportMemoryAllocateInfo +ExternalSemaphoreHandleTypeFlagsKHR :: ExternalSemaphoreHandleTypeFlags +ExternalSemaphoreHandleTypeFlagKHR :: ExternalSemaphoreHandleTypeFlag +ExternalSemaphoreFeatureFlagsKHR :: ExternalSemaphoreFeatureFlags +ExternalSemaphoreFeatureFlagKHR :: ExternalSemaphoreFeatureFlag +PhysicalDeviceExternalSemaphoreInfoKHR :: PhysicalDeviceExternalSemaphoreInfo +ExternalSemaphorePropertiesKHR :: ExternalSemaphoreProperties +SemaphoreImportFlagsKHR :: SemaphoreImportFlags +SemaphoreImportFlagKHR :: SemaphoreImportFlag +ExportSemaphoreCreateInfoKHR :: ExportSemaphoreCreateInfo +PhysicalDeviceShaderFloat16Int8FeaturesKHR :: PhysicalDeviceShaderFloat16Int8Features +PhysicalDeviceFloat16Int8FeaturesKHR :: PhysicalDeviceShaderFloat16Int8Features +PhysicalDevice16BitStorageFeaturesKHR :: PhysicalDevice16BitStorageFeatures +DescriptorUpdateTemplateKHR :: DescriptorUpdateTemplate +DescriptorUpdateTemplateTypeKHR :: DescriptorUpdateTemplateType +DescriptorUpdateTemplateCreateFlagsKHR :: DescriptorUpdateTemplateCreateFlags +DescriptorUpdateTemplateEntryKHR :: DescriptorUpdateTemplateEntry +DescriptorUpdateTemplateCreateInfoKHR :: DescriptorUpdateTemplateCreateInfo +PhysicalDeviceImagelessFramebufferFeaturesKHR :: PhysicalDeviceImagelessFramebufferFeatures +FramebufferAttachmentsCreateInfoKHR :: FramebufferAttachmentsCreateInfo +FramebufferAttachmentImageInfoKHR :: FramebufferAttachmentImageInfo +RenderPassAttachmentBeginInfoKHR :: RenderPassAttachmentBeginInfo +RenderPassCreateInfo2KHR :: RenderPassCreateInfo2 +AttachmentDescription2KHR :: AttachmentDescription2 +AttachmentReference2KHR :: AttachmentReference2 +SubpassDescription2KHR :: SubpassDescription2 +SubpassDependency2KHR :: SubpassDependency2 +SubpassBeginInfoKHR :: SubpassBeginInfo +SubpassEndInfoKHR :: SubpassEndInfo +ExternalFenceHandleTypeFlagsKHR :: ExternalFenceHandleTypeFlags +ExternalFenceHandleTypeFlagKHR :: ExternalFenceHandleTypeFlag +ExternalFenceFeatureFlagsKHR :: ExternalFenceFeatureFlags +ExternalFenceFeatureFlagKHR :: ExternalFenceFeatureFlag +PhysicalDeviceExternalFenceInfoKHR :: PhysicalDeviceExternalFenceInfo +ExternalFencePropertiesKHR :: ExternalFenceProperties +FenceImportFlagsKHR :: FenceImportFlags +FenceImportFlagKHR :: FenceImportFlag +ExportFenceCreateInfoKHR :: ExportFenceCreateInfo +PointClippingBehaviorKHR :: PointClippingBehavior +TessellationDomainOriginKHR :: TessellationDomainOrigin +PhysicalDevicePointClippingPropertiesKHR :: PhysicalDevicePointClippingProperties +RenderPassInputAttachmentAspectCreateInfoKHR :: RenderPassInputAttachmentAspectCreateInfo +InputAttachmentAspectReferenceKHR :: InputAttachmentAspectReference +ImageViewUsageCreateInfoKHR :: ImageViewUsageCreateInfo +PipelineTessellationDomainOriginStateCreateInfoKHR :: PipelineTessellationDomainOriginStateCreateInfo +PhysicalDeviceVariablePointerFeaturesKHR :: PhysicalDeviceVariablePointersFeatures +PhysicalDeviceVariablePointersFeaturesKHR :: PhysicalDeviceVariablePointersFeatures +MemoryDedicatedRequirementsKHR :: MemoryDedicatedRequirements +MemoryDedicatedAllocateInfoKHR :: MemoryDedicatedAllocateInfo +BufferMemoryRequirementsInfo2KHR :: BufferMemoryRequirementsInfo2 +ImageMemoryRequirementsInfo2KHR :: ImageMemoryRequirementsInfo2 +ImageSparseMemoryRequirementsInfo2KHR :: ImageSparseMemoryRequirementsInfo2 +MemoryRequirements2KHR :: MemoryRequirements2 +SparseImageMemoryRequirements2KHR :: SparseImageMemoryRequirements2 +ImageFormatListCreateInfoKHR :: ImageFormatListCreateInfo +SamplerYcbcrConversionKHR :: SamplerYcbcrConversion +SamplerYcbcrModelConversionKHR :: SamplerYcbcrModelConversion +SamplerYcbcrRangeKHR :: SamplerYcbcrRange +ChromaLocationKHR :: ChromaLocation +SamplerYcbcrConversionCreateInfoKHR :: SamplerYcbcrConversionCreateInfo +SamplerYcbcrConversionInfoKHR :: SamplerYcbcrConversionInfo +BindImagePlaneMemoryInfoKHR :: BindImagePlaneMemoryInfo +ImagePlaneMemoryRequirementsInfoKHR :: ImagePlaneMemoryRequirementsInfo +PhysicalDeviceSamplerYcbcrConversionFeaturesKHR :: PhysicalDeviceSamplerYcbcrConversionFeatures +SamplerYcbcrConversionImageFormatPropertiesKHR :: SamplerYcbcrConversionImageFormatProperties +BindBufferMemoryInfoKHR :: BindBufferMemoryInfo +BindImageMemoryInfoKHR :: BindImageMemoryInfo +PhysicalDeviceMaintenance3PropertiesKHR :: PhysicalDeviceMaintenance3Properties +DescriptorSetLayoutSupportKHR :: DescriptorSetLayoutSupport +PhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR :: PhysicalDeviceShaderSubgroupExtendedTypesFeatures +PhysicalDevice8BitStorageFeaturesKHR :: PhysicalDevice8BitStorageFeatures +PhysicalDeviceShaderAtomicInt64FeaturesKHR :: PhysicalDeviceShaderAtomicInt64Features +DriverIdKHR :: DriverId +ConformanceVersionKHR :: ConformanceVersion +PhysicalDeviceDriverPropertiesKHR :: PhysicalDeviceDriverProperties +ShaderFloatControlsIndependenceKHR :: ShaderFloatControlsIndependence +PhysicalDeviceFloatControlsPropertiesKHR :: PhysicalDeviceFloatControlsProperties +ResolveModeFlagKHR :: ResolveModeFlag +ResolveModeFlagsKHR :: ResolveModeFlags +SubpassDescriptionDepthStencilResolveKHR :: SubpassDescriptionDepthStencilResolve +PhysicalDeviceDepthStencilResolvePropertiesKHR :: PhysicalDeviceDepthStencilResolveProperties +SemaphoreTypeKHR :: SemaphoreType +SemaphoreWaitFlagKHR :: SemaphoreWaitFlag +SemaphoreWaitFlagsKHR :: SemaphoreWaitFlags +PhysicalDeviceTimelineSemaphoreFeaturesKHR :: PhysicalDeviceTimelineSemaphoreFeatures +PhysicalDeviceTimelineSemaphorePropertiesKHR :: PhysicalDeviceTimelineSemaphoreProperties +SemaphoreTypeCreateInfoKHR :: SemaphoreTypeCreateInfo +TimelineSemaphoreSubmitInfoKHR :: TimelineSemaphoreSubmitInfo +SemaphoreWaitInfoKHR :: SemaphoreWaitInfo +SemaphoreSignalInfoKHR :: SemaphoreSignalInfo +PhysicalDeviceVulkanMemoryModelFeaturesKHR :: PhysicalDeviceVulkanMemoryModelFeatures +PhysicalDeviceShaderTerminateInvocationFeaturesKHR :: PhysicalDeviceShaderTerminateInvocationFeatures +PhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR :: PhysicalDeviceSeparateDepthStencilLayoutsFeatures +AttachmentReferenceStencilLayoutKHR :: AttachmentReferenceStencilLayout +AttachmentDescriptionStencilLayoutKHR :: AttachmentDescriptionStencilLayout +PhysicalDeviceUniformBufferStandardLayoutFeaturesKHR :: PhysicalDeviceUniformBufferStandardLayoutFeatures +PhysicalDeviceBufferDeviceAddressFeaturesKHR :: PhysicalDeviceBufferDeviceAddressFeatures +BufferDeviceAddressInfoKHR :: BufferDeviceAddressInfo +BufferOpaqueCaptureAddressCreateInfoKHR :: BufferOpaqueCaptureAddressCreateInfo +MemoryOpaqueCaptureAddressAllocateInfoKHR :: MemoryOpaqueCaptureAddressAllocateInfo +DeviceMemoryOpaqueCaptureAddressInfoKHR :: DeviceMemoryOpaqueCaptureAddressInfo +PhysicalDeviceShaderIntegerDotProductFeaturesKHR :: PhysicalDeviceShaderIntegerDotProductFeatures +PhysicalDeviceShaderIntegerDotProductPropertiesKHR :: PhysicalDeviceShaderIntegerDotProductProperties +PipelineStageFlags2KHR :: PipelineStageFlags2 +PipelineStageFlag2KHR :: PipelineStageFlag2 +AccessFlags2KHR :: AccessFlags2 +AccessFlag2KHR :: AccessFlag2 +SubmitFlagKHR :: SubmitFlag +SubmitFlagsKHR :: SubmitFlags +MemoryBarrier2KHR :: MemoryBarrier2 +BufferMemoryBarrier2KHR :: BufferMemoryBarrier2 +ImageMemoryBarrier2KHR :: ImageMemoryBarrier2 +DependencyInfoKHR :: DependencyInfo +SubmitInfo2KHR :: SubmitInfo2 +SemaphoreSubmitInfoKHR :: SemaphoreSubmitInfo +CommandBufferSubmitInfoKHR :: CommandBufferSubmitInfo +PhysicalDeviceSynchronization2FeaturesKHR :: PhysicalDeviceSynchronization2Features +PhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR :: PhysicalDeviceZeroInitializeWorkgroupMemoryFeatures +CopyBufferInfo2KHR :: CopyBufferInfo2 +CopyImageInfo2KHR :: CopyImageInfo2 +CopyBufferToImageInfo2KHR :: CopyBufferToImageInfo2 +CopyImageToBufferInfo2KHR :: CopyImageToBufferInfo2 +BlitImageInfo2KHR :: BlitImageInfo2 +ResolveImageInfo2KHR :: ResolveImageInfo2 +BufferCopy2KHR :: BufferCopy2 +ImageCopy2KHR :: ImageCopy2 +ImageBlit2KHR :: ImageBlit2 +BufferImageCopy2KHR :: BufferImageCopy2 +ImageResolve2KHR :: ImageResolve2 +FormatFeatureFlags2KHR :: FormatFeatureFlags2 +FormatFeatureFlag2KHR :: FormatFeatureFlag2 +FormatProperties3KHR :: FormatProperties3 +PhysicalDeviceMaintenance4FeaturesKHR :: PhysicalDeviceMaintenance4Features +PhysicalDeviceMaintenance4PropertiesKHR :: PhysicalDeviceMaintenance4Properties +DeviceBufferMemoryRequirementsKHR :: DeviceBufferMemoryRequirements +DeviceImageMemoryRequirementsKHR :: DeviceImageMemoryRequirements +PhysicalDeviceTextureCompressionASTCHDRFeaturesEXT :: PhysicalDeviceTextureCompressionASTCHDRFeatures +SamplerReductionModeEXT :: SamplerReductionMode +SamplerReductionModeCreateInfoEXT :: SamplerReductionModeCreateInfo +PhysicalDeviceSamplerFilterMinmaxPropertiesEXT :: PhysicalDeviceSamplerFilterMinmaxProperties +PhysicalDeviceInlineUniformBlockFeaturesEXT :: PhysicalDeviceInlineUniformBlockFeatures +PhysicalDeviceInlineUniformBlockPropertiesEXT :: PhysicalDeviceInlineUniformBlockProperties +WriteDescriptorSetInlineUniformBlockEXT :: WriteDescriptorSetInlineUniformBlock +DescriptorPoolInlineUniformBlockCreateInfoEXT :: DescriptorPoolInlineUniformBlockCreateInfo +DescriptorBindingFlagEXT :: DescriptorBindingFlag +DescriptorBindingFlagsEXT :: DescriptorBindingFlags +DescriptorSetLayoutBindingFlagsCreateInfoEXT :: DescriptorSetLayoutBindingFlagsCreateInfo +PhysicalDeviceDescriptorIndexingFeaturesEXT :: PhysicalDeviceDescriptorIndexingFeatures +PhysicalDeviceDescriptorIndexingPropertiesEXT :: PhysicalDeviceDescriptorIndexingProperties +DescriptorSetVariableDescriptorCountAllocateInfoEXT :: DescriptorSetVariableDescriptorCountAllocateInfo +DescriptorSetVariableDescriptorCountLayoutSupportEXT :: DescriptorSetVariableDescriptorCountLayoutSupport +RayTracingShaderGroupTypeNV :: RayTracingShaderGroupTypeKHR +GeometryTypeNV :: GeometryTypeKHR +AccelerationStructureTypeNV :: AccelerationStructureTypeKHR +CopyAccelerationStructureModeNV :: CopyAccelerationStructureModeKHR +GeometryFlagsNV :: GeometryFlagsKHR +GeometryFlagNV :: GeometryFlagKHR +GeometryInstanceFlagsNV :: GeometryInstanceFlagsKHR +GeometryInstanceFlagNV :: GeometryInstanceFlagKHR +BuildAccelerationStructureFlagsNV :: BuildAccelerationStructureFlagsKHR +BuildAccelerationStructureFlagNV :: BuildAccelerationStructureFlagKHR +TransformMatrixNV :: TransformMatrixKHR +AabbPositionsNV :: AabbPositionsKHR +AccelerationStructureInstanceNV :: AccelerationStructureInstanceKHR +QueueGlobalPriorityEXT :: QueueGlobalPriorityKHR +DeviceQueueGlobalPriorityCreateInfoEXT :: DeviceQueueGlobalPriorityCreateInfoKHR +PipelineCreationFeedbackFlagEXT :: PipelineCreationFeedbackFlag +PipelineCreationFeedbackFlagsEXT :: PipelineCreationFeedbackFlags +PipelineCreationFeedbackCreateInfoEXT :: PipelineCreationFeedbackCreateInfo +PipelineCreationFeedbackEXT :: PipelineCreationFeedback +QueryPoolCreateInfoINTEL :: QueryPoolPerformanceQueryCreateInfoINTEL +PhysicalDeviceScalarBlockLayoutFeaturesEXT :: PhysicalDeviceScalarBlockLayoutFeatures +PhysicalDeviceSubgroupSizeControlFeaturesEXT :: PhysicalDeviceSubgroupSizeControlFeatures +PhysicalDeviceSubgroupSizeControlPropertiesEXT :: PhysicalDeviceSubgroupSizeControlProperties +PipelineShaderStageRequiredSubgroupSizeCreateInfoEXT :: PipelineShaderStageRequiredSubgroupSizeCreateInfo +PhysicalDeviceBufferAddressFeaturesEXT :: PhysicalDeviceBufferDeviceAddressFeaturesEXT +BufferDeviceAddressInfoEXT :: BufferDeviceAddressInfo +ToolPurposeFlagEXT :: ToolPurposeFlag +ToolPurposeFlagsEXT :: ToolPurposeFlags +PhysicalDeviceToolPropertiesEXT :: PhysicalDeviceToolProperties +ImageStencilUsageCreateInfoEXT :: ImageStencilUsageCreateInfo +PhysicalDeviceHostQueryResetFeaturesEXT :: PhysicalDeviceHostQueryResetFeatures +PhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT :: PhysicalDeviceShaderDemoteToHelperInvocationFeatures +PhysicalDeviceTexelBufferAlignmentPropertiesEXT :: PhysicalDeviceTexelBufferAlignmentProperties +PrivateDataSlotEXT :: PrivateDataSlot +PrivateDataSlotCreateFlagsEXT :: PrivateDataSlotCreateFlags +PhysicalDevicePrivateDataFeaturesEXT :: PhysicalDevicePrivateDataFeatures +DevicePrivateDataCreateInfoEXT :: DevicePrivateDataCreateInfo +PrivateDataSlotCreateInfoEXT :: PrivateDataSlotCreateInfo +PhysicalDevicePipelineCreationCacheControlFeaturesEXT :: PhysicalDevicePipelineCreationCacheControlFeatures +PhysicalDeviceImageRobustnessFeaturesEXT :: PhysicalDeviceImageRobustnessFeatures +PhysicalDeviceGlobalPriorityQueryFeaturesEXT :: PhysicalDeviceGlobalPriorityQueryFeaturesKHR +QueueFamilyGlobalPriorityPropertiesEXT :: QueueFamilyGlobalPriorityPropertiesKHR diff --git a/vendor/wasm/WebGL/runtime.js b/vendor/wasm/WebGL/runtime.js index b6994a8ec..3dc5186ca 100644 --- a/vendor/wasm/WebGL/runtime.js +++ b/vendor/wasm/WebGL/runtime.js @@ -416,7 +416,7 @@ class WebGLInterface { log = log.substring(0, n); this.mem.loadBytes(buf_ptr, buf_len).set(new TextEncoder("utf-8").encode(log)) - storeInt(length_ptr, n); + this.mem.storeInt(length_ptr, n); } }, GetShaderInfoLog: (shader, buf_ptr, buf_len, length_ptr) => { @@ -429,7 +429,7 @@ class WebGLInterface { log = log.substring(0, n); this.mem.loadBytes(buf_ptr, buf_len).set(new TextEncoder("utf-8").encode(log)) - storeInt(length_ptr, n); + this.mem.storeInt(length_ptr, n); } }, GetShaderiv: (shader, pname, p) => { @@ -439,11 +439,11 @@ class WebGLInterface { if (log === null) { log = "(unknown error)"; } - storeInt(p, log.length+1); + this.mem.storeInt(p, log.length+1); } else if (pname == 35720) { let source = this.ctx.getShaderSource(this.shaders[shader]); let sourceLength = (source === null || source.length == 0) ? 0 : source.length+1; - storeInt(p, sourceLength); + this.mem.storeInt(p, sourceLength); } else { let param = this.ctx.getShaderParameter(this.shaders[shader], pname); this.mem.storeI32(p, param); @@ -672,9 +672,9 @@ class WebGLInterface { this.ctx.texImage3D(target, level, internalformat, width, height, depth, border, format, type, null); } }, - TexSubImage3D: (target, level, xoffset, yoffset, width, height, depth, format, type, size, data) => { + TexSubImage3D: (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, size, data) => { this.assertWebGL2(); - this.ctx.texSubImage3D(target, level, xoffset, yoffset, width, height, depth, format, type, this.mem.loadBytes(data, size)); + this.ctx.texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, this.mem.loadBytes(data, size)); }, CompressedTexImage3D: (target, level, internalformat, width, height, depth, border, imageSize, data) => { this.assertWebGL2(); @@ -684,12 +684,12 @@ class WebGLInterface { this.ctx.compressedTexImage3D(target, level, internalformat, width, height, depth, border, null); } }, - CompressedTexSubImage3D: (target, level, xoffset, yoffset, width, height, depth, format, imageSize, data) => { + CompressedTexSubImage3D: (target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data) => { this.assertWebGL2(); if (data) { - this.ctx.compressedTexSubImage3D(target, level, xoffset, yoffset, width, height, depth, format, this.mem.loadBytes(data, imageSize)); + this.ctx.compressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, this.mem.loadBytes(data, imageSize)); } else { - this.ctx.compressedTexSubImage3D(target, level, xoffset, yoffset, width, height, depth, format, null); + this.ctx.compressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, null); } }, @@ -994,7 +994,7 @@ class WebGLInterface { let n = Math.min(buf_len, name.length); name = name.substring(0, n); this.mem.loadBytes(buf_ptr, buf_len).set(new TextEncoder("utf-8").encode(name)) - storeInt(length_ptr, n); + this.mem.storeInt(length_ptr, n); }, UniformBlockBinding: (program, uniformBlockIndex, uniformBlockBinding) => { this.assertWebGL2(); @@ -1031,4 +1031,4 @@ class WebGLInterface { }; -export {WebGLInterface}; \ No newline at end of file +export {WebGLInterface};