Merge branch 'master' into llvm-12.0.1-windows

This commit is contained in:
gingerBill
2021-09-18 12:55:13 +01:00
committed by GitHub
99 changed files with 112397 additions and 4769 deletions
+7 -4
View File
@@ -3,7 +3,7 @@
setlocal EnableDelayedExpansion
for /f "usebackq tokens=1,2 delims=,=- " %%i in (`wmic os get LocalDateTime /value`) do @if %%i==LocalDateTime (
set CURR_DATE_TIME=%%j
set CURR_DATE_TIME=%%j
)
set curr_year=%CURR_DATE_TIME:~0,4%
@@ -23,9 +23,9 @@ if "%1" == "1" (
:: Normal = 0, CI Nightly = 1
if "%2" == "1" (
set nightly=1
set nightly=1
) else (
set nightly=0
set nightly=0
)
set odin_version_raw="dev-%curr_year%-%curr_month%"
@@ -70,8 +70,11 @@ del *.pdb > NUL 2> NUL
del *.ilk > NUL 2> NUL
cl %compiler_settings% "src\main.cpp" "src\libtommath.cpp" /link %linker_settings% -OUT:%exe_name%
if %errorlevel% neq 0 goto end_of_build
call build_vendor.bat
if %errorlevel% neq 0 goto end_of_build
if %release_mode% EQU 0 odin run examples/demo
del *.obj > NUL 2> NUL
+17
View File
@@ -0,0 +1,17 @@
@echo off
setlocal EnableDelayedExpansion
rem build the .lib files already exist
if not exist "vendor\stb\lib\*.lib" (
pushd vendor\stb\src
call build.bat
popd
)
if not exist "vendor\miniaudio\lib\*.lib" (
pushd vendor\miniaudio\src
call build.bat
popd
)
+10 -4
View File
@@ -41,13 +41,18 @@ Alignment :: enum {
}
Error :: enum {
Okay = 0,
None = 0,
Error,
}
XXH_DISABLE_PREFETCH :: #config(XXH_DISABLE_PREFETCH, false)
XXH_DISABLE_PREFETCH :: #config(XXH_DISABLE_PREFETCH, true)
when !XXH_DISABLE_PREFETCH {
/*
llvm.prefetch fails code generation on Linux.
*/
when XXH_DISABLE_PREFETCH {
import "core:sys/llvm"
prefetch_address :: #force_inline proc(address: rawptr) {
intrinsics.prefetch_read_data(address, /*high*/3)
}
@@ -55,13 +60,14 @@ when !XXH_DISABLE_PREFETCH {
ptr := rawptr(uintptr(address) + offset)
prefetch_address(ptr)
}
prefetch :: proc { prefetch_address, prefetch_offset, }
} else {
prefetch_address :: #force_inline proc(address: rawptr) {
}
prefetch_offset :: #force_inline proc(address: rawptr, #any_int offset: uintptr) {
}
}
prefetch :: proc { prefetch_address, prefetch_offset, }
@(optimization_mode="speed")
XXH_rotl32 :: #force_inline proc(x, r: u32) -> (res: u32) {
+372
View File
@@ -0,0 +1,372 @@
/*
An implementation of Yann Collet's [xxhash Fast Hash Algorithm](https://cyan4973.github.io/xxHash/).
Copyright 2021 Jeroen van Rijn <nom@duclavier.com>.
Made available under Odin's BSD-3 license, based on the original C code.
List of contributors:
Jeroen van Rijn: Initial implementation.
*/
package xxhash
import "core:mem"
import "core:intrinsics"
/*
=== XXH3 128-bit streaming ===
All the functions are actually the same as for 64-bit streaming variant.
The only difference is the finalization routine.
*/
XXH3_128_reset :: proc(state: ^XXH3_state) -> (err: Error) {
if state == nil {
return .Error
}
XXH3_reset_internal(state, 0, XXH3_kSecret[:], len(XXH3_kSecret))
return .None
}
XXH3_64_reset :: XXH3_128_reset
XXH3_128_reset_with_secret :: proc(state: ^XXH3_state, secret: []u8) -> (err: Error) {
if state == nil {
return .Error
}
if secret == nil || len(secret) < XXH3_SECRET_SIZE_MIN {
return .Error
}
XXH3_reset_internal(state, 0, secret, len(secret))
return .None
}
XXH3_64_reset_with_secret :: XXH3_128_reset_with_secret
XXH3_128_reset_with_seed :: proc(state: ^XXH3_state, seed: XXH64_hash) -> (err: Error) {
if seed == 0 {
return XXH3_128_reset(state)
}
if seed != state.seed {
XXH3_init_custom_secret(state.custom_secret[:], seed)
}
XXH3_reset_internal(state, seed, nil, XXH_SECRET_DEFAULT_SIZE)
return .None
}
XXH3_64_reset_with_seed :: XXH3_128_reset_with_seed
XXH3_128_update :: proc(state: ^XXH3_state, input: []u8) -> (err: Error) {
if len(input) < XXH3_MIDSIZE_MAX {
return .Error
}
return XXH3_update(state, input, XXH3_accumulate_512, XXH3_scramble_accumulator)
}
XXH3_64_update :: XXH3_128_update
XXH3_128_digest :: proc(state: ^XXH3_state) -> (hash: XXH3_128_hash) {
secret := state.custom_secret[:] if len(state.external_secret) == 0 else state.external_secret[:]
if state.total_length > XXH3_MIDSIZE_MAX {
acc: [XXH_ACC_NB]XXH64_hash
XXH3_digest_long(acc[:], state, secret)
assert(state.secret_limit + XXH_STRIPE_LEN >= XXH_ACC_NB + XXH_SECRET_MERGEACCS_START)
{
h128 := XXH128_hash_t{}
h128.low = XXH3_mergeAccs(
acc[:],
secret[XXH_SECRET_MERGEACCS_START:],
state.total_length * XXH_PRIME64_1)
h128.high = XXH3_mergeAccs(
acc[:],
secret[state.secret_limit + XXH_STRIPE_LEN - size_of(acc) - XXH_SECRET_MERGEACCS_START:],
~(u64(state.total_length) * XXH_PRIME64_2))
return h128.h
}
}
/* len <= XXH3_MIDSIZE_MAX : short code */
if state.seed != 0 {
return XXH3_128_with_seed(state.buffer[:state.total_length], state.seed)
}
return XXH3_128_with_secret(state.buffer[:state.total_length], secret[:state.secret_limit + XXH_STRIPE_LEN])
}
/*====== Canonical representation ======*/
XXH3_128_canonical_from_hash :: proc(hash: XXH128_hash_t) -> (canonical: XXH128_canonical) {
#assert(size_of(XXH128_canonical) == size_of(XXH128_hash_t))
t := hash
when ODIN_ENDIAN == "little" {
t.high = byte_swap(t.high)
t.low = byte_swap(t.low)
}
mem_copy(&canonical.digest, &t.high, size_of(u64))
mem_copy(&canonical.digest[8], &t.low, size_of(u64))
return
}
XXH3_128_hash_from_canonical :: proc(src: ^XXH128_canonical) -> (hash: u128) {
h := XXH128_hash_t{}
high := (^u64be)(&src.digest[0])^
low := (^u64be)(&src.digest[8])^
h.high = u64(high)
h.low = u64(low)
return h.h
}
/* === XXH3 streaming === */
XXH3_init_state :: proc(state: ^XXH3_state) {
state.seed = 0
}
XXH3_create_state :: proc(allocator := context.allocator) -> (res: ^XXH3_state, err: Error) {
state, mem_error := mem.new_aligned(XXH3_state, 64, allocator)
err = nil if mem_error == nil else .Error
XXH3_init_state(state)
return state, nil
}
XXH3_destroy_state :: proc(state: ^XXH3_state, allocator := context.allocator) -> (err: Error) {
free(state)
return .None
}
XXH3_copy_state :: proc(dest, src: ^XXH3_state) {
assert(dest != nil && src != nil)
mem_copy(dest, src, size_of(XXH3_state))
}
XXH3_reset_internal :: proc(state: ^XXH3_state, seed: XXH64_hash, secret: []u8, secret_size: uint) {
assert(state != nil)
init_start := offset_of(XXH3_state, buffered_size)
init_length := offset_of(XXH3_state, stripes_per_block) - init_start
assert(offset_of(XXH3_state, stripes_per_block) > init_start)
/*
Set members from buffered_size to stripes_per_block (excluded) to 0
*/
offset := rawptr(uintptr(state) + uintptr(init_start))
intrinsics.mem_zero(offset, init_length)
state.acc[0] = XXH_PRIME32_3
state.acc[1] = XXH_PRIME64_1
state.acc[2] = XXH_PRIME64_2
state.acc[3] = XXH_PRIME64_3
state.acc[4] = XXH_PRIME64_4
state.acc[5] = XXH_PRIME32_2
state.acc[6] = XXH_PRIME64_5
state.acc[7] = XXH_PRIME32_1
state.seed = seed
state.external_secret = secret
assert(secret_size >= XXH3_SECRET_SIZE_MIN)
state.secret_limit = secret_size - XXH_STRIPE_LEN
state.stripes_per_block = state.secret_limit / XXH_SECRET_CONSUME_RATE
}
/*
Note: when XXH3_consumeStripes() is invoked, there must be a guarantee that at least
one more byte must be consumed from input so that the function can blindly consume
all stripes using the "normal" secret segment.
*/
XXH3_consume_stripes :: #force_inline proc(
acc: []xxh_u64, stripes_so_far: ^uint, stripes_per_block: uint, input: []u8,
number_of_stripes: uint, secret: []u8, secret_limit: uint,
f_acc512: XXH3_accumulate_512_f, f_scramble: XXH3_scramble_accumulator_f) {
assert(number_of_stripes <= stripes_per_block) /* can handle max 1 scramble per invocation */
assert(stripes_so_far^ < stripes_per_block)
if stripes_per_block - stripes_so_far^ <= number_of_stripes {
/* need a scrambling operation */
stripes_to_end_of_block := stripes_per_block - stripes_so_far^
stripes_after_block := number_of_stripes - stripes_to_end_of_block
XXH3_accumulate(acc, input, secret[stripes_so_far^ * XXH_SECRET_CONSUME_RATE:], stripes_to_end_of_block, f_acc512)
f_scramble(acc, secret[secret_limit:])
XXH3_accumulate(acc, input[stripes_to_end_of_block * XXH_STRIPE_LEN:], secret, stripes_after_block, f_acc512)
stripes_so_far^ = stripes_after_block
} else {
XXH3_accumulate(acc, input, secret[stripes_so_far^ * XXH_SECRET_CONSUME_RATE:], number_of_stripes, f_acc512)
stripes_so_far^ += number_of_stripes
}
}
/*
Both XXH3_64bits_update and XXH3_128bits_update use this routine.
*/
XXH3_update :: #force_inline proc(
state: ^XXH3_state, input: []u8,
f_acc512: XXH3_accumulate_512_f,
f_scramble: XXH3_scramble_accumulator_f) -> (err: Error) {
input := input
length := len(input)
secret := state.custom_secret[:] if len(state.external_secret) == 0 else state.external_secret[:]
assert(len(input) > 0)
state.total_length += u64(length)
assert(state.buffered_size <= XXH3_INTERNAL_BUFFER_SIZE)
if int(state.buffered_size) + length <= XXH3_INTERNAL_BUFFER_SIZE { /* fill in tmp buffer */
mem_copy(&state.buffer[state.buffered_size], &input[0], length)
state.buffered_size += u32(length)
return .None
}
/* total input is now > XXH3_INTERNAL_BUFFER_SIZE */
XXH3_INTERNAL_BUFFER_STRIPES :: XXH3_INTERNAL_BUFFER_SIZE / XXH_STRIPE_LEN
#assert(XXH3_INTERNAL_BUFFER_SIZE % XXH_STRIPE_LEN == 0) /* clean multiple */
/*
Internal buffer is partially filled (always, except at beginning)
Complete it, then consume it.
*/
if state.buffered_size > 0 {
load_size := int(XXH3_INTERNAL_BUFFER_SIZE - state.buffered_size)
mem_copy(&state.buffer[state.buffered_size], &input[0], load_size)
input = input[load_size:]
XXH3_consume_stripes(
state.acc[:], &state.stripes_so_far, state.stripes_per_block,
state.buffer[:], XXH3_INTERNAL_BUFFER_STRIPES,
secret, state.secret_limit, f_acc512, f_scramble)
state.buffered_size = 0
}
assert(len(input) > 0)
/* Consume input by a multiple of internal buffer size */
if len(input) > XXH3_INTERNAL_BUFFER_SIZE {
tail := input[:len(input) - XXH_STRIPE_LEN]
for len(input) > XXH3_INTERNAL_BUFFER_SIZE {
XXH3_consume_stripes(
state.acc[:], &state.stripes_so_far, state.stripes_per_block,
input, XXH3_INTERNAL_BUFFER_STRIPES,
secret, state.secret_limit, f_acc512, f_scramble)
input = input[XXH3_INTERNAL_BUFFER_SIZE:]
}
/* for last partial stripe */
mem_copy(&state.buffer[XXH3_INTERNAL_BUFFER_SIZE - XXH_STRIPE_LEN], &tail[0], XXH_STRIPE_LEN)
}
length = len(input)
assert(length > 0)
/* Some remaining input (always) : buffer it */
mem_copy(&state.buffer[0], &input[0], length)
state.buffered_size = u32(length)
return .None
}
XXH3_digest_long :: #force_inline proc(acc: []u64, state: ^XXH3_state, secret: []u8) {
/*
Digest on a local copy. This way, the state remains unaltered, and it can
continue ingesting more input afterwards.
*/
mem_copy(&acc[0], &state.acc[0], size_of(state.acc))
if state.buffered_size >= XXH_STRIPE_LEN {
number_of_stripes := uint((state.buffered_size - 1) / XXH_STRIPE_LEN)
stripes_so_far := state.stripes_so_far
XXH3_consume_stripes(
acc[:], &stripes_so_far, state.stripes_per_block, state.buffer[:], number_of_stripes,
secret, state.secret_limit, XXH3_accumulate_512, XXH3_scramble_accumulator)
/* last stripe */
XXH3_accumulate_512(
acc[:],
state.buffer[state.buffered_size - XXH_STRIPE_LEN:],
secret[state.secret_limit - XXH_SECRET_LASTACC_START:])
} else { /* bufferedSize < XXH_STRIPE_LEN */
last_stripe: [XXH_STRIPE_LEN]u8
catchup_size := int(XXH_STRIPE_LEN) - int(state.buffered_size)
assert(state.buffered_size > 0) /* there is always some input buffered */
mem_copy(&last_stripe[0], &state.buffer[XXH3_INTERNAL_BUFFER_SIZE - catchup_size], catchup_size)
mem_copy(&last_stripe[catchup_size], &state.buffer[0], int(state.buffered_size))
XXH3_accumulate_512(acc[:], last_stripe[:], secret[state.secret_limit - XXH_SECRET_LASTACC_START:])
}
}
XXH3_64_digest :: proc(state: ^XXH3_state) -> (hash: XXH64_hash) {
secret := state.custom_secret[:] if len(state.external_secret) == 0 else state.external_secret[:]
if state.total_length > XXH3_MIDSIZE_MAX {
acc: [XXH_ACC_NB]xxh_u64
XXH3_digest_long(acc[:], state, secret[:])
return XXH3_mergeAccs(acc[:], secret[ XXH_SECRET_MERGEACCS_START:], state.total_length * XXH_PRIME64_1)
}
/* totalLen <= XXH3_MIDSIZE_MAX: digesting a short input */
if state.seed == 0 {
return XXH3_64_with_seed(state.buffer[:state.total_length], state.seed)
}
return XXH3_64_with_secret(state.buffer[:state.total_length], secret[:state.secret_limit + XXH_STRIPE_LEN])
}
XXH3_generate_secret :: proc(secret_buffer: []u8, custom_seed: []u8) {
secret_length := len(secret_buffer)
assert(secret_length >= XXH3_SECRET_SIZE_MIN)
custom_seed_size := len(custom_seed)
if custom_seed_size == 0 {
k := XXH3_kSecret
mem_copy(&secret_buffer[0], &k[0], XXH_SECRET_DEFAULT_SIZE)
return
}
{
segment_size :: size_of(XXH128_hash_t)
number_of_segments := u64(XXH_SECRET_DEFAULT_SIZE / segment_size)
seeds: [12]u64le
assert(number_of_segments == 12)
assert(segment_size * number_of_segments == XXH_SECRET_DEFAULT_SIZE) /* exact multiple */
scrambler := XXH3_128_canonical_from_hash(XXH128_hash_t{h=XXH3_128(custom_seed[:])})
/*
Copy customSeed to seeds[], truncating or repeating as necessary.
TODO: Convert `mem_copy` to slice copies.
*/
{
to_fill := min(custom_seed_size, size_of(seeds))
filled := to_fill
mem_copy(&seeds[0], &custom_seed[0], to_fill)
for filled < size_of(seeds) {
to_fill = min(filled, size_of(seeds) - filled)
seed_offset := rawptr(uintptr(&seeds[0]) + uintptr(filled))
mem_copy(seed_offset, &seeds[0], to_fill)
filled += to_fill
}
}
/*
Generate secret
*/
mem_copy(&secret_buffer[0], &scrambler, size_of(scrambler))
for segment_number := u64(1); segment_number < number_of_segments; segment_number += 1 {
segment_start := segment_number * segment_size
this_seed := u64(seeds[segment_number]) + segment_number
segment := XXH3_128_canonical_from_hash(XXH128_hash_t{h=XXH3_128(scrambler.digest[:], this_seed)})
mem_copy(&secret_buffer[segment_start], &segment, size_of(segment))
}
}
}
+217 -170
View File
@@ -8,91 +8,29 @@
Jeroen van Rijn: Initial implementation.
*/
package xxhash
import "core:intrinsics"
/* *********************************************************************
* XXH3
* New generation hash designed for speed on small keys and vectorization
************************************************************************
/*
*************************************************************************
* XXH3
* New generation hash designed for speed on small keys and vectorization
*************************************************************************
* One goal of XXH3 is to make it fast on both 32-bit and 64-bit, while
* remaining a true 64-bit/128-bit hash function.
*
* This is done by prioritizing a subset of 64-bit operations that can be
* emulated without too many steps on the average 32-bit machine.
*
* For example, these two lines seem similar, and run equally fast on 64-bit:
*
* xxh_u64 x;
* x ^= (x >> 47); // good
* x ^= (x >> 13); // bad
*
* However, to a 32-bit machine, there is a major difference.
*
* x ^= (x >> 47) looks like this:
*
* x.lo ^= (x.hi >> (47 - 32));
*
* while x ^= (x >> 13) looks like this:
*
* // note: funnel shifts are not usually cheap.
* x.lo ^= (x.lo >> 13) | (x.hi << (32 - 13));
* x.hi ^= (x.hi >> 13);
*
* The first one is significantly faster than the second, simply because the
* shift is larger than 32. This means:
* - All the bits we need are in the upper 32 bits, so we can ignore the lower
* 32 bits in the shift.
* - The shift result will always fit in the lower 32 bits, and therefore,
* we can ignore the upper 32 bits in the xor.
*
* Thanks to this optimization, XXH3 only requires these features to be efficient:
*
* - Usable unaligned access
* - A 32-bit or 64-bit ALU
* - If 32-bit, a decent ADC instruction
* - A 32 or 64-bit multiply with a 64-bit result
* - For the 128-bit variant, a decent byteswap helps short inputs.
*
* The first two are already required by XXH32, and almost all 32-bit and 64-bit
* platforms which can run XXH32 can run XXH3 efficiently.
*
* Thumb-1, the classic 16-bit only subset of ARM's instruction set, is one
* notable exception.
*
* First of all, Thumb-1 lacks support for the UMULL instruction which
* performs the important long multiply. This means numerous __aeabi_lmul
* calls.
*
* Second of all, the 8 functional registers are just not enough.
* Setup for __aeabi_lmul, byteshift loads, pointers, and all arithmetic need
* Lo registers, and this shuffling results in thousands more MOVs than A32.
*
* A32 and T32 don't have this limitation. They can access all 14 registers,
* do a 32->64 multiply with UMULL, and the flexible operand allowing free
* shifts is helpful, too.
*
* Therefore, we do a quick sanity check.
*
* If compiling Thumb-1 for a target which supports ARM instructions, we will
* emit a warning, as it is not a "sane" platform to compile for.
*
* Usually, if this happens, it is because of an accident and you probably need
* to specify -march, as you likely meant to compile for a newer architecture.
*
* Credit: large sections of the vectorial and asm source code paths
* have been contributed by @easyaspi314
* ==========================================
* XXH3 default settings
* ==========================================
*/
XXH_ACC_ALIGN :: 8 /* scalar */
/* ==========================================
* XXH3 default settings
* ========================================== */
XXH3_SECRET_SIZE_MIN :: 136
/*
Custom secrets have a default length of 192, but can be set to a different size.
The minimum secret size is 136 bytes. It must also be a multiple of 64.
*/
XXH_SECRET_DEFAULT_SIZE :: max(XXH3_SECRET_SIZE_MIN, #config(XXH_SECRET_DEFAULT_SIZE, 192))
#assert(XXH_SECRET_DEFAULT_SIZE % 64 == 0)
XXH3_kSecret :: [?]u8{
XXH3_kSecret := [XXH_SECRET_DEFAULT_SIZE]u8{
0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c,
0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f,
0xcb, 0x79, 0xe6, 0x4e, 0xcc, 0xc0, 0xe5, 0x78, 0x82, 0x5a, 0xd0, 0x7d, 0xcc, 0xff, 0x72, 0x21,
@@ -106,8 +44,42 @@ XXH3_kSecret :: [?]u8{
0x2b, 0x16, 0xbe, 0x58, 0x7d, 0x47, 0xa1, 0xfc, 0x8f, 0xf8, 0xb8, 0xd1, 0x7a, 0xd0, 0x31, 0xce,
0x45, 0xcb, 0x3a, 0x8f, 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e,
}
#assert(size_of(XXH3_kSecret) == 192)
/*
Do not change this constant.
*/
XXH3_SECRET_SIZE_MIN :: 136
#assert(len(XXH3_kSecret) == 192 && len(XXH3_kSecret) > XXH3_SECRET_SIZE_MIN)
XXH_ACC_ALIGN :: 8 /* scalar */
/*
This is the optimal update size for incremental hashing.
*/
XXH3_INTERNAL_BUFFER_SIZE :: 256
/*
Streaming state.
IMPORTANT: This structure has a strict alignment requirement of 64 bytes!! **
Do not allocate this with `make()` or `new`, it will not be sufficiently aligned.
Use`XXH3_create_state` and `XXH3_destroy_state, or stack allocation.
*/
XXH3_state :: struct {
acc: [8]u64,
custom_secret: [XXH_SECRET_DEFAULT_SIZE]u8,
buffer: [XXH3_INTERNAL_BUFFER_SIZE]u8,
buffered_size: u32,
reserved32: u32,
stripes_so_far: uint,
total_length: u64,
stripes_per_block: uint,
secret_limit: uint,
seed: u64,
reserved64: u64,
external_secret: []u8,
}
#assert(offset_of(XXH3_state, acc) % 64 == 0 && offset_of(XXH3_state, custom_secret) % 64 == 0 &&
offset_of(XXH3_state, buffer) % 64 == 0)
/************************************************************************
* XXH3 128-bit variant
@@ -118,7 +90,6 @@ XXH3_kSecret :: [?]u8{
*/
xxh_u128 :: u128
XXH3_128_hash :: u128
XXH3_128_DEFAULT_SEED :: xxh_u64(0)
XXH128_hash_t :: struct #raw_union {
using raw: struct {
@@ -129,14 +100,8 @@ XXH128_hash_t :: struct #raw_union {
}
#assert(size_of(xxh_u128) == size_of(XXH128_hash_t))
@(optimization_mode="speed")
XXH_mul_32_to_64 :: #force_inline proc(x, y: xxh_u32) -> (res: xxh_u64) {
return u64(x) * u64(y)
}
@(optimization_mode="speed")
XXH_mul_64_to_128 :: #force_inline proc(lhs, rhs: xxh_u64) -> (res: xxh_u128) {
return xxh_u128(lhs) * xxh_u128(rhs)
XXH128_canonical :: struct {
digest: [size_of(XXH128_hash_t)]u8,
}
/*
@@ -148,9 +113,8 @@ XXH_mul_64_to_128 :: #force_inline proc(lhs, rhs: xxh_u64) -> (res: xxh_u128) {
*/
@(optimization_mode="speed")
XXH_mul_64_to_128_fold_64 :: #force_inline proc(lhs, rhs: xxh_u64) -> (res: xxh_u64) {
t := XXH128_hash_t{}
t.h = #force_inline XXH_mul_64_to_128(lhs, rhs)
return t.low ~ t.high
t := u128(lhs) * u128(rhs)
return u64(t & 0xFFFFFFFFFFFFFFFF) ~ u64(t >> 64)
}
@(optimization_mode="speed")
@@ -186,12 +150,12 @@ XXH3_rrmxmx :: #force_inline proc(h64, length: xxh_u64) -> (res: xxh_u64) {
/*
==========================================
XXH3 128 bits (a.k.a XXH128)
XXH3 128 bits (a.k.a XXH128)
==========================================
XXH3's 128-bit variant has better mixing and strength than the 64-bit variant,
even without counting the significantly larger output size.
For example, extra steps are taken to avoid the seed-dependent collisions
For example, extra steps are taken to avoid the seed-dependent collisions
in 17-240 byte inputs (See XXH3_mix16B and XXH128_mix32B).
This strength naturally comes at the cost of some speed, especially on short
@@ -241,7 +205,7 @@ XXH3_len_4to8_128b :: #force_inline proc(input: []u8, secret: []u8, seed: xxh_u6
/* Shift len to the left to ensure it is even, this avoids even multiplies. */
m128 := XXH128_hash_t{
h = XXH_mul_64_to_128(keyed, u64(XXH_PRIME64_1) + (u64(length) << 2)),
h = u128(keyed) * (XXH_PRIME64_1 + u128(length) << 2),
}
m128.high += (m128.low << 1)
m128.low ~= (m128.high >> 3)
@@ -265,7 +229,7 @@ XXH3_len_9to16_128b :: #force_inline proc(input: []u8, secret: []u8, seed: xxh_u
input_lo := XXH64_read64(input[0:])
input_hi := XXH64_read64(input[length - 8:])
m128 := XXH128_hash_t{
h = XXH_mul_64_to_128(input_lo ~ input_hi ~ bitflipl, XXH_PRIME64_1),
h = u128(input_lo ~ input_hi ~ bitflipl) * XXH_PRIME64_1,
}
/*
* Put len in the middle of m128 to ensure that the length gets mixed to
@@ -277,49 +241,14 @@ XXH3_len_9to16_128b :: #force_inline proc(input: []u8, secret: []u8, seed: xxh_u
* Add the high 32 bits of input_hi to the high 32 bits of m128, then
* add the long product of the low 32 bits of input_hi and XXH_XXH_PRIME32_2 to
* the high 64 bits of m128.
*
* The best approach to this operation is different on 32-bit and 64-bit.
*/
when size_of(rawptr) == 4 { /* 32-bit */
/*
* 32-bit optimized version, which is more readable.
*
* On 32-bit, it removes an ADC and delays a dependency between the two
* halves of m128.high64, but it generates an extra mask on 64-bit.
*/
m128.high += (input_hi & 0xFFFFFFFF00000000) + XXH_mul_32_to_64(u32(input_hi), XXH_PRIME32_2)
} else {
/*
* 64-bit optimized (albeit more confusing) version.
*
* Uses some properties of addition and multiplication to remove the mask:
*
* Let:
* a = input_hi.lo = (input_hi & 0x00000000FFFFFFFF)
* b = input_hi.hi = (input_hi & 0xFFFFFFFF00000000)
* c = XXH_XXH_PRIME32_2
*
* a + (b * c)
* Inverse Property: x + y - x == y
* a + (b * (1 + c - 1))
* Distributive Property: x * (y + z) == (x * y) + (x * z)
* a + (b * 1) + (b * (c - 1))
* Identity Property: x * 1 == x
* a + b + (b * (c - 1))
*
* Substitute a, b, and c:
* input_hi.hi + input_hi.lo + ((xxh_u64)input_hi.lo * (XXH_XXH_PRIME32_2 - 1))
*
* Since input_hi.hi + input_hi.lo == input_hi, we get this:
* input_hi + ((xxh_u64)input_hi.lo * (XXH_XXH_PRIME32_2 - 1))
*/
m128.high += input_hi + XXH_mul_32_to_64(u32(input_hi), XXH_PRIME32_2 - 1)
}
m128.high += input_hi + u64(u32(input_hi)) * u64(XXH_PRIME32_2 - 1)
/* m128 ^= XXH_swap64(m128 >> 64); */
m128.low ~= byte_swap(m128.high)
{ /* 128x64 multiply: h128 = m128 * XXH_PRIME64_2; */
h128 := XXH128_hash_t{
h = XXH_mul_64_to_128(m128.low, XXH_PRIME64_2),
h = u128(m128.low) * XXH_PRIME64_2,
}
h128.high += m128.high * XXH_PRIME64_2
h128.low = XXH3_avalanche(h128.low)
@@ -364,9 +293,6 @@ XXH128_mix32B :: #force_inline proc(acc: xxh_u128, input_1: []u8, input_2: []u8,
}
}
@(optimization_mode="speed")
XXH3_len_17to128_128b :: #force_inline proc(input: []u8, secret: []u8, seed: xxh_u64) -> (res: xxh_u128) {
length := len(input)
@@ -410,18 +336,18 @@ XXH3_len_129to240_128b :: #force_inline proc(input: []u8, secret: []u8, seed: xx
i: int
#no_bounds_check for i = 0; i < 4; i += 1 {
acc.h = XXH128_mix32B(acc.h,
input[32 * i:],
input [32 * i + 16:],
secret[32 * i:],
seed)
input[32 * i:],
input [32 * i + 16:],
secret[32 * i:],
seed)
}
acc.low = XXH3_avalanche(acc.low)
acc.high = XXH3_avalanche(acc.high)
#no_bounds_check for i = 4; i < nbRounds; i += 1 {
acc.h = XXH128_mix32B(acc.h,
input[32 * i:], input[32 * i + 16:],
secret[XXH3_MIDSIZE_STARTOFFSET + (32 * (i - 4)):],
input[32 * i:], input[32 * i + 16:],
secret[XXH3_MIDSIZE_STARTOFFSET + (32 * (i - 4)):],
seed)
}
/* last bytes */
@@ -435,9 +361,9 @@ XXH3_len_129to240_128b :: #force_inline proc(input: []u8, secret: []u8, seed: xx
h128 := XXH128_hash_t{}
h128.low = acc.low + acc.high
h128.high = u64(
u128(acc.low * XXH_PRIME64_1) \
+ u128(acc.high * XXH_PRIME64_4) \
+ u128((u64(length) - seed) * XXH_PRIME64_2))
u128(acc.low * XXH_PRIME64_1) \
+ u128(acc.high * XXH_PRIME64_4) \
+ u128((u64(length) - seed) * XXH_PRIME64_2))
h128.low = XXH3_avalanche(h128.low)
h128.high = u64(i64(0) - i64(XXH3_avalanche(h128.high)))
return h128.h
@@ -481,18 +407,20 @@ XXH3_hashLong_128b_internal :: #force_inline proc(
/*
* It's important for performance that XXH3_hashLong is not inlined.
*/
@(optimization_mode="speed")
XXH3_hashLong_128b_default :: #force_no_inline proc(input: []u8, seed: xxh_u64, secret: []u8) -> (res: XXH3_128_hash) {
k_secret := XXH3_kSecret
return XXH3_hashLong_128b_internal(input, k_secret[:], XXH3_accumulate_512, XXH3_scramble_accumulator)
return XXH3_hashLong_128b_internal(input, XXH3_kSecret[:], XXH3_accumulate_512, XXH3_scramble_accumulator)
}
/*
* It's important for performance that XXH3_hashLong is not inlined.
*/
@(optimization_mode="speed")
XXH3_hashLong_128b_withSecret :: #force_no_inline proc(input: []u8, seed: xxh_u64, secret: []u8) -> (res: XXH3_128_hash) {
return XXH3_hashLong_128b_internal(input, secret, XXH3_accumulate_512, XXH3_scramble_accumulator)
}
@(optimization_mode="speed")
XXH3_hashLong_128b_withSeed_internal :: #force_inline proc(
input: []u8, seed: xxh_u64, secret: []u8,
f_acc512: XXH3_accumulate_512_f,
@@ -500,26 +428,27 @@ XXH3_hashLong_128b_withSeed_internal :: #force_inline proc(
f_initSec: XXH3_init_custom_secret_f) -> (res: XXH3_128_hash) {
if seed == 0 {
k := XXH3_kSecret
return XXH3_hashLong_128b_internal(input, k[:], f_acc512, f_scramble)
return XXH3_hashLong_128b_internal(input, XXH3_kSecret[:], f_acc512, f_scramble)
}
{
secret := [XXH_SECRET_DEFAULT_SIZE]u8{}
f_initSec(secret[:], seed)
return XXH3_hashLong_128b_internal(input, secret[:], f_acc512, f_scramble)
_secret := [XXH_SECRET_DEFAULT_SIZE]u8{}
f_initSec(_secret[:], seed)
return XXH3_hashLong_128b_internal(input, _secret[:], f_acc512, f_scramble)
}
}
/*
* It's important for performance that XXH3_hashLong is not inlined.
*/
@(optimization_mode="speed")
XXH3_hashLong_128b_withSeed :: #force_no_inline proc(input: []u8, seed: xxh_u64, secret: []u8) -> (res: XXH3_128_hash) {
return XXH3_hashLong_128b_withSeed_internal(input, seed, secret, XXH3_accumulate_512, XXH3_scramble_accumulator , XXH3_init_custom_secret)
}
XXH3_hashLong128_f :: #type proc(input: []u8, seed: xxh_u64, secret: []u8) -> (res: XXH3_128_hash)
@(optimization_mode="speed")
XXH3_128bits_internal :: #force_inline proc(
input: []u8, seed: xxh_u64, secret: []u8, f_hl128: XXH3_hashLong128_f) -> (res: XXH3_128_hash) {
@@ -545,13 +474,21 @@ XXH3_128bits_internal :: #force_inline proc(
}
/* === Public XXH128 API === */
XXH3_128bits :: proc(input: []u8) -> (hash: XXH3_128_hash) {
k := XXH3_kSecret
return XXH3_128bits_internal(input, XXH3_128_DEFAULT_SEED, k[:], XXH3_hashLong_128b_default)
@(optimization_mode="speed")
XXH3_128_default :: proc(input: []u8) -> (hash: XXH3_128_hash) {
return XXH3_128bits_internal(input, 0, XXH3_kSecret[:], XXH3_hashLong_128b_withSeed)
}
@(optimization_mode="speed")
XXH3_128_with_seed :: proc(input: []u8, seed: xxh_u64) -> (hash: XXH3_128_hash) {
return XXH3_128bits_internal(input, seed, XXH3_kSecret[:], XXH3_hashLong_128b_withSeed)
}
@(optimization_mode="speed")
XXH3_128_with_secret :: proc(input: []u8, secret: []u8) -> (hash: XXH3_128_hash) {
return XXH3_128bits_internal(input, 0, secret, XXH3_hashLong_128b_withSecret)
}
XXH3_128 :: proc { XXH3_128_default, XXH3_128_with_seed, XXH3_128_with_secret }
/*
==========================================
@@ -613,7 +550,8 @@ XXH3_len_4to8_64b :: #force_inline proc(input: []u8, secret: []u8, seed: xxh_u64
assert(secret != nil)
seed := seed
seed ~= u64(byte_swap(u32(seed) << 32))
seed ~= (u64(byte_swap(u32(seed))) << 32)
#no_bounds_check {
input1 := XXH32_read32(input)
input2 := XXH32_read32(input[length - 4:])
@@ -756,9 +694,10 @@ XXH3_len_129to240_64b :: proc(input: []u8, secret: []u8, seed: xxh_u64) -> (res:
/* ======= Long Keys ======= */
XXH_STRIPE_LEN :: 64
XXH_SECRET_CONSUME_RATE :: 8 /* nb of secret bytes consumed at each accumulation */
XXH_ACC_NB :: (XXH_STRIPE_LEN / size_of(xxh_u64))
XXH_STRIPE_LEN :: 64
XXH_SECRET_CONSUME_RATE :: 8 /* nb of secret bytes consumed at each accumulation */
XXH_ACC_NB :: (XXH_STRIPE_LEN / size_of(xxh_u64))
XXH_SECRET_LASTACC_START :: 7 /* not aligned on 8, last secret is different from acc & scrambler */
@(optimization_mode="speed")
XXH_writeLE64 :: #force_inline proc(dst: []u8, v64: u64le) {
@@ -808,9 +747,10 @@ XXH3_accumulate_512_scalar :: #force_inline proc(acc: []xxh_u64, input: []u8, se
#no_bounds_check for i := uint(0); i < XXH_ACC_NB; i += 1 {
data_val := XXH64_read64(xinput[8 * i:])
data_key := data_val ~ XXH64_read64(xsecret[8 * i:])
sec := XXH64_read64(xsecret[8 * i:])
data_key := data_val ~ sec
xacc[i ~ 1] += data_val /* swap adjacent lanes */
xacc[i ] += XXH_mul_32_to_64(u32(data_key & 0xFFFFFFFF), u32(data_key >> 32))
xacc[i ] += u64(u128(u32(data_key)) * u128(u64(data_key >> 32)))
}
}
@@ -835,12 +775,10 @@ XXH3_scramble_accumulator_scalar :: #force_inline proc(acc: []xxh_u64, secret: [
XXH3_init_custom_secret_scalar :: #force_inline proc(custom_secret: []u8, seed64: xxh_u64) {
#assert((XXH_SECRET_DEFAULT_SIZE & 15) == 0)
kSecretPtr := XXH3_kSecret
nbRounds := XXH_SECRET_DEFAULT_SIZE / 16
#no_bounds_check for i := 0; i < nbRounds; i += 1 {
lo := XXH64_read64(kSecretPtr[16 * i: ]) + seed64
hi := XXH64_read64(kSecretPtr[16 * i + 8:]) - seed64
lo := XXH64_read64(XXH3_kSecret[16 * i: ]) + seed64
hi := XXH64_read64(XXH3_kSecret[16 * i + 8:]) - seed64
XXH_writeLE64(custom_secret[16 * i: ], u64le(lo))
XXH_writeLE64(custom_secret[16 * i + 8:], u64le(hi))
}
@@ -854,8 +792,8 @@ XXH_PREFETCH_DIST :: 320
* Assumption: nbStripes will not overflow the secret size
*/
@(optimization_mode="speed")
XXH3_accumulate :: #force_inline proc(acc: []xxh_u64, input: []u8, secret: []u8, nbStripes: uint,
f_acc512: XXH3_accumulate_512_f) {
XXH3_accumulate :: #force_inline proc(
acc: []xxh_u64, input: []u8, secret: []u8, nbStripes: uint, f_acc512: XXH3_accumulate_512_f) {
for n := uint(0); n < nbStripes; n += 1 {
when !XXH_DISABLE_PREFETCH {
@@ -885,13 +823,11 @@ XXH3_hashLong_internal_loop :: #force_inline proc(acc: []xxh_u64, input: []u8, s
/* last partial block */
#no_bounds_check {
stripes := ((length - 1) - (block_len * blocks)) / XXH_STRIPE_LEN
XXH3_accumulate(acc, input[blocks * block_len:], secret, stripes, f_acc512)
/* last stripe */
#no_bounds_check {
p := input[length - XXH_STRIPE_LEN:]
XXH_SECRET_LASTACC_START :: 7 /* not aligned on 8, last secret is different from acc & scrambler */
f_acc512(acc, p, secret[secret_size - XXH_STRIPE_LEN - XXH_SECRET_LASTACC_START:])
}
}
@@ -911,4 +847,115 @@ XXH3_mergeAccs :: #force_inline proc(acc: []xxh_u64, secret: []u8, start: xxh_u6
result64 += XXH3_mix2Accs(acc[2 * i:], secret[16 * i:])
}
return XXH3_avalanche(result64)
}
}
@(optimization_mode="speed")
XXH3_hashLong_64b_internal :: #force_inline proc(input: []u8, secret: []u8,
f_acc512: XXH3_accumulate_512_f, f_scramble: XXH3_scramble_accumulator_f) -> (hash: xxh_u64) {
acc: [XXH_ACC_NB]xxh_u64 = XXH3_INIT_ACC
XXH3_hashLong_internal_loop(acc[:], input, secret, f_acc512, f_scramble)
/* converge into final hash */
#assert(size_of(acc) == 64)
/* do not align on 8, so that the secret is different from the accumulator */
XXH_SECRET_MERGEACCS_START :: 11
assert(len(secret) >= size_of(acc) + XXH_SECRET_MERGEACCS_START)
return XXH3_mergeAccs(acc[:], secret[XXH_SECRET_MERGEACCS_START:], xxh_u64(len(input)) * XXH_PRIME64_1)
}
/*
It's important for performance that XXH3_hashLong is not inlined.
*/
@(optimization_mode="speed")
XXH3_hashLong_64b_withSecret :: #force_no_inline proc(input: []u8, seed64: xxh_u64, secret: []u8) -> (hash: xxh_u64) {
return XXH3_hashLong_64b_internal(input, secret, XXH3_accumulate_512, XXH3_scramble_accumulator)
}
/*
It's important for performance that XXH3_hashLong is not inlined.
Since the function is not inlined, the compiler may not be able to understand that,
in some scenarios, its `secret` argument is actually a compile time constant.
This variant enforces that the compiler can detect that,
and uses this opportunity to streamline the generated code for better performance.
*/
@(optimization_mode="speed")
XXH3_hashLong_64b_default :: #force_no_inline proc(input: []u8, seed64: xxh_u64, secret: []u8) -> (hash: xxh_u64) {
return XXH3_hashLong_64b_internal(input, XXH3_kSecret[:], XXH3_accumulate_512, XXH3_scramble_accumulator)
}
/*
XXH3_hashLong_64b_withSeed():
Generate a custom key based on alteration of default XXH3_kSecret with the seed,
and then use this key for long mode hashing.
This operation is decently fast but nonetheless costs a little bit of time.
Try to avoid it whenever possible (typically when seed==0).
It's important for performance that XXH3_hashLong is not inlined. Not sure
why (uop cache maybe?), but the difference is large and easily measurable.
*/
@(optimization_mode="speed")
XXH3_hashLong_64b_withSeed_internal :: #force_no_inline proc(input: []u8,
seed: xxh_u64,
f_acc512: XXH3_accumulate_512_f,
f_scramble: XXH3_scramble_accumulator_f,
f_init_sec: XXH3_init_custom_secret_f) -> (hash: xxh_u64) {
if seed == 0 {
return XXH3_hashLong_64b_internal(input, XXH3_kSecret[:], f_acc512, f_scramble)
}
{
secret: [XXH_SECRET_DEFAULT_SIZE]u8
f_init_sec(secret[:], seed)
return XXH3_hashLong_64b_internal(input, secret[:], f_acc512, f_scramble)
}
}
/*
It's important for performance that XXH3_hashLong is not inlined.
*/
@(optimization_mode="speed")
XXH3_hashLong_64b_withSeed :: #force_no_inline proc(input: []u8, seed: xxh_u64, secret: []u8) -> (hash: xxh_u64) {
return XXH3_hashLong_64b_withSeed_internal(input, seed, XXH3_accumulate_512, XXH3_scramble_accumulator, XXH3_init_custom_secret)
}
XXH3_hashLong64_f :: #type proc(input: []u8, seed: xxh_u64, secret: []u8) -> (res: xxh_u64)
@(optimization_mode="speed")
XXH3_64bits_internal :: proc(input: []u8, seed: xxh_u64, secret: []u8, f_hashLong: XXH3_hashLong64_f) -> (hash: xxh_u64) {
assert(len(secret) >= XXH3_SECRET_SIZE_MIN)
/*
If an action is to be taken if len(secret) condition is not respected, it should be done here.
For now, it's a contract pre-condition.
Adding a check and a branch here would cost performance at every hash.
Also, note that function signature doesn't offer room to return an error.
*/
length := len(input)
switch {
case length <= 16: return XXH3_len_0to16_64b(input, secret, seed)
case length <= 128: return XXH3_len_17to128_64b(input, secret, seed)
case length <= XXH3_MIDSIZE_MAX: return XXH3_len_129to240_64b(input, secret, seed)
case: return f_hashLong(input, seed, secret)
}
unreachable()
}
/* === Public entry point === */
@(optimization_mode="speed")
XXH3_64_default :: proc(input: []u8) -> (hash: xxh_u64) {
return XXH3_64bits_internal(input, 0, XXH3_kSecret[:], XXH3_hashLong_64b_default)
}
@(optimization_mode="speed")
XXH3_64_with_seed :: proc(input: []u8, seed: xxh_u64) -> (hash: xxh_u64) {
return XXH3_64bits_internal(input, seed, XXH3_kSecret[:], XXH3_hashLong_64b_withSeed)
}
@(optimization_mode="speed")
XXH3_64_with_secret :: proc(input, secret: []u8) -> (hash: xxh_u64) {
return XXH3_64bits_internal(input, 0, secret, XXH3_hashLong_64b_withSecret)
}
XXH3_64 :: proc { XXH3_64_default, XXH3_64_with_seed, XXH3_64_with_secret }
+5 -5
View File
@@ -197,12 +197,12 @@ XXH32 :: proc(input: []u8, seed := XXH32_DEFAULT_SEED) -> (digest: XXH32_hash) {
*/
XXH32_create_state :: proc(allocator := context.allocator) -> (res: ^XXH32_state, err: Error) {
state := new(XXH32_state, allocator)
return state, nil if state != nil else .Error
return state, .None if state != nil else .Error
}
XXH32_destroy_state :: proc(state: ^XXH32_state, allocator := context.allocator) -> (err: Error) {
free(state, allocator)
return nil
return .None
}
XXH32_copy_state :: proc(dest, src: ^XXH32_state) {
@@ -221,7 +221,7 @@ XXH32_reset_state :: proc(state_ptr: ^XXH32_state, seed := XXH32_DEFAULT_SEED) -
Do not write into reserved, planned to be removed in a future version.
*/
mem_copy(state_ptr, &state, size_of(state) - size_of(state.reserved))
return nil
return .None
}
XXH32_update :: proc(state: ^XXH32_state, input: []u8) -> (err: Error) {
@@ -236,7 +236,7 @@ XXH32_update :: proc(state: ^XXH32_state, input: []u8) -> (err: Error) {
ptr := uintptr(raw_data(state.mem32[:])) + uintptr(state.memsize)
mem_copy(rawptr(ptr), raw_data(input), int(length))
state.memsize += XXH32_hash(length)
return nil
return .None
}
if state.memsize > 0 {/* Some data left from previous update */
@@ -276,7 +276,7 @@ XXH32_update :: proc(state: ^XXH32_state, input: []u8) -> (err: Error) {
mem_copy(raw_data(state.mem32[:]), raw_data(buf[:]), int(length))
state.memsize = u32(length)
}
return nil
return .None
}
XXH32_digest :: proc(state: ^XXH32_state) -> (res: XXH32_hash) {
+5 -5
View File
@@ -163,12 +163,12 @@ XXH64 :: proc(input: []u8, seed := XXH64_DEFAULT_SEED) -> (digest: XXH64_hash) {
*/
XXH64_create_state :: proc(allocator := context.allocator) -> (res: ^XXH64_state, err: Error) {
state := new(XXH64_state, allocator)
return state, nil if state != nil else .Error
return state, .None if state != nil else .Error
}
XXH64_destroy_state :: proc(state: ^XXH64_state, allocator := context.allocator) -> (err: Error) {
free(state, allocator)
return nil
return .None
}
XXH64_copy_state :: proc(dest, src: ^XXH64_state) {
@@ -187,7 +187,7 @@ XXH64_reset_state :: proc(state_ptr: ^XXH64_state, seed := XXH64_DEFAULT_SEED) -
Fo not write into reserved64, might be removed in a future version.
*/
mem_copy(state_ptr, &state, size_of(state) - size_of(state.reserved64))
return nil
return .None
}
@(optimization_mode="speed")
@@ -201,7 +201,7 @@ XXH64_update :: proc(state: ^XXH64_state, input: []u8) -> (err: Error) {
ptr := uintptr(raw_data(state.mem64[:])) + uintptr(state.memsize)
mem_copy(rawptr(ptr), raw_data(input), int(length))
state.memsize += u32(length)
return nil
return .None
}
if state.memsize > 0 { /* tmp buffer is full */
@@ -241,7 +241,7 @@ XXH64_update :: proc(state: ^XXH64_state, input: []u8) -> (err: Error) {
mem_copy(raw_data(state.mem64[:]), raw_data(buf[:]), int(length))
state.memsize = u32(length)
}
return nil
return .None
}
@(optimization_mode="speed")
+4
View File
@@ -37,6 +37,10 @@ overflowing_sub :: intrinsics.overflow_sub
overflowing_mul :: intrinsics.overflow_mul
log2 :: proc(x: $T) -> T where intrinsics.type_is_integer(T), intrinsics.type_is_unsigned(T) {
return (8*size_of(T)-1) - count_leading_zeros(x)
}
rotate_left8 :: proc(x: u8, k: int) -> u8 {
n :: 8
s := uint(k) & (n-1)
-2
View File
@@ -19,8 +19,6 @@ read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []F
return
}
defer delete(dirpath)
n := n
size := n
if n <= 0 {
+6 -5
View File
@@ -215,13 +215,14 @@ OS_Stat :: struct {
_reserve2: i64, // RESERVED
}
// NOTE(laleksic, 2021-01-21): Comment and rename these to match OS_Stat above
DARWIN_MAXPATHLEN :: 1024
Dirent :: struct {
ino: u64,
off: u64,
reclen: u16,
namlen: u16,
type: u8,
name: [256]byte,
name: [DARWIN_MAXPATHLEN]byte,
}
Dir :: distinct rawptr // DIR*
@@ -289,10 +290,10 @@ 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") _unix_fdopendir :: proc(fd: Handle) -> Dir ---
@(link_name="fdopendir$INODE64") _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="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="malloc") _unix_malloc :: proc(size: int) -> rawptr ---
@@ -450,7 +451,7 @@ _rewinddir :: proc(dirp: Dir) {
_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
+5 -5
View File
@@ -666,12 +666,12 @@ remove_all :: proc(s, key: string, allocator := context.allocator) -> (output: s
return remove(s, key, -1, allocator)
}
@(private) _ascii_space := [256]u8{'\t' = 1, '\n' = 1, '\v' = 1, '\f' = 1, '\r' = 1, ' ' = 1}
@(private) _ascii_space := [256]bool{'\t' = true, '\n' = true, '\v' = true, '\f' = true, '\r' = true, ' ' = true}
is_ascii_space :: proc(r: rune) -> bool {
if r < utf8.RUNE_SELF {
return _ascii_space[u8(r)] != 0
return _ascii_space[u8(r)]
}
return false
}
@@ -1237,19 +1237,19 @@ fields :: proc(s: string, allocator := context.allocator) -> []string #no_bounds
na := 0
field_start := 0
i := 0
for i < len(s) && _ascii_space[s[i]] != 0 {
for i < len(s) && _ascii_space[s[i]] {
i += 1
}
field_start = i
for i < len(s) {
if _ascii_space[s[i]] == 0 {
if !_ascii_space[s[i]] {
i += 1
continue
}
a[na] = s[field_start : i]
na += 1
i += 1
for i < len(s) && _ascii_space[s[i]] != 0 {
for i < len(s) && _ascii_space[s[i]] {
i += 1
}
field_start = i
+1
View File
@@ -1,3 +1,4 @@
//+build darwin
package unix
import "core:c"
+2 -1
View File
@@ -1,4 +1,5 @@
package unix;
//+build freebsd
package unix
import "core:c";
+1
View File
@@ -1,3 +1,4 @@
//+build linux
package unix
import "core:c"
+1
View File
@@ -1,3 +1,4 @@
//+build linux, darwin, freebsd
package unix
foreign import "system:pthread"
+104
View File
@@ -0,0 +1,104 @@
// +build windows
package sys_windows
foreign import "system:bthprops.lib"
HBLUETOOTH_DEVICE_FIND :: distinct HANDLE
HBLUETOOTH_RADIO_FIND :: distinct HANDLE
BLUETOOTH_FIND_RADIO_PARAMS :: struct {
dw_size: DWORD,
}
BLUETOOTH_RADIO_INFO :: struct {
dw_size: DWORD, // Size of this structure
address: BLUETOOTH_ADDRESS, // Address of radio
name: [BLUETOOTH_MAX_NAME_SIZE]u16, // Name of the radio
device_class: ULONG, // Bluetooth "Class of Device". See: https://btprodspecificationrefs.blob.core.windows.net/assigned-numbers/Assigned%20Number%20Types/Baseband.pdf
lmp_minor_version: USHORT, // This member contains data specific to individual Bluetooth device manufacturers.
manufacturer: USHORT, // Manufacturer of the Bluetooth radio, expressed as a BTH_MFG_Xxx value. See https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers/
}
BLUETOOTH_DEVICE_SEARCH_PARAMS :: struct {
dw_size: DWORD, // Size of this structure
return_authenticated: BOOL, // Return authenticated devices
return_remembered: BOOL, // Return remembered devices
return_unknown: BOOL, // Return unknown devices
return_connected: BOOL, // Return connected devices
issue_inquiry: BOOL, // Issue a new inquiry
timeout_multiplier: UCHAR, // Timeout for the inquiry, expressed in increments of 1.28 seconds
radio: HANDLE, // Handle to radio to enumerate - NULL == all radios will be searched
}
BLUETOOTH_ADDRESS :: struct #raw_union {
addr: u64,
val: [6]u8, // The first 3 bytes can be used to find the Manufacturer using http://standards-oui.ieee.org/oui/oui.txt
}
BLUETOOTH_MAX_NAME_SIZE :: 248
BLUETOOTH_DEVICE_INFO :: struct {
dw_size: DWORD, // Size in bytes of this structure - must be the size_of(BLUETOOTH_DEVICE_INFO)
address: BLUETOOTH_ADDRESS, // Bluetooth address
device_class: ULONG, // Bluetooth "Class of Device". See: https://btprodspecificationrefs.blob.core.windows.net/assigned-numbers/Assigned%20Number%20Types/Baseband.pdf
connected: BOOL, // Device connected/in use
remembered: BOOL, // Device remembered
authenticated: BOOL, // Device authenticated/paired/bonded
last_seen: SYSTEMTIME, // Last time the device was seen
last_used: SYSTEMTIME, // Last time the device was used for other than RNR, inquiry, or SDP
name: [BLUETOOTH_MAX_NAME_SIZE]u16, // Name of the device
}
@(default_calling_convention = "std")
foreign bthprops {
/*
Version
*/
@(link_name="BluetoothIsVersionAvailable") bluetooth_is_version_available :: proc(
major: u8, minor: u8,
) -> BOOL ---
/*
Radio enumeration
*/
@(link_name="BluetoothFindFirstRadio") bluetooth_find_first_radio :: proc(
find_radio_params: ^BLUETOOTH_FIND_RADIO_PARAMS, radio: ^HANDLE,
) -> HBLUETOOTH_RADIO_FIND ---
@(link_name="BluetoothFindNextRadio") bluetooth_find_next_radio :: proc(
handle: HBLUETOOTH_RADIO_FIND, radio: ^HANDLE,
) -> BOOL ---
@(link_name="BluetoothFindRadioClose") bluetooth_find_radio_close :: proc(
handle: HBLUETOOTH_RADIO_FIND,
) -> BOOL ---
@(link_name="BluetoothGetRadioInfo") bluetooth_get_radio_info :: proc(
radio: HANDLE, radio_info: ^BLUETOOTH_RADIO_INFO,
) -> DWORD ---
/*
Device enumeration
*/
@(link_name="BluetoothFindFirstDevice") bluetooth_find_first_device :: proc(
search_params: ^BLUETOOTH_DEVICE_SEARCH_PARAMS, device_info: ^BLUETOOTH_DEVICE_INFO,
) -> HBLUETOOTH_DEVICE_FIND ---
@(link_name="BluetoothFindNextDevice") bluetooth_find_next_device :: proc(
handle: HBLUETOOTH_DEVICE_FIND, device_info: ^BLUETOOTH_DEVICE_INFO,
) -> BOOL ---
@(link_name="BluetoothFindDeviceClose") bluetooth_find_device_close :: proc(
handle: HBLUETOOTH_DEVICE_FIND,
) -> BOOL ---
@(link_name="BluetoothGetDeviceInfo") bluetooth_get_device_info :: proc(
radio: HANDLE, device_info: ^BLUETOOTH_DEVICE_INFO,
) -> DWORD ---
@(link_name="BluetoothDisplayDeviceProperties") bluetooth_display_device_properties :: proc(
hwnd_parent: HWND, device_info: ^BLUETOOTH_DEVICE_INFO,
) -> BOOL ---
}
+12
View File
@@ -1238,3 +1238,15 @@ NET_API_STATUS :: enum DWORD {
PasswordNotComplexEnough = 2704,
PasswordFilterError = 2705,
}
SYSTEMTIME :: struct {
year: WORD,
month: WORD,
day_of_week: WORD,
day: WORD,
hour: WORD,
minute: WORD,
second: WORD,
milliseconds: WORD,
}
+13
View File
@@ -150,6 +150,19 @@ void slice_copy(Slice<T> *slice, Slice<T> const &data, isize offset, isize count
template <typename T>
gb_inline Slice<T> slice(Slice<T> const &array, isize lo, isize hi) {
GB_ASSERT(0 <= lo && lo <= hi && hi <= array.count);
Slice<T> out = {};
isize len = hi-lo;
if (len > 0) {
out.data = array.data+lo;
out.count = len;
}
return out;
}
template <typename T>
void slice_ordered_remove(Slice<T> *array, isize index) {
GB_ASSERT(0 <= index && index < array->count);
+23 -19
View File
@@ -64,13 +64,13 @@ void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name
Type *right_type = nullptr;
if (x->type->kind == Type_Tuple) {
auto const &vars = x->type->Tuple.variables;
auto lhs = array_slice(vars, 0, vars.count-1);
auto lhs = slice(vars, 0, vars.count-1);
auto rhs = vars[vars.count-1];
if (lhs.count == 1) {
left_type = lhs[0]->type;
} else if (lhs.count != 0) {
left_type = alloc_type_tuple();
left_type->Tuple.variables = array_make_from_ptr(lhs.data, lhs.count, lhs.count);
left_type->Tuple.variables = lhs;
}
right_type = rhs->type;
@@ -120,13 +120,13 @@ void check_or_return_split_types(CheckerContext *c, Operand *x, String const &na
Type *right_type = nullptr;
if (x->type->kind == Type_Tuple) {
auto const &vars = x->type->Tuple.variables;
auto lhs = array_slice(vars, 0, vars.count-1);
auto lhs = slice(vars, 0, vars.count-1);
auto rhs = vars[vars.count-1];
if (lhs.count == 1) {
left_type = lhs[0]->type;
} else if (lhs.count != 0) {
left_type = alloc_type_tuple();
left_type->Tuple.variables = array_make_from_ptr(lhs.data, lhs.count, lhs.count);
left_type->Tuple.variables = lhs;
}
right_type = rhs->type;
@@ -1156,12 +1156,12 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
if (is_type_struct(type)) {
isize variable_count = type->Struct.fields.count;
array_init(&tuple->Tuple.variables, a, variable_count);
slice_init(&tuple->Tuple.variables, a, variable_count);
// TODO(bill): Should I copy each of the entities or is this good enough?
gb_memmove_array(tuple->Tuple.variables.data, type->Struct.fields.data, variable_count);
} else if (is_type_array(type)) {
isize variable_count = cast(isize)type->Array.count;
array_init(&tuple->Tuple.variables, a, variable_count);
slice_init(&tuple->Tuple.variables, a, variable_count);
for (isize i = 0; i < variable_count; i++) {
tuple->Tuple.variables[i] = alloc_entity_array_elem(nullptr, blank_token, type->Array.elem, cast(i32)i);
}
@@ -1240,14 +1240,14 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
} else if (is_type_enum(type)) {
operand->mode = Addressing_Constant;
operand->type = original_type;
operand->value = type->Enum.min_value;
operand->value = *type->Enum.min_value;
return true;
} else if (is_type_enumerated_array(type)) {
Type *bt = base_type(type);
GB_ASSERT(bt->kind == Type_EnumeratedArray);
operand->mode = Addressing_Constant;
operand->type = bt->EnumeratedArray.index;
operand->value = bt->EnumeratedArray.min_value;
operand->value = *bt->EnumeratedArray.min_value;
return true;
}
gbString type_str = type_to_string(original_type);
@@ -1414,14 +1414,14 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
} else if (is_type_enum(type)) {
operand->mode = Addressing_Constant;
operand->type = original_type;
operand->value = type->Enum.max_value;
operand->value = *type->Enum.max_value;
return true;
} else if (is_type_enumerated_array(type)) {
Type *bt = base_type(type);
GB_ASSERT(bt->kind == Type_EnumeratedArray);
operand->mode = Addressing_Constant;
operand->type = bt->EnumeratedArray.index;
operand->value = bt->EnumeratedArray.max_value;
operand->value = *bt->EnumeratedArray.max_value;
return true;
}
gbString type_str = type_to_string(original_type);
@@ -1788,8 +1788,8 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
if (elem == nullptr) {
elem = alloc_type_struct();
elem->Struct.scope = s;
elem->Struct.fields = fields;
elem->Struct.tags = array_make<String>(permanent_allocator(), fields.count);
elem->Struct.fields = slice_from_array(fields);
elem->Struct.tags = gb_alloc_array(permanent_allocator(), String, fields.count);
elem->Struct.node = dummy_node_struct;
type_set_offsets(elem);
}
@@ -1938,12 +1938,12 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
if (is_type_array(elem)) {
Type *old_array = base_type(elem);
soa_struct = alloc_type_struct();
soa_struct->Struct.fields = array_make<Entity *>(heap_allocator(), cast(isize)old_array->Array.count);
soa_struct->Struct.tags = array_make<String>(heap_allocator(), cast(isize)old_array->Array.count);
soa_struct->Struct.fields = slice_make<Entity *>(heap_allocator(), cast(isize)old_array->Array.count);
soa_struct->Struct.tags = gb_alloc_array(permanent_allocator(), String, cast(isize)old_array->Array.count);
soa_struct->Struct.node = operand->expr;
soa_struct->Struct.soa_kind = StructSoa_Fixed;
soa_struct->Struct.soa_elem = elem;
soa_struct->Struct.soa_count = count;
soa_struct->Struct.soa_count = cast(i32)count;
scope = create_scope(c->info, c->scope);
soa_struct->Struct.scope = scope;
@@ -1971,12 +1971,16 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
Type *old_struct = base_type(elem);
soa_struct = alloc_type_struct();
soa_struct->Struct.fields = array_make<Entity *>(heap_allocator(), old_struct->Struct.fields.count);
soa_struct->Struct.tags = array_make<String>(heap_allocator(), old_struct->Struct.tags.count);
soa_struct->Struct.fields = slice_make<Entity *>(heap_allocator(), old_struct->Struct.fields.count);
soa_struct->Struct.tags = gb_alloc_array(permanent_allocator(), String, old_struct->Struct.fields.count);
soa_struct->Struct.node = operand->expr;
soa_struct->Struct.soa_kind = StructSoa_Fixed;
soa_struct->Struct.soa_elem = elem;
soa_struct->Struct.soa_count = count;
if (count > I32_MAX) {
count = I32_MAX;
error(call, "Array count too large for an #soa struct, got %lld", cast(long long)count);
}
soa_struct->Struct.soa_count = cast(i32)count;
scope = create_scope(c->info, old_struct->Struct.scope->parent);
soa_struct->Struct.scope = scope;
@@ -1985,7 +1989,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
Entity *old_field = old_struct->Struct.fields[i];
if (old_field->kind == Entity_Variable) {
Type *array_type = alloc_type_array(old_field->type, count);
Entity *new_field = alloc_entity_field(scope, old_field->token, array_type, false, old_field->Variable.field_src_index);
Entity *new_field = alloc_entity_field(scope, old_field->token, array_type, false, old_field->Variable.field_index);
soa_struct->Struct.fields[i] = new_field;
add_entity(c, scope, nullptr, new_field);
} else {
+25 -13
View File
@@ -1023,10 +1023,10 @@ bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, Type *source,
if (poly->EnumeratedArray.count != source->EnumeratedArray.count) {
return false;
}
if (compare_exact_values(Token_NotEq, poly->EnumeratedArray.min_value, source->EnumeratedArray.min_value)) {
if (compare_exact_values(Token_NotEq, *poly->EnumeratedArray.min_value, *source->EnumeratedArray.min_value)) {
return false;
}
if (compare_exact_values(Token_NotEq, poly->EnumeratedArray.max_value, source->EnumeratedArray.max_value)) {
if (compare_exact_values(Token_NotEq, *poly->EnumeratedArray.max_value, *source->EnumeratedArray.max_value)) {
return false;
}
return is_polymorphic_type_assignable(c, poly->EnumeratedArray.index, source->EnumeratedArray.index, true, modify_type);
@@ -3425,8 +3425,8 @@ bool check_index_value(CheckerContext *c, Type *main_type, bool open_range, Ast
if (is_type_enum(index_type)) {
Type *bt = base_type(index_type);
GB_ASSERT(bt->kind == Type_Enum);
ExactValue lo = bt->Enum.min_value;
ExactValue hi = bt->Enum.max_value;
ExactValue const &lo = *bt->Enum.min_value;
ExactValue const &hi = *bt->Enum.max_value;
String lo_str = {};
String hi_str = {};
if (bt->Enum.fields.count > 0) {
@@ -3556,7 +3556,7 @@ ExactValue get_constant_field_single(CheckerContext *c, ExactValue value, i32 in
if (is_type_enumerated_array(node->tav.type)) {
Type *bt = base_type(node->tav.type);
GB_ASSERT(bt->kind == Type_EnumeratedArray);
corrected_index = index + exact_value_to_i64(bt->EnumeratedArray.min_value);
corrected_index = index + exact_value_to_i64(*bt->EnumeratedArray.min_value);
}
if (op != Token_RangeHalf) {
if (lo <= corrected_index && corrected_index <= hi) {
@@ -3580,7 +3580,7 @@ ExactValue get_constant_field_single(CheckerContext *c, ExactValue value, i32 in
if (is_type_enumerated_array(node->tav.type)) {
Type *bt = base_type(node->tav.type);
GB_ASSERT(bt->kind == Type_EnumeratedArray);
index_value = exact_value_sub(index_value, bt->EnumeratedArray.min_value);
index_value = exact_value_sub(index_value, *bt->EnumeratedArray.min_value);
}
i64 field_index = exact_value_to_i64(index_value);
@@ -3738,6 +3738,18 @@ void check_did_you_mean_type(String const &name, Array<Entity *> const &fields)
check_did_you_mean_print(&d);
}
void check_did_you_mean_type(String const &name, Slice<Entity *> 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();
@@ -4942,7 +4954,7 @@ Entity **populate_proc_parameter_list(CheckerContext *c, Type *proc_type, isize
} else {
lhs_count = pt->params->Tuple.variables.count;
}
lhs = gb_alloc_array(heap_allocator(), Entity *, lhs_count);
lhs = gb_alloc_array(permanent_allocator(), Entity *, lhs_count);
for (isize i = 0; i < lhs_count; i++) {
Entity *e = pt->params->Tuple.variables[i];
if (!is_type_polymorphic(e->type)) {
@@ -7305,8 +7317,8 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
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);
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 = {};
@@ -7319,10 +7331,10 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
if (f->kind != Entity_Constant) {
continue;
}
if (total_lo_string.len == 0 && compare_exact_values(Token_CmpEq, f->Constant.value, t->EnumeratedArray.min_value)) {
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)) {
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) {
@@ -8472,13 +8484,13 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
Type *params = alloc_type_tuple();
Type *results = alloc_type_tuple();
if (param_types.count != 0) {
array_init(&params->Tuple.variables, heap_allocator(), param_types.count);
slice_init(&params->Tuple.variables, heap_allocator(), param_types.count);
for_array(i, param_types) {
params->Tuple.variables[i] = alloc_entity_param(scope, blank_token, param_types[i], false, true);
}
}
if (return_type != nullptr) {
array_init(&results->Tuple.variables, heap_allocator(), 1);
slice_init(&results->Tuple.variables, heap_allocator(), 1);
results->Tuple.variables[0] = alloc_entity_param(scope, blank_token, return_type, false, true);
}
+44 -49
View File
@@ -92,10 +92,10 @@ bool does_field_type_allow_using(Type *t) {
return false;
}
void check_struct_fields(CheckerContext *ctx, Ast *node, Array<Entity *> *fields, Array<String> *tags, Slice<Ast *> const &params,
void check_struct_fields(CheckerContext *ctx, Ast *node, Slice<Entity *> *fields, String **tags, Slice<Ast *> const &params,
isize init_field_capacity, Type *struct_type, String context) {
*fields = array_make<Entity *>(heap_allocator(), 0, init_field_capacity);
*tags = array_make<String>(heap_allocator(), 0, init_field_capacity);
auto fields_array = array_make<Entity *>(heap_allocator(), 0, init_field_capacity);
auto tags_array = array_make<String>(heap_allocator(), 0, init_field_capacity);
GB_ASSERT(node->kind == Ast_StructType);
GB_ASSERT(struct_type->kind == Type_Struct);
@@ -153,20 +153,20 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Array<Entity *> *fields
Entity *field = alloc_entity_field(ctx->scope, name_token, type, is_using, field_src_index);
add_entity(ctx, ctx->scope, name, field);
array_add(fields, field);
array_add(&fields_array, field);
String tag = p->tag.string;
if (tag.len != 0 && !unquote_string(permanent_allocator(), &tag, 0, tag.text[0] == '`')) {
error(p->tag, "Invalid string literal");
tag = {};
}
array_add(tags, tag);
array_add(&tags_array, tag);
field_src_index += 1;
}
if (is_using && p->names.count > 0) {
Type *first_type = (*fields)[fields->count-1]->type;
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) &&
@@ -182,16 +182,12 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Array<Entity *> *fields
populate_using_entity_scope(ctx, node, p, type);
}
}
*fields = slice_from_array(fields_array);
*tags = tags_array.data;
}
Entity *make_names_field_for_struct(CheckerContext *ctx, Scope *scope) {
Entity *e = alloc_entity_field(scope, make_token_ident(str_lit("names")), t_string_slice, false, 0);
e->flags |= EntityFlag_TypeField;
e->flags |= EntityFlag_Value;
return e;
}
bool check_custom_align(CheckerContext *ctx, Ast *node, i64 *align_) {
GB_ASSERT(align_ != nullptr);
Operand o = {};
@@ -219,13 +215,7 @@ bool check_custom_align(CheckerContext *ctx, Ast *node, i64 *align_) {
error(node, "#align must be a power of 2, got %lld", align);
return false;
}
// NOTE(bill): Success!!!
i64 custom_align = gb_clamp(align, 1, build_context.max_align);
if (custom_align < align) {
warning(node, "Custom alignment has been clamped to %lld from %lld", align, custom_align);
}
*align_ = custom_align;
*align_ = align;
return true;
}
}
@@ -498,7 +488,7 @@ Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_para
if (entities.count > 0) {
Type *tuple = alloc_type_tuple();
tuple->Tuple.variables = entities;
tuple->Tuple.variables = slice_from_array(entities);
polymorphic_params_type = tuple;
}
}
@@ -562,8 +552,7 @@ void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast *node, Array<
case_end;
}
}
struct_type->Struct.names = make_names_field_for_struct(ctx, ctx->scope);
scope_reserve(ctx->scope, min_field_count);
if (st->is_raw_union && min_field_count > 1) {
@@ -655,7 +644,7 @@ void check_union_type(CheckerContext *ctx, Type *union_type, Ast *node, Array<Op
}
}
union_type->Union.variants = variants;
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) {
@@ -815,9 +804,8 @@ void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *named_type, Ast
enum_type->Enum.fields = fields;
enum_type->Enum.names = make_names_field_for_struct(ctx, ctx->scope);
enum_type->Enum.min_value = min_value;
enum_type->Enum.max_value = max_value;
*enum_type->Enum.min_value = min_value;
*enum_type->Enum.max_value = max_value;
enum_type->Enum.min_value_index = min_value_index;
enum_type->Enum.max_value_index = max_value_index;
@@ -838,7 +826,7 @@ void check_bit_set_type(CheckerContext *c, Type *type, Type *named_type, Ast *no
GB_ASSERT(type->kind == Type_BitSet);
type->BitSet.node = node;
i64 const DEFAULT_BITS = cast(i64)(8*build_context.word_size);
/* i64 const DEFAULT_BITS = cast(i64)(8*build_context.word_size); */
i64 const MAX_BITS = 128;
Ast *base = unparen_expr(bs->elem);
@@ -1705,7 +1693,7 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
}
Type *tuple = alloc_type_tuple();
tuple->Tuple.variables = variables;
tuple->Tuple.variables = slice_from_array(variables);
if (success_) *success_ = success;
if (specialization_count_) *specialization_count_ = specialization_count;
@@ -1815,7 +1803,7 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) {
}
}
tuple->Tuple.variables = variables;
tuple->Tuple.variables = slice_from_array(variables);
return tuple;
}
@@ -2059,7 +2047,7 @@ i64 check_array_count(CheckerContext *ctx, Operand *o, Ast *e) {
Type *make_optional_ok_type(Type *value, bool typed) {
gbAllocator a = permanent_allocator();
Type *t = alloc_type_tuple();
array_init(&t->Tuple.variables, a, 2);
slice_init(&t->Tuple.variables, a, 2);
t->Tuple.variables[0] = alloc_entity_field(nullptr, blank_token, value, false, 0);
t->Tuple.variables[1] = alloc_entity_field(nullptr, blank_token, typed ? t_bool : t_untyped_bool, false, 1);
return t;
@@ -2083,11 +2071,11 @@ void init_map_entry_type(Type *type) {
*/
Scope *s = create_scope(nullptr, builtin_pkg->scope);
auto fields = array_make<Entity *>(permanent_allocator(), 0, 4);
array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("hash")), t_uintptr, false, cast(i32)fields.count, EntityState_Resolved));
array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("next")), t_int, false, cast(i32)fields.count, EntityState_Resolved));
array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("key")), type->Map.key, false, cast(i32)fields.count, EntityState_Resolved));
array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("value")), type->Map.value, false, cast(i32)fields.count, EntityState_Resolved));
auto fields = slice_make<Entity *>(permanent_allocator(), 4);
fields[0] = alloc_entity_field(s, make_token_ident(str_lit("hash")), t_uintptr, false, cast(i32)fields.count, EntityState_Resolved);
fields[1] = alloc_entity_field(s, make_token_ident(str_lit("next")), t_int, false, cast(i32)fields.count, EntityState_Resolved);
fields[2] = alloc_entity_field(s, make_token_ident(str_lit("key")), type->Map.key, false, cast(i32)fields.count, EntityState_Resolved);
fields[3] = alloc_entity_field(s, make_token_ident(str_lit("value")), type->Map.value, false, cast(i32)fields.count, EntityState_Resolved);
entry_type->Struct.fields = fields;
@@ -2120,9 +2108,9 @@ void init_map_internal_types(Type *type) {
Type *entries_type = alloc_type_dynamic_array(type->Map.entry_type);
auto fields = array_make<Entity *>(permanent_allocator(), 0, 2);
array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("hashes")), hashes_type, false, 0, EntityState_Resolved));
array_add(&fields, alloc_entity_field(s, make_token_ident(str_lit("entries")), entries_type, false, 1, EntityState_Resolved));
auto fields = slice_make<Entity *>(permanent_allocator(), 2);
fields[0] = alloc_entity_field(s, make_token_ident(str_lit("hashes")), hashes_type, false, 0, EntityState_Resolved);
fields[1] = alloc_entity_field(s, make_token_ident(str_lit("entries")), entries_type, false, 1, EntityState_Resolved);
generated_struct_type->Struct.fields = fields;
@@ -2239,8 +2227,8 @@ Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *el
field_count = 0;
soa_struct = alloc_type_struct();
soa_struct->Struct.fields = array_make<Entity *>(heap_allocator(), field_count+extra_field_count);
soa_struct->Struct.tags = array_make<String>(heap_allocator(), field_count+extra_field_count);
soa_struct->Struct.fields = slice_make<Entity *>(permanent_allocator(), field_count+extra_field_count);
soa_struct->Struct.tags = gb_alloc_array(permanent_allocator(), String, field_count+extra_field_count);
soa_struct->Struct.node = array_typ_expr;
soa_struct->Struct.soa_kind = soa_kind;
soa_struct->Struct.soa_elem = elem;
@@ -2254,12 +2242,16 @@ Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *el
field_count = cast(isize)old_array->Array.count;
soa_struct = alloc_type_struct();
soa_struct->Struct.fields = array_make<Entity *>(heap_allocator(), field_count+extra_field_count);
soa_struct->Struct.tags = array_make<String>(heap_allocator(), field_count+extra_field_count);
soa_struct->Struct.fields = slice_make<Entity *>(permanent_allocator(), field_count+extra_field_count);
soa_struct->Struct.tags = gb_alloc_array(permanent_allocator(), String, field_count+extra_field_count);
soa_struct->Struct.node = array_typ_expr;
soa_struct->Struct.soa_kind = soa_kind;
soa_struct->Struct.soa_elem = elem;
soa_struct->Struct.soa_count = count;
if (count > I32_MAX) {
count = I32_MAX;
error(array_typ_expr, "Array count too large for an #soa struct, got %lld", cast(long long)count);
}
soa_struct->Struct.soa_count = cast(i32)count;
scope = create_scope(ctx->info, ctx->scope, 8);
soa_struct->Struct.scope = scope;
@@ -2293,15 +2285,18 @@ Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *el
Type *old_struct = base_type(elem);
field_count = old_struct->Struct.fields.count;
GB_ASSERT(old_struct->Struct.tags.count == field_count);
soa_struct = alloc_type_struct();
soa_struct->Struct.fields = array_make<Entity *>(heap_allocator(), field_count+extra_field_count);
soa_struct->Struct.tags = array_make<String>(heap_allocator(), field_count+extra_field_count);
soa_struct->Struct.fields = slice_make<Entity *>(permanent_allocator(), field_count+extra_field_count);
soa_struct->Struct.tags = gb_alloc_array(permanent_allocator(), String, field_count+extra_field_count);
soa_struct->Struct.node = array_typ_expr;
soa_struct->Struct.soa_kind = soa_kind;
soa_struct->Struct.soa_elem = elem;
soa_struct->Struct.soa_count = count;
if (count > I32_MAX) {
count = I32_MAX;
error(array_typ_expr, "Array count too large for an #soa struct, got %lld", cast(long long)count);
}
soa_struct->Struct.soa_count = cast(i32)count;
scope = create_scope(ctx->info, old_struct->Struct.scope->parent);
soa_struct->Struct.scope = scope;
@@ -2316,7 +2311,7 @@ Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *el
} else {
field_type = alloc_type_pointer(old_field->type);
}
Entity *new_field = alloc_entity_field(scope, old_field->token, field_type, false, old_field->Variable.field_src_index);
Entity *new_field = alloc_entity_field(scope, old_field->token, field_type, false, old_field->Variable.field_index);
soa_struct->Struct.fields[i] = new_field;
add_entity(ctx, scope, nullptr, new_field);
add_entity_use(ctx, nullptr, new_field);
+22 -17
View File
@@ -4865,22 +4865,25 @@ 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:
attribute = "deferred_none";
break;
case DeferredProcedure_in:
attribute = "deferred_in";
break;
case DeferredProcedure_out:
attribute = "deferred_out";
break;
case DeferredProcedure_in_out:
attribute = "deferred_in_out";
break;
}
if (is_type_polymorphic(src->type) || is_type_polymorphic(dst->type)) {
switch (dst_kind) {
case DeferredProcedure_none:
error(src->token, "'deferred_none' cannot be used with a polymorphic procedure");
break;
case DeferredProcedure_in:
error(src->token, "'deferred_in' cannot be used with a polymorphic procedure");
break;
case DeferredProcedure_out:
error(src->token, "'deferred_out' cannot be used with a polymorphic procedure");
break;
case DeferredProcedure_in_out:
error(src->token, "'deferred_in_out' cannot be used with a polymorphic procedure");
break;
}
error(src->token, "'%s' cannot be used with a polymorphic procedure", attribute);
continue;
}
@@ -4974,17 +4977,19 @@ void check_deferred_procedures(Checker *c) {
GB_ASSERT(src_results->kind == Type_Tuple);
len += src_results->Tuple.variables.count;
}
array_init(&sv, heap_allocator(), 0, len);
slice_init(&sv, heap_allocator(), len);
isize offset = 0;
if (src_params != nullptr) {
for_array(i, src_params->Tuple.variables) {
array_add(&sv, src_params->Tuple.variables[i]);
sv[offset++] = src_params->Tuple.variables[i];
}
}
if (src_results != nullptr) {
for_array(i, src_results->Tuple.variables) {
array_add(&sv, src_results->Tuple.variables[i]);
sv[offset++] = src_results->Tuple.variables[i];
}
}
GB_ASSERT(offset == len);
if (are_types_identical(tsrc, dst_params)) {
+121
View File
@@ -850,6 +850,127 @@ ReadDirectoryError read_directory(String path, Array<FileInfo> *fi) {
struct MemoryMappedFile {
void *handle;
void *data;
i32 size;
};
enum MemoryMappedFileError {
MemoryMappedFile_None,
MemoryMappedFile_Empty,
MemoryMappedFile_FileTooLarge,
MemoryMappedFile_Invalid,
MemoryMappedFile_NotExists,
MemoryMappedFile_Permission,
MemoryMappedFile_COUNT,
};
MemoryMappedFileError memory_map_file_32(char const *fullpath, MemoryMappedFile *memory_mapped_file, bool copy_file_contents) {
MemoryMappedFileError err = MemoryMappedFile_None;
if (!copy_file_contents) {
#if defined(GB_SYSTEM_WINDOWS)
isize w_len = 0;
wchar_t *w_str = gb__alloc_utf8_to_ucs2(temporary_allocator(), fullpath, &w_len);
if (w_str == nullptr) {
return MemoryMappedFile_Invalid;
}
i64 file_size = 0;
LARGE_INTEGER li_file_size = {};
HANDLE handle = nullptr;
HANDLE file_mapping = nullptr;
void *file_data = nullptr;
handle = CreateFileW(w_str, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (handle == INVALID_HANDLE_VALUE) {
handle = nullptr;
goto window_handle_file_error;
}
li_file_size = {};
if (!GetFileSizeEx(handle, &li_file_size)) {
goto window_handle_file_error;
}
file_size = cast(i64)li_file_size.QuadPart;
if (file_size > I32_MAX) {
CloseHandle(handle);
return MemoryMappedFile_FileTooLarge;
}
if (file_size == 0) {
CloseHandle(handle);
err = MemoryMappedFile_Empty;
memory_mapped_file->handle = nullptr;
memory_mapped_file->data = nullptr;
memory_mapped_file->size = 0;
return err;
}
file_mapping = CreateFileMappingW(handle, nullptr, PAGE_READONLY, 0, 0, nullptr);
CloseHandle(handle);
file_data = MapViewOfFileEx(file_mapping, FILE_MAP_READ, 0, 0, 0/*file_size*/, nullptr/*base address*/);
memory_mapped_file->handle = cast(void *)file_mapping;
memory_mapped_file->data = file_data;
memory_mapped_file->size = cast(i32)file_size;
return err;
window_handle_file_error:;
{
DWORD handle_err = GetLastError();
CloseHandle(handle);
err = MemoryMappedFile_Invalid;
switch (handle_err) {
case ERROR_FILE_NOT_FOUND:
case ERROR_PATH_NOT_FOUND:
case ERROR_INVALID_DRIVE:
err = MemoryMappedFile_NotExists;
break;
case ERROR_ACCESS_DENIED:
case ERROR_INVALID_ACCESS:
err = MemoryMappedFile_Permission;
break;
}
return err;
}
#endif
}
gbFileContents fc = gb_file_read_contents(heap_allocator(), true, fullpath);
if (fc.size > I32_MAX) {
err = MemoryMappedFile_FileTooLarge;
gb_file_free_contents(&fc);
} else if (fc.data != nullptr) {
memory_mapped_file->handle = nullptr;
memory_mapped_file->data = fc.data;
memory_mapped_file->size = cast(i32)fc.size;
} else {
gbFile f = {};
gbFileError file_err = gb_file_open(&f, fullpath);
defer (gb_file_close(&f));
switch (file_err) {
case gbFileError_Invalid: err = MemoryMappedFile_Invalid; break;
case gbFileError_NotExists: err = MemoryMappedFile_NotExists; break;
case gbFileError_Permission: err = MemoryMappedFile_Permission; break;
}
if (err == MemoryMappedFile_None && gb_file_size(&f) == 0) {
err = MemoryMappedFile_Empty;
}
}
return err;
}
#define USE_DAMERAU_LEVENSHTEIN 1
isize levenstein_distance_case_insensitive(String const &a, String const &b) {
+9 -15
View File
@@ -50,17 +50,16 @@ void virtual_memory_init(void) {
struct MemoryBlock {
MemoryBlock *prev;
u8 * base;
isize size;
isize used;
MemoryBlock *prev;
};
struct Arena {
MemoryBlock *curr_block;
isize minimum_block_size;
bool use_local_mutex;
BlockingMutex local_mutex;
bool ignore_mutex;
};
enum { DEFAULT_MINIMUM_BLOCK_SIZE = 8ll*1024ll*1024ll };
@@ -72,10 +71,6 @@ void virtual_memory_dealloc(MemoryBlock *block);
void *arena_alloc(Arena *arena, isize min_size, isize alignment);
void arena_free_all(Arena *arena);
void arena_init_local_mutex(Arena *arena) {
mutex_init(&arena->local_mutex);
arena->use_local_mutex = true;
}
isize arena_align_forward_offset(Arena *arena, isize alignment) {
isize alignment_offset = 0;
@@ -91,11 +86,9 @@ void *arena_alloc(Arena *arena, isize min_size, isize alignment) {
GB_ASSERT(gb_is_power_of_two(alignment));
BlockingMutex *mutex = &global_memory_allocator_mutex;
if (arena->use_local_mutex) {
mutex = &arena->local_mutex;
if (!arena->ignore_mutex) {
mutex_lock(mutex);
}
mutex_lock(mutex);
isize size = 0;
if (arena->curr_block != nullptr) {
@@ -122,7 +115,9 @@ void *arena_alloc(Arena *arena, isize min_size, isize alignment) {
curr_block->used += size;
GB_ASSERT(curr_block->used <= curr_block->size);
mutex_unlock(mutex);
if (!arena->ignore_mutex) {
mutex_unlock(mutex);
}
// NOTE(bill): memory will be zeroed by default due to virtual memory
return ptr;
@@ -296,14 +291,13 @@ GB_ALLOCATOR_PROC(arena_allocator_proc) {
}
gb_global Arena permanent_arena = {};
gb_global gb_thread_local Arena permanent_arena = {nullptr, DEFAULT_MINIMUM_BLOCK_SIZE, true};
gbAllocator permanent_allocator() {
return arena_allocator(&permanent_arena);
}
gb_global Arena temporary_arena = {};
gbAllocator temporary_allocator() {
return arena_allocator(&temporary_arena);
return permanent_allocator();
}
+5 -8
View File
@@ -155,8 +155,7 @@ struct Entity {
} Constant;
struct {
Ast *init_expr; // only used for some variables within procedure bodies
i32 field_index;
i32 field_src_index;
i32 field_index;
ParameterValue param_value;
Ast * param_expr;
@@ -319,20 +318,18 @@ Entity *alloc_entity_const_param(Scope *scope, Token token, Type *type, ExactVal
}
Entity *alloc_entity_field(Scope *scope, Token token, Type *type, bool is_using, i32 field_src_index, EntityState state = EntityState_Unresolved) {
Entity *alloc_entity_field(Scope *scope, Token token, Type *type, bool is_using, i32 field_index, EntityState state = EntityState_Unresolved) {
Entity *entity = alloc_entity_variable(scope, token, type);
entity->Variable.field_src_index = field_src_index;
entity->Variable.field_index = field_src_index;
entity->Variable.field_index = field_index;
if (is_using) entity->flags |= EntityFlag_Using;
entity->flags |= EntityFlag_Field;
entity->state = state;
return entity;
}
Entity *alloc_entity_array_elem(Scope *scope, Token token, Type *type, i32 field_src_index) {
Entity *alloc_entity_array_elem(Scope *scope, Token token, Type *type, i32 field_index) {
Entity *entity = alloc_entity_variable(scope, token, type);
entity->Variable.field_src_index = field_src_index;
entity->Variable.field_index = field_src_index;
entity->Variable.field_index = field_index;
entity->flags |= EntityFlag_Field;
entity->flags |= EntityFlag_ArrayElem;
entity->state = EntityState_Resolved;
+1 -1
View File
@@ -832,7 +832,7 @@ ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, ExactValue y)
String sx = x.value_string;
String sy = y.value_string;
isize len = sx.len+sy.len;
u8 *data = gb_alloc_array(heap_allocator(), u8, len);
u8 *data = gb_alloc_array(permanent_allocator(), u8, len);
gb_memmove(data, sx.text, sx.len);
gb_memmove(data+sx.len, sy.text, sy.len);
return exact_value_string(make_string(data, len));
+6 -6
View File
@@ -82,7 +82,7 @@ LLVMTypeRef lb_function_type_to_llvm_ptr(lbFunctionType *ft, bool is_var_arg) {
GB_ASSERT_MSG(ret != nullptr, "%d", ft->ret.kind);
unsigned maximum_arg_count = offset+arg_count;
LLVMTypeRef *args = gb_alloc_array(heap_allocator(), LLVMTypeRef, maximum_arg_count);
LLVMTypeRef *args = gb_alloc_array(permanent_allocator(), LLVMTypeRef, maximum_arg_count);
if (offset == 1) {
GB_ASSERT(ft->ret.kind == lbArg_Indirect);
args[0] = LLVMPointerType(ft->ret.type, 0);
@@ -300,7 +300,7 @@ namespace lbAbi386 {
lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef return_type, bool return_is_defined);
LB_ABI_INFO(abi_info) {
lbFunctionType *ft = gb_alloc_item(heap_allocator(), lbFunctionType);
lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
ft->ctx = c;
ft->args = compute_arg_types(c, arg_types, arg_count);
ft->ret = compute_return_type(c, return_type, return_is_defined);
@@ -378,7 +378,7 @@ namespace lbAbiAmd64Win64 {
LB_ABI_INFO(abi_info) {
lbFunctionType *ft = gb_alloc_item(heap_allocator(), lbFunctionType);
lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
ft->ctx = c;
ft->args = compute_arg_types(c, arg_types, arg_count);
ft->ret = lbAbi386::compute_return_type(c, return_type, return_is_defined);
@@ -469,7 +469,7 @@ namespace lbAbiAmd64SysV {
LLVMTypeRef llreg(LLVMContextRef c, Array<RegClass> const &reg_classes);
LB_ABI_INFO(abi_info) {
lbFunctionType *ft = gb_alloc_item(heap_allocator(), lbFunctionType);
lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
ft->ctx = c;
ft->calling_convention = calling_convention;
@@ -849,7 +849,7 @@ namespace lbAbiArm64 {
bool is_homogenous_aggregate(LLVMContextRef c, LLVMTypeRef type, LLVMTypeRef *base_type_, unsigned *member_count_);
LB_ABI_INFO(abi_info) {
lbFunctionType *ft = gb_alloc_item(heap_allocator(), lbFunctionType);
lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
ft->ctx = c;
ft->ret = compute_return_type(c, return_type, return_is_defined);
ft -> args = compute_arg_types(c, arg_types, arg_count);
@@ -1034,7 +1034,7 @@ LB_ABI_INFO(lb_get_abi_info) {
case ProcCC_None:
case ProcCC_InlineAsm:
{
lbFunctionType *ft = gb_alloc_item(heap_allocator(), lbFunctionType);
lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
ft->ctx = c;
ft->args = array_make<lbArgType>(heap_allocator(), arg_count);
for (unsigned i = 0; i < arg_count; i++) {
+5 -7
View File
@@ -763,7 +763,7 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
if (build_context.metrics.os == TargetOs_windows && build_context.build_mode == BuildMode_DynamicLibrary) {
is_dll_main = true;
name = str_lit("DllMain");
array_init(&params->Tuple.variables, permanent_allocator(), 3);
slice_init(&params->Tuple.variables, permanent_allocator(), 3);
params->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("hinstDLL"), t_rawptr, false, true);
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);
@@ -771,12 +771,12 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
name = str_lit("mainCRTStartup");
} else {
has_args = true;
array_init(&params->Tuple.variables, permanent_allocator(), 2);
slice_init(&params->Tuple.variables, permanent_allocator(), 2);
params->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("argc"), t_i32, false, true);
params->Tuple.variables[1] = alloc_entity_param(nullptr, make_token_ident("argv"), t_ptr_cstring, false, true);
}
array_init(&results->Tuple.variables, permanent_allocator(), 1);
slice_init(&results->Tuple.variables, permanent_allocator(), 1);
results->Tuple.variables[0] = alloc_entity_param(nullptr, blank_token, t_i32, false, true);
Type *proc_type = alloc_type_proc(nullptr,
@@ -808,8 +808,6 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
lbAddr all_tests_array_addr = lb_add_global_generated(p->module, array_type, {});
lbValue all_tests_array = lb_addr_get_ptr(p, all_tests_array_addr);
LLVMTypeRef lbt_Internal_Test = lb_type(m, t_Internal_Test);
LLVMValueRef indices[2] = {};
indices[0] = LLVMConstInt(lb_type(m, t_i32), 0, false);
@@ -836,7 +834,7 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
GB_ASSERT(LLVMIsConstant(vals[2]));
LLVMValueRef dst = LLVMConstInBoundsGEP(all_tests_array.value, indices, gb_count_of(indices));
LLVMValueRef src = llvm_const_named_struct(lbt_Internal_Test, vals, gb_count_of(vals));
LLVMValueRef src = llvm_const_named_struct(m, t_Internal_Test, vals, gb_count_of(vals));
LLVMBuildStore(p->builder, src, dst);
}
@@ -1689,7 +1687,7 @@ void lb_generate_code(lbGenerator *gen) {
array_add(&gen->output_object_paths, filepath_obj);
array_add(&gen->output_temp_paths, filepath_ll);
auto *wd = gb_alloc_item(heap_allocator(), lbLLVMEmitWorker);
auto *wd = gb_alloc_item(permanent_allocator(), lbLLVMEmitWorker);
wd->target_machine = target_machines[j];
wd->code_gen_file_type = code_gen_file_type;
wd->filepath_obj = filepath_obj;
+3
View File
@@ -432,6 +432,7 @@ void lb_build_nested_proc(lbProcedure *p, AstProcLit *pd, Entity *e);
lbValue lb_emit_logical_binary_expr(lbProcedure *p, TokenKind op, Ast *left, Ast *right, Type *type);
lbValue lb_build_cond(lbProcedure *p, Ast *cond, lbBlock *true_block, lbBlock *false_block);
LLVMValueRef llvm_const_named_struct(lbModule *m, Type *t, LLVMValueRef *values, isize value_count_);
LLVMValueRef llvm_const_named_struct(LLVMTypeRef t, LLVMValueRef *values, isize value_count_);
void lb_set_entity_from_other_modules_linkage_correctly(lbModule *other_module, Entity *e, String const &name);
@@ -446,6 +447,8 @@ lbCopyElisionHint lb_set_copy_elision_hint(lbProcedure *p, lbAddr const &addr, A
void lb_reset_copy_elision_hint(lbProcedure *p, lbCopyElisionHint prev_hint);
lbValue lb_consume_copy_elision_hint(lbProcedure *p);
bool lb_struct_has_padding_prefix(Type *t);
#define LB_STARTUP_RUNTIME_PROC_NAME "__$startup_runtime"
#define LB_STARTUP_TYPE_INFO_PROC_NAME "__$startup_type_info"
#define LB_TYPE_INFO_DATA_NAME "__$type_info_data"
+62 -26
View File
@@ -99,7 +99,7 @@ LLVMValueRef llvm_const_cast(LLVMValueRef val, LLVMTypeRef dst) {
return LLVMConstNull(dst);
}
GB_ASSERT(LLVMSizeOf(dst) == LLVMSizeOf(src));
GB_ASSERT_MSG(LLVMSizeOf(dst) == LLVMSizeOf(src), "%s vs %s", LLVMPrintTypeToString(dst), LLVMPrintTypeToString(src));
LLVMTypeKind kind = LLVMGetTypeKind(dst);
switch (kind) {
case LLVMPointerTypeKind:
@@ -125,11 +125,43 @@ lbValue lb_const_ptr_cast(lbModule *m, lbValue value, Type *t) {
return res;
}
LLVMValueRef llvm_const_named_struct(lbModule *m, Type *t, LLVMValueRef *values, isize value_count_) {
LLVMTypeRef struct_type = lb_type(m, t);
GB_ASSERT(LLVMGetTypeKind(struct_type) == LLVMStructTypeKind);
unsigned value_count = cast(unsigned)value_count_;
unsigned elem_count = LLVMCountStructElementTypes(struct_type);
if (elem_count == value_count) {
return llvm_const_named_struct(struct_type, values, value_count_);
}
Type *bt = base_type(t);
GB_ASSERT(bt->kind == Type_Struct);
GB_ASSERT(value_count_ == bt->Struct.fields.count);
unsigned field_offset = 0;
if (lb_struct_has_padding_prefix(bt)) {
field_offset = 1;
}
unsigned values_with_padding_count = field_offset + cast(unsigned)(bt->Struct.fields.count*2 + 1);
LLVMValueRef *values_with_padding = gb_alloc_array(permanent_allocator(), LLVMValueRef, values_with_padding_count);
for (unsigned i = 0; i < value_count; i++) {
values_with_padding[field_offset + i*2 + 1] = values[i];
}
for (unsigned i = 0; i < values_with_padding_count; i++) {
if (values_with_padding[i] == nullptr) {
values_with_padding[i] = LLVMConstNull(LLVMStructGetTypeAtIndex(struct_type, i));
}
}
return llvm_const_named_struct(struct_type, values_with_padding, values_with_padding_count);
}
LLVMValueRef llvm_const_named_struct(LLVMTypeRef t, LLVMValueRef *values, isize value_count_) {
unsigned value_count = cast(unsigned)value_count_;
unsigned elem_count = LLVMCountStructElementTypes(t);
GB_ASSERT(value_count == elem_count);
GB_ASSERT_MSG(value_count == elem_count, "%s %u %u", LLVMPrintTypeToString(t), value_count, elem_count);
for (unsigned i = 0; i < elem_count; i++) {
LLVMTypeRef elem_type = LLVMStructGetTypeAtIndex(t, i);
values[i] = llvm_const_cast(values[i], elem_type);
@@ -235,7 +267,7 @@ lbValue lb_emit_source_code_location(lbProcedure *p, String const &procedure, To
fields[3]/*procedure*/ = lb_find_or_add_entity_string(p->module, procedure).value;
lbValue res = {};
res.value = llvm_const_named_struct(lb_type(m, t_source_code_location), fields, gb_count_of(fields));
res.value = llvm_const_named_struct(m, t_source_code_location, fields, gb_count_of(fields));
res.type = t_source_code_location;
return res;
}
@@ -422,7 +454,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), count, true);
LLVMValueRef values[2] = {ptr, len};
res.value = llvm_const_named_struct(lb_type(m, original_type), values, 2);
res.value = llvm_const_named_struct(m, original_type, values, 2);
return res;
}
}
@@ -512,7 +544,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
LLVMValueRef values[2] = {ptr, str_len};
GB_ASSERT(is_type_string(original_type));
res.value = llvm_const_named_struct(lb_type(m, original_type), values, 2);
res.value = llvm_const_named_struct(m, original_type, values, 2);
}
return res;
@@ -554,7 +586,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
break;
}
res.value = llvm_const_named_struct(lb_type(m, original_type), values, 2);
res.value = llvm_const_named_struct(m, original_type, values, 2);
return res;
}
break;
@@ -585,7 +617,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
break;
}
res.value = llvm_const_named_struct(lb_type(m, original_type), values, 4);
res.value = llvm_const_named_struct(m, original_type, values, 4);
return res;
}
break;
@@ -690,8 +722,8 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
isize value_index = 0;
i64 total_lo = exact_value_to_i64(type->EnumeratedArray.min_value);
i64 total_hi = exact_value_to_i64(type->EnumeratedArray.max_value);
i64 total_lo = exact_value_to_i64(*type->EnumeratedArray.min_value);
i64 total_hi = exact_value_to_i64(*type->EnumeratedArray.max_value);
for (i64 i = total_lo; i <= total_hi; i++) {
bool found = false;
@@ -802,11 +834,15 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
}
isize offset = 0;
if (type->Struct.custom_align > 0) {
if (lb_struct_has_padding_prefix(type)) {
offset = 1;
}
LLVMTypeRef struct_type = lb_type(m, original_type);
isize value_count = type->Struct.fields.count + offset;
unsigned value_count = cast(unsigned)(offset + type->Struct.fields.count*2 + 1);
GB_ASSERT(LLVMCountStructElementTypes(struct_type) == value_count);
LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, value_count);
bool *visited = gb_alloc_array(temporary_allocator(), bool, value_count);
@@ -822,9 +858,11 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
Selection sel = lookup_field(type, name, false);
Entity *f = type->Struct.fields[sel.index[0]];
isize index = offset + f->Variable.field_index*2 + 1;
if (elem_type_can_be_constant(f->type)) {
values[offset+f->Variable.field_index] = lb_const_value(m, f->type, tav.value, allow_local).value;
visited[offset+f->Variable.field_index] = true;
values[index] = lb_const_value(m, f->type, tav.value, allow_local).value;
visited[index] = true;
}
}
} else {
@@ -835,25 +873,24 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
if (tav.mode != Addressing_Invalid) {
val = tav.value;
}
isize index = offset + f->Variable.field_index*2 + 1;
if (elem_type_can_be_constant(f->type)) {
values[offset+f->Variable.field_index] = lb_const_value(m, f->type, val, allow_local).value;
visited[offset+f->Variable.field_index] = true;
values[index] = lb_const_value(m, f->type, val, allow_local).value;
visited[index] = true;
}
}
}
}
for (isize i = 0; i < type->Struct.fields.count; i++) {
if (!visited[offset+i]) {
GB_ASSERT(values[offset+i] == nullptr);
values[offset+i] = lb_const_nil(m, get_struct_field_type(type, i)).value;
for (isize i = 0; i < value_count; i++) {
if (!visited[i]) {
GB_ASSERT(values[i] == nullptr);
LLVMTypeRef type = LLVMStructGetTypeAtIndex(struct_type, cast(unsigned)i);
values[i] = LLVMConstNull(type);
}
}
if (type->Struct.custom_align > 0) {
values[0] = LLVMConstNull(lb_alignment_prefix_type_hack(m, type->Struct.custom_align));
}
bool is_constant = true;
for (isize i = 0; i < value_count; i++) {
@@ -866,7 +903,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
}
if (is_constant) {
res.value = llvm_const_named_struct(lb_type(m, original_type), values, cast(unsigned)value_count);
res.value = llvm_const_named_struct(struct_type, values, cast(unsigned)value_count);
return res;
} else {
// TODO(bill): THIS IS HACK BUT IT WORKS FOR WHAT I NEED
@@ -880,8 +917,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
new_values[i] = LLVMConstNull(LLVMTypeOf(old_value));
}
}
LLVMValueRef constant_value = llvm_const_named_struct(lb_type(m, original_type), new_values, cast(unsigned)value_count);
LLVMValueRef constant_value = llvm_const_named_struct(struct_type, new_values, cast(unsigned)value_count);
GB_ASSERT(is_local);
lbProcedure *p = m->curr_procedure;
+4 -4
View File
@@ -50,8 +50,8 @@ LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type) {
GB_ASSERT(type != t_invalid);
unsigned const word_size = cast(unsigned)build_context.word_size;
unsigned const word_bits = cast(unsigned)(8*build_context.word_size);
/* unsigned const word_size = cast(unsigned)build_context.word_size;
unsigned const word_bits = cast(unsigned)(8*build_context.word_size); */
GB_ASSERT(type->kind == Type_Proc);
unsigned parameter_count = 1;
@@ -129,7 +129,7 @@ LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
GB_ASSERT(type != t_invalid);
unsigned const word_size = cast(unsigned)build_context.word_size;
/* unsigned const word_size = cast(unsigned)build_context.word_size; */
unsigned const word_bits = cast(unsigned)(8*build_context.word_size);
switch (type->kind) {
@@ -564,7 +564,7 @@ LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) {
}
void lb_debug_complete_types(lbModule *m) {
unsigned const word_size = cast(unsigned)build_context.word_size;
/* unsigned const word_size = cast(unsigned)build_context.word_size; */
unsigned const word_bits = cast(unsigned)(8*build_context.word_size);
for_array(debug_incomplete_type_index, m->debug_incomplete_types) {
+9 -10
View File
@@ -1923,9 +1923,9 @@ lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x) {
lbValue map_ptr = lb_address_from_load_or_generate_local(p, x);
unsigned indices[2] = {0, 0};
LLVMValueRef hashes_data = LLVMBuildStructGEP(p->builder, map_ptr.value, 0, "");
LLVMValueRef hashes_data_ptr_ptr = LLVMBuildStructGEP(p->builder, hashes_data, 0, "");
LLVMValueRef hashes_data_ptr = LLVMBuildLoad(p->builder, hashes_data_ptr_ptr, "");
lbValue hashes_data = lb_emit_struct_ep(p, map_ptr, 0);
lbValue hashes_data_ptr_ptr = lb_emit_struct_ep(p, hashes_data, 0);
LLVMValueRef hashes_data_ptr = LLVMBuildLoad(p->builder, hashes_data_ptr_ptr.value, "");
if (op_kind == Token_CmpEq) {
res.value = LLVMBuildIsNull(p->builder, hashes_data_ptr, "");
@@ -2786,7 +2786,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
bool deref = is_type_pointer(t);
t = base_type(type_deref(t));
if (is_type_soa_struct(t)) {
if (is_type_soa_struct(t)) {
// SOA STRUCTURES!!!!
lbValue val = lb_build_addr_ptr(p, ie->expr);
if (deref) {
@@ -2821,7 +2821,6 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
// lbValue len = ir_soa_struct_len(p, base_struct);
// lb_emit_bounds_check(p, ast_token(ie->index), index, len);
}
lbValue val = lb_emit_ptr_offset(p, field, index);
return lb_addr(val);
}
@@ -2872,13 +2871,13 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
auto index_tv = type_and_value_of_expr(ie->index);
lbValue index = {};
if (compare_exact_values(Token_NotEq, t->EnumeratedArray.min_value, exact_value_i64(0))) {
if (compare_exact_values(Token_NotEq, *t->EnumeratedArray.min_value, exact_value_i64(0))) {
if (index_tv.mode == Addressing_Constant) {
ExactValue idx = exact_value_sub(index_tv.value, t->EnumeratedArray.min_value);
ExactValue idx = exact_value_sub(index_tv.value, *t->EnumeratedArray.min_value);
index = lb_const_value(p->module, index_type, idx);
} else {
index = lb_emit_conv(p, lb_build_expr(p, ie->index), t_int);
index = lb_emit_arith(p, Token_Sub, index, lb_const_value(p->module, index_type, t->EnumeratedArray.min_value), index_type);
index = lb_emit_arith(p, Token_Sub, index, lb_const_value(p->module, index_type, *t->EnumeratedArray.min_value), index_type);
}
} else {
index = lb_emit_conv(p, lb_build_expr(p, ie->index), t_int);
@@ -3259,7 +3258,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
TypeAndValue tav = type_and_value_of_expr(elem);
} else {
TypeAndValue tav = type_and_value_of_expr(elem);
Selection sel = lookup_field_from_index(bt, st->fields[field_index]->Variable.field_src_index);
Selection sel = lookup_field_from_index(bt, st->fields[field_index]->Variable.field_index);
index = sel.index[0];
}
@@ -3472,7 +3471,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
}
i32 index_offset = cast(i32)exact_value_to_i64(bt->EnumeratedArray.min_value);
i32 index_offset = cast(i32)exact_value_to_i64(*bt->EnumeratedArray.min_value);
for_array(i, temp_data) {
i32 index = temp_data[i].elem_index - index_offset;
+58 -18
View File
@@ -1109,7 +1109,7 @@ lbValue lb_emit_union_tag_ptr(lbProcedure *p, lbValue u) {
LLVMTypeRef uvt = LLVMGetElementType(LLVMTypeOf(u.value));
unsigned element_count = LLVMCountStructElementTypes(uvt);
GB_ASSERT_MSG(element_count == 3, "(%s) != (%s)", type_to_string(ut), LLVMPrintTypeToString(uvt));
GB_ASSERT_MSG(element_count == 3, "element_count=%u (%s) != (%s)", element_count, type_to_string(ut), LLVMPrintTypeToString(uvt));
lbValue tag_ptr = {};
tag_ptr.value = LLVMBuildStructGEP(p->builder, u.value, 2, "");
@@ -1160,13 +1160,9 @@ LLVMTypeRef lb_alignment_prefix_type_hack(lbModule *m, i64 alignment) {
return LLVMArrayType(lb_type(m, t_u32), 0);
case 8:
return LLVMArrayType(lb_type(m, t_u64), 0);
case 16:
default: case 16:
return LLVMArrayType(LLVMVectorType(lb_type(m, t_u32), 4), 0);
default:
GB_PANIC("Invalid alignment %d", cast(i32)alignment);
break;
}
return nullptr;
}
String lb_mangle_name(lbModule *m, Entity *e) {
@@ -1650,11 +1646,17 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
GB_ASSERT(field_count == 2);
LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count);
LLVMTypeRef entries_fields[4] = {
lb_type(m, t_rawptr),
LLVMTypeRef padding_type = LLVMArrayType(lb_type(m, t_uintptr), 0);
LLVMTypeRef entries_fields[] = {
padding_type,
lb_type(m, t_rawptr), // data
padding_type,
lb_type(m, t_int), // len
padding_type,
lb_type(m, t_int), // cap
padding_type,
lb_type(m, t_allocator), // allocator
padding_type,
};
fields[0] = lb_type(m, internal_type->Struct.fields[0]->type);
@@ -1670,31 +1672,69 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
LLVMTypeRef *fields = gb_alloc_array(permanent_allocator(), LLVMTypeRef, field_count);
i64 alignment = type_align_of(type);
unsigned size_of_union = cast(unsigned)type_size_of(type);
fields[0] = lb_alignment_prefix_type_hack(m, alignment);
fields[0] = lb_alignment_prefix_type_hack(m, gb_min(alignment, 16));
fields[1] = LLVMArrayType(lb_type(m, t_u8), size_of_union);
return LLVMStructTypeInContext(ctx, fields, field_count, false);
}
isize offset = 0;
if (type->Struct.custom_align > 0) {
if (lb_struct_has_padding_prefix(type)) {
offset = 1;
}
m->internal_type_level += 1;
defer (m->internal_type_level -= 1);
unsigned field_count = cast(unsigned)(type->Struct.fields.count + offset);
unsigned field_count = cast(unsigned)(offset + type->Struct.fields.count*2 + 1);
LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count);
LLVMTypeRef type_u8 = lb_type(m, t_u8);
LLVMTypeRef type_u16 = lb_type(m, t_u16);
LLVMTypeRef type_u32 = lb_type(m, t_u32);
LLVMTypeRef type_u64 = lb_type(m, t_u64);
i64 padding_offset = 0;
for_array(i, type->Struct.fields) {
Entity *field = type->Struct.fields[i];
fields[i+offset] = lb_type(m, field->type);
i64 padding = type->Struct.offsets[i]-padding_offset;
LLVMTypeRef padding_type = nullptr;
if (padding_offset == 0) {
padding_type = lb_alignment_prefix_type_hack(m, type_align_of(type));
} else {
i64 alignment = type_align_of(field->type);
// NOTE(bill): limit to `[N x u64]` to prevent ABI issues
alignment = gb_min(alignment, 8);
if (padding % alignment == 0) {
isize len = padding/alignment;
switch (alignment) {
case 1: padding_type = LLVMArrayType(type_u8, cast(unsigned)len); break;
case 2: padding_type = LLVMArrayType(type_u16, cast(unsigned)len); break;
case 4: padding_type = LLVMArrayType(type_u32, cast(unsigned)len); break;
case 8: padding_type = LLVMArrayType(type_u64, cast(unsigned)len); break;
}
} else {
padding_type = LLVMArrayType(type_u8, cast(unsigned)padding);
}
}
fields[offset + i*2 + 0] = padding_type;
fields[offset + i*2 + 1] = lb_type(m, field->type);
if (!type->Struct.is_packed) {
padding_offset = align_formula(padding_offset, type_align_of(field->type));
}
padding_offset += type_size_of(field->type);
}
i64 end_padding = type_size_of(type)-padding_offset;
fields[field_count-1] = LLVMArrayType(type_u8, cast(unsigned)end_padding);
if (type->Struct.custom_align > 0) {
if (offset != 0) {
GB_ASSERT(offset == 1);
fields[0] = lb_alignment_prefix_type_hack(m, type->Struct.custom_align);
}
for (unsigned i = 0; i < field_count; i++) {
GB_ASSERT(fields[i] != nullptr);
}
return LLVMStructTypeInContext(ctx, fields, field_count, type->Struct.is_packed);
}
@@ -1789,7 +1829,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
defer (m->internal_type_level -= 1);
LLVMTypeRef ret = nullptr;
LLVMTypeRef *params = gb_alloc_array(heap_allocator(), LLVMTypeRef, param_count);
LLVMTypeRef *params = gb_alloc_array(permanent_allocator(), LLVMTypeRef, param_count);
if (type->Proc.result_count != 0) {
Type *single_ret = reduce_tuple_to_single_type(type->Proc.results);
ret = lb_type(m, single_ret);
@@ -1883,7 +1923,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
LLVMTypeRef base_integer = lb_type_internal(m, type->RelativeSlice.base_integer);
unsigned field_count = 2;
LLVMTypeRef *fields = gb_alloc_array(heap_allocator(), LLVMTypeRef, field_count);
LLVMTypeRef *fields = gb_alloc_array(permanent_allocator(), LLVMTypeRef, field_count);
fields[0] = base_integer;
fields[1] = base_integer;
return LLVMStructTypeInContext(ctx, fields, field_count, false);
@@ -2230,7 +2270,7 @@ lbValue lb_find_or_add_entity_string(lbModule *m, String const &str) {
LLVMValueRef values[2] = {ptr, str_len};
lbValue res = {};
res.value = llvm_const_named_struct(lb_type(m, t_string), values, 2);
res.value = llvm_const_named_struct(m, t_string, values, 2);
res.type = t_string;
return res;
}
@@ -2265,7 +2305,7 @@ lbValue lb_find_or_add_entity_string_byte_slice(lbModule *m, String const &str)
LLVMValueRef values[2] = {ptr, len};
lbValue res = {};
res.value = llvm_const_named_struct(lb_type(m, t_u8_slice), values, 2);
res.value = llvm_const_named_struct(m, t_u8_slice, values, 2);
res.type = t_u8_slice;
return res;
}
+2 -2
View File
@@ -1393,7 +1393,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
Type *res_type = nullptr;
gbAllocator a = permanent_allocator();
res_type = alloc_type_tuple();
array_init(&res_type->Tuple.variables, a, 2);
slice_init(&res_type->Tuple.variables, a, 2);
res_type->Tuple.variables[0] = alloc_entity_field(nullptr, blank_token, type, false, 0);
res_type->Tuple.variables[1] = alloc_entity_field(nullptr, blank_token, t_llvm_bool, false, 1);
@@ -1738,7 +1738,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
if (tv.type->kind == Type_Tuple) {
Type *fix_typed = alloc_type_tuple();
array_init(&fix_typed->Tuple.variables, permanent_allocator(), 2);
slice_init(&fix_typed->Tuple.variables, permanent_allocator(), 2);
fix_typed->Tuple.variables[0] = tv.type->Tuple.variables[0];
fix_typed->Tuple.variables[1] = alloc_entity_field(nullptr, blank_token, t_llvm_bool, false, 1);
+4 -5
View File
@@ -332,8 +332,8 @@ void lb_build_range_indexed(lbProcedure *p, lbValue expr, Type *val_type, lbValu
val = lb_emit_load(p, lb_emit_array_ep(p, expr, idx));
// NOTE(bill): Override the idx value for the enumeration
Type *index_type = expr_type->EnumeratedArray.index;
if (compare_exact_values(Token_NotEq, expr_type->EnumeratedArray.min_value, exact_value_u64(0))) {
idx = lb_emit_arith(p, Token_Add, idx, lb_const_value(m, index_type, expr_type->EnumeratedArray.min_value), index_type);
if (compare_exact_values(Token_NotEq, *expr_type->EnumeratedArray.min_value, exact_value_u64(0))) {
idx = lb_emit_arith(p, Token_Add, idx, lb_const_value(m, index_type, *expr_type->EnumeratedArray.min_value), index_type);
}
}
break;
@@ -357,8 +357,7 @@ void lb_build_range_indexed(lbProcedure *p, lbValue expr, Type *val_type, lbValu
lbValue entries = lb_map_entries_ptr(p, expr);
lbValue elem = lb_emit_struct_ep(p, entries, 0);
elem = lb_emit_load(p, elem);
lbValue entry = lb_emit_ptr_offset(p, elem, idx);
lbValue entry = lb_emit_ptr_offset(p, elem, idx);
idx = lb_emit_load(p, lb_emit_struct_ep(p, entry, 2));
val = lb_emit_load(p, lb_emit_struct_ep(p, entry, 3));
@@ -984,7 +983,7 @@ void lb_build_unroll_range_stmt(lbProcedure *p, AstUnrollRangeStmt *rs, Scope *s
lb_addr_store(p, val0_addr, lb_emit_load(p, elem));
}
if (val1_type) {
ExactValue idx = exact_value_add(exact_value_i64(i), t->EnumeratedArray.min_value);
ExactValue idx = exact_value_add(exact_value_i64(i), *t->EnumeratedArray.min_value);
lb_addr_store(p, val1_addr, lb_const_value(m, val1_type, idx));
}
+65 -36
View File
@@ -157,12 +157,14 @@ 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
lbModule *m = p->module;
CheckerInfo *info = m->info;
i64 global_type_info_data_entity_count = 0;
{
// NOTE(bill): Set the type_table slice with the global backing array
lbValue global_type_table = lb_find_runtime_value(m, str_lit("type_table"));
Type *type = base_type(lb_global_type_info_data_entity->type);
GB_ASSERT(is_type_array(type));
global_type_info_data_entity_count = type->Array.count;
LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
LLVMValueRef values[2] = {
@@ -179,6 +181,11 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
Entity *type_info_flags_entity = find_core_entity(info->checker, str_lit("Type_Info_Flags"));
Type *t_type_info_flags = type_info_flags_entity->type;
auto entries_handled = slice_make<bool>(heap_allocator(), cast(isize)global_type_info_data_entity_count);
defer (gb_free(heap_allocator(), entries_handled.data));
entries_handled[0] = true;
for_array(type_info_type_index, info->type_info_types) {
Type *t = info->type_info_types[type_info_type_index];
if (t == nullptr || t == t_invalid) {
@@ -189,19 +196,36 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
if (entry_index <= 0) {
continue;
}
if (entries_handled[entry_index]) {
continue;
}
entries_handled[entry_index] = true;
lbValue global_data_ptr = lb_global_type_info_data_ptr(m);
lbValue tag = {};
lbValue ti_ptr = lb_emit_array_epi(p, lb_global_type_info_data_ptr(m), cast(i32)entry_index);
lbValue ti_ptr = lb_emit_array_epi(p, global_data_ptr, cast(i32)entry_index);
i64 size = type_size_of(t);
i64 align = type_align_of(t);
u32 flags = type_info_flags_of_type(t);
lbValue id = lb_typeid(m, t);
GB_ASSERT_MSG(align != 0, "%lld %s", align, type_to_string(t));
lbValue type_info_flags = lb_const_int(p->module, t_type_info_flags, flags);
lbValue size_ptr = lb_emit_struct_ep(p, ti_ptr, 0);
lbValue align_ptr = lb_emit_struct_ep(p, ti_ptr, 1);
lbValue flags_ptr = lb_emit_struct_ep(p, ti_ptr, 2);
lbValue id_ptr = lb_emit_struct_ep(p, ti_ptr, 3);
lb_emit_store(p, size_ptr, lb_const_int(m, t_int, size));
lb_emit_store(p, align_ptr, lb_const_int(m, t_int, align));
lb_emit_store(p, flags_ptr, type_info_flags);
lb_emit_store(p, id_ptr, id);
lbValue variant_ptr = lb_emit_struct_ep(p, ti_ptr, 4);
lbValue type_info_flags = lb_const_int(p->module, t_type_info_flags, type_info_flags_of_type(t));
lb_emit_store(p, lb_emit_struct_ep(p, ti_ptr, 0), lb_const_int(m, t_int, type_size_of(t)));
lb_emit_store(p, lb_emit_struct_ep(p, ti_ptr, 1), lb_const_int(m, t_int, type_align_of(t)));
lb_emit_store(p, lb_emit_struct_ep(p, ti_ptr, 2), type_info_flags);
lb_emit_store(p, lb_emit_struct_ep(p, ti_ptr, 3), lb_typeid(m, t));
switch (t->kind) {
case Type_Named: {
tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_named_ptr);
@@ -233,7 +257,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
lbValue res = {};
res.type = type_deref(tag.type);
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
lb_emit_store(p, tag, res);
break;
}
@@ -298,7 +322,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
lbValue res = {};
res.type = type_deref(tag.type);
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
lb_emit_store(p, tag, res);
break;
}
@@ -334,7 +358,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
lbValue res = {};
res.type = type_deref(tag.type);
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
lb_emit_store(p, tag, res);
}
break;
@@ -368,7 +392,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
lbValue res = {};
res.type = type_deref(tag.type);
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
lb_emit_store(p, tag, res);
}
break;
@@ -393,7 +417,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
lbValue res = {};
res.type = type_deref(tag.type);
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
lb_emit_store(p, tag, res);
break;
}
@@ -407,7 +431,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
lbValue res = {};
res.type = type_deref(tag.type);
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
lb_emit_store(p, tag, res);
break;
}
@@ -423,7 +447,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
lbValue res = {};
res.type = type_deref(tag.type);
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
lb_emit_store(p, tag, res);
break;
}
@@ -443,15 +467,15 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
lbValue res = {};
res.type = type_deref(tag.type);
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
lb_emit_store(p, tag, res);
// NOTE(bill): Union assignment
lbValue min_value = lb_emit_struct_ep(p, tag, 4);
lbValue max_value = lb_emit_struct_ep(p, tag, 5);
lbValue min_v = lb_const_value(m, t_i64, t->EnumeratedArray.min_value);
lbValue max_v = lb_const_value(m, t_i64, t->EnumeratedArray.max_value);
lbValue min_v = lb_const_value(m, t_i64, *t->EnumeratedArray.min_value);
lbValue max_v = lb_const_value(m, t_i64, *t->EnumeratedArray.max_value);
lb_emit_store(p, min_value, min_v);
lb_emit_store(p, max_value, max_v);
@@ -467,7 +491,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
lbValue res = {};
res.type = type_deref(tag.type);
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
lb_emit_store(p, tag, res);
break;
}
@@ -481,7 +505,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
lbValue res = {};
res.type = type_deref(tag.type);
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
lb_emit_store(p, tag, res);
break;
}
@@ -506,7 +530,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
lbValue res = {};
res.type = type_deref(tag.type);
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
lb_emit_store(p, tag, res);
break;
}
@@ -545,7 +569,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
lbValue res = {};
res.type = type_deref(tag.type);
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
lb_emit_store(p, tag, res);
break;
@@ -596,7 +620,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
lbValue res = {};
res.type = type_deref(tag.type);
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
lb_emit_store(p, tag, res);
}
break;
@@ -650,7 +674,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
lbValue res = {};
res.type = type_deref(tag.type);
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
lb_emit_store(p, tag, res);
}
@@ -688,7 +712,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
vals[11] = soa_len.value;
}
}
isize count = t->Struct.fields.count;
if (count > 0) {
lbValue memory_types = lb_type_info_member_types_offset (p, count);
@@ -721,7 +745,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
lb_emit_store(p, offset, lb_const_int(m, t_uintptr, foffset));
lb_emit_store(p, is_using, lb_const_bool(m, t_bool, (f->flags&EntityFlag_Using) != 0));
if (t->Struct.tags.count > 0) {
if (t->Struct.tags != nullptr) {
String tag_string = t->Struct.tags[source_index];
if (tag_string.len > 0) {
lbValue tag_ptr = lb_emit_ptr_offset(p, memory_tags, index);
@@ -743,11 +767,10 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
vals[i] = LLVMConstNull(lb_type(m, get_struct_field_type(tag.type, i)));
}
}
lbValue res = {};
res.type = type_deref(tag.type);
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
lb_emit_store(p, tag, res);
break;
@@ -767,7 +790,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
lbValue res = {};
res.type = type_deref(tag.type);
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
lb_emit_store(p, tag, res);
break;
}
@@ -791,7 +814,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
lbValue res = {};
res.type = type_deref(tag.type);
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
lb_emit_store(p, tag, res);
}
break;
@@ -808,7 +831,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
lbValue res = {};
res.type = type_deref(tag.type);
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
lb_emit_store(p, tag, res);
}
break;
@@ -823,7 +846,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
lbValue res = {};
res.type = type_deref(tag.type);
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
lb_emit_store(p, tag, res);
}
break;
@@ -837,7 +860,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
lbValue res = {};
res.type = type_deref(tag.type);
res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
lb_emit_store(p, tag, res);
}
break;
@@ -856,4 +879,10 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
}
}
}
for_array(i, entries_handled) {
if (!entries_handled[i]) {
GB_PANIC("UNHANDLED ENTRY %td (%td)", i, entries_handled.count);
}
}
}
+56 -9
View File
@@ -807,6 +807,47 @@ lbValue lb_address_from_load(lbProcedure *p, lbValue value) {
return {};
}
bool lb_struct_has_padding_prefix(Type *t) {
Type *bt = base_type(t);
GB_ASSERT(bt->kind == Type_Struct);
return bt->Struct.custom_align != 0 && bt->Struct.fields.count == 0;
}
i32 lb_convert_struct_index(lbModule *m, Type *t, i32 index) {
if (t->kind == Type_Struct) {
index = index*2 + 1;
if (lb_struct_has_padding_prefix(t)) {
index += 1;
}
unsigned count = LLVMCountStructElementTypes(lb_type(m, t));
GB_ASSERT(count >= cast(unsigned)index);
}
return index;
}
char const *llvm_type_kinds[] = {
"LLVMVoidTypeKind",
"LLVMHalfTypeKind",
"LLVMFloatTypeKind",
"LLVMDoubleTypeKind",
"LLVMX86_FP80TypeKind",
"LLVMFP128TypeKind",
"LLVMPPC_FP128TypeKind",
"LLVMLabelTypeKind",
"LLVMIntegerTypeKind",
"LLVMFunctionTypeKind",
"LLVMStructTypeKind",
"LLVMArrayTypeKind",
"LLVMPointerTypeKind",
"LLVMVectorTypeKind",
"LLVMMetadataTypeKind",
"LLVMX86_MMXTypeKind",
"LLVMTokenTypeKind",
"LLVMScalableVectorTypeKind",
"LLVMBFloatTypeKind",
};
lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
GB_ASSERT(is_type_pointer(s.type));
Type *t = base_type(type_deref(s.type));
@@ -871,6 +912,7 @@ lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
case 0: result_type = get_struct_field_type(gst, 0); break;
case 1: result_type = get_struct_field_type(gst, 1); break;
}
index = index*2 + 1;
} else if (is_type_array(t)) {
return lb_emit_array_epi(p, s, index);
} else if (is_type_relative_slice(t)) {
@@ -883,10 +925,9 @@ lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
}
GB_ASSERT_MSG(result_type != nullptr, "%s %d", type_to_string(t), index);
if (t->kind == Type_Struct && t->Struct.custom_align != 0) {
index += 1;
}
index = lb_convert_struct_index(p->module, t, index);
if (lb_is_const(s)) {
lbModule *m = p->module;
lbValue res = {};
@@ -896,6 +937,14 @@ lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
return res;
} else {
lbValue res = {};
LLVMTypeRef st = LLVMGetElementType(LLVMTypeOf(s.value));
// gb_printf_err("%s\n", type_to_string(s.type));
// gb_printf_err("%s\n", LLVMPrintTypeToString(LLVMTypeOf(s.value)));
// gb_printf_err("%d\n", index);
GB_ASSERT_MSG(LLVMGetTypeKind(st) == LLVMStructTypeKind, "%s", llvm_type_kinds[LLVMGetTypeKind(st)]);
unsigned count = LLVMCountStructElementTypes(st);
GB_ASSERT(count >= cast(unsigned)index);
res.value = LLVMBuildStructGEP(p->builder, s.value, cast(unsigned)index, "");
res.type = alloc_type_pointer(result_type);
return res;
@@ -1006,10 +1055,8 @@ lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index) {
}
GB_ASSERT_MSG(result_type != nullptr, "%s, %d", type_to_string(s.type), index);
if (t->kind == Type_Struct && t->Struct.custom_align != 0) {
index += 1;
}
index = lb_convert_struct_index(p->module, t, index);
lbValue res = {};
res.value = LLVMBuildExtractValue(p->builder, s.value, cast(unsigned)index, "");
@@ -1228,7 +1275,7 @@ lbValue lb_map_entries_ptr(lbProcedure *p, lbValue value) {
GB_ASSERT_MSG(t->kind == Type_Map, "%s", type_to_string(t));
init_map_internal_types(t);
i32 index = 1;
lbValue entries = lb_emit_struct_ep(p, value, index);
lbValue entries = lb_emit_struct_ep(p, value, index);
return entries;
}
-2
View File
@@ -2220,7 +2220,6 @@ int strip_semicolons(Parser *parser) {
int main(int arg_count, char const **arg_ptr) {
#define TIME_SECTION(str) do { debugf("[Section] %s\n", str); timings_start_section(&global_timings, str_lit(str)); } while (0)
if (arg_count < 2) {
usage(make_string_c(arg_ptr[0]));
return 1;
@@ -2490,7 +2489,6 @@ int main(int arg_count, char const **arg_ptr) {
}
remove_temp_files(gen);
arena_free_all(&temporary_arena);
if (run_output) {
#if defined(GB_SYSTEM_WINDOWS)
+6 -10
View File
@@ -1196,7 +1196,7 @@ CommentGroup *consume_comment_group(AstFile *f, isize n, isize *end_line_) {
CommentGroup *comments = nullptr;
if (list.count > 0) {
comments = gb_alloc_item(heap_allocator(), CommentGroup);
comments = gb_alloc_item(permanent_allocator(), CommentGroup);
comments->list = slice_from_array(list);
array_add(&f->comments, comments);
}
@@ -4645,7 +4645,8 @@ ParseFileError init_ast_file(AstFile *f, String fullpath, TokenPos *err_pos) {
zero_item(&f->tokenizer);
f->tokenizer.curr_file_id = f->id;
TokenizerInitError err = init_tokenizer_from_fullpath(&f->tokenizer, f->fullpath);
bool copy_file_contents = build_context.command_kind == Command_strip_semicolon;
TokenizerInitError err = init_tokenizer_from_fullpath(&f->tokenizer, f->fullpath, copy_file_contents);
if (err != TokenizerInit_None) {
switch (err) {
case TokenizerInit_Empty:
@@ -4710,9 +4711,6 @@ ParseFileError init_ast_file(AstFile *f, String fullpath, TokenPos *err_pos) {
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;
#if 0
arena_init_local_mutex(&f->arena);
#endif
array_init(&f->comments, heap_allocator(), 0, 0);
array_init(&f->imports, heap_allocator(), 0, 0);
@@ -4727,8 +4725,6 @@ void destroy_ast_file(AstFile *f) {
array_free(&f->tokens);
array_free(&f->comments);
array_free(&f->imports);
gb_free(heap_allocator(), f->tokenizer.fullpath.text);
destroy_tokenizer(&f->tokenizer);
}
bool init_parser(Parser *p) {
@@ -4795,7 +4791,7 @@ WORKER_TASK_PROC(parser_worker_proc) {
void parser_add_file_to_process(Parser *p, AstPackage *pkg, FileInfo fi, TokenPos pos) {
// TODO(bill): Use a better allocator
ImportedFile f = {pkg, fi, pos, p->file_to_process_count++};
auto wd = gb_alloc_item(heap_allocator(), ParserWorkerData);
auto wd = gb_alloc_item(permanent_allocator(), ParserWorkerData);
wd->parser = p;
wd->imported_file = f;
global_thread_pool_add_task(parser_worker_proc, wd);
@@ -4833,7 +4829,7 @@ WORKER_TASK_PROC(foreign_file_worker_proc) {
void parser_add_foreign_file_to_process(Parser *p, AstPackage *pkg, AstForeignFileKind kind, FileInfo fi, TokenPos pos) {
// TODO(bill): Use a better allocator
ImportedFile f = {pkg, fi, pos, p->file_to_process_count++};
auto wd = gb_alloc_item(heap_allocator(), ForeignFileWorkerData);
auto wd = gb_alloc_item(permanent_allocator(), ForeignFileWorkerData);
wd->parser = p;
wd->imported_file = f;
wd->foreign_kind = kind;
@@ -4854,7 +4850,7 @@ AstPackage *try_add_import_path(Parser *p, String const &path, String const &rel
string_set_add(&p->imported_files, path);
AstPackage *pkg = gb_alloc_item(heap_allocator(), AstPackage);
AstPackage *pkg = gb_alloc_item(permanent_allocator(), AstPackage);
pkg->kind = kind;
pkg->fullpath = path;
array_init(&pkg->files, heap_allocator());
+28 -38
View File
@@ -371,7 +371,7 @@ void begin_error_block(void) {
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(heap_allocator(), u8, n+1);
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};
@@ -404,7 +404,7 @@ ERROR_OUT_PROC(default_error_out_va) {
} else {
mutex_lock(&global_error_collector.error_out_mutex);
{
u8 *text = gb_alloc_array(heap_allocator(), u8, n+1);
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));
@@ -722,6 +722,8 @@ struct Tokenizer {
i32 error_count;
bool insert_semicolon;
MemoryMappedFile memory_mapped_file;
};
@@ -802,48 +804,36 @@ void init_tokenizer_with_data(Tokenizer *t, String const &fullpath, void *data,
}
}
TokenizerInitError init_tokenizer_from_fullpath(Tokenizer *t, String const &fullpath) {
TokenizerInitError err = TokenizerInit_None;
TokenizerInitError memory_mapped_file_error_map_to_tokenizer[MemoryMappedFile_COUNT] = {
TokenizerInit_None, /*MemoryMappedFile_None*/
TokenizerInit_Empty, /*MemoryMappedFile_Empty*/
TokenizerInit_FileTooLarge, /*MemoryMappedFile_FileTooLarge*/
TokenizerInit_Invalid, /*MemoryMappedFile_Invalid*/
TokenizerInit_NotExists, /*MemoryMappedFile_NotExists*/
TokenizerInit_Permission, /*MemoryMappedFile_Permission*/
};
char *c_str = alloc_cstring(temporary_allocator(), fullpath);
// TODO(bill): Memory map rather than copy contents
gbFileContents fc = gb_file_read_contents(heap_allocator(), true, c_str);
if (fc.size > I32_MAX) {
TokenizerInitError init_tokenizer_from_fullpath(Tokenizer *t, String const &fullpath, bool copy_file_contents) {
MemoryMappedFileError mmf_err = memory_map_file_32(
alloc_cstring(temporary_allocator(), fullpath),
&t->memory_mapped_file,
copy_file_contents
);
TokenizerInitError err = memory_mapped_file_error_map_to_tokenizer[mmf_err];
switch (mmf_err) {
case MemoryMappedFile_None:
init_tokenizer_with_data(t, fullpath, t->memory_mapped_file.data, cast(isize)t->memory_mapped_file.size);
break;
case MemoryMappedFile_FileTooLarge:
case MemoryMappedFile_Empty:
t->fullpath = fullpath;
t->line_count = 1;
err = TokenizerInit_FileTooLarge;
gb_file_free_contents(&fc);
} else if (fc.data != nullptr) {
init_tokenizer_with_data(t, fullpath, fc.data, fc.size);
} else {
t->fullpath = fullpath;
t->line_count = 1;
gbFile f = {};
gbFileError file_err = gb_file_open(&f, c_str);
defer (gb_file_close(&f));
switch (file_err) {
case gbFileError_Invalid: err = TokenizerInit_Invalid; break;
case gbFileError_NotExists: err = TokenizerInit_NotExists; break;
case gbFileError_Permission: err = TokenizerInit_Permission; break;
}
if (err == TokenizerInit_None && gb_file_size(&f) == 0) {
err = TokenizerInit_Empty;
}
}
break;
}
return err;
}
gb_inline void destroy_tokenizer(Tokenizer *t) {
if (t->start != nullptr) {
gb_free(heap_allocator(), t->start);
}
}
gb_inline i32 digit_value(Rune r) {
switch (r) {
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
+49 -76
View File
@@ -121,7 +121,7 @@ struct BasicType {
String name;
};
enum StructSoaKind {
enum StructSoaKind : u8 {
StructSoa_None = 0,
StructSoa_Fixed = 1,
StructSoa_Slice = 2,
@@ -129,44 +129,45 @@ enum StructSoaKind {
};
struct TypeStruct {
Array<Entity *> fields;
Array<String> tags;
Array<i64> offsets;
Slice<Entity *> fields;
String * tags; // count == fields.count
i64 * offsets; // count == fields.count
Ast * node;
Scope * scope;
Type * polymorphic_params; // Type_Tuple
Type * polymorphic_parent;
i64 custom_align;
Type * polymorphic_params; // Type_Tuple
Type * polymorphic_parent;
i64 custom_align;
Entity * names;
Type * soa_elem;
i32 soa_count;
StructSoaKind soa_kind;
Type * soa_elem;
i64 soa_count;
StructSoaKind soa_kind;
bool are_offsets_set;
bool are_offsets_being_processed;
bool is_packed;
bool is_raw_union;
bool is_polymorphic;
bool is_poly_specialized;
bool is_polymorphic;
bool are_offsets_set : 1;
bool are_offsets_being_processed : 1;
bool is_packed : 1;
bool is_raw_union : 1;
bool is_poly_specialized : 1;
};
struct TypeUnion {
Array<Type *> variants;
Slice<Type *> variants;
Ast * node;
Scope * scope;
i64 variant_block_size;
i64 custom_align;
i64 tag_size;
Type * polymorphic_params; // Type_Tuple
Type * polymorphic_parent;
bool no_nil;
bool maybe;
i16 tag_size;
bool is_polymorphic;
bool is_poly_specialized;
bool is_poly_specialized : 1;
bool no_nil : 1;
bool maybe : 1;
};
struct TypeProc {
@@ -216,8 +217,8 @@ struct TypeProc {
TYPE_KIND(EnumeratedArray, struct { \
Type *elem; \
Type *index; \
ExactValue min_value; \
ExactValue max_value; \
ExactValue *min_value; \
ExactValue *max_value; \
i64 count; \
TokenKind op; \
}) \
@@ -237,16 +238,15 @@ struct TypeProc {
Array<Entity *> fields; \
Ast *node; \
Scope * scope; \
Entity * names; \
Type * base_type; \
ExactValue min_value; \
ExactValue max_value; \
ExactValue *min_value; \
ExactValue *max_value; \
isize min_value_index; \
isize max_value_index; \
}) \
TYPE_KIND(Tuple, struct { \
Array<Entity *> variables; /* Entity_Variable */ \
Array<i64> offsets; \
Slice<Entity *> variables; /* Entity_Variable */ \
i64 * offsets; \
bool are_offsets_being_processed; \
bool are_offsets_set; \
bool is_packed; \
@@ -803,15 +803,17 @@ Type *alloc_type_array(Type *elem, i64 count, Type *generic_count = nullptr) {
return t;
}
Type *alloc_type_enumerated_array(Type *elem, Type *index, ExactValue min_value, ExactValue max_value, TokenKind op) {
Type *alloc_type_enumerated_array(Type *elem, Type *index, ExactValue const *min_value, ExactValue const *max_value, TokenKind op) {
Type *t = alloc_type(Type_EnumeratedArray);
t->EnumeratedArray.elem = elem;
t->EnumeratedArray.index = index;
t->EnumeratedArray.min_value = min_value;
t->EnumeratedArray.max_value = max_value;
t->EnumeratedArray.min_value = gb_alloc_item(permanent_allocator(), ExactValue);
t->EnumeratedArray.max_value = gb_alloc_item(permanent_allocator(), ExactValue);
gb_memmove(t->EnumeratedArray.min_value, min_value, gb_size_of(ExactValue));
gb_memmove(t->EnumeratedArray.max_value, max_value, gb_size_of(ExactValue));
t->EnumeratedArray.op = op;
t->EnumeratedArray.count = 1 + exact_value_to_i64(exact_value_sub(max_value, min_value));
t->EnumeratedArray.count = 1 + exact_value_to_i64(exact_value_sub(*max_value, *min_value));
return t;
}
@@ -841,6 +843,8 @@ Type *alloc_type_union() {
Type *alloc_type_enum() {
Type *t = alloc_type(Type_Enum);
t->Enum.min_value = gb_alloc_item(permanent_allocator(), ExactValue);
t->Enum.max_value = gb_alloc_item(permanent_allocator(), ExactValue);
return t;
}
@@ -2169,12 +2173,6 @@ bool are_types_identical(Type *x, Type *y) {
if (xf_is_using ^ yf_is_using) {
return false;
}
if (x->Struct.tags.count != y->Struct.tags.count) {
return false;
}
if (x->Struct.tags.count > 0 && x->Struct.tags[i] != y->Struct.tags[i]) {
return false;
}
}
return true;
}
@@ -2307,7 +2305,7 @@ i64 union_tag_size(Type *u) {
}
}
u->Union.tag_size = gb_min3(max_align, build_context.max_align, 8);
u->Union.tag_size = cast(i16)gb_min3(max_align, build_context.max_align, 8);
return u->Union.tag_size;
}
@@ -2434,7 +2432,7 @@ Selection lookup_field_from_index(Type *type, i64 index) {
for (isize i = 0; i < max_count; i++) {
Entity *f = type->Struct.fields[i];
if (f->kind == Entity_Variable) {
if (f->Variable.field_src_index == index) {
if (f->Variable.field_index == index) {
auto sel_array = array_make<i32>(a, 1);
sel_array[0] = cast(i32)i;
return make_selection(f, sel_array, false);
@@ -2474,24 +2472,6 @@ Selection lookup_field_with_selection(Type *type_, String field_name, bool is_ty
type = base_type(type);
if (is_type) {
switch (type->kind) {
case Type_Struct:
if (type->Struct.names != nullptr &&
field_name == "names") {
sel.entity = type->Struct.names;
return sel;
}
break;
case Type_Enum:
if (type->Enum.names != nullptr &&
field_name == "names") {
sel.entity = type->Enum.names;
return sel;
}
break;
}
if (is_type_enum(type)) {
// NOTE(bill): These may not have been added yet, so check in case
for_array(i, type->Enum.fields) {
@@ -2992,7 +2972,7 @@ i64 type_align_of_internal(Type *t, TypePath *path) {
return 1;
}
if (t->Union.custom_align > 0) {
return gb_clamp(t->Union.custom_align, 1, build_context.max_align);
return gb_max(t->Union.custom_align, 1);
}
i64 max = 1;
@@ -3013,7 +2993,7 @@ i64 type_align_of_internal(Type *t, TypePath *path) {
case Type_Struct: {
if (t->Struct.custom_align > 0) {
return gb_clamp(t->Struct.custom_align, 1, build_context.max_align);
return gb_max(t->Struct.custom_align, 1);
}
if (t->Struct.is_raw_union) {
i64 max = 1;
@@ -3080,9 +3060,9 @@ i64 type_align_of_internal(Type *t, TypePath *path) {
return gb_clamp(next_pow2(type_size_of_internal(t, path)), 1, build_context.word_size);
}
Array<i64> type_set_offsets_of(Array<Entity *> const &fields, bool is_packed, bool is_raw_union) {
i64 *type_set_offsets_of(Slice<Entity *> const &fields, bool is_packed, bool is_raw_union) {
gbAllocator a = permanent_allocator();
auto offsets = array_make<i64>(a, fields.count);
auto offsets = gb_alloc_array(a, i64, fields.count);
i64 curr_offset = 0;
if (is_raw_union) {
for_array(i, fields) {
@@ -3116,7 +3096,6 @@ bool type_set_offsets(Type *t) {
if (!t->Struct.are_offsets_set) {
t->Struct.are_offsets_being_processed = true;
t->Struct.offsets = type_set_offsets_of(t->Struct.fields, t->Struct.is_packed, t->Struct.is_raw_union);
GB_ASSERT(t->Struct.offsets.count == t->Struct.fields.count);
t->Struct.are_offsets_being_processed = false;
t->Struct.are_offsets_set = true;
return true;
@@ -3265,7 +3244,7 @@ i64 type_size_of_internal(Type *t, TypePath *path) {
i64 tag_size = union_tag_size(t);
size = align_formula(max, tag_size);
// NOTE(bill): Calculate the padding between the common fields and the tag
t->Union.tag_size = tag_size;
t->Union.tag_size = cast(i16)tag_size;
t->Union.variant_block_size = size - field_size;
size += tag_size;
@@ -3301,18 +3280,12 @@ i64 type_size_of_internal(Type *t, TypePath *path) {
if (path->failure) {
return FAILURE_SIZE;
}
if (t->Struct.are_offsets_being_processed && t->Struct.offsets.data == nullptr) {
if (t->Struct.are_offsets_being_processed && t->Struct.offsets == nullptr) {
type_path_print_illegal_cycle(path, path->path.count-1);
return FAILURE_SIZE;
}
if (t->Struct.are_offsets_set && t->Struct.offsets.count != t->Struct.fields.count) {
// TODO(bill, 2019-04-28): Determine exactly why the offsets length is different thatn the field length
// Are the the same at some point and then the struct length is increased?
// Why is this not handled by the type cycle checker?
t->Struct.are_offsets_set = false;
}
type_set_offsets(t);
GB_ASSERT_MSG(t->Struct.offsets.count == t->Struct.fields.count, "%s", type_to_string(t));
GB_ASSERT(t->Struct.fields.count == 0 || t->Struct.offsets != nullptr);
size = t->Struct.offsets[cast(isize)count-1] + type_size_of_internal(t->Struct.fields[cast(isize)count-1]->type, path);
return align_formula(size, align);
}
@@ -3463,7 +3436,7 @@ Type *reduce_tuple_to_single_type(Type *original_type) {
Type *alloc_type_struct_from_field_types(Type **field_types, isize field_count, bool is_packed) {
Type *t = alloc_type_struct();
t->Struct.fields = array_make<Entity *>(heap_allocator(), field_count);
t->Struct.fields = slice_make<Entity *>(heap_allocator(), field_count);
Scope *scope = nullptr;
for_array(i, t->Struct.fields) {
@@ -3483,7 +3456,7 @@ Type *alloc_type_tuple_from_field_types(Type **field_types, isize field_count, b
}
Type *t = alloc_type_tuple();
t->Tuple.variables = array_make<Entity *>(heap_allocator(), field_count);
t->Tuple.variables = slice_make<Entity *>(heap_allocator(), field_count);
Scope *scope = nullptr;
for_array(i, t->Tuple.variables) {
+193 -122
View File
@@ -9,177 +9,248 @@ TEST_count := 0
TEST_fail := 0
when ODIN_TEST {
expect :: testing.expect
log :: testing.log
expect :: testing.expect
log :: testing.log
} else {
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
fmt.printf("[%v] ", loc)
TEST_count += 1
if !condition {
TEST_fail += 1
fmt.println(" FAIL:", message)
return
}
fmt.println(" PASS")
}
log :: proc(t: ^testing.T, v: any, loc := #caller_location) {
fmt.printf("[%v] ", loc)
fmt.printf("log: %v\n", v)
}
expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) {
fmt.printf("[%v] ", loc)
TEST_count += 1
if !condition {
TEST_fail += 1
fmt.println(" FAIL:", message)
return
}
fmt.println(" PASS")
}
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_benchmark_runner(&t)
test_xxhash_vectors(&t)
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
t := testing.T{}
test_benchmark_runner(&t)
test_xxhash_vectors(&t)
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
}
/*
Benchmarks
Benchmarks
*/
setup_xxhash :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
assert(options != nil)
assert(options != nil)
options.input = make([]u8, options.bytes, allocator)
return nil if len(options.input) == options.bytes else .Allocation_Error
options.input = make([]u8, options.bytes, allocator)
return nil if len(options.input) == options.bytes else .Allocation_Error
}
teardown_xxhash :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
assert(options != nil)
assert(options != nil)
delete(options.input)
return nil
delete(options.input)
return nil
}
benchmark_xxh32 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
buf := options.input
buf := options.input
h: u32
for _ in 0..=options.rounds {
h = xxhash.XXH32(buf)
}
options.count = options.rounds
options.processed = options.rounds * options.bytes
options.hash = u128(h)
return nil
h: u32
for _ in 0..=options.rounds {
h = xxhash.XXH32(buf)
}
options.count = options.rounds
options.processed = options.rounds * options.bytes
options.hash = u128(h)
return nil
}
benchmark_xxh64 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
buf := options.input
buf := options.input
h: u64
for _ in 0..=options.rounds {
h = xxhash.XXH64(buf)
}
options.count = options.rounds
options.processed = options.rounds * options.bytes
options.hash = u128(h)
return nil
h: u64
for _ in 0..=options.rounds {
h = xxhash.XXH64(buf)
}
options.count = options.rounds
options.processed = options.rounds * options.bytes
options.hash = u128(h)
return nil
}
benchmark_xxh3_64 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
buf := options.input
h: u64
for _ in 0..=options.rounds {
h = xxhash.XXH3_64(buf)
}
options.count = options.rounds
options.processed = options.rounds * options.bytes
options.hash = u128(h)
return nil
}
benchmark_xxh3_128 :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) {
buf := options.input
buf := options.input
h: u128
for _ in 0..=options.rounds {
h = xxhash.XXH3_128bits(buf)
}
options.count = options.rounds
options.processed = options.rounds * options.bytes
options.hash = h
return nil
h: u128
for _ in 0..=options.rounds {
h = xxhash.XXH3_128(buf)
}
options.count = options.rounds
options.processed = options.rounds * options.bytes
options.hash = h
return nil
}
benchmark_print :: proc(name: string, options: ^time.Benchmark_Options) {
fmt.printf("\t[%v] %v rounds, %v bytes processed in %v ns\n\t\t%5.3f rounds/s, %5.3f MiB/s\n",
name,
options.rounds,
options.processed,
time.duration_nanoseconds(options.duration),
options.rounds_per_second,
options.megabytes_per_second,
)
fmt.printf("\t[%v] %v rounds, %v bytes processed in %v ns\n\t\t%5.3f rounds/s, %5.3f MiB/s\n",
name,
options.rounds,
options.processed,
time.duration_nanoseconds(options.duration),
options.rounds_per_second,
options.megabytes_per_second,
)
}
@test
test_benchmark_runner :: proc(t: ^testing.T) {
fmt.println("Starting benchmarks:")
fmt.println("Starting benchmarks:")
name := "XXH32 100 zero bytes"
options := &time.Benchmark_Options{
rounds = 1_000,
bytes = 100,
setup = setup_xxhash,
bench = benchmark_xxh32,
teardown = teardown_xxhash,
}
name := "XXH32 100 zero bytes"
options := &time.Benchmark_Options{
rounds = 1_000,
bytes = 100,
setup = setup_xxhash,
bench = benchmark_xxh32,
teardown = teardown_xxhash,
}
err := time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0x85f6413c, name)
benchmark_print(name, options)
err := time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0x85f6413c, name)
benchmark_print(name, options)
name = "XXH32 1 MiB zero bytes"
options.bytes = 1_048_576
err = time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0x9430f97f, name)
benchmark_print(name, options)
name = "XXH32 1 MiB zero bytes"
options.bytes = 1_048_576
err = time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0x9430f97f, name)
benchmark_print(name, options)
name = "XXH64 100 zero bytes"
options.bytes = 100
options.bench = benchmark_xxh64
err = time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0x17bb1103c92c502f, name)
benchmark_print(name, options)
name = "XXH64 100 zero bytes"
options.bytes = 100
options.bench = benchmark_xxh64
err = time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0x17bb1103c92c502f, name)
benchmark_print(name, options)
name = "XXH64 1 MiB zero bytes"
options.bytes = 1_048_576
err = time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0x87d2a1b6e1163ef1, name)
benchmark_print(name, options)
name = "XXH64 1 MiB zero bytes"
options.bytes = 1_048_576
err = time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0x87d2a1b6e1163ef1, name)
benchmark_print(name, options)
name = "XXH3_128 100 zero bytes"
options.bytes = 100
options.bench = benchmark_xxh3_128
err = time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0x6ba30a4e9dffe1ff801fedc74ccd608c, name)
benchmark_print(name, options)
name = "XXH3_64 100 zero bytes"
options.bytes = 100
options.bench = benchmark_xxh3_64
err = time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0x801fedc74ccd608c, name)
benchmark_print(name, options)
name = "XXH3_128 1 MiB zero bytes"
options.bytes = 1_048_576
err = time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0xb6ef17a3448492b6918780b90550bf34, name)
benchmark_print(name, options)
name = "XXH3_64 1 MiB zero bytes"
options.bytes = 1_048_576
err = time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0x918780b90550bf34, name)
benchmark_print(name, options)
name = "XXH3_128 100 zero bytes"
options.bytes = 100
options.bench = benchmark_xxh3_128
err = time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0x6ba30a4e9dffe1ff801fedc74ccd608c, name)
benchmark_print(name, options)
name = "XXH3_128 1 MiB zero bytes"
options.bytes = 1_048_576
err = time.benchmark(options, context.allocator)
expect(t, err == nil, name)
expect(t, options.hash == 0xb6ef17a3448492b6918780b90550bf34, name)
benchmark_print(name, options)
}
@test
test_xxhash_vectors :: proc(t: ^testing.T) {
fmt.println("Verifying against XXHASH_TEST_VECTOR_ZERO:")
fmt.println("Verifying against XXHASH_TEST_VECTOR_SEEDED:")
buf := make([]u8, 256)
defer delete(buf)
buf := make([]u8, 256)
defer delete(buf)
for v, i in XXHASH_TEST_VECTOR_ZERO[:] {
b := buf[:i]
for seed, table in XXHASH_TEST_VECTOR_SEEDED {
fmt.printf("\tSeed: %v\n", seed)
xxh32 := xxhash.XXH32(b)
xxh64 := xxhash.XXH64(b)
xxh3_128 := xxhash.XXH3_128bits(b)
for v, i in table {
b := buf[:i]
xxh32_error := fmt.tprintf("[ XXH32(%03d] Expected: %08x. Got: %08x.", i, v.xxh_32, xxh32)
xxh64_error := fmt.tprintf("[ XXH64(%03d] Expected: %16x. Got: %16x.", i, v.xxh_64, xxh64)
xxh3_128_error := fmt.tprintf("[XXH3_128(%03d] Expected: %32x. Got: %32x.", i, v.xxh3_128, xxh3_128)
xxh32 := xxhash.XXH32(b, u32(seed))
xxh64 := xxhash.XXH64(b, seed)
xxh3_64 := xxhash.XXH3_64(b, seed)
xxh3_128 := xxhash.XXH3_128(b, seed)
expect(t, xxh32 == v.xxh_32, xxh32_error)
expect(t, xxh64 == v.xxh_64, xxh64_error)
expect(t, xxh3_128 == v.xxh3_128, xxh3_128_error)
}
xxh32_error := fmt.tprintf("[ XXH32(%03d) ] Expected: %08x. Got: %08x.", i, v.xxh_32, xxh32)
xxh64_error := fmt.tprintf("[ XXH64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh_64, xxh64)
xxh3_64_error := fmt.tprintf("[XXH3_64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh3_64, xxh3_64)
xxh3_128_error := fmt.tprintf("[XXH3_128(%03d) ] Expected: %32x. Got: %32x.", i, v.xxh3_128, xxh3_128)
expect(t, xxh32 == v.xxh_32, xxh32_error)
expect(t, xxh64 == v.xxh_64, xxh64_error)
expect(t, xxh3_64 == v.xxh3_64, xxh3_64_error)
expect(t, xxh3_128 == v.xxh3_128, xxh3_128_error)
if len(b) > xxhash.XXH3_MIDSIZE_MAX {
fmt.printf("XXH3 - size: %v\n", len(b))
xxh3_state, _ := xxhash.XXH3_create_state()
xxhash.XXH3_64_reset_with_seed(xxh3_state, seed)
xxhash.XXH3_64_update(xxh3_state, b)
xxh3_64_streamed := xxhash.XXH3_64_digest(xxh3_state)
xxhash.XXH3_destroy_state(xxh3_state)
xxh3_64s_error := fmt.tprintf("[XXH3_64s(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh3_64, xxh3_64_streamed)
expect(t, xxh3_64_streamed == v.xxh3_64, xxh3_64s_error)
xxh3_state2, _ := xxhash.XXH3_create_state()
xxhash.XXH3_128_reset_with_seed(xxh3_state2, seed)
xxhash.XXH3_128_update(xxh3_state2, b)
xxh3_128_streamed := xxhash.XXH3_128_digest(xxh3_state2)
xxhash.XXH3_destroy_state(xxh3_state2)
xxh3_128s_error := fmt.tprintf("[XXH3_128s(%03d) ] Expected: %32x. Got: %32x.", i, v.xxh3_128, xxh3_128_streamed)
expect(t, xxh3_128_streamed == v.xxh3_128, xxh3_128s_error)
}
}
}
fmt.println("Verifying against XXHASH_TEST_VECTOR_SECRET:")
for secret, table in XXHASH_TEST_VECTOR_SECRET {
fmt.printf("\tSecret:\n\t\t\"%v\"\n", secret)
secret_bytes := transmute([]u8)secret
for v, i in table {
b := buf[:i]
xxh3_128 := xxhash.XXH3_128(b, secret_bytes)
xxh3_128_error := fmt.tprintf("[XXH3_128(%03d)] Expected: %32x. Got: %32x.", i, v.xxh3_128_secret, xxh3_128)
expect(t, xxh3_128 == v.xxh3_128_secret, xxh3_128_error)
}
}
}
File diff suppressed because it is too large Load Diff
+5 -1
View File
@@ -2,6 +2,7 @@
rem math/big tests
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 COMMON=-build-mode:shared -show-timings -no-bounds-check -define:MATH_BIG_EXE=false -vet -strict-style
@@ -9,5 +10,8 @@ echo ---
echo Running core:math/big tests
echo ---
%PATH_TO_ODIN% build . %COMMON% -o:speed -out:%OUT_NAME%
rem Fails
:%PATH_TO_ODIN% build . %COMMON% -o:speed -out:%OUT_NAME%
rem Passes
%PATH_TO_ODIN% build . %COMMON% -o:size -out:%OUT_NAME%
python3 test.py %TEST_ARGS%
+25 -52
View File
@@ -24,6 +24,12 @@ PyRes :: struct {
err: big.Error,
}
print_to_buffer :: proc(val: ^big.Int) -> cstring {
context = runtime.default_context()
r, _ := big.int_itoa_cstring(val, 16, context.allocator)
return r
}
@export test_initialize_constants :: proc "c" () -> (res: u64) {
context = runtime.default_context()
res = u64(big.initialize_constants())
@@ -34,7 +40,7 @@ PyRes :: struct {
@export test_error_string :: proc "c" (err: big.Error) -> (res: cstring) {
context = runtime.default_context()
es := big.Error_String
return strings.clone_to_cstring(es[err], context.temp_allocator)
return strings.clone_to_cstring(es[err], context.allocator)
}
@export test_add :: proc "c" (a, b: cstring) -> (res: PyRes) {
@@ -52,9 +58,8 @@ PyRes :: struct {
if err = #force_inline big.internal_add(sum, aa, bb); err != nil { return PyRes{res=":add:add(sum,a,b):", err=err} }
}
r: cstring
r, err = big.int_itoa_cstring(sum, 16, context.temp_allocator)
if err != nil { return PyRes{res=":add:itoa(sum):", err=err} }
r := print_to_buffer(sum)
return PyRes{res = r, err = nil}
}
@@ -73,8 +78,7 @@ PyRes :: struct {
if err = #force_inline big.internal_sub(sum, aa, bb); err != nil { return PyRes{res=":sub:sub(sum,a,b):", err=err} }
}
r: cstring
r, err = big.int_itoa_cstring(sum, 16, context.temp_allocator)
r := print_to_buffer(sum)
if err != nil { return PyRes{res=":sub:itoa(sum):", err=err} }
return PyRes{res = r, err = nil}
}
@@ -90,9 +94,7 @@ PyRes :: struct {
if err = big.atoi(bb, string(b), 16); err != nil { return PyRes{res=":mul:atoi(b):", err=err} }
if err = #force_inline big.internal_mul(product, aa, bb); err != nil { return PyRes{res=":mul:mul(product,a,b):", err=err} }
r: cstring
r, err = big.int_itoa_cstring(product, 16, context.temp_allocator)
if err != nil { return PyRes{res=":mul:itoa(product):", err=err} }
r := print_to_buffer(product)
return PyRes{res = r, err = nil}
}
@@ -106,9 +108,7 @@ PyRes :: struct {
if err = big.atoi(aa, string(a), 16); err != nil { return PyRes{res=":sqr:atoi(a):", err=err} }
if err = #force_inline big.internal_sqr(square, aa); err != nil { return PyRes{res=":sqr:sqr(square,a):", err=err} }
r: cstring
r, err = big.int_itoa_cstring(square, 16, context.temp_allocator)
if err != nil { return PyRes{res=":sqr:itoa(square):", err=err} }
r := print_to_buffer(square)
return PyRes{res = r, err = nil}
}
@@ -126,13 +126,10 @@ PyRes :: struct {
if err = big.atoi(bb, string(b), 16); err != nil { return PyRes{res=":div:atoi(b):", err=err} }
if err = #force_inline big.internal_div(quotient, aa, bb); err != nil { return PyRes{res=":div:div(quotient,a,b):", err=err} }
r: cstring
r, err = big.int_itoa_cstring(quotient, 16, context.temp_allocator)
if err != nil { return PyRes{res=":div:itoa(quotient):", err=err} }
r := print_to_buffer(quotient)
return PyRes{res = r, err = nil}
}
/*
res = log(a, base)
*/
@@ -153,9 +150,7 @@ PyRes :: struct {
aa.used = 2
big.clamp(aa)
r: cstring
r, err = big.int_itoa_cstring(aa, 16, context.temp_allocator)
if err != nil { return PyRes{res=":log:itoa(res):", err=err} }
r := print_to_buffer(aa)
return PyRes{res = r, err = nil}
}
@@ -172,9 +167,7 @@ PyRes :: struct {
if err = big.atoi(bb, string(base), 16); err != nil { return PyRes{res=":pow:atoi(base):", err=err} }
if err = #force_inline big.internal_pow(dest, bb, power); err != nil { return PyRes{res=":pow:pow(dest, base, power):", err=err} }
r: cstring
r, err = big.int_itoa_cstring(dest, 16, context.temp_allocator)
if err != nil { return PyRes{res=":log:itoa(res):", err=err} }
r := print_to_buffer(dest)
return PyRes{res = r, err = nil}
}
@@ -191,9 +184,7 @@ PyRes :: struct {
if err = big.atoi(src, string(source), 16); err != nil { return PyRes{res=":sqrt:atoi(src):", err=err} }
if err = #force_inline big.internal_sqrt(src, src); err != nil { return PyRes{res=":sqrt:sqrt(src):", err=err} }
r: cstring
r, err = big.int_itoa_cstring(src, 16, context.temp_allocator)
if err != nil { return PyRes{res=":log:itoa(res):", err=err} }
r := print_to_buffer(src)
return PyRes{res = r, err = nil}
}
@@ -210,9 +201,7 @@ PyRes :: struct {
if err = big.atoi(src, string(source), 16); err != nil { return PyRes{res=":root_n:atoi(src):", err=err} }
if err = #force_inline big.internal_root_n(src, src, power); err != nil { return PyRes{res=":root_n:root_n(src):", err=err} }
r: cstring
r, err = big.int_itoa_cstring(src, 16, context.temp_allocator)
if err != nil { return PyRes{res=":root_n:itoa(res):", err=err} }
r := print_to_buffer(src)
return PyRes{res = r, err = nil}
}
@@ -229,9 +218,7 @@ PyRes :: struct {
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} }
r: cstring
r, err = big.int_itoa_cstring(src, 16, context.temp_allocator)
if err != nil { return PyRes{res=":shr_digit:itoa(res):", err=err} }
r := print_to_buffer(src)
return PyRes{res = r, err = nil}
}
@@ -248,9 +235,7 @@ PyRes :: struct {
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} }
r: cstring
r, err = big.int_itoa_cstring(src, 16, context.temp_allocator)
if err != nil { return PyRes{res=":shl_digit:itoa(res):", err=err} }
r := print_to_buffer(src)
return PyRes{res = r, err = nil}
}
@@ -267,9 +252,7 @@ PyRes :: struct {
if err = big.atoi(src, string(source), 16); err != nil { return PyRes{res=":shr:atoi(src):", err=err} }
if err = #force_inline big.internal_shr(src, src, bits); err != nil { return PyRes{res=":shr:shr(src, bits):", err=err} }
r: cstring
r, err = big.int_itoa_cstring(src, 16, context.temp_allocator)
if err != nil { return PyRes{res=":shr:itoa(res):", err=err} }
r := print_to_buffer(src)
return PyRes{res = r, err = nil}
}
@@ -286,9 +269,7 @@ PyRes :: struct {
if err = big.atoi(src, string(source), 16); err != nil { return PyRes{res=":shr_signed:atoi(src):", err=err} }
if err = #force_inline big.internal_shr_signed(src, src, bits); err != nil { return PyRes{res=":shr_signed:shr_signed(src, bits):", err=err} }
r: cstring
r, err = big.int_itoa_cstring(src, 16, context.temp_allocator)
if err != nil { return PyRes{res=":shr_signed:itoa(res):", err=err} }
r := print_to_buffer(src)
return PyRes{res = r, err = nil}
}
@@ -305,9 +286,7 @@ PyRes :: struct {
if err = big.atoi(src, string(source), 16); err != nil { return PyRes{res=":shl:atoi(src):", err=err} }
if err = #force_inline big.internal_shl(src, src, bits); err != nil { return PyRes{res=":shl:shl(src, bits):", err=err} }
r: cstring
r, err = big.int_itoa_cstring(src, 16, context.temp_allocator)
if err != nil { return PyRes{res=":shl:itoa(res):", err=err} }
r := print_to_buffer(src)
return PyRes{res = r, err = nil}
}
@@ -323,9 +302,7 @@ PyRes :: struct {
if err = #force_inline big.internal_int_factorial(dest, n); err != nil { return PyRes{res=":factorial:factorial(n):", err=err} }
r: cstring
r, err = big.int_itoa_cstring(dest, 16, context.temp_allocator)
if err != nil { return PyRes{res=":factorial:itoa(res):", err=err} }
r := print_to_buffer(dest)
return PyRes{res = r, err = nil}
}
@@ -343,9 +320,7 @@ PyRes :: struct {
if err = big.atoi(bi, string(b), 16); err != nil { return PyRes{res=":gcd:atoi(b):", err=err} }
if err = #force_inline big.internal_int_gcd_lcm(dest, nil, ai, bi); err != nil { return PyRes{res=":gcd:gcd(a, b):", err=err} }
r: cstring
r, err = big.int_itoa_cstring(dest, 16, context.temp_allocator)
if err != nil { return PyRes{res=":gcd:itoa(res):", err=err} }
r := print_to_buffer(dest)
return PyRes{res = r, err = nil}
}
@@ -363,9 +338,7 @@ PyRes :: struct {
if err = big.atoi(bi, string(b), 16); err != nil { return PyRes{res=":lcm:atoi(b):", err=err} }
if err = #force_inline big.internal_int_gcd_lcm(nil, dest, ai, bi); err != nil { return PyRes{res=":lcm:lcm(a, b):", err=err} }
r: cstring
r, err = big.int_itoa_cstring(dest, 16, context.temp_allocator)
if err != nil { return PyRes{res=":lcm:itoa(res):", err=err} }
r := print_to_buffer(dest)
return PyRes{res = r, err = nil}
}
File diff suppressed because one or more lines are too long
+9 -9
View File
@@ -735,8 +735,8 @@ impl_GetSynciv: proc "c" (sync: sync_t, pname: u32, bufSiz
impl_GetInteger64i_v: proc "c" (target: u32, index: u32, data: ^i64)
impl_GetBufferParameteri64v: proc "c" (target: u32, pname: u32, params: [^]i64)
impl_FramebufferTexture: proc "c" (target: u32, attachment: u32, texture: u32, level: i32)
impl_TexImage2DMultisample: proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, fixedsamplelocations: u8)
impl_TexImage3DMultisample: proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, depth: i32, fixedsamplelocations: u8)
impl_TexImage2DMultisample: proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, fixedsamplelocations: b8)
impl_TexImage3DMultisample: proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, depth: i32, fixedsamplelocations: b8)
impl_GetMultisamplefv: proc "c" (pname: u32, index: u32, val: ^f32)
impl_SampleMaski: proc "c" (maskNumber: u32, mask: u32)
@@ -1186,7 +1186,7 @@ impl_DrawElementsInstancedBaseInstance: proc "c" (mode: u32, count: i3
impl_DrawElementsInstancedBaseVertexBaseInstance: proc "c" (mode: u32, count: i32, type: u32, indices: rawptr, instancecount: i32, basevertex: i32, baseinstance: u32)
impl_GetInternalformativ: proc "c" (target: u32, internalformat: u32, pname: u32, bufSize: i32, params: [^]i32)
impl_GetActiveAtomicCounterBufferiv: proc "c" (program: u32, bufferIndex: u32, pname: u32, params: [^]i32)
impl_BindImageTexture: proc "c" (unit: u32, texture: u32, level: i32, layered: u8, layer: i32, access: u32, format: u32)
impl_BindImageTexture: proc "c" (unit: u32, texture: u32, level: i32, layered: b8, layer: i32, access: u32, format: u32)
impl_MemoryBarrier: proc "c" (barriers: u32)
impl_TexStorage1D: proc "c" (target: u32, levels: i32, internalformat: u32, width: i32)
impl_TexStorage2D: proc "c" (target: u32, levels: i32, internalformat: u32, width: i32, height: i32)
@@ -1240,8 +1240,8 @@ impl_GetProgramResourceLocation: proc "c" (program: u32, programInterface:
impl_GetProgramResourceLocationIndex: proc "c" (program: u32, programInterface: u32, name: cstring) -> i32
impl_ShaderStorageBlockBinding: proc "c" (program: u32, storageBlockIndex: u32, storageBlockBinding: u32)
impl_TexBufferRange: proc "c" (target: u32, internalformat: u32, buffer: u32, offset: int, size: int)
impl_TexStorage2DMultisample: proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, fixedsamplelocations: u8)
impl_TexStorage3DMultisample: proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, depth: i32, fixedsamplelocations: u8)
impl_TexStorage2DMultisample: proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, fixedsamplelocations: b8)
impl_TexStorage3DMultisample: proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, depth: i32, fixedsamplelocations: b8)
impl_TextureView: proc "c" (texture: u32, target: u32, origtexture: u32, internalformat: u32, minlevel: u32, numlevels: u32, minlayer: u32, numlayers: u32)
impl_BindVertexBuffer: proc "c" (bindingindex: u32, buffer: u32, offset: int, stride: i32)
impl_VertexAttribFormat: proc "c" (attribindex: u32, size: i32, type: u32, normalized: bool, relativeoffset: u32)
@@ -1249,8 +1249,8 @@ impl_VertexAttribIFormat: proc "c" (attribindex: u32, size: i32, typ
impl_VertexAttribLFormat: proc "c" (attribindex: u32, size: i32, type: u32, relativeoffset: u32)
impl_VertexAttribBinding: proc "c" (attribindex: u32, bindingindex: u32)
impl_VertexBindingDivisor: proc "c" (bindingindex: u32, divisor: u32)
impl_DebugMessageControl: proc "c" (source: u32, type: u32, severity: u32, count: i32, ids: ^u32, enabled: u8)
impl_DebugMessageInsert: proc "c" (source: u32, type: u32, id: u32, severity: u32, length: i32, buf: ^u8)
impl_DebugMessageControl: proc "c" (source: u32, type: u32, severity: u32, count: i32, ids: [^]u32, enabled: b8)
impl_DebugMessageInsert: proc "c" (source: u32, type: u32, id: u32, severity: u32, length: i32, buf: [^]u8)
impl_DebugMessageCallback: proc "c" (callback: debug_proc_t, userParam: rawptr)
impl_GetDebugMessageLog: proc "c" (count: u32, bufSize: i32, sources: [^]u32, types: [^]u32, ids: [^]u32, severities: [^]u32, lengths: [^]i32, messageLog: [^]u8) -> u32
impl_PushDebugGroup: proc "c" (source: u32, id: u32, length: i32, message: cstring)
@@ -1380,8 +1380,8 @@ impl_TextureBufferRange: proc "c" (texture: u32, internalf
impl_TextureStorage1D: proc "c" (texture: u32, levels: i32, internalformat: u32, width: i32)
impl_TextureStorage2D: proc "c" (texture: u32, levels: i32, internalformat: u32, width: i32, height: i32)
impl_TextureStorage3D: proc "c" (texture: u32, levels: i32, internalformat: u32, width: i32, height: i32, depth: i32)
impl_TextureStorage2DMultisample: proc "c" (texture: u32, samples: i32, internalformat: u32, width: i32, height: i32, fixedsamplelocations: u8)
impl_TextureStorage3DMultisample: proc "c" (texture: u32, samples: i32, internalformat: u32, width: i32, height: i32, depth: i32, fixedsamplelocations: u8)
impl_TextureStorage2DMultisample: proc "c" (texture: u32, samples: i32, internalformat: u32, width: i32, height: i32, fixedsamplelocations: b8)
impl_TextureStorage3DMultisample: proc "c" (texture: u32, samples: i32, internalformat: u32, width: i32, height: i32, depth: i32, fixedsamplelocations: b8)
impl_TextureSubImage1D: proc "c" (texture: u32, level: i32, xoffset: i32, width: i32, format: u32, type: u32, pixels: rawptr)
impl_TextureSubImage2D: proc "c" (texture: u32, level: i32, xoffset: i32, yoffset: i32, width: i32, height: i32, format: u32, type: u32, pixels: rawptr)
impl_TextureSubImage3D: proc "c" (texture: u32, level: i32, xoffset: i32, yoffset: i32, zoffset: i32, width: i32, height: i32, depth: i32, format: u32, type: u32, pixels: rawptr)
+16 -16
View File
@@ -335,8 +335,8 @@ when !ODIN_DEBUG {
GetInteger64i_v :: #force_inline proc "c" (target: u32, index: u32, data: ^i64) { impl_GetInteger64i_v(target, index, data) }
GetBufferParameteri64v :: #force_inline proc "c" (target: u32, pname: u32, params: [^]i64) { impl_GetBufferParameteri64v(target, pname, params) }
FramebufferTexture :: #force_inline proc "c" (target: u32, attachment: u32, texture: u32, level: i32) { impl_FramebufferTexture(target, attachment, texture, level) }
TexImage2DMultisample :: #force_inline proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, fixedsamplelocations: u8) { impl_TexImage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations) }
TexImage3DMultisample :: #force_inline proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, depth: i32, fixedsamplelocations: u8) { impl_TexImage3DMultisample(target, samples, internalformat, width, height, depth, fixedsamplelocations) }
TexImage2DMultisample :: #force_inline proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, fixedsamplelocations: b8) { impl_TexImage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations) }
TexImage3DMultisample :: #force_inline proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, depth: i32, fixedsamplelocations: b8) { impl_TexImage3DMultisample(target, samples, internalformat, width, height, depth, fixedsamplelocations) }
GetMultisamplefv :: #force_inline proc "c" (pname: u32, index: u32, val: ^f32) { impl_GetMultisamplefv(pname, index, val) }
SampleMaski :: #force_inline proc "c" (maskNumber: u32, mask: u32) { impl_SampleMaski(maskNumber, mask) }
@@ -544,7 +544,7 @@ when !ODIN_DEBUG {
DrawElementsInstancedBaseVertexBaseInstance :: #force_inline proc "c" (mode: u32, count: i32, type: u32, indices: rawptr, instancecount: i32, basevertex: i32, baseinstance: u32) { impl_DrawElementsInstancedBaseVertexBaseInstance(mode, count, type, indices, instancecount, basevertex, baseinstance) }
GetInternalformativ :: #force_inline proc "c" (target: u32, internalformat: u32, pname: u32, bufSize: i32, params: [^]i32) { impl_GetInternalformativ(target, internalformat, pname, bufSize, params) }
GetActiveAtomicCounterBufferiv :: #force_inline proc "c" (program: u32, bufferIndex: u32, pname: u32, params: [^]i32) { impl_GetActiveAtomicCounterBufferiv(program, bufferIndex, pname, params) }
BindImageTexture :: #force_inline proc "c" (unit: u32, texture: u32, level: i32, layered: u8, layer: i32, access: u32, format: u32) { impl_BindImageTexture(unit, texture, level, layered, layer, access, format) }
BindImageTexture :: #force_inline proc "c" (unit: u32, texture: u32, level: i32, layered: b8, layer: i32, access: u32, format: u32) { impl_BindImageTexture(unit, texture, level, layered, layer, access, format) }
MemoryBarrier :: #force_inline proc "c" (barriers: u32) { impl_MemoryBarrier(barriers) }
TexStorage1D :: #force_inline proc "c" (target: u32, levels: i32, internalformat: u32, width: i32) { impl_TexStorage1D(target, levels, internalformat, width) }
TexStorage2D :: #force_inline proc "c" (target: u32, levels: i32, internalformat: u32, width: i32, height: i32) { impl_TexStorage2D(target, levels, internalformat, width, height) }
@@ -577,8 +577,8 @@ when !ODIN_DEBUG {
GetProgramResourceLocationIndex :: #force_inline proc "c" (program: u32, programInterface: u32, name: cstring) -> i32 { ret := impl_GetProgramResourceLocationIndex(program, programInterface, name); return ret }
ShaderStorageBlockBinding :: #force_inline proc "c" (program: u32, storageBlockIndex: u32, storageBlockBinding: u32) { impl_ShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding) }
TexBufferRange :: #force_inline proc "c" (target: u32, internalformat: u32, buffer: u32, offset: int, size: int) { impl_TexBufferRange(target, internalformat, buffer, offset, size) }
TexStorage2DMultisample :: #force_inline proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, fixedsamplelocations: u8) { impl_TexStorage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations) }
TexStorage3DMultisample :: #force_inline proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, depth: i32, fixedsamplelocations: u8) { impl_TexStorage3DMultisample(target, samples, internalformat, width, height, depth, fixedsamplelocations) }
TexStorage2DMultisample :: #force_inline proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, fixedsamplelocations: b8) { impl_TexStorage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations) }
TexStorage3DMultisample :: #force_inline proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, depth: i32, fixedsamplelocations: b8) { impl_TexStorage3DMultisample(target, samples, internalformat, width, height, depth, fixedsamplelocations) }
TextureView :: #force_inline proc "c" (texture: u32, target: u32, origtexture: u32, internalformat: u32, minlevel: u32, numlevels: u32, minlayer: u32, numlayers: u32) { impl_TextureView(texture, target, origtexture, internalformat, minlevel, numlevels, minlayer, numlayers) }
BindVertexBuffer :: #force_inline proc "c" (bindingindex: u32, buffer: u32, offset: int, stride: i32) { impl_BindVertexBuffer(bindingindex, buffer, offset, stride) }
VertexAttribFormat :: #force_inline proc "c" (attribindex: u32, size: i32, type: u32, normalized: bool, relativeoffset: u32) { impl_VertexAttribFormat(attribindex, size, type, normalized, relativeoffset) }
@@ -586,7 +586,7 @@ when !ODIN_DEBUG {
VertexAttribLFormat :: #force_inline proc "c" (attribindex: u32, size: i32, type: u32, relativeoffset: u32) { impl_VertexAttribLFormat(attribindex, size, type, relativeoffset) }
VertexAttribBinding :: #force_inline proc "c" (attribindex: u32, bindingindex: u32) { impl_VertexAttribBinding(attribindex, bindingindex) }
VertexBindingDivisor :: #force_inline proc "c" (bindingindex: u32, divisor: u32) { impl_VertexBindingDivisor(bindingindex, divisor) }
DebugMessageControl :: #force_inline proc "c" (source: u32, type: u32, severity: u32, count: i32, ids: [^]u32, enabled: u8) { impl_DebugMessageControl(source, type, severity, count, ids, enabled) }
DebugMessageControl :: #force_inline proc "c" (source: u32, type: u32, severity: u32, count: i32, ids: [^]u32, enabled: b8) { impl_DebugMessageControl(source, type, severity, count, ids, enabled) }
DebugMessageInsert :: #force_inline proc "c" (source: u32, type: u32, id: u32, severity: u32, length: i32, buf: ^u8) { impl_DebugMessageInsert(source, type, id, severity, length, buf) }
DebugMessageCallback :: #force_inline proc "c" (callback: debug_proc_t, userParam: rawptr) { impl_DebugMessageCallback(callback, userParam) }
GetDebugMessageLog :: #force_inline proc "c" (count: u32, bufSize: i32, sources: [^]u32, types: [^]u32, ids: [^]u32, severities: [^]u32, lengths: [^]i32, messageLog: [^]u8) -> u32 { ret := impl_GetDebugMessageLog(count, bufSize, sources, types, ids, severities, lengths, messageLog); return ret }
@@ -659,8 +659,8 @@ when !ODIN_DEBUG {
TextureStorage1D :: #force_inline proc "c" (texture: u32, levels: i32, internalformat: u32, width: i32) { impl_TextureStorage1D(texture, levels, internalformat, width) }
TextureStorage2D :: #force_inline proc "c" (texture: u32, levels: i32, internalformat: u32, width: i32, height: i32) { impl_TextureStorage2D(texture, levels, internalformat, width, height) }
TextureStorage3D :: #force_inline proc "c" (texture: u32, levels: i32, internalformat: u32, width: i32, height: i32, depth: i32) { impl_TextureStorage3D(texture, levels, internalformat, width, height, depth) }
TextureStorage2DMultisample :: #force_inline proc "c" (texture: u32, samples: i32, internalformat: u32, width: i32, height: i32, fixedsamplelocations: u8) { impl_TextureStorage2DMultisample(texture, samples, internalformat, width, height, fixedsamplelocations) }
TextureStorage3DMultisample :: #force_inline proc "c" (texture: u32, samples: i32, internalformat: u32, width: i32, height: i32, depth: i32, fixedsamplelocations: u8) { impl_TextureStorage3DMultisample(texture, samples, internalformat, width, height, depth, fixedsamplelocations) }
TextureStorage2DMultisample :: #force_inline proc "c" (texture: u32, samples: i32, internalformat: u32, width: i32, height: i32, fixedsamplelocations: b8) { impl_TextureStorage2DMultisample(texture, samples, internalformat, width, height, fixedsamplelocations) }
TextureStorage3DMultisample :: #force_inline proc "c" (texture: u32, samples: i32, internalformat: u32, width: i32, height: i32, depth: i32, fixedsamplelocations: b8) { impl_TextureStorage3DMultisample(texture, samples, internalformat, width, height, depth, fixedsamplelocations) }
TextureSubImage1D :: #force_inline proc "c" (texture: u32, level: i32, xoffset: i32, width: i32, format: u32, type: u32, pixels: rawptr) { impl_TextureSubImage1D(texture, level, xoffset, width, format, type, pixels) }
TextureSubImage2D :: #force_inline proc "c" (texture: u32, level: i32, xoffset: i32, yoffset: i32, width: i32, height: i32, format: u32, type: u32, pixels: rawptr) { impl_TextureSubImage2D(texture, level, xoffset, yoffset, width, height, format, type, pixels) }
TextureSubImage3D :: #force_inline proc "c" (texture: u32, level: i32, xoffset: i32, yoffset: i32, zoffset: i32, width: i32, height: i32, depth: i32, format: u32, type: u32, pixels: rawptr) { impl_TextureSubImage3D(texture, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels) }
@@ -1135,8 +1135,8 @@ when !ODIN_DEBUG {
GetInteger64i_v :: #force_inline proc "c" (target: u32, index: u32, data: ^i64, loc := #caller_location) { impl_GetInteger64i_v(target, index, data); debug_helper(loc, 0, target, index, data) }
GetBufferParameteri64v :: #force_inline proc "c" (target: u32, pname: u32, params: [^]i64, loc := #caller_location) { impl_GetBufferParameteri64v(target, pname, params); debug_helper(loc, 0, target, pname, params) }
FramebufferTexture :: #force_inline proc "c" (target: u32, attachment: u32, texture: u32, level: i32, loc := #caller_location) { impl_FramebufferTexture(target, attachment, texture, level); debug_helper(loc, 0, target, attachment, texture, level) }
TexImage2DMultisample :: #force_inline proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, fixedsamplelocations: u8, loc := #caller_location) { impl_TexImage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations); debug_helper(loc, 0, target, samples, internalformat, width, height, fixedsamplelocations) }
TexImage3DMultisample :: #force_inline proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, depth: i32, fixedsamplelocations: u8, loc := #caller_location) { impl_TexImage3DMultisample(target, samples, internalformat, width, height, depth, fixedsamplelocations); debug_helper(loc, 0, target, samples, internalformat, width, height, depth, fixedsamplelocations) }
TexImage2DMultisample :: #force_inline proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, fixedsamplelocations: b8, loc := #caller_location) { impl_TexImage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations); debug_helper(loc, 0, target, samples, internalformat, width, height, fixedsamplelocations) }
TexImage3DMultisample :: #force_inline proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, depth: i32, fixedsamplelocations: b8, loc := #caller_location) { impl_TexImage3DMultisample(target, samples, internalformat, width, height, depth, fixedsamplelocations); debug_helper(loc, 0, target, samples, internalformat, width, height, depth, fixedsamplelocations) }
GetMultisamplefv :: #force_inline proc "c" (pname: u32, index: u32, val: ^f32, loc := #caller_location) { impl_GetMultisamplefv(pname, index, val); debug_helper(loc, 0, pname, index, val) }
SampleMaski :: #force_inline proc "c" (maskNumber: u32, mask: u32, loc := #caller_location) { impl_SampleMaski(maskNumber, mask); debug_helper(loc, 0, maskNumber, mask) }
@@ -1344,7 +1344,7 @@ when !ODIN_DEBUG {
DrawElementsInstancedBaseVertexBaseInstance :: #force_inline proc "c" (mode: u32, count: i32, type: u32, indices: rawptr, instancecount: i32, basevertex: i32, baseinstance: u32, loc := #caller_location) { impl_DrawElementsInstancedBaseVertexBaseInstance(mode, count, type, indices, instancecount, basevertex, baseinstance); debug_helper(loc, 0, mode, count, type, indices, instancecount, basevertex, baseinstance) }
GetInternalformativ :: #force_inline proc "c" (target: u32, internalformat: u32, pname: u32, bufSize: i32, params: [^]i32, loc := #caller_location) { impl_GetInternalformativ(target, internalformat, pname, bufSize, params); debug_helper(loc, 0, target, internalformat, pname, bufSize, params) }
GetActiveAtomicCounterBufferiv :: #force_inline proc "c" (program: u32, bufferIndex: u32, pname: u32, params: [^]i32, loc := #caller_location) { impl_GetActiveAtomicCounterBufferiv(program, bufferIndex, pname, params); debug_helper(loc, 0, program, bufferIndex, pname, params) }
BindImageTexture :: #force_inline proc "c" (unit: u32, texture: u32, level: i32, layered: u8, layer: i32, access: u32, format: u32, loc := #caller_location) { impl_BindImageTexture(unit, texture, level, layered, layer, access, format); debug_helper(loc, 0, unit, texture, level, layered, layer, access, format) }
BindImageTexture :: #force_inline proc "c" (unit: u32, texture: u32, level: i32, layered: b8, layer: i32, access: u32, format: u32, loc := #caller_location) { impl_BindImageTexture(unit, texture, level, layered, layer, access, format); debug_helper(loc, 0, unit, texture, level, layered, layer, access, format) }
MemoryBarrier :: #force_inline proc "c" (barriers: u32, loc := #caller_location) { impl_MemoryBarrier(barriers); debug_helper(loc, 0, barriers) }
TexStorage1D :: #force_inline proc "c" (target: u32, levels: i32, internalformat: u32, width: i32, loc := #caller_location) { impl_TexStorage1D(target, levels, internalformat, width); debug_helper(loc, 0, target, levels, internalformat, width) }
TexStorage2D :: #force_inline proc "c" (target: u32, levels: i32, internalformat: u32, width: i32, height: i32, loc := #caller_location) { impl_TexStorage2D(target, levels, internalformat, width, height); debug_helper(loc, 0, target, levels, internalformat, width, height) }
@@ -1377,8 +1377,8 @@ when !ODIN_DEBUG {
GetProgramResourceLocationIndex :: #force_inline proc "c" (program: u32, programInterface: u32, name: cstring, loc := #caller_location) -> i32 { ret := impl_GetProgramResourceLocationIndex(program, programInterface, name); debug_helper(loc, 1, ret, program, programInterface, name); return ret }
ShaderStorageBlockBinding :: #force_inline proc "c" (program: u32, storageBlockIndex: u32, storageBlockBinding: u32, loc := #caller_location) { impl_ShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding); debug_helper(loc, 0, program, storageBlockIndex, storageBlockBinding) }
TexBufferRange :: #force_inline proc "c" (target: u32, internalformat: u32, buffer: u32, offset: int, size: int, loc := #caller_location) { impl_TexBufferRange(target, internalformat, buffer, offset, size); debug_helper(loc, 0, target, internalformat, buffer, offset, size) }
TexStorage2DMultisample :: #force_inline proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, fixedsamplelocations: u8, loc := #caller_location) { impl_TexStorage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations); debug_helper(loc, 0, target, samples, internalformat, width, height, fixedsamplelocations) }
TexStorage3DMultisample :: #force_inline proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, depth: i32, fixedsamplelocations: u8, loc := #caller_location) { impl_TexStorage3DMultisample(target, samples, internalformat, width, height, depth, fixedsamplelocations); debug_helper(loc, 0, target, samples, internalformat, width, height, depth, fixedsamplelocations) }
TexStorage2DMultisample :: #force_inline proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, fixedsamplelocations: b8, loc := #caller_location) { impl_TexStorage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations); debug_helper(loc, 0, target, samples, internalformat, width, height, fixedsamplelocations) }
TexStorage3DMultisample :: #force_inline proc "c" (target: u32, samples: i32, internalformat: u32, width: i32, height: i32, depth: i32, fixedsamplelocations: b8, loc := #caller_location) { impl_TexStorage3DMultisample(target, samples, internalformat, width, height, depth, fixedsamplelocations); debug_helper(loc, 0, target, samples, internalformat, width, height, depth, fixedsamplelocations) }
TextureView :: #force_inline proc "c" (texture: u32, target: u32, origtexture: u32, internalformat: u32, minlevel: u32, numlevels: u32, minlayer: u32, numlayers: u32, loc := #caller_location) { impl_TextureView(texture, target, origtexture, internalformat, minlevel, numlevels, minlayer, numlayers); debug_helper(loc, 0, texture, target, origtexture, internalformat, minlevel, numlevels, minlayer, numlayers) }
BindVertexBuffer :: #force_inline proc "c" (bindingindex: u32, buffer: u32, offset: int, stride: i32, loc := #caller_location) { impl_BindVertexBuffer(bindingindex, buffer, offset, stride); debug_helper(loc, 0, bindingindex, buffer, offset, stride) }
VertexAttribFormat :: #force_inline proc "c" (attribindex: u32, size: i32, type: u32, normalized: bool, relativeoffset: u32, loc := #caller_location) { impl_VertexAttribFormat(attribindex, size, type, normalized, relativeoffset); debug_helper(loc, 0, attribindex, size, type, normalized, relativeoffset) }
@@ -1386,7 +1386,7 @@ when !ODIN_DEBUG {
VertexAttribLFormat :: #force_inline proc "c" (attribindex: u32, size: i32, type: u32, relativeoffset: u32, loc := #caller_location) { impl_VertexAttribLFormat(attribindex, size, type, relativeoffset); debug_helper(loc, 0, attribindex, size, type, relativeoffset) }
VertexAttribBinding :: #force_inline proc "c" (attribindex: u32, bindingindex: u32, loc := #caller_location) { impl_VertexAttribBinding(attribindex, bindingindex); debug_helper(loc, 0, attribindex, bindingindex) }
VertexBindingDivisor :: #force_inline proc "c" (bindingindex: u32, divisor: u32, loc := #caller_location) { impl_VertexBindingDivisor(bindingindex, divisor); debug_helper(loc, 0, bindingindex, divisor) }
DebugMessageControl :: #force_inline proc "c" (source: u32, type: u32, severity: u32, count: i32, ids: [^]u32, enabled: u8, loc := #caller_location) { impl_DebugMessageControl(source, type, severity, count, ids, enabled); debug_helper(loc, 0, source, type, severity, count, ids, enabled) }
DebugMessageControl :: #force_inline proc "c" (source: u32, type: u32, severity: u32, count: i32, ids: [^]u32, enabled: b8, loc := #caller_location) { impl_DebugMessageControl(source, type, severity, count, ids, enabled); debug_helper(loc, 0, source, type, severity, count, ids, enabled) }
DebugMessageInsert :: #force_inline proc "c" (source: u32, type: u32, id: u32, severity: u32, length: i32, buf: ^u8, loc := #caller_location) { impl_DebugMessageInsert(source, type, id, severity, length, buf); debug_helper(loc, 0, source, type, id, severity, length, buf) }
DebugMessageCallback :: #force_inline proc "c" (callback: debug_proc_t, userParam: rawptr, loc := #caller_location) { impl_DebugMessageCallback(callback, userParam); debug_helper(loc, 0, callback, userParam) }
GetDebugMessageLog :: #force_inline proc "c" (count: u32, bufSize: i32, sources: [^]u32, types: [^]u32, ids: [^]u32, severities: [^]u32, lengths: [^]i32, messageLog: [^]u8, loc := #caller_location) -> u32 { ret := impl_GetDebugMessageLog(count, bufSize, sources, types, ids, severities, lengths, messageLog); debug_helper(loc, 1, ret, count, bufSize, sources, types, ids, severities, lengths, messageLog); return ret }
@@ -1459,8 +1459,8 @@ when !ODIN_DEBUG {
TextureStorage1D :: #force_inline proc "c" (texture: u32, levels: i32, internalformat: u32, width: i32, loc := #caller_location) { impl_TextureStorage1D(texture, levels, internalformat, width); debug_helper(loc, 0, texture, levels, internalformat, width) }
TextureStorage2D :: #force_inline proc "c" (texture: u32, levels: i32, internalformat: u32, width: i32, height: i32, loc := #caller_location) { impl_TextureStorage2D(texture, levels, internalformat, width, height); debug_helper(loc, 0, texture, levels, internalformat, width, height) }
TextureStorage3D :: #force_inline proc "c" (texture: u32, levels: i32, internalformat: u32, width: i32, height: i32, depth: i32, loc := #caller_location) { impl_TextureStorage3D(texture, levels, internalformat, width, height, depth); debug_helper(loc, 0, texture, levels, internalformat, width, height, depth) }
TextureStorage2DMultisample :: #force_inline proc "c" (texture: u32, samples: i32, internalformat: u32, width: i32, height: i32, fixedsamplelocations: u8, loc := #caller_location) { impl_TextureStorage2DMultisample(texture, samples, internalformat, width, height, fixedsamplelocations); debug_helper(loc, 0, texture, samples, internalformat, width, height, fixedsamplelocations) }
TextureStorage3DMultisample :: #force_inline proc "c" (texture: u32, samples: i32, internalformat: u32, width: i32, height: i32, depth: i32, fixedsamplelocations: u8, loc := #caller_location) { impl_TextureStorage3DMultisample(texture, samples, internalformat, width, height, depth, fixedsamplelocations); debug_helper(loc, 0, texture, samples, internalformat, width, height, depth, fixedsamplelocations) }
TextureStorage2DMultisample :: #force_inline proc "c" (texture: u32, samples: i32, internalformat: u32, width: i32, height: i32, fixedsamplelocations: b8, loc := #caller_location) { impl_TextureStorage2DMultisample(texture, samples, internalformat, width, height, fixedsamplelocations); debug_helper(loc, 0, texture, samples, internalformat, width, height, fixedsamplelocations) }
TextureStorage3DMultisample :: #force_inline proc "c" (texture: u32, samples: i32, internalformat: u32, width: i32, height: i32, depth: i32, fixedsamplelocations: b8, loc := #caller_location) { impl_TextureStorage3DMultisample(texture, samples, internalformat, width, height, depth, fixedsamplelocations); debug_helper(loc, 0, texture, samples, internalformat, width, height, depth, fixedsamplelocations) }
TextureSubImage1D :: #force_inline proc "c" (texture: u32, level: i32, xoffset: i32, width: i32, format: u32, type: u32, pixels: rawptr, loc := #caller_location) { impl_TextureSubImage1D(texture, level, xoffset, width, format, type, pixels); debug_helper(loc, 0, texture, level, xoffset, width, format, type, pixels) }
TextureSubImage2D :: #force_inline proc "c" (texture: u32, level: i32, xoffset: i32, yoffset: i32, width: i32, height: i32, format: u32, type: u32, pixels: rawptr, loc := #caller_location) { impl_TextureSubImage2D(texture, level, xoffset, yoffset, width, height, format, type, pixels); debug_helper(loc, 0, texture, level, xoffset, yoffset, width, height, format, type, pixels) }
TextureSubImage3D :: #force_inline proc "c" (texture: u32, level: i32, xoffset: i32, yoffset: i32, zoffset: i32, width: i32, height: i32, depth: i32, format: u32, type: u32, pixels: rawptr, loc := #caller_location) { impl_TextureSubImage3D(texture, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); debug_helper(loc, 0, texture, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels) }
+36
View File
@@ -18,6 +18,42 @@ Bindings for the raylib, a simple and easy-to-use library to enjoy videogames pr
This package is available under the Zlib license. See `LICENSE` for more details.
## STB
Bindings/ports for many of the [STB libraries](https://github.com/nothings/stb), single-file public domain (or MIT licensed) libraries for C/C++.
### vendor:stb/easy_font
quick-and-dirty easy-to-deploy bitmap font for printing frame rate, etc
Source port of `stb_easy_font.h`
### vendor:stb/image
Image _loader_, _writer_, and _resizer_.
image loading/decoding from file/memory: JPG, PNG, TGA, BMP, PSD, GIF, HDR, PIC
image writing to disk: PNG, TGA, BMP
resize images larger/smaller with good quality
Bindings of `stb_image.h`, `stb_image_rewrite.h`, `stb_image_resize.h`
### vendor:stb/rect_pack
simple 2D rectangle packer with decent quality
Bindings of `stb_rect_pack.h`
### vendor:stb/truetype
parse, decode, and rasterize characters from truetype fonts
Bindings of `stb_truetype.h`
### vendor:stb/vorbis
decode ogg vorbis files from file/memory to float/16-bit signed output
Bindings of `stb_vorbis.c`
## SDL2
Bindings for the cross platform multimedia API [SDL2](https://github.com/libsdl-org/SDL) and its sub-projects.
+433
View File
@@ -0,0 +1,433 @@
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" }
handle :: distinct rawptr
/* SIMD alignment in bytes. Currently set to 64 bytes in preparation for future AVX-512 optimizations. */
SIMD_ALIGNMENT :: 64
LOG_LEVEL_DEBUG :: 4
LOG_LEVEL_INFO :: 3
LOG_LEVEL_WARNING :: 2
LOG_LEVEL_ERROR :: 1
channel :: enum u8 {
NONE = 0,
MONO = 1,
FRONT_LEFT = 2,
FRONT_RIGHT = 3,
FRONT_CENTER = 4,
LFE = 5,
BACK_LEFT = 6,
BACK_RIGHT = 7,
FRONT_LEFT_CENTER = 8,
FRONT_RIGHT_CENTER = 9,
BACK_CENTER = 10,
SIDE_LEFT = 11,
SIDE_RIGHT = 12,
TOP_CENTER = 13,
TOP_FRONT_LEFT = 14,
TOP_FRONT_CENTER = 15,
TOP_FRONT_RIGHT = 16,
TOP_BACK_LEFT = 17,
TOP_BACK_CENTER = 18,
TOP_BACK_RIGHT = 19,
AUX_0 = 20,
AUX_1 = 21,
AUX_2 = 22,
AUX_3 = 23,
AUX_4 = 24,
AUX_5 = 25,
AUX_6 = 26,
AUX_7 = 27,
AUX_8 = 28,
AUX_9 = 29,
AUX_10 = 30,
AUX_11 = 31,
AUX_12 = 32,
AUX_13 = 33,
AUX_14 = 34,
AUX_15 = 35,
AUX_16 = 36,
AUX_17 = 37,
AUX_18 = 38,
AUX_19 = 39,
AUX_20 = 40,
AUX_21 = 41,
AUX_22 = 42,
AUX_23 = 43,
AUX_24 = 44,
AUX_25 = 45,
AUX_26 = 46,
AUX_27 = 47,
AUX_28 = 48,
AUX_29 = 49,
AUX_30 = 50,
AUX_31 = 51,
LEFT = FRONT_LEFT,
RIGHT = FRONT_RIGHT,
POSITION_COUNT = AUX_31 + 1,
}
result :: enum c.int {
SUCCESS = 0,
ERROR = -1, /* A generic error. */
INVALID_ARGS = -2,
INVALID_OPERATION = -3,
OUT_OF_MEMORY = -4,
OUT_OF_RANGE = -5,
ACCESS_DENIED = -6,
DOES_NOT_EXIST = -7,
ALREADY_EXISTS = -8,
TOO_MANY_OPEN_FILES = -9,
INVALID_FILE = -10,
TOO_BIG = -11,
PATH_TOO_LONG = -12,
NAME_TOO_LONG = -13,
NOT_DIRECTORY = -14,
IS_DIRECTORY = -15,
DIRECTORY_NOT_EMPTY = -16,
AT_END = -17,
NO_SPACE = -18,
BUSY = -19,
IO_ERROR = -20,
INTERRUPT = -21,
UNAVAILABLE = -22,
ALREADY_IN_USE = -23,
BAD_ADDRESS = -24,
BAD_SEEK = -25,
BAD_PIPE = -26,
DEADLOCK = -27,
TOO_MANY_LINKS = -28,
NOT_IMPLEMENTED = -29,
NO_MESSAGE = -30,
BAD_MESSAGE = -31,
NO_DATA_AVAILABLE = -32,
INVALID_DATA = -33,
TIMEOUT = -34,
NO_NETWORK = -35,
NOT_UNIQUE = -36,
NOT_SOCKET = -37,
NO_ADDRESS = -38,
BAD_PROTOCOL = -39,
PROTOCOL_UNAVAILABLE = -40,
PROTOCOL_NOT_SUPPORTED = -41,
PROTOCOL_FAMILY_NOT_SUPPORTED = -42,
ADDRESS_FAMILY_NOT_SUPPORTED = -43,
SOCKET_NOT_SUPPORTED = -44,
CONNECTION_RESET = -45,
ALREADY_CONNECTED = -46,
NOT_CONNECTED = -47,
CONNECTION_REFUSED = -48,
NO_HOST = -49,
IN_PROGRESS = -50,
CANCELLED = -51,
MEMORY_ALREADY_MAPPED = -52,
/* General miniaudio-specific errors. */
FORMAT_NOT_SUPPORTED = -100,
DEVICE_TYPE_NOT_SUPPORTED = -101,
SHARE_MODE_NOT_SUPPORTED = -102,
NO_BACKEND = -103,
NO_DEVICE = -104,
API_NOT_FOUND = -105,
INVALID_DEVICE_CONFIG = -106,
LOOP = -107,
/* State errors. */
DEVICE_NOT_INITIALIZED = -200,
DEVICE_ALREADY_INITIALIZED = -201,
DEVICE_NOT_STARTED = -202,
DEVICE_NOT_STOPPED = -203,
/* Operation errors. */
FAILED_TO_INIT_BACKEND = -300,
FAILED_TO_OPEN_BACKEND_DEVICE = -301,
FAILED_TO_START_BACKEND_DEVICE = -302,
FAILED_TO_STOP_BACKEND_DEVICE = -303,
}
MIN_CHANNELS :: 1
MAX_CHANNELS :: 32
MAX_FILTER_ORDER :: 8
stream_format :: enum c.int {
pcm = 0,
}
stream_layout :: enum c.int {
interleaved = 0,
deinterleaved,
}
dither_mode :: enum c.int {
none = 0,
rectangle,
triangle,
}
format :: enum c.int {
/*
I like to keep these explicitly defined because they're used as a key into a lookup table. When items are
added to this, make sure there are no gaps and that they're added to the lookup table in ma_get_bytes_per_sample().
*/
unknown = 0, /* Mainly used for indicating an error, but also used as the default for the output format for decoders. */
u8 = 1,
s16 = 2, /* Seems to be the most widely supported format. */
s24 = 3, /* Tightly packed. 3 bytes per sample. */
s32 = 4,
f32 = 5,
}
standard_sample_rate :: enum u32 {
/* Standard rates need to be in priority order. */
rate_48000 = 48000, /* Most common */
rate_44100 = 44100,
rate_32000 = 32000, /* Lows */
rate_24000 = 24000,
rate_22050 = 22050,
rate_88200 = 88200, /* Highs */
rate_96000 = 96000,
rate_176400 = 176400,
rate_192000 = 192000,
rate_16000 = 16000, /* Extreme lows */
rate_11025 = 11250,
rate_8000 = 8000,
rate_352800 = 352800, /* Extreme highs */
rate_384000 = 384000,
rate_min = rate_8000,
rate_max = rate_384000,
rate_count = 14, /* Need to maintain the count manually. Make sure this is updated if items are added to enum. */
}
channel_mix_mode :: enum c.int {
rectangular = 0, /* Simple averaging based on the plane(s) the channel is sitting on. */
simple, /* Drop excess channels; zeroed out extra channels. */
custom_weights, /* Use custom weights specified in ma_channel_router_config. */
planar_blend = rectangular,
default = rectangular,
}
standard_channel_map :: enum c.int {
microsoft,
alsa,
rfc3551, /* Based off AIFF. */
flac,
vorbis,
sound4, /* FreeBSD's sound(4). */
sndio, /* www.sndio.org/tips.html */
webaudio = flac, /* https://webaudio.github.io/web-audio-api/#ChannelOrdering. Only 1, 2, 4 and 6 channels are defined, but can fill in the gaps with logical assumptions. */
default = microsoft,
}
performance_profile :: enum c.int {
low_latency = 0,
conservative,
}
allocation_callbacks :: struct {
pUserData: rawptr,
onMalloc: proc "c" (sz: c.size_t, pUserData: rawptr) -> rawptr,
onRealloc: proc "c" (p: rawptr, sz: c.size_t, pUserData: rawptr) -> rawptr,
onFree: proc "c" (p: rawptr, pUserData: rawptr),
}
lcg :: struct {
state: i32,
}
NO_THREADING :: false
when !NO_THREADING {
/* Thread priorities should be ordered such that the default priority of the worker thread is 0. */
thread_priority :: enum c.int {
idle = -5,
lowest = -4,
low = -3,
normal = -2,
high = -1,
highest = 0,
realtime = 1,
default = 0,
}
/* Spinlocks are 32-bit for compatibility reasons. */
spinlock :: distinct u32
when ODIN_OS == "windows" {
thread :: distinct rawptr
mutex :: distinct rawptr
event :: distinct rawptr
semaphore :: distinct rawptr
} else {
import "core:sys/unix"
thread :: unix.pthread_t
mutex :: unix.pthread_mutex_t
event :: struct {
value: u32,
lock: unix.pthread_mutex_t,
cond: unix.pthread_cond_t,
}
semaphore :: struct {
value: c.int,
lock: unix.pthread_mutex_t,
cond: unix.pthread_cond_t,
}
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
/*
Locks a spinlock.
*/
spinlock_lock :: proc(/*volatile*/ pSpinlock: ^spinlock) -> result ---
/*
Locks a spinlock, but does not yield() when looping.
*/
spinlock_lock_noyield :: proc(/*volatile*/ pSpinlock: ^spinlock) -> result ---
/*
Unlocks a spinlock.
*/
spinlock_unlock :: proc(/*volatile*/ pSpinlock: ^spinlock) -> result ---
/*
Creates a mutex.
A mutex must be created from a valid context. A mutex is initially unlocked.
*/
mutex_init :: proc(pMutex: ^mutex) -> result ---
/*
Deletes a mutex.
*/
mutex_uninit :: proc(pMutex: ^mutex) ---
/*
Locks a mutex with an infinite timeout.
*/
mutex_lock :: proc(pMutex: ^mutex) ---
/*
Unlocks a mutex.
*/
mutex_unlock :: proc(pMutex: ^mutex) ---
/*
Initializes an auto-reset event.
*/
event_init :: proc(pEvent: ^event) -> result ---
/*
Uninitializes an auto-reset event.
*/
event_uninit :: proc(pEvent: ^event) ---
/*
Waits for the specified auto-reset event to become signalled.
*/
event_wait :: proc(pEvent: ^event) -> result ---
/*
Signals the specified auto-reset event.
*/
event_signal :: proc(pEvent: ^event) -> result ---
}
} /* NO_THREADING */
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
version :: proc(pMajor, pMinor, pRevision: ^u32) ---
version_string :: proc() -> cstring ---
}
/************************************************************************************************************************************************************
Miscellaneous Helpers
************************************************************************************************************************************************************/
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
/*
Retrieves a human readable description of the given result code.
*/
result_description :: proc(result: result) -> cstring ---
/*
malloc(). Calls MA_MALLOC().
*/
malloc :: proc(sz: c.size_t, pAllocationCallbacks: ^allocation_callbacks) -> rawptr ---
/*
realloc(). Calls MA_REALLOC().
*/
realloc :: proc(p: rawptr, sz: c.size_t, pAllocationCallbacks: ^allocation_callbacks) -> rawptr ---
/*
free(). Calls MA_FREE().
*/
free :: proc(p: rawptr, pAllocationCallbacks: ^allocation_callbacks) ---
/*
Performs an aligned malloc, with the assumption that the alignment is a power of 2.
*/
aligned_malloc :: proc(sz, alignment: c.size_t, pAllocationCallbacks: ^allocation_callbacks) -> rawptr ---
/*
Free's an aligned malloc'd buffer.
*/
aligned_free :: proc(p: rawptr, pAllocationCallbacks: ^allocation_callbacks) ---
/*
Retrieves a friendly name for a format.
*/
get_format_name :: proc(format: format) -> cstring ---
/*
Blends two frames in floating point format.
*/
blend_f32 :: proc(pOut, pInA, pInB: ^f32, factor: f32, channels: u32) ---
/*
Retrieves the size of a sample in bytes for the given format.
This API is efficient and is implemented using a lookup table.
Thread Safety: SAFE
This API is pure.
*/
get_bytes_per_sample :: proc(format: format) -> u32 ---
/*
Converts a log level to a string.
*/
log_level_to_string :: proc(logLevel: u32) -> cstring ---
}
get_bytes_per_frame :: #force_inline proc "c" (format: format, channels: u32) -> u32 { return get_bytes_per_sample(format) * channels }
+511
View File
@@ -0,0 +1,511 @@
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" }
/************************************************************************************************************************************************************
*************************************************************************************************************************************************************
DATA CONVERSION
===============
This section contains the APIs for data conversion. You will find everything here for channel mapping, sample format conversion, resampling, etc.
*************************************************************************************************************************************************************
************************************************************************************************************************************************************/
/**************************************************************************************************************************************************************
Resampling
**************************************************************************************************************************************************************/
linear_resampler_config :: struct {
format: format,
channels: u32,
sampleRateIn: u32,
sampleRateOut: u32,
lpfOrder: u32, /* The low-pass filter order. Setting this to 0 will disable low-pass filtering. */
lpfNyquistFactor: f64, /* 0..1. Defaults to 1. 1 = Half the sampling frequency (Nyquist Frequency), 0.5 = Quarter the sampling frequency (half Nyquest Frequency), etc. */
}
linear_resampler :: struct {
config: linear_resampler_config,
inAdvanceInt: u32,
inAdvanceFrac: u32,
inTimeInt: u32,
inTimeFrac: u32,
x0: struct #raw_union {
f32: [MAX_CHANNELS]f32,
s16: [MAX_CHANNELS]i16,
}, /* The previous input frame. */
x1: struct #raw_union {
f32: [MAX_CHANNELS]f32,
s16: [MAX_CHANNELS]i16,
}, /* The next input frame. */
lpf: lpf,
}
resample_algorithm :: enum {
linear = 0, /* Fastest, lowest quality. Optional low-pass filtering. Default. */
speex,
}
resampler_config :: struct {
format: format, /* Must be either ma_format_f32 or ma_format_s16. */
channels: u32,
sampleRateIn: u32,
sampleRateOut: u32,
algorithm: resample_algorithm,
linear: struct {
lpfOrder: u32,
lpfNyquistFactor: f64,
},
speex: struct {
quality: c.int, /* 0 to 10. Defaults to 3. */
},
}
resampler :: struct {
config: resampler_config,
state: struct #raw_union {
linear: linear_resampler,
speex: struct {
pSpeexResamplerState: rawptr, /* SpeexResamplerState* */
},
},
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
linear_resampler_config_init :: proc(format: format, channels: u32, sampleRateIn, sampleRateOut: u32) -> linear_resampler_config ---
linear_resampler_init :: proc(pConfig: ^linear_resampler_config, pResampler: ^linear_resampler) -> result ---
linear_resampler_uninit :: proc(pResampler: ^linear_resampler) ---
linear_resampler_process_pcm_frames :: proc(pResampler: ^linear_resampler, pFramesIn: rawptr, pFrameCountIn: ^u64, pFramesOut: rawptr, pFrameCountOut: ^u64) -> result ---
linear_resampler_set_rate :: proc(pResampler: ^linear_resampler, sampleRateIn, sampleRateOut: u32) -> result ---
linear_resampler_set_rate_ratio :: proc(pResampler: ^linear_resampler, ratioInOut: f32) -> result ---
linear_resampler_get_required_input_frame_count :: proc(pResampler: ^linear_resampler, outputFrameCount: u64) -> u64 ---
linear_resampler_get_expected_output_frame_count :: proc(pResampler: ^linear_resampler, inputFrameCount: u64) -> u64 ---
linear_resampler_get_input_latency :: proc(pResampler: ^linear_resampler) -> u64 ---
linear_resampler_get_output_latency :: proc(pResampler: ^linear_resampler) -> u64 ---
resampler_config_init :: proc(format: format, channels: u32, sampleRateIn, sampleRateOut: u32, algorithm: resample_algorithm) -> resampler_config ---
/*
Initializes a new resampler object from a config.
*/
resampler_init :: proc(pConfig: ^resampler_config, pResampler: ^resampler) -> result ---
/*
Uninitializes a resampler.
*/
resampler_uninit :: proc(pResampler: ^resampler) ---
/*
Converts the given input data.
Both the input and output frames must be in the format specified in the config when the resampler was initilized.
On input, [pFrameCountOut] contains the number of output frames to process. On output it contains the number of output frames that
were actually processed, which may be less than the requested amount which will happen if there's not enough input data. You can use
ma_resampler_get_expected_output_frame_count() to know how many output frames will be processed for a given number of input frames.
On input, [pFrameCountIn] contains the number of input frames contained in [pFramesIn]. On output it contains the number of whole
input frames that were actually processed. You can use ma_resampler_get_required_input_frame_count() to know how many input frames
you should provide for a given number of output frames. [pFramesIn] can be NULL, in which case zeroes will be used instead.
If [pFramesOut] is NULL, a seek is performed. In this case, if [pFrameCountOut] is not NULL it will seek by the specified number of
output frames. Otherwise, if [pFramesCountOut] is NULL and [pFrameCountIn] is not NULL, it will seek by the specified number of input
frames. When seeking, [pFramesIn] is allowed to NULL, in which case the internal timing state will be updated, but no input will be
processed. In this case, any internal filter state will be updated as if zeroes were passed in.
It is an error for [pFramesOut] to be non-NULL and [pFrameCountOut] to be NULL.
It is an error for both [pFrameCountOut] and [pFrameCountIn] to be NULL.
*/
resampler_process_pcm_frames :: proc(pResampler: ^resampler, pFramesIn: rawptr, pFrameCountIn: ^u64, pFramesOut: rawptr, pFrameCountOut: ^u64) -> result ---
/*
Sets the input and output sample sample rate.
*/
resampler_set_rate :: proc(pResampler: ^resampler, sampleRateIn, sampleRateOut: u32) -> result ---
/*
Sets the input and output sample rate as a ratio.
The ration is in/out.
*/
resampler_set_rate_ratio :: proc(pResampler: ^resampler, ratio: f32) -> result ---
/*
Calculates the number of whole input frames that would need to be read from the client in order to output the specified
number of output frames.
The returned value does not include cached input frames. It only returns the number of extra frames that would need to be
read from the input buffer in order to output the specified number of output frames.
*/
resampler_get_required_input_frame_count :: proc(pResampler: ^resampler, outputFrameCount: u64) -> u64 ---
/*
Calculates the number of whole output frames that would be output after fully reading and consuming the specified number of
input frames.
*/
resampler_get_expected_output_frame_count :: proc(pResampler: ^resampler, inputFrameCount: u64) -> u64 ---
/*
Retrieves the latency introduced by the resampler in input frames.
*/
resampler_get_input_latency :: proc(pResampler: ^resampler) -> u64 ---
/*
Retrieves the latency introduced by the resampler in output frames.
*/
resampler_get_output_latency :: proc(pResampler: ^resampler) -> u64 ---
}
/**************************************************************************************************************************************************************
Channel Conversion
**************************************************************************************************************************************************************/
channel_converter_config :: struct {
format: format,
channelsIn: u32,
channelsOut: u32,
channelMapIn: [MAX_CHANNELS]channel,
channelMapOut: [MAX_CHANNELS]channel,
mixingMode: channel_mix_mode,
weights: [MAX_CHANNELS][MAX_CHANNELS]f32, /* [in][out]. Only used when mixingMode is set to ma_channel_mix_mode_custom_weights. */
}
channel_converter :: struct {
format: format,
channelsIn: u32,
channelsOut: u32,
channelMapIn: [MAX_CHANNELS]channel,
channelMapOut: [MAX_CHANNELS]channel,
mixingMode: channel_mix_mode,
weights: struct #raw_union {
f32: [MAX_CHANNELS][MAX_CHANNELS]f32,
s16: [MAX_CHANNELS][MAX_CHANNELS]i32,
},
isPassthrough: b8,
isSimpleShuffle: b8,
isSimpleMonoExpansion: b8,
isStereoToMono: b8,
shuffleTable: [MAX_CHANNELS]u8,
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
channel_converter_config_init :: proc(format: format, channelsIn: u32, pChannelMapIn: ^channel, channelsOut: u32, pChannelMapOut: ^channel, mixingMode: channel_mix_mode) -> channel_converter_config ---
channel_converter_init :: proc(pConfig: ^channel_converter_config, pConverter: ^channel_converter) -> result ---
channel_converter_uninit :: proc(pConverter: ^channel_converter) ---
channel_converter_process_pcm_frames :: proc(pConverter: ^channel_converter, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
}
/**************************************************************************************************************************************************************
Data Conversion
**************************************************************************************************************************************************************/
data_converter_config :: struct {
formatIn: format,
formatOut: format,
channelsIn: u32,
channelsOut: u32,
sampleRateIn: u32,
sampleRateOut: u32,
channelMapIn: [MAX_CHANNELS]channel,
channelMapOut: [MAX_CHANNELS]channel,
ditherMode: dither_mode,
channelMixMode: channel_mix_mode,
channelWeights: [MAX_CHANNELS][MAX_CHANNELS]f32, /* [in][out]. Only used when channelMixMode is set to ma_channel_mix_mode_custom_weights. */
resampling: struct {
algorithm: resample_algorithm,
allowDynamicSampleRate: b32,
linear: struct {
lpfOrderL: u32,
lpfNyquistFactor: f64,
},
speex: struct {
quality: c.int,
},
},
}
data_converter :: struct {
config: data_converter_config,
channelConverter: channel_converter,
resampler: resampler,
hasPreFormatConversion: b8,
hasPostFormatConversion: b8,
hasChannelConverter: b8,
hasResampler: b8,
isPassthrough: b8,
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
data_converter_config_init_default :: proc() -> data_converter_config ---
data_converter_config_init :: proc(formatIn, formatOut: format, channelsIn, channelsOut: u32, sampleRateIn, sampleRateOut: u32) -> data_converter_config ---
data_converter_init :: proc(pConfig: ^data_converter_config, pConverter: ^data_converter) -> result ---
data_converter_uninit :: proc(pConverter: ^data_converter) ---
data_converter_process_pcm_frames :: proc(pConverter: ^data_converter, pFramesIn: rawptr, pFrameCountIn: ^u64, pFramesOut: rawptr, pFrameCountOut: ^u64) -> result ---
data_converter_set_rate :: proc(pConverter: ^data_converter, sampleRateIn, sampleRateOut: u32) -> result ---
data_converter_set_rate_ratio :: proc(pConverter: ^data_converter, ratioInOut: f32) -> result ---
data_converter_get_required_input_frame_count :: proc(pConverter: ^data_converter, outputFrameCount: u64) -> u64 ---
data_converter_get_expected_output_frame_count :: proc(pConverter: ^data_converter, inputFrameCount: u64) -> u64 ---
data_converter_get_input_latency :: proc(pConverter: ^data_converter) -> u64 ---
data_converter_get_output_latency :: proc(pConverter: ^data_converter) -> u64 ---
}
/************************************************************************************************************************************************************
Format Conversion
************************************************************************************************************************************************************/
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
pcm_u8_to_s16 :: proc(pOut: rawptr, pIn: rawptr, count: u64, ditherMode: dither_mode) ---
pcm_u8_to_s24 :: proc(pOut: rawptr, pIn: rawptr, count: u64, ditherMode: dither_mode) ---
pcm_u8_to_s32 :: proc(pOut: rawptr, pIn: rawptr, count: u64, ditherMode: dither_mode) ---
pcm_u8_to_f32 :: proc(pOut: rawptr, pIn: rawptr, count: u64, ditherMode: dither_mode) ---
pcm_s16_to_u8 :: proc(pOut: rawptr, pIn: rawptr, count: u64, ditherMode: dither_mode) ---
pcm_s16_to_s24 :: proc(pOut: rawptr, pIn: rawptr, count: u64, ditherMode: dither_mode) ---
pcm_s16_to_s32 :: proc(pOut: rawptr, pIn: rawptr, count: u64, ditherMode: dither_mode) ---
pcm_s16_to_f32 :: proc(pOut: rawptr, pIn: rawptr, count: u64, ditherMode: dither_mode) ---
pcm_s24_to_u8 :: proc(pOut: rawptr, pIn: rawptr, count: u64, ditherMode: dither_mode) ---
pcm_s24_to_s16 :: proc(pOut: rawptr, pIn: rawptr, count: u64, ditherMode: dither_mode) ---
pcm_s24_to_s32 :: proc(pOut: rawptr, pIn: rawptr, count: u64, ditherMode: dither_mode) ---
pcm_s24_to_f32 :: proc(pOut: rawptr, pIn: rawptr, count: u64, ditherMode: dither_mode) ---
pcm_s32_to_u8 :: proc(pOut: rawptr, pIn: rawptr, count: u64, ditherMode: dither_mode) ---
pcm_s32_to_s16 :: proc(pOut: rawptr, pIn: rawptr, count: u64, ditherMode: dither_mode) ---
pcm_s32_to_s24 :: proc(pOut: rawptr, pIn: rawptr, count: u64, ditherMode: dither_mode) ---
pcm_s32_to_f32 :: proc(pOut: rawptr, pIn: rawptr, count: u64, ditherMode: dither_mode) ---
pcm_f32_to_u8 :: proc(pOut: rawptr, pIn: rawptr, count: u64, ditherMode: dither_mode) ---
pcm_f32_to_s16 :: proc(pOut: rawptr, pIn: rawptr, count: u64, ditherMode: dither_mode) ---
pcm_f32_to_s24 :: proc(pOut: rawptr, pIn: rawptr, count: u64, ditherMode: dither_mode) ---
pcm_f32_to_s32 :: proc(pOut: rawptr, pIn: rawptr, count: u64, ditherMode: dither_mode) ---
pcm_convert :: proc(pOut: rawptr, formatOut: format, pIn: rawptr, formatIn: format, sampleCount: u64, ditherMode: dither_mode) ---
convert_pcm_frames_format :: proc(pOut: rawptr, formatOut: format, pIn: rawptr, formatIn: format, frameCount: u64, channels: u32, ditherMode: dither_mode) ---
/*
Deinterleaves an interleaved buffer.
*/
deinterleave_pcm_frames :: proc(format: format, channels: u32, frameCount: u64, pInterleavedPCMFrames: rawptr, ppDeinterleavedPCMFrames: ^rawptr) ---
/*
Interleaves a group of deinterleaved buffers.
*/
interleave_pcm_frames :: proc(format: format, channels: u32, frameCount: u64, ppDeinterleavedPCMFrames: ^rawptr, pInterleavedPCMFrames: rawptr) ---
}
/************************************************************************************************************************************************************
Channel Maps
************************************************************************************************************************************************************/
/*
This is used in the shuffle table to indicate that the channel index is undefined and should be ignored.
*/
CHANNEL_INDEX_NULL :: 255
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
/* Retrieves the channel position of the specified channel based on miniaudio's default channel map. */
channel_map_get_default_channel :: proc(channelCount: u32, channelIndex: u32) -> channel ---
/*
Retrieves the channel position of the specified channel in the given channel map.
The pChannelMap parameter can be null, in which case miniaudio's default channel map will be assumed.
*/
channel_map_get_channel :: proc(pChannelMap: ^channel, channelCount: u32, channelIndex: u32) -> channel ---
/*
Initializes a blank channel map.
When a blank channel map is specified anywhere it indicates that the native channel map should be used.
*/
channel_map_init_blank :: proc(channels: u32, pChannelMap: ^channel) ---
/*
Helper for retrieving a standard channel map.
The output channel map buffer must have a capacity of at least `channels`.
*/
get_standard_channel_map :: proc(standardChannelMap: standard_channel_map, channels: u32, pChannelMap: ^channel) ---
/*
Copies a channel map.
Both input and output channel map buffers must have a capacity of at at least `channels`.
*/
channel_map_copy :: proc(pOut: ^channel, pIn: ^channel, channels: u32) ---
/*
Copies a channel map if one is specified, otherwise copies the default channel map.
The output buffer must have a capacity of at least `channels`. If not NULL, the input channel map must also have a capacity of at least `channels`.
*/
channel_map_copy_or_default :: proc(pOut: ^channel, pIn: ^channel, channels: u32) ---
/*
Determines whether or not a channel map is valid.
A blank channel map is valid (all channels set to MA_CHANNEL_NONE). The way a blank channel map is handled is context specific, but
is usually treated as a passthrough.
Invalid channel maps:
- A channel map with no channels
- A channel map with more than one channel and a mono channel
The channel map buffer must have a capacity of at least `channels`.
*/
channel_map_valid :: proc(channels: u32, pChannelMap: ^channel) -> b32 ---
/*
Helper for comparing two channel maps for equality.
This assumes the channel count is the same between the two.
Both channels map buffers must have a capacity of at least `channels`.
*/
channel_map_equal :: proc(channels: u32, pChannelMapA, pChannelMapB: ^channel) -> b32 ---
/*
Helper for determining if a channel map is blank (all channels set to MA_CHANNEL_NONE).
The channel map buffer must have a capacity of at least `channels`.
*/
channel_map_blank :: proc(channels: u32, pChannelMap: ^channel) -> b32 ---
/*
Helper for determining whether or not a channel is present in the given channel map.
The channel map buffer must have a capacity of at least `channels`.
*/
channel_map_contains_channel_position :: proc(channels: u32, pChannelMap: ^channel, channelPosition: channel) -> b32 ---
}
/************************************************************************************************************************************************************
Conversion Helpers
************************************************************************************************************************************************************/
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
/*
High-level helper for doing a full format conversion in one go. Returns the number of output frames. Call this with pOut set to NULL to
determine the required size of the output buffer. frameCountOut should be set to the capacity of pOut. If pOut is NULL, frameCountOut is
ignored.
A return value of 0 indicates an error.
This function is useful for one-off bulk conversions, but if you're streaming data you should use the ma_data_converter APIs instead.
*/
convert_frames :: proc(pOut: rawptr, frameCountOut: u64, formatOut: format, channelsOut: u32, sampleRateOut: u32, pIn: rawptr, frameCountIn: u64, formatIn: format, channelsIn: u32, sampleRateIn: u32) -> u64 ---
convert_frames_ex :: proc(pOut: rawptr, frameCountOut: u64, pIn: rawptr, frameCountIn: u64, pConfig: ^data_converter_config) -> u64 ---
}
/************************************************************************************************************************************************************
Ring Buffer
************************************************************************************************************************************************************/
rb :: struct {
pBuffer: rawptr,
subbufferSizeInBytes: u32,
subbufferCount: u32,
subbufferStrideInBytes: u32,
encodedReadOffset: u32, /*atomic*/ /* Most significant bit is the loop flag. Lower 31 bits contains the actual offset in bytes. Must be used atomically. */
encodedWriteOffset: u32, /*atomic*/ /* Most significant bit is the loop flag. Lower 31 bits contains the actual offset in bytes. Must be used atomically. */
ownsBuffer: b8, /* Used to know whether or not miniaudio is responsible for free()-ing the buffer. */
clearOnWriteAcquire: b8, /* When set, clears the acquired write buffer before returning from ma_rb_acquire_write(). */
allocationCallbacks: allocation_callbacks,
}
pcm_rb :: struct {
rb: rb,
format: format,
channels: u32,
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
rb_init_ex :: proc(subbufferSizeInBytes, subbufferCount, subbufferStrideInBytes: c.size_t, pOptionalPreallocatedBuffer: rawptr, pAllocationCallbacks: ^allocation_callbacks, pRB: ^rb) -> result ---
rb_init :: proc(bufferSizeInBytes: c.size_t, pOptionalPreallocatedBuffer: rawptr, pAllocationCallbacks: ^allocation_callbacks, pRB: ^rb) -> result ---
rb_uninit :: proc(pRB: ^rb) ---
rb_reset :: proc(pRB: ^rb) ---
rb_acquire_read :: proc(pRB: ^rb, pSizeInBytes: ^c.size_t, ppBufferOut: ^rawptr) -> result ---
rb_commit_read :: proc(pRB: ^rb, sizeInBytes: c.size_t, pBufferOut: rawptr) -> result ---
rb_acquire_write :: proc(pRB: ^rb, pSizeInBytes: ^c.size_t, ppBufferOut: ^rawptr) -> result ---
rb_commit_write :: proc(pRB: ^rb, sizeInBytes: c.size_t, pBufferOut: rawptr) -> result ---
rb_seek_read :: proc(pRB: ^rb, offsetInBytes: c.size_t) -> result ---
rb_seek_write :: proc(pRB: ^rb, offsetInBytes: c.size_t) -> result ---
rb_pointer_distance :: proc(pRB: ^rb) -> i32 --- /* Returns the distance between the write pointer and the read pointer. Should never be negative for a correct program. Will return the number of bytes that can be read before the read pointer hits the write pointer. */
rb_available_read :: proc(pRB: ^rb) -> u32 ---
rb_available_write :: proc(pRB: ^rb) -> u32 ---
rb_get_subbuffer_size :: proc(pRB: ^rb) -> c.size_t ---
rb_get_subbuffer_stride :: proc(pRB: ^rb) -> c.size_t ---
rb_get_subbuffer_offset :: proc(pRB: ^rb, subbufferIndex: c.size_t) -> c.size_t ---
rb_get_subbuffer_ptr :: proc(pRB: ^rb, subbufferIndex: c.size_t, pBuffer: rawptr) -> rawptr ---
pcm_rb_init_ex :: proc(format: format, channels: u32, subbufferSizeInFrames, subbufferCount, subbufferStrideInFrames: u32, pOptionalPreallocatedBuffer: rawptr, pAllocationCallbacks: ^allocation_callbacks, pRB: ^pcm_rb) -> result ---
pcm_rb_init :: proc(format: format, channels: u32, bufferSizeInFrames: u32, pOptionalPreallocatedBuffer: rawptr, pAllocationCallbacks: ^allocation_callbacks, pRB: ^pcm_rb) -> result ---
pcm_rb_uninit :: proc(pRB: ^pcm_rb) ---
pcm_rb_reset :: proc(pRB: ^pcm_rb) ---
pcm_rb_acquire_read :: proc(pRB: ^pcm_rb, pSizeInFrames: ^u32, ppBufferOut: ^rawptr) -> result ---
pcm_rb_commit_read :: proc(pRB: ^pcm_rb, sizeInFrames: u32, pBufferOut: rawptr) -> result ---
pcm_rb_acquire_write :: proc(pRB: ^pcm_rb, pSizeInFrames: ^u32, ppBufferOut: ^rawptr) -> result ---
pcm_rb_commit_write :: proc(pRB: ^pcm_rb, sizeInFrames: u32, pBufferOut: rawptr) -> result ---
pcm_rb_seek_read :: proc(pRB: ^pcm_rb, offsetInFrames: u32) -> result ---
pcm_rb_seek_write :: proc(pRB: ^pcm_rb, offsetInFrames: u32) -> result ---
pcm_rb_pointer_distance :: proc(pRB: ^pcm_rb) -> i32 --- /* Return value is in frames. */
pcm_rb_available_read :: proc(pRB: ^pcm_rb) -> u32 ---
pcm_rb_available_write :: proc(pRB: ^pcm_rb) -> u32 ---
pcm_rb_get_subbuffer_size :: proc(pRB: ^pcm_rb) -> u32 ---
pcm_rb_get_subbuffer_stride :: proc(pRB: ^pcm_rb) -> u32 ---
pcm_rb_get_subbuffer_offset :: proc(pRB: ^pcm_rb, subbufferIndex: u32) -> u32 ---
pcm_rb_get_subbuffer_ptr :: proc(pRB: ^pcm_rb, subbufferIndex: u32, pBuffer: rawptr) -> rawptr ---
}
/*
The idea of the duplex ring buffer is to act as the intermediary buffer when running two asynchronous devices in a duplex set up. The
capture device writes to it, and then a playback device reads from it.
At the moment this is just a simple naive implementation, but in the future I want to implement some dynamic resampling to seamlessly
handle desyncs. Note that the API is work in progress and may change at any time in any version.
The size of the buffer is based on the capture side since that's what'll be written to the buffer. It is based on the capture period size
in frames. The internal sample rate of the capture device is also needed in order to calculate the size.
*/
duplex_rb :: struct {
rb: pcm_rb,
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
duplex_rb_init :: proc(captureFormat: format, captureChannels: u32, sampleRate: u32, captureInternalSampleRate, captureInternalPeriodSizeInFrames: u32, pAllocationCallbacks: ^allocation_callbacks, pRB: ^duplex_rb) -> result ---
duplex_rb_uninit :: proc(pRB: ^duplex_rb) -> result ---
}
+167
View File
@@ -0,0 +1,167 @@
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" }
/************************************************************************************************************************************************************
Decoding
========
Decoders are independent of the main device API. Decoding APIs can be called freely inside the device's data callback, but they are not thread safe unless
you do your own synchronization.
************************************************************************************************************************************************************/
decoding_backend_config :: struct {
preferredFormat: format,
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
decoding_backend_config_init :: proc(preferredFormat: format) -> decoding_backend_config ---
}
decoding_backend_vtable :: struct {
onInit: proc "c" (pUserData: rawptr, onRead: decoder_read_proc, onSeek: decoder_seek_proc, onTell: decoder_tell_proc, pReadSeekTellUserData: rawptr, pConfig: ^decoding_backend_config, pAllocationCallbacks: ^allocation_callbacks, ppBackend: ^^data_source) -> result,
onInitFile: proc "c" (pUserData: rawptr, pFilePath: cstring, pConfig: ^decoding_backend_config, pAllocationCallbacks: ^allocation_callbacks, ppBackend: ^^data_source) -> result, /* Optional. */
onInitFileW: proc "c" (pUserData: rawptr, pFilePath: [^]c.wchar_t, pConfig: ^decoding_backend_config, pAllocationCallbacks: ^allocation_callbacks, ppBackend: ^^data_source) -> result, /* Optional. */
onInitMemory: proc "c" (pUserData: rawptr, pData: rawptr, dataSize: c.size_t, pConfig: ^decoding_backend_config, pAllocationCallbacks: ^allocation_callbacks, ppBackend: ^^data_source) -> result, /* Optional. */
onUninit: proc "c" (pUserData: rawptr, pBackend: ^data_source, pAllocationCallbacks: ^allocation_callbacks),
onGetChannelMap: proc "c" (pUserData: rawptr, pBackend: ^data_source, pChannelMap: ^channel, channelMapCap: c.size_t) -> result,
}
/* TODO: Convert read and seek to be consistent with the VFS API (ma_result return value, bytes read moved to an output parameter). */
decoder_read_proc :: proc "c" (pDecoder: ^decoder, pBufferOut: rawptr, bytesToRead: c.size_t) -> c.size_t /* Returns the number of bytes read. */
decoder_seek_proc :: proc "c" (pDecoder: ^decoder, byteOffset: i64, origin: seek_origin) -> b32
decoder_tell_proc :: proc "c" (pDecoder: ^decoder, pCursor: ^i64) -> result
decoder_config :: struct {
format: format, /* Set to 0 or ma_format_unknown to use the stream's internal format. */
channels: u32, /* Set to 0 to use the stream's internal channels. */
sampleRate: u32, /* Set to 0 to use the stream's internal sample rate. */
channelMap: [MAX_CHANNELS]channel,
channelMixMode: channel_mix_mode,
ditherMode: dither_mode,
resampling: struct {
algorithm: resample_algorithm,
linear: struct {
lpfOrder: u32,
},
speex: struct {
quality: c.int,
},
},
allocationCallbacks: allocation_callbacks,
encodingFormat: encoding_format,
ppCustomBackendVTables: ^^decoding_backend_vtable,
customBackendCount: u32,
pCustomBackendUserData: rawptr,
}
decoder :: struct {
ds: data_source_base,
pBackend: ^data_source, /* The decoding backend we'll be pulling data from. */
pBackendVTable: ^^decoding_backend_vtable, /* The vtable for the decoding backend. This needs to be stored so we can access the onUninit() callback. */
pBackendUserData: rawptr,
onRead: decoder_read_proc,
onSeek: decoder_seek_proc,
onTell: decoder_tell_proc,
pUserData: rawptr,
readPointerInPCMFrames: u64, /* In output sample rate. Used for keeping track of how many frames are available for decoding. */
outputFormat: format,
outputChannels: u32,
outputSampleRate: u32,
outputChannelMap: [MAX_CHANNELS]channel,
converter: data_converter, /* <-- Data conversion is achieved by running frames through this. */
allocationCallbacks: allocation_callbacks,
data: struct #raw_union {
vfs: struct {
pVFS: ^vfs,
file: vfs_file,
},
memory: struct {
pData: [^]u8,
dataSize: c.size_t,
currentReadPos: c.size_t,
}, /* Only used for decoders that were opened against a block of memory. */
},
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
decoder_config_init :: proc(outputFormat: format, outputChannels, outputSampleRate: u32) -> decoder_config ---
decoder_config_init_default :: proc() -> decoder_config ---
decoder_init :: proc(onRead: decoder_read_proc, onSeek: decoder_seek_proc, pUserData: rawptr, pConfig: ^decoder_config, pDecoder: ^decoder) -> result ---
decoder_init_memory :: proc(pData: rawptr, dataSize: c.size_t, pConfig: ^decoder_config, pDecoder: ^decoder) -> result ---
decoder_init_vfs :: proc(pVFS: ^vfs, pFilePath: cstring, pConfig: ^decoder_config, pDecoder: ^decoder) -> result ---
decoder_init_vfs_w :: proc(pVFS: ^vfs, pFilePath: [^]c.wchar_t, pConfig: ^decoder_config, pDecoder: ^decoder) -> result ---
decoder_init_file :: proc(pFilePath: cstring, pConfig: ^decoder_config, pDecoder: ^decoder) -> result ---
decoder_init_file_w :: proc(pFilePath: [^]c.wchar_t, pConfig: ^decoder_config, pDecoder: ^decoder) -> result ---
/*
Uninitializes a decoder.
*/
decoder_uninit :: proc(pDecoder: ^decoder) -> result ---
/*
Retrieves the current position of the read cursor in PCM frames.
*/
decoder_get_cursor_in_pcm_frames :: proc(pDecoder: ^decoder, pCursor: ^u64) -> result ---
/*
Retrieves the length of the decoder in PCM frames.
Do not call this on streams of an undefined length, such as internet radio.
If the length is unknown or an error occurs, 0 will be returned.
This will always return 0 for Vorbis decoders. This is due to a limitation with stb_vorbis in push mode which is what miniaudio
uses internally.
For MP3's, this will decode the entire file. Do not call this in time critical scenarios.
This function is not thread safe without your own synchronization.
*/
decoder_get_length_in_pcm_frames :: proc(pDecoder: ^decoder) -> u64 ---
/*
Reads PCM frames from the given decoder.
This is not thread safe without your own synchronization.
*/
decoder_read_pcm_frames :: proc(pDecoder: ^decoder, pFramesOut: rawptr, frameCount: u64) -> u64 ---
/*
Seeks to a PCM frame based on it's absolute index.
This is not thread safe without your own synchronization.
*/
decoder_seek_to_pcm_frame :: proc(pDecoder: ^decoder, frameIndex: u64) -> result ---
/*
Retrieves the number of frames that can be read before reaching the end.
This calls `ma_decoder_get_length_in_pcm_frames()` so you need to be aware of the rules for that function, in
particular ensuring you do not call it on streams of an undefined length, such as internet radio.
If the total length of the decoder cannot be retrieved, such as with Vorbis decoders, `MA_NOT_IMPLEMENTED` will be
returned.
*/
decoder_get_available_frames :: proc(pDecoder: ^decoder, pAvailableFrames: ^u64) -> result ---
/*
Helper for opening and decoding a file into a heap allocated block of memory. Free the returned pointer with ma_free(). On input,
pConfig should be set to what you want. On output it will be set to what you got.
*/
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 ---
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1490
View File
File diff suppressed because it is too large Load Diff
+52
View File
@@ -0,0 +1,52 @@
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" }
/************************************************************************************************************************************************************
Encoding
========
Encoders do not perform any format conversion for you. If your target format does not support the format, and error will be returned.
************************************************************************************************************************************************************/
encoder_write_proc :: proc "c" (pEncoder: ^encoder, pBufferIn: rawptr, bytesToWrite: c.size_t) -> c.size_t /* Returns the number of bytes written. */
encoder_seek_proc :: proc "c" (pEncoder: ^encoder, byteOffset: c.int, origin: seek_origin) -> b32
encoder_init_proc :: proc "c" (pEncoder: ^encoder) -> result
encoder_uninit_proc :: proc "c" (pEncoder: ^encoder)
encoder_write_pcm_frames_proc :: proc "c" (pEncoder: ^encoder, pFramesIn: rawptr, frameCount: u64) -> u64
encoder_config :: struct {
resourceFormat: resource_format,
format: format,
channels: u32,
sampleRate: u32,
allocationCallbacks: allocation_callbacks,
}
encoder :: struct {
config: encoder_config,
onWrite: encoder_write_proc,
onSeek: encoder_seek_proc,
onInit: encoder_init_proc,
onUninit: encoder_uninit_proc,
onWritePCMFrames: encoder_write_pcm_frames_proc,
pUserData: rawptr,
pInternalEncoder: rawptr, /* <-- The drwav/drflac/stb_vorbis/etc. objects. */
pFile: rawptr, /* FILE*. Only used when initialized with ma_encoder_init_file(). */
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
encoder_config_init :: proc(resourceFormat: resource_format, format: format, channels: u32, sampleRate: u32) -> encoder_config ---
encoder_init :: proc(onWrite: encoder_write_proc, onSeek: encoder_seek_proc, pUserData: rawptr, pConfig: ^encoder_config, pEncoder: ^encoder) -> result ---
encoder_init_file :: proc(pFilePath: cstring, pConfig: ^encoder_config, pEncoder: ^encoder) -> result ---
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 ---
}
+352
View File
@@ -0,0 +1,352 @@
package miniaudio
when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" }
when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" }
/**************************************************************************************************************************************************************
Biquad Filtering
**************************************************************************************************************************************************************/
biquad_coefficient :: struct #raw_union {
f32: f32,
s32: i32,
}
biquad_config :: struct {
format: format,
channels: u32,
b0: f64,
b1: f64,
b2: f64,
a0: f64,
a1: f64,
a2: f64,
}
biquad :: struct {
format: format,
channels: u32,
b0: biquad_coefficient,
b1: biquad_coefficient,
b2: biquad_coefficient,
a1: biquad_coefficient,
a2: biquad_coefficient,
r1: [MAX_CHANNELS]biquad_coefficient,
r2: [MAX_CHANNELS]biquad_coefficient,
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
biquad_config_init :: proc(format: format, channels: u32, b0, b1, b2, a0, a1, a2: f64) -> biquad_config ---
biquad_init :: proc(pConfig: ^biquad_config, pBQ: ^biquad) -> result ---
biquad_reinit :: proc(pConfig: ^biquad_config, pBQ: ^biquad) -> result ---
biquad_process_pcm_frames :: proc(pBQ: ^biquad, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
biquad_get_latency :: proc(pBQ: ^biquad) -> u32 ---
}
/**************************************************************************************************************************************************************
Low-Pass Filtering
**************************************************************************************************************************************************************/
lpf1_config :: struct {
format: format,
channels: u32,
sampleRate: u32,
cutoffFrequency: f64,
q: f64,
}
lpf2_config :: lpf1_config
lpf1 :: struct {
format: format,
channels: u32,
a: biquad_coefficient,
r1: [MAX_CHANNELS]biquad_coefficient,
}
lpf2 :: struct {
bq: biquad, /* The second order low-pass filter is implemented as a biquad filter. */
}
lpf_config :: struct {
format: format,
channels: u32,
sampleRate: u32,
cutoffFrequency: f64,
order: u32, /* If set to 0, will be treated as a passthrough (no filtering will be applied). */
}
lpf :: struct {
format: format,
channels: u32,
sampleRate: u32,
lpf1Count: u32,
lpf2Count: u32,
lpf1: [1]lpf1,
lpf2: [MAX_FILTER_ORDER/2]lpf2,
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
lpf1_config_init :: proc(format: format, channels: u32, sampleRate: u32, cutoffFrequency: f64) -> lpf1_config ---
lpf2_config_init :: proc(format: format, channels: u32, sampleRate: u32, cutoffFrequency, q: f64) -> lpf2_config ---
lpf1_init :: proc(pConfig: ^lpf1_config, pLPF: ^lpf1) -> result ---
lpf1_reinit :: proc(pConfig: ^lpf1_config, pLPF: ^lpf1) -> result ---
lpf1_process_pcm_frames :: proc(pLPF: ^lpf1, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
lpf1_get_latency :: proc(pLPF: ^lpf1) -> u32 ---
lpf2_init :: proc(pConfig: ^lpf2_config, pLPF: ^lpf2) -> result ---
lpf2_reinit :: proc(pConfig: ^lpf2_config, pLPF: ^lpf2) -> result ---
lpf2_process_pcm_frames :: proc(pLPF: ^lpf2, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
lpf2_get_latency :: proc(pLPF: ^lpf2) -> u32 ---
lpf_config_init :: proc(format: format, channels: u32, sampleRate: u32, cutoffFrequency: f64, order: u32) -> lpf_config ---
lpf_init :: proc(pConfig: ^lpf_config, pLPF: ^lpf) -> result ---
lpf_reinit :: proc(pConfig: ^lpf_config, pLPF: ^lpf) -> result ---
lpf_process_pcm_frames :: proc(pLPF: ^lpf, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
lpf_get_latency :: proc(pLPF: ^lpf) -> u32 ---
}
/**************************************************************************************************************************************************************
High-Pass Filtering
**************************************************************************************************************************************************************/
hpf1_config :: struct {
format: format,
channels: u32,
sampleRate: u32,
cutoffFrequency: f64,
q: f64,
}
hpf2_config :: hpf1_config
hpf1 :: struct {
format: format,
channels: u32,
a: biquad_coefficient,
r1: [MAX_CHANNELS]biquad_coefficient,
}
hpf2 :: struct {
bq: biquad, /* The second order low-pass filter is implemented as a biquad filter. */
}
hpf_config :: struct {
format: format,
channels: u32,
sampleRate: u32,
cutoffFrequency: f64,
order: u32, /* If set to 0, will be treated as a passthrough (no filtering will be applied). */
}
hpf :: struct {
format: format,
channels: u32,
sampleRate: u32,
hpf1Count: u32,
hpf2Count: u32,
hpf1: [1]hpf1,
hpf2: [MAX_FILTER_ORDER/2]hpf2,
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
hpf1_config_init :: proc(format: format, channels: u32, sampleRate: u32, cutoffFrequency: f64) -> hpf1_config ---
hpf2_config_init :: proc(format: format, channels: u32, sampleRate: u32, cutoffFrequency, q: f64) -> hpf2_config ---
hpf1_init :: proc(pConfig: ^hpf1_config, pHPF: ^hpf1) -> result ---
hpf1_reinit :: proc(pConfig: ^hpf1_config, pHPF: ^hpf1) -> result ---
hpf1_process_pcm_frames :: proc(pHPF: ^hpf1, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
hpf1_get_latency :: proc(pHPF: ^hpf1) -> u32 ---
hpf2_init :: proc(pConfig: ^hpf2_config, pHPF: ^hpf2) -> result ---
hpf2_reinit :: proc(pConfig: ^hpf2_config, pHPF: ^hpf2) -> result ---
hpf2_process_pcm_frames :: proc(pHPF: ^hpf2, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
hpf2_get_latency :: proc(pHPF: ^hpf2) -> u32 ---
hpf_config_init :: proc(format: format, channels: u32, sampleRate: u32, cutoffFrequency: f64, order: u32) -> hpf_config ---
hpf_init :: proc(pConfig: ^hpf_config, pHPF: ^hpf) -> result ---
hpf_reinit :: proc(pConfig: ^hpf_config, pHPF: ^hpf) -> result ---
hpf_process_pcm_frames :: proc(pHPF: ^hpf, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
hpf_get_latency :: proc(pHPF: ^hpf) -> u32 ---
}
/**************************************************************************************************************************************************************
Band-Pass Filtering
**************************************************************************************************************************************************************/
bpf2_config :: struct {
format: format,
channels: u32,
sampleRate: u32,
cutoffFrequency: f64,
q: f64,
}
bpf2 :: struct {
bq: biquad, /* The second order band-pass filter is implemented as a biquad filter. */
}
bpf_config :: struct {
format: format,
channels: u32,
sampleRate: u32,
cutoffFrequency: f64,
order: u32, /* If set to 0, will be treated as a passthrough (no filtering will be applied). */
}
bpf :: struct {
format: format,
channels: u32,
bpf2Count: u32,
bpf2: [MAX_FILTER_ORDER/2]bpf2,
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
bpf2_config_init :: proc(format: format, channels: u32, sampleRate: u32, cutoffFrequency: f64, q: f64) -> bpf2_config ---
bpf2_init :: proc(pConfig: ^bpf2_config, pBPF: ^bpf2) -> result ---
bpf2_reinit :: proc(pConfig: ^bpf2_config, pBPF: ^bpf2) -> result ---
bpf2_process_pcm_frames :: proc(pBPF: ^bpf2, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
bpf2_get_latency :: proc(pBPF: ^bpf2) -> u32 ---
bpf_config_init :: proc(format: format, channels: u32, sampleRate: u32, cutoffFrequency: f64, order: u32) -> bpf_config ---
bpf_init :: proc(pConfig: ^bpf_config, pBPF: ^bpf) -> result ---
bpf_reinit :: proc(pConfig: ^bpf_config, pBPF: ^bpf) -> result ---
bpf_process_pcm_frames :: proc(pBPF: ^bpf, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
bpf_get_latency :: proc(pBPF: ^bpf) -> u32 ---
}
/**************************************************************************************************************************************************************
Notching Filter
**************************************************************************************************************************************************************/
notch_config :: struct {
format: format,
channels: u32,
sampleRate: u32,
q: f64,
frequency: f64,
}
notch2_config :: notch_config
notch2 :: struct {
bq: biquad,
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
notch2_config_init :: proc(format: format, channels: u32, sampleRate: u32, q: f64, frequency: f64) -> notch2_config ---
notch2_init :: proc(pConfig: ^notch2_config, pFilter: ^notch2) -> result ---
notch2_reinit :: proc(pConfig: ^notch2_config, pFilter: ^notch2) -> result ---
notch2_process_pcm_frames :: proc(pFilter: ^notch2, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
notch2_get_latency :: proc(pFilter: ^notch2) -> u32 ---
}
/**************************************************************************************************************************************************************
Peaking EQ Filter
**************************************************************************************************************************************************************/
peak_config :: struct {
format: format,
channels: u32,
sampleRate: u32,
gainDB: f64,
q: f64,
frequency: f64,
}
peak2_config :: peak_config
peak2 :: struct {
bq: biquad,
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
peak2_config_init :: proc(format: format, channels: u32, sampleRate: u32, gainDB, q, frequency: f64) -> peak2_config ---
peak2_init :: proc(pConfig: ^peak2_config, pFilter: ^peak2) -> result ---
peak2_reinit :: proc(pConfig: ^peak2_config, pFilter: ^peak2) -> result ---
peak2_process_pcm_frames :: proc(pFilter: ^peak2, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
peak2_get_latency :: proc(pFilter: ^peak2) -> u32 ---
}
/**************************************************************************************************************************************************************
Low Shelf Filter
**************************************************************************************************************************************************************/
loshelf_config :: struct {
format: format,
channels: u32,
sampleRate: u32,
gainDB: f64,
shelfSlope: f64,
frequency: f64,
}
loshelf2_config :: loshelf_config
loshelf2 :: struct {
bq: biquad,
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
loshelf2_config_init :: proc(format: format, channels: u32, sampleRate: u32, gainDB, shelfSlope, frequency: f64) -> loshelf2_config ---
loshelf2_init :: proc(pConfig: ^loshelf2_config, pFilter: ^loshelf2) -> result ---
loshelf2_reinit :: proc(pConfig: ^loshelf2_config, pFilter: ^loshelf2) -> result ---
loshelf2_process_pcm_frames :: proc(pFilter: ^loshelf2, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
loshelf2_get_latency :: proc(pFilter: ^loshelf2) -> u32 ---
}
/**************************************************************************************************************************************************************
High Shelf Filter
**************************************************************************************************************************************************************/
hishelf_config :: struct {
format: format,
channels: u32,
sampleRate: u32,
gainDB: f64,
shelfSlope: f64,
frequency: f64,
}
hishelf2_config :: hishelf_config
hishelf2 :: struct {
bq: biquad,
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
hishelf2_config_init :: proc(format: format, channels: u32, sampleRate: u32, gainDB, shelfSlope, frequency: f64) -> hishelf2_config ---
hishelf2_init :: proc(pConfig: ^hishelf2_config, pFilter: ^hishelf2) -> result ---
hishelf2_reinit :: proc(pConfig: ^hishelf2_config, pFilter: ^hishelf2) -> result ---
hishelf2_process_pcm_frames :: proc(pFilter: ^hishelf2, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
hishelf2_get_latency :: proc(pFilter: ^hishelf2) -> u32 ---
}
+85
View File
@@ -0,0 +1,85 @@
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" }
waveform_type :: enum c.int {
sine,
square,
triangle,
sawtooth,
}
waveform_config :: struct {
format: format,
channels: u32,
sampleRate: u32,
type: waveform_type,
amplitude: f64,
frequency: f64,
}
waveform :: struct {
ds: data_source_base,
config: waveform_config,
advance: f64,
time: f64,
}
noise_type :: enum c. int {
white,
pink,
brownian,
}
noise_config :: struct {
format: format,
channels: u32,
type: noise_type,
seed: i32,
amplitude: f64,
duplicateChannels: b32,
}
noise :: struct {
ds: data_source_vtable,
config: noise_config,
lcg: lcg,
state: struct #raw_union {
pink: struct {
bin: [MAX_CHANNELS][16]f64,
accumulation: [MAX_CHANNELS]f64,
counter: [MAX_CHANNELS]u32,
},
brownian: struct {
accumulation: [MAX_CHANNELS]f64,
},
},
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
waveform_config_init :: proc(format: format, channels: u32, sampleRate: u32, type: waveform_type, amplitude: f64, frequency: f64) -> waveform_config ---
waveform_init :: proc(pConfig: ^waveform_config, pWaveform: ^waveform) -> result ---
waveform_uninit :: proc(pWaveform: ^waveform) ---
waveform_read_pcm_frames :: proc(pWaveform: ^waveform, pFramesOut: rawptr, frameCount: u64) -> u64 ---
waveform_seek_to_pcm_frame :: proc(pWaveform: ^waveform, frameIndex: u64) -> result ---
waveform_set_amplitude :: proc(pWaveform: ^waveform, amplitude: f64) -> result ---
waveform_set_frequency :: proc(pWaveform: ^waveform, frequency: f64) -> result ---
waveform_set_type :: proc(pWaveform: ^waveform, type: waveform_type) -> result ---
waveform_set_sample_rate :: proc(pWaveform: ^waveform, sampleRate: u32) -> result ---
noise_config_init :: proc(format: format, channels: u32, type: noise_type, seed: i32, amplitude: f64) -> noise_config ---
noise_init :: proc(pConfig: ^noise_config, pNoise: ^noise) -> result ---
noise_uninit :: proc(pNoise: ^noise) ---
noise_read_pcm_frames :: proc(pNoise: ^noise, pFramesOut: rawptr, frameCount: u64) -> u64 ---
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 ---
}
Binary file not shown.
+35
View File
@@ -0,0 +1,35 @@
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" }
MAX_LOG_CALLBACKS :: 4
log_callback_proc :: proc "c" (pUserData: rawptr, level: u32, pMessage: cstring)
log_callback :: struct {
onLog: log_callback_proc,
pUserData: rawptr,
}
log :: struct {
callbacks: [MAX_LOG_CALLBACKS]log_callback,
callbackCount: u32,
allocationCallbacks: allocation_callbacks, /* Need to store these persistently because log_postv() might need to allocate a buffer on the heap. */
lock: (struct {} when NO_THREADING else mutex),
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
log_callback_init :: proc(onLog: log_callback_proc, pUserData: rawptr) -> log_callback ---
log_init :: proc(pAllocationCallbacks: ^allocation_callbacks, pLog: ^log) -> result ---
log_uninit :: proc(pLog: ^log) ---
log_register_callback :: proc(pLog: ^log, callback: log_callback) -> result ---
log_unregister_callback :: proc(pLog: ^log, callback: log_callback) -> result ---
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 ---
}
+6
View File
@@ -0,0 +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
rm *.o
+8
View File
@@ -0,0 +1,8 @@
@echo off
if not exist "..\lib" mkdir ..\lib
cl -nologo -MT -TC -O2 -c miniaudio.c
lib -nologo miniaudio.obj -out:..\lib\miniaudio.lib
del *.obj
+9
View File
@@ -0,0 +1,9 @@
#define STB_VORBIS_HEADER_ONLY
#include "../../stb/src/stb_vorbis.c" /* Enables Vorbis decoding. */
#define MINIAUDIO_IMPLEMENTATION
#include "miniaudio.h"
/* stb_vorbis implementation must come after the implementation of miniaudio. */
#undef STB_VORBIS_HEADER_ONLY
#include "../../stb/src/stb_vorbis.c"
+70273
View File
File diff suppressed because it is too large Load Diff
+231
View File
@@ -0,0 +1,231 @@
package miniaudio
when ODIN_OS == "windows" { foreign import lib "lib/miniaudio.lib" }
when ODIN_OS == "linux" { foreign import lib "lib/miniaudio.a" }
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
/*
Adjust buffer size based on a scaling factor.
This just multiplies the base size by the scaling factor, making sure it's a size of at least 1.
*/
scale_buffer_size :: proc(baseBufferSize: u32, scale: f32) -> u32 ---
/*
Calculates a buffer size in milliseconds from the specified number of frames and sample rate.
*/
calculate_buffer_size_in_milliseconds_from_frames :: proc(bufferSizeInFrames: u32, sampleRate: u32) -> u32 ---
/*
Calculates a buffer size in frames from the specified number of milliseconds and sample rate.
*/
calculate_buffer_size_in_frames_from_milliseconds :: proc(bufferSizeInMilliseconds: u32, sampleRate: u32) -> u32 ---
/*
Copies PCM frames from one buffer to another.
*/
copy_pcm_frames :: proc(dst: rawptr, src: rawptr, frameCount: u64, format: format, channels: u32) ---
/*
Copies silent frames into the given buffer.
Remarks
-------
For all formats except `ma_format_u8`, the output buffer will be filled with 0. For `ma_format_u8` it will be filled with 128. The reason for this is that it
makes more sense for the purpose of mixing to initialize it to the center point.
*/
silence_pcm_frames :: proc(p: rawptr, frameCount: u64, format: format, channels: u32) ---
/*
Offsets a pointer by the specified number of PCM frames.
*/
offset_pcm_frames_ptr :: proc(p: rawptr, offsetInFrames: u64, format: format, channels: u32) -> rawptr ---
offset_pcm_frames_const_ptr :: proc(p: rawptr, offsetInFrames: u64, format: format, channels: u32) -> rawptr ---
/*
Clips f32 samples.
*/
clip_samples_f32 :: proc(p: [^]f32, sampleCount: u64) ---
/*
Helper for applying a volume factor to samples.
Note that the source and destination buffers can be the same, in which case it'll perform the operation in-place.
*/
copy_and_apply_volume_factor_u8 :: proc(pSamplesOut, pSamplesIn: [^]u8, sampleCount: u64, factor: f64) ---
copy_and_apply_volume_factor_s16 :: proc(pSamplesOut, pSamplesIn: [^]i16, sampleCount: u64, factor: f64) ---
copy_and_apply_volume_factor_s24 :: proc(pSamplesOut, pSamplesIn: rawptr, sampleCount: u64, factor: f64) ---
copy_and_apply_volume_factor_s32 :: proc(pSamplesOut, pSamplesIn: [^]i32, sampleCount: u64, factor: f64) ---
copy_and_apply_volume_factor_f32 :: proc(pSamplesOut, pSamplesIn: [^]f32, sampleCount: u64, factor: f64) ---
apply_volume_factor_u8 :: proc(pSamples: [^]u8, sampleCount: u64, factor: f32) ---
apply_volume_factor_s16 :: proc(pSamples: [^]i16, sampleCount: u64, factor: f32) ---
apply_volume_factor_s24 :: proc(pSamples: rawptr, sampleCount: u64, factor: f32) ---
apply_volume_factor_s32 :: proc(pSamples: [^]i32, sampleCount: u64, factor: f32) ---
apply_volume_factor_f32 :: proc(pSamples: [^]f32, sampleCount: u64, factor: f32) ---
copy_and_apply_volume_factor_pcm_frames_u8 :: proc(pPCMFramesOut, pPCMFramesIn: [^]u8, frameCount: u64, channels: u32, factor: f32) ---
copy_and_apply_volume_factor_pcm_frames_s16 :: proc(pPCMFramesOut, pPCMFramesIn: [^]i16, frameCount: u64, channels: u32, factor: f32) ---
copy_and_apply_volume_factor_pcm_frames_s24 :: proc(pPCMFramesOut, pPCMFramesIn: rawptr, frameCount: u64, channels: u32, factor: f32) ---
copy_and_apply_volume_factor_pcm_frames_s32 :: proc(pPCMFramesOut, pPCMFramesIn: [^]i32, frameCount: u64, channels: u32, factor: f32) ---
copy_and_apply_volume_factor_pcm_frames_f32 :: proc(pPCMFramesOut, pPCMFramesIn: [^]f32, frameCount: u64, channels: u32, factor: f32) ---
copy_and_apply_volume_factor_pcm_frames :: proc(pFramesOut, pFramesIn: rawptr, frameCount: u64, format: format, channels: u32, factor: f32) ---
apply_volume_factor_pcm_frames_u8 :: proc(pFrames: [^]u8, frameCount: u64, channels: u32, factor: f32) ---
apply_volume_factor_pcm_frames_s16 :: proc(pFrames: [^]i16, frameCount: u64, channels: u32, factor: f32) ---
apply_volume_factor_pcm_frames_s24 :: proc(pFrames: rawptr, frameCount: u64, channels: u32, factor: f32) ---
apply_volume_factor_pcm_frames_s32 :: proc(pFrames: [^]i32, frameCount: u64, channels: u32, factor: f32) ---
apply_volume_factor_pcm_frames_f32 :: proc(pFrames: [^]f32, frameCount: u64, channels: u32, factor: f32) ---
apply_volume_factor_pcm_frames :: proc(pFrames: rawptr, frameCount: u64, format: format, channels: u32, factor: f32) ---
/*
Helper for converting a linear factor to gain in decibels.
*/
factor_to_gain_db :: proc(factor: f32) -> f32 ---
/*
Helper for converting gain in decibels to a linear factor.
*/
gain_db_to_factor :: proc(gain: f32) -> f32 ---
}
zero_pcm_frames :: #force_inline proc "c" (p: rawptr, frameCount: u64, format: format, channels: u32) {
silence_pcm_frames(p, frameCount, format, channels)
}
offset_pcm_frames_ptr_f32 :: #force_inline proc "c" (p: [^]f32, offsetInFrames: u64, channels: u32) -> [^]f32 {
return cast([^]f32)offset_pcm_frames_ptr(p, offsetInFrames, .f32, channels)
}
offset_pcm_frames_const_ptr_f32 :: #force_inline proc "c" (p: [^]f32, offsetInFrames: u64, channels: u32) -> [^]f32 {
return cast([^]f32)offset_pcm_frames_ptr(p, offsetInFrames, .f32, channels)
}
clip_pcm_frames_f32 :: #force_inline proc "c" (p: [^]f32, frameCount: u64, channels: u32) {
clip_samples_f32(p, frameCount*u64(channels))
}
data_source :: struct {}
data_source_vtable :: struct {
onRead: proc "c" (pDataSource: ^data_source, pFramesOut: rawptr, frameCount: u64, pFramesRead: ^u64) -> result,
onSeek: proc "c" (pDataSource: ^data_source, frameIndex: u64) -> result,
onMap: proc "c" (pDataSource: ^data_source, ppFramesOut: ^rawptr, pFrameCount: ^u64) -> result, /* Returns MA_AT_END if the end has been reached. This should be considered successful. */
onUnmap: proc "c" (pDataSource: ^data_source, frameCount: u64) -> result,
onGetDataFormat: proc "c" (pDataSource: ^data_source, pFormat: ^format, pChannels: ^u32, pSampleRate: ^u32) -> result,
onGetCursor: proc "c" (pDataSource: ^data_source, pCursor: ^u64) -> result,
onGetLength: proc "c" (pDataSource: ^data_source, pLength: ^u64) -> result,
}
data_source_callbacks :: data_source_vtable /* TODO: Remove ma_data_source_callbacks in version 0.11. */
data_source_get_next_proc :: proc "c" (pDataSource: ^data_source) -> ^data_source
data_source_config :: struct {
vtable: ^data_source_vtable, /* Can be null, which is useful for proxies. */
}
data_source_base :: struct {
cb: data_source_callbacks, /* TODO: Remove this. */
/* Variables below are placeholder and not yet used. */
vtable: ^data_source_vtable,
rangeBegInFrames: u64,
rangeEndInFrames: u64, /* Set to -1 for unranged (default). */
loopBegInFrames: u64, /* Relative to rangeBegInFrames. */
loopEndInFrames: u64, /* Relative to rangeBegInFrames. Set to -1 for the end of the range. */
pCurrent: ^data_source, /* When non-NULL, the data source being initialized will act as a proxy and will route all operations to pCurrent. Used in conjunction with pNext/onGetNext for seamless chaining. */
pNext: ^data_source, /* When set to NULL, onGetNext will be used. */
onGetNext: ^data_source_get_next_proc, /* Will be used when pNext is NULL. If both are NULL, no next will be used. */
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
ma_data_source_config_init :: proc() -> data_source_config ---
data_source_init :: proc(pConfig: ^data_source_config, pDataSource: ^data_source) -> result ---
data_source_uninit :: proc(pDataSource: ^data_source) ---
data_source_read_pcm_frames :: proc(pDataSource: ^data_source, pFramesOut: rawptr, frameCount: u64, pFramesRead: ^u64, loop: b32) -> result --- /* Must support pFramesOut = NULL in which case a forward seek should be performed. */
data_source_seek_pcm_frames :: proc(pDataSource: ^data_source, frameCount: u64, pFramesSeeked: ^u64, loop: b32) -> result --- /* Can only seek forward. Equivalent to ma_data_source_read_pcm_frames(pDataSource, NULL, frameCount); */
data_source_seek_to_pcm_frame :: proc(pDataSource: ^data_source, frameIndex: u64) -> result ---
data_source_map :: proc(pDataSource: ^data_source, ppFramesOut: ^rawptr, pFrameCount: ^u64) -> result --- /* Returns MA_NOT_IMPLEMENTED if mapping is not supported. */
data_source_unmap :: proc(pDataSource: ^data_source, frameCount: u64) -> result --- /* Returns MA_AT_END if the end has been reached. */
data_source_get_data_format :: proc(pDataSource: ^data_source, pFormat: ^format, pChannels: ^u32, pSampleRate: ^u32) -> result ---
data_source_get_cursor_in_pcm_frames :: proc(pDataSource: ^data_source, pCursor: ^u64) -> result ---
data_source_get_length_in_pcm_frames :: proc(pDataSource: ^data_source, pLength: ^u64) -> result --- /* Returns MA_NOT_IMPLEMENTED if the length is unknown or cannot be determined. Decoders can return this. */
// #if defined(MA_EXPERIMENTAL__DATA_LOOPING_AND_CHAINING)
// MA_API ma_result ma_data_source_set_range_in_pcm_frames(ma_data_source* pDataSource, ma_uint64 rangeBegInFrames, ma_uint64 rangeEndInFrames);
// MA_API void ma_data_source_get_range_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pRangeBegInFrames, ma_uint64* pRangeEndInFrames);
// MA_API ma_result ma_data_source_set_loop_point_in_pcm_frames(ma_data_source* pDataSource, ma_uint64 loopBegInFrames, ma_uint64 loopEndInFrames);
// MA_API void ma_data_source_get_loop_point_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pLoopBegInFrames, ma_uint64* pLoopEndInFrames);
// MA_API ma_result ma_data_source_set_current(ma_data_source* pDataSource, ma_data_source* pCurrentDataSource);
// MA_API ma_data_source* ma_data_source_get_current(ma_data_source* pDataSource);
// MA_API ma_result ma_data_source_set_next(ma_data_source* pDataSource, ma_data_source* pNextDataSource);
// MA_API ma_data_source* ma_data_source_get_next(ma_data_source* pDataSource);
// MA_API ma_result ma_data_source_set_next_callback(ma_data_source* pDataSource, ma_data_source_get_next_proc onGetNext);
// MA_API ma_data_source_get_next_proc ma_data_source_get_next_callback(ma_data_source* pDataSource);
// #endif
}
audio_buffer_ref :: struct {
ds: data_source_base,
format: format,
channels: u32,
cursor: u64,
sizeInFrames: u64,
pData: rawptr,
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
audio_buffer_ref_init :: proc(format: format, channels: u32, pData: rawptr, sizeInFrames: u64, pAudioBufferRef: ^audio_buffer_ref) -> result ---
audio_buffer_ref_uninit :: proc(pAudioBufferRef: ^audio_buffer_ref) ---
audio_buffer_ref_set_data :: proc(pAudioBufferRef: ^audio_buffer_ref, pData: rawptr, sizeInFrames: u64) -> result ---
audio_buffer_ref_read_pcm_frames :: proc(pAudioBufferRef: ^audio_buffer_ref, pFramesOut: rawptr, frameCount: u64, loop: b32) -> u64 ---
audio_buffer_ref_seek_to_pcm_frame :: proc(pAudioBufferRef: ^audio_buffer_ref, frameIndex: u64) -> result ---
audio_buffer_ref_map :: proc(pAudioBufferRef: ^audio_buffer_ref, ppFramesOut: ^rawptr, pFrameCount: ^u64) -> result ---
audio_buffer_ref_unmap :: proc(pAudioBufferRef: ^audio_buffer_ref, frameCount: u64) -> result --- /* Returns MA_AT_END if the end has been reached. This should be considered successful. */
audio_buffer_ref_at_end :: proc(pAudioBufferRef: ^audio_buffer_ref) -> b32 ---
audio_buffer_ref_get_cursor_in_pcm_frames :: proc(pAudioBufferRef: ^audio_buffer_ref, pCursor: ^u64) -> result ---
audio_buffer_ref_get_length_in_pcm_frames :: proc(pAudioBufferRef: ^audio_buffer_ref, pLength: ^u64) -> result ---
audio_buffer_ref_get_available_frames :: proc(pAudioBufferRef: ^audio_buffer_ref, pAvailableFrames: ^u64) -> result ---
}
audio_buffer_config :: struct {
format: format,
channels: u32,
sizeInFrames: u64,
pData: rawptr, /* If set to NULL, will allocate a block of memory for you. */
allocationCallbacks: allocation_callbacks,
}
audio_buffer :: struct {
ref: audio_buffer_ref,
allocationCallbacks: allocation_callbacks,
ownsData: b32, /* Used to control whether or not miniaudio owns the data buffer. If set to true, pData will be freed in ma_audio_buffer_uninit(). */
_pExtraData: [1]u8, /* For allocating a buffer with the memory located directly after the other memory of the structure. */
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
audio_buffer_config_init :: proc(format: format, channels: u32, sizeInFrames: u64, pData: rawptr, pAllocationCallbacks: ^allocation_callbacks) -> audio_buffer_config ---
audio_buffer_init :: proc(pConfig: ^audio_buffer_config, pAudioBuffer: ^audio_buffer) -> result ---
audio_buffer_init_copy :: proc(pConfig: ^audio_buffer_config, pAudioBuffer: ^audio_buffer) -> result ---
audio_buffer_alloc_and_init :: proc(pConfig: ^audio_buffer_config, ppAudioBuffer: ^^audio_buffer) -> result --- /* Always copies the data. Doesn't make sense to use this otherwise. Use ma_audio_buffer_uninit_and_free() to uninit. */
audio_buffer_uninit :: proc(pAudioBuffer: ^audio_buffer) ---
audio_buffer_uninit_and_free :: proc(pAudioBuffer: ^audio_buffer) ---
audio_buffer_read_pcm_frames :: proc(pAudioBuffer: ^audio_buffer, pFramesOut: rawptr, frameCount: u64, loop: b32) -> u64 ---
audio_buffer_seek_to_pcm_frame :: proc(pAudioBuffer: ^audio_buffer, frameIndex: u64) -> result ---
audio_buffer_map :: proc(pAudioBuffer: ^audio_buffer, ppFramesOut: ^rawptr, pFrameCount: ^u64) -> result ---
audio_buffer_unmap :: proc(pAudioBuffer: ^audio_buffer, frameCount: u64) -> result --- /* Returns MA_AT_END if the end has been reached. This should be considered successful. */
audio_buffer_at_end :: proc(pAudioBuffer: ^audio_buffer) -> b32 ---
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 ---
}
+79
View File
@@ -0,0 +1,79 @@
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" }
/************************************************************************************************************************************************************
VFS
===
The VFS object (virtual file system) is what's used to customize file access. This is useful in cases where stdio FILE* based APIs may not be entirely
appropriate for a given situation.
************************************************************************************************************************************************************/
vfs :: struct {}
vfs_file :: distinct handle
OPEN_MODE_READ :: 0x00000001
OPEN_MODE_WRITE :: 0x00000002
seek_origin :: enum c.int {
start,
current,
end, /* Not used by decoders. */
}
file_info :: struct {
sizeInBytes: u64,
}
vfs_callbacks :: struct {
onOpen: proc "c" (pVFS: ^vfs, pFilePath: cstring, openMode: u32, pFile: ^vfs_file) -> result,
onOpenW: proc "c" (pVFS: ^vfs, pFilePath: [^]c.wchar_t, openMode: u32, pFile: ^vfs_file) -> result,
onClose: proc "c" (pVFS: ^vfs, file: vfs_file) -> result,
onRead: proc "c" (pVFS: ^vfs, file: vfs_file, pDst: rawptr, sizeInBytes: c.size_t, pBytesRead: ^c.size_t) -> result,
onWrite: proc "c" (pVFS: ^vfs, file: vfs_file, pSrc: rawptr, sizeInBytes: c.size_t, pBytesWritten: ^c.size_t) -> result,
onSeek: proc "c" (pVFS: ^vfs, file: vfs_file, offset: i64, origin: seek_origin) -> result,
onTell: proc "c" (pVFS: ^vfs, file: vfs_file, pCursor: ^i64) -> result,
onInfo: proc "c" (pVFS: ^vfs, file: vfs_file, pInfo: ^file_info) -> result,
}
default_vfs :: struct {
cb: vfs_callbacks,
allocationCallbacks: allocation_callbacks, /* Only used for the wchar_t version of open() on non-Windows platforms. */
}
ma_read_proc :: proc "c" (pUserData: rawptr, pBufferOut: rawptr, bytesToRead: c.size_t, pBytesRead: ^c.size_t) -> result
ma_seek_proc :: proc "c" (pUserData: rawptr, offset: i64, origin: seek_origin) -> result
ma_tell_proc :: proc "c" (pUserData: rawptr, pCursor: ^i64) -> result
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
vfs_open :: proc(pVFS: ^vfs, pFilePath: cstring, openMode: u32, pFile: ^vfs_file) -> result ---
vfs_open_w :: proc(pVFS: ^vfs, pFilePath: [^]c.wchar_t, openMode: u32, pFile: ^vfs_file) -> result ---
vfs_close :: proc(pVFS: ^vfs, file: vfs_file) -> result ---
vfs_read :: proc(pVFS: ^vfs, file: vfs_file, pDst: rawptr, sizeInBytes: c.size_t, pBytesRead: ^c.size_t) -> result ---
vfs_write :: proc(pVFS: ^vfs, file: vfs_file, pSrc: rawptr, sizeInBytes: c.size_t, pBytesWritten: ^c.size_t) -> result ---
vfs_seek :: proc(pVFS: ^vfs, file: vfs_file, offset: i64, origin: seek_origin) -> result ---
vfs_tell :: proc(pVFS: ^vfs, file: vfs_file, pCursor: ^i64) -> result ---
vfs_info :: proc(pVFS: ^vfs, file: vfs_file, pInfo: ^file_info) -> result ---
vfs_open_and_read_file :: proc(pVFS: ^vfs, pFilePath: cstring, ppData: ^rawptr, pSize: ^c.size_t, pAllocationCallbacks: ^allocation_callbacks) -> result ---
default_vfs_init :: proc(pVFS: ^default_vfs, pAllocationCallbacks: ^allocation_callbacks) -> result ---
}
resource_format :: enum c.int {
wav,
}
encoding_format :: enum c.int {
unknown = 0,
wav,
flac,
mp3,
vorbis,
}
+8 -2
View File
@@ -18,7 +18,13 @@ when ODIN_OS == "windows" {
"system:Shell32.lib",
}
}
when ODIN_OS == "linux" { foreign import lib "linux/libraylib.a" }
when ODIN_OS == "linux" {
foreign import lib {
"linux/libraylib.a",
"system:dl",
"system:pthread",
}
}
when ODIN_OS == "darwin" { foreign import lib "macos/libraylib.a" }
VERSION :: "3.7"
@@ -1393,4 +1399,4 @@ foreign lib {
SetAudioStreamVolume :: proc(stream: AudioStream, volume: f32) --- // Set volume for audio stream (1.0 is max level)
SetAudioStreamPitch :: proc(stream: AudioStream, pitch: f32) --- // Set pitch for audio stream (1.0 is base level)
SetAudioStreamBufferSizeDefault :: proc(size: c.int) --- // Default size for new audio streams
}
}
+206
View File
@@ -0,0 +1,206 @@
package stb_easy_font
// Source port of stb_easy_font.h
import "core:math"
color :: struct {
c: [4]u8,
}
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..<len(segs) {
n := segs[i] & 7
x += f32((segs[i]>>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
}
}
}
return offset
}
@(private)
_spacing_val := f32(0)
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
text := text
start_x := x
offset := 0
for len(text) != 0 && offset < len(vertex_buffer) {
c := text[0]
if c == '\n' {
y += 12
x = start_x
} else {
advance := charinfo[c-32].advance
y_ch := y+1 if advance & 16 != 0 else y
h_seg := charinfo[c-32].h_seg
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
}
text = text[1:]
}
return offset/64
}
width :: proc(text: string) -> int {
length := f32(0)
max_length := f32(0)
for i in 0..<len(text) {
c := text[i]
if c == '\n' {
if length > max_length {
max_length = length
}
length = 0
} else {
length += f32(charinfo[c-32].advance & 15)
length += _spacing_val
}
}
if length > max_length {
max_length = length
}
return int(math.ceil(max_length))
}
height :: proc(text: string) -> int {
y := f32(0)
nonempty_line := false
for i in 0..<len(text) {
c := text[i]
if c == '\n' {
y += 12
nonempty_line = false
} else {
nonempty_line = true
}
}
return int(math.ceil(y + 12 if nonempty_line else 0))
}
info_struct :: struct{
advance: u8,
h_seg: u8,
v_seg: u8,
}
@(private)
charinfo := [96]info_struct{
{ 6, 0, 0 }, { 3, 0, 0 }, { 5, 1, 1 }, { 7, 1, 4 },
{ 7, 3, 7 }, { 7, 6, 12 }, { 7, 8, 19 }, { 4, 16, 21 },
{ 4, 17, 22 }, { 4, 19, 23 }, { 23, 21, 24 }, { 23, 22, 31 },
{ 20, 23, 34 }, { 22, 23, 36 }, { 19, 24, 36 }, { 21, 25, 36 },
{ 6, 25, 39 }, { 6, 27, 43 }, { 6, 28, 45 }, { 6, 30, 49 },
{ 6, 33, 53 }, { 6, 34, 57 }, { 6, 40, 58 }, { 6, 46, 59 },
{ 6, 47, 62 }, { 6, 55, 64 }, { 19, 57, 68 }, { 20, 59, 68 },
{ 21, 61, 69 }, { 22, 66, 69 }, { 21, 68, 69 }, { 7, 73, 69 },
{ 9, 75, 74 }, { 6, 78, 81 }, { 6, 80, 85 }, { 6, 83, 90 },
{ 6, 85, 91 }, { 6, 87, 95 }, { 6, 90, 96 }, { 7, 92, 97 },
{ 6, 96,102 }, { 5, 97,106 }, { 6, 99,107 }, { 6,100,110 },
{ 6,100,115 }, { 7,101,116 }, { 6,101,121 }, { 6,101,125 },
{ 6,102,129 }, { 7,103,133 }, { 6,104,140 }, { 6,105,145 },
{ 7,107,149 }, { 6,108,151 }, { 7,109,155 }, { 7,109,160 },
{ 7,109,165 }, { 7,118,167 }, { 6,118,172 }, { 4,120,176 },
{ 6,122,177 }, { 4,122,181 }, { 23,124,182 }, { 22,129,182 },
{ 4,130,182 }, { 22,131,183 }, { 6,133,187 }, { 22,135,191 },
{ 6,137,192 }, { 22,139,196 }, { 6,144,197 }, { 22,147,198 },
{ 6,150,202 }, { 19,151,206 }, { 21,152,207 }, { 6,155,209 },
{ 3,160,210 }, { 23,160,211 }, { 22,164,216 }, { 22,165,220 },
{ 22,167,224 }, { 22,169,228 }, { 21,171,232 }, { 21,173,233 },
{ 5,178,233 }, { 22,179,234 }, { 23,180,238 }, { 23,180,243 },
{ 23,180,248 }, { 22,189,248 }, { 22,191,252 }, { 5,196,252 },
{ 3,203,252 }, { 5,203,253 }, { 22,210,253 }, { 0,214,253 },
}
@(private)
hseg := [214]u8{
97,37,69,84,28,51,2,18,10,49,98,41,65,25,81,105,33,9,97,1,97,37,37,36,
81,10,98,107,3,100,3,99,58,51,4,99,58,8,73,81,10,50,98,8,73,81,4,10,50,
98,8,25,33,65,81,10,50,17,65,97,25,33,25,49,9,65,20,68,1,65,25,49,41,
11,105,13,101,76,10,50,10,50,98,11,99,10,98,11,50,99,11,50,11,99,8,57,
58,3,99,99,107,10,10,11,10,99,11,5,100,41,65,57,41,65,9,17,81,97,3,107,
9,97,1,97,33,25,9,25,41,100,41,26,82,42,98,27,83,42,98,26,51,82,8,41,
35,8,10,26,82,114,42,1,114,8,9,73,57,81,41,97,18,8,8,25,26,26,82,26,82,
26,82,41,25,33,82,26,49,73,35,90,17,81,41,65,57,41,65,25,81,90,114,20,
84,73,57,41,49,25,33,65,81,9,97,1,97,25,33,65,81,57,33,25,41,25,
}
@(private)
vseg := [253]u8{
4,2,8,10,15,8,15,33,8,15,8,73,82,73,57,41,82,10,82,18,66,10,21,29,1,65,
27,8,27,9,65,8,10,50,97,74,66,42,10,21,57,41,29,25,14,81,73,57,26,8,8,
26,66,3,8,8,15,19,21,90,58,26,18,66,18,105,89,28,74,17,8,73,57,26,21,
8,42,41,42,8,28,22,8,8,30,7,8,8,26,66,21,7,8,8,29,7,7,21,8,8,8,59,7,8,
8,15,29,8,8,14,7,57,43,10,82,7,7,25,42,25,15,7,25,41,15,21,105,105,29,
7,57,57,26,21,105,73,97,89,28,97,7,57,58,26,82,18,57,57,74,8,30,6,8,8,
14,3,58,90,58,11,7,74,43,74,15,2,82,2,42,75,42,10,67,57,41,10,7,2,42,
74,106,15,2,35,8,8,29,7,8,8,59,35,51,8,8,15,35,30,35,8,8,30,7,8,8,60,
36,8,45,7,7,36,8,43,8,44,21,8,8,44,35,8,8,43,23,8,8,43,35,8,8,31,21,15,
20,8,8,28,18,58,89,58,26,21,89,73,89,29,20,8,8,30,7,
}
/*
------------------------------------------------------------------------------
This software is available under 2 licenses -- choose whichever you prefer.
------------------------------------------------------------------------------
ALTERNATIVE A - MIT License
Copyright (c) 2017 Sean Barrett
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
------------------------------------------------------------------------------
ALTERNATIVE B - Public Domain (www.unlicense.org)
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------
*/
+107
View File
@@ -0,0 +1,107 @@
package stb_image
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" }
#assert(size_of(b32) == size_of(c.int))
//
// load image by filename, open file, or memory buffer
//
Io_Callbacks :: struct {
read: proc "c" (user: rawptr, data: [^]byte, size: c.int) -> c.int, // fill 'data' with 'size' u8s. return number of u8s actually read
skip: proc "c" (user: rawptr, n: c.int), // skip the next 'n' u8s, or 'unget' the last -n u8s if negative
eof: proc "c" (user: rawptr) -> c.int, // returns nonzero if we are at end of file/data
}
@(default_calling_convention="c", link_prefix="stbi_")
foreign stbi {
////////////////////////////////////
//
// 8-bits-per-channel interface
//
load :: proc(filename: cstring, x, y, channels_in_file: ^c.int, desired_channels: c.int) -> [^]byte ---
load_from_file :: proc(f: ^c.FILE, x, y, channels_in_file: ^c.int, desired_channels: c.int) -> [^]byte ---
load_from_memory :: proc(buffer: [^]byte, len: c.int, x, y, channels_in_file: ^c.int, desired_channels: c.int) -> [^]byte ---
load_from_callbacks :: proc(clbk: ^Io_Callbacks, user: rawptr, x, y, channels_in_file: ^c.int, desired_channels: c.int) -> [^]byte ---
load_gif_from_memory :: proc(buffer: [^]byte, len: c.int, delays: ^[^]c.int, x, y, z, comp: ^c.int, req_comp: c.int) -> [^]byte ---
////////////////////////////////////
//
// 16-bits-per-channel interface
//
load_16 :: proc(filename: cstring, x, y, channels_in_file: ^c.int, desired_channels: c.int) -> [^]u16 ---
load_16_from_file :: proc(f: ^c.FILE, x, y, channels_in_file: ^c.int, desired_channels: c.int) -> [^]u16 ---
load_16_from_memory :: proc(buffer: [^]byte, len: c.int, x, y, channels_in_file: ^c.int, desired_channels: c.int) -> [^]u16 ---
load_16_from_callbacks :: proc(clbk: ^Io_Callbacks, x, y, channels_in_file: ^c.int, desired_channels: c.int) -> [^]u16 ---
////////////////////////////////////
//
// float-per-channel interface
//
loadf :: proc(filename: cstring, x, y, channels_in_file: ^c.int, desired_channels: c.int) -> [^]f32 ---
loadf_from_file :: proc(f: ^c.FILE, x, y, channels_in_file: ^c.int, desired_channels: c.int) -> [^]f32 ---
loadf_from_memory :: proc(buffer: [^]byte, len: c.int, x, y, channels_in_file: ^c.int, desired_channels: c.int) -> [^]f32 ---
loadf_from_callbacks :: proc(clbk: ^Io_Callbacks, user: rawptr, x, y, channels_in_file: ^c.int, desired_channels: c.int) -> [^]f32 ---
hdr_to_ldr_gamma :: proc(gamma: f32) ---
hdr_to_ldr_scale :: proc(scale: f32) ---
ldr_to_hdr_gamma :: proc(gamma: f32) ---
ldr_to_hdr_scale :: proc(scale: f32) ---
is_hdr_from_callbacks :: proc(clbk: ^Io_Callbacks, user: rawptr) -> c.int ---
is_hdr_from_memory :: proc(buffer: [^]byte, len: c.int) -> c.int ---
is_hdr :: proc(filename: cstring) -> c.int ---
is_hdr_from_file :: proc(f: ^c.FILE) -> c.int ---
// get a VERY brief reason for failure
// NOT THREADSAFE
failure_reason :: proc() -> cstring ---
// free the loaded image -- this is just free()
image_free :: proc(retval_from_load: rawptr) ---
// get image dimensions & components without fully decoding
info :: proc(filename: cstring, x, y, comp: ^c.int) -> c.int ---
info_from_file :: proc(f: ^c.FILE, x, y, comp: ^c.int) -> c.int ---
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 ---
// 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
// unpremultiplication. results are undefined if the unpremultiply overflow.
set_unpremultiply_on_load :: proc (flag_true_if_should_unpremultiply: c.int) ---
// indicate whether we should process iphone images back to canonical format,
// or just pass them through "as-is"
convert_iphone_png_to_rgb :: proc(flag_true_if_should_convert: c.int) ---
// flip the image vertically, so the first pixel in the output array is the bottom left
set_flip_vertically_on_load :: proc(flag_true_if_should_flip: c.int) ---
// as above, but only applies to images loaded on the thread that calls the function
// this function is only available if your compiler supports thread-local variables;
// calling it will fail to link if your compiler doesn't
set_unpremultiply_on_load_thread :: proc(flag_true_if_should_unpremultiply: b32) ---
convert_iphone_png_to_rgb_thread :: proc(flag_true_if_should_convert: b32) ---
set_flip_vertically_on_load_thread :: proc(flag_true_if_should_flip: b32) ---
// ZLIB client - used by PNG, available for other purposes
zlib_decode_malloc_guesssize :: proc(buffer: [^]byte, len: c.int, initial_size: c.int, outlen: ^c.int) -> [^]byte ---
zlib_decode_malloc_guesssize_headerflag :: proc(buffer: [^]byte, len: c.int, initial_size: c.int, outlen: ^c.int, parse_header: b32) -> [^]byte ---
zlib_decode_malloc :: proc(buffer: [^]byte, len: c.int, outlen: ^c.int) -> [^]byte ---
zlib_decode_buffer :: proc(obuffer: [^]byte, olen: c.int, ibuffer: [^]byte, ilen: c.int) -> c.int ---
zlib_decode_noheader_malloc :: proc(buffer: [^]byte, len: c.int, outlen: ^c.int) -> [^]byte ---
zlib_decode_noheader_buffer :: proc(obuffer: [^]byte, olen: c.int, ibuffer: [^]byte, ilen: c.int) -> c.int ---
}
+187
View File
@@ -0,0 +1,187 @@
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" }
//////////////////////////////////////////////////////////////////////////////
//
// Easy-to-use API:
//
// * "input pixels" points to an array of image data with 'num_channels' channels (e.g. RGB=3, RGBA=4)
// * input_w is input image width (x-axis), input_h is input image height (y-axis)
// * stride is the offset between successive rows of image data in memory, in bytes. you can
// specify 0 to mean packed continuously in memory
// * alpha channel is treated identically to other channels.
// * colorspace is linear or sRGB as specified by function name
// * returned result is 1 for success or 0 in case of an error.
// * Memory required grows approximately linearly with input and output size, but with
// discontinuities at input_w == output_w and input_h == output_h.
// * These functions use a "default" resampling filter defined at compile time. To change the filter,
// you can change the compile-time defaults by #defining STBIR_DEFAULT_FILTER_UPSAMPLE
// and STBIR_DEFAULT_FILTER_DOWNSAMPLE, or you can use the medium-complexity API.
@(default_calling_convention="c", link_prefix="stbir_")
foreign lib {
resize_uint8 :: proc(input_pixels: [^]u8, input_w, input_h, input_stride_in_bytes: c.int,
output_pixels: [^]u8, output_w, output_h, output_stride_in_bytes: c.int,
num_channels: c.int) -> c.int ---
resize_float :: proc(input_pixels: [^]f32, input_w, input_h, input_stride_in_bytes: c.int,
output_pixels: [^]f32, output_w, output_h, output_stride_in_bytes: c.int,
num_channels: c.int) -> c.int ---
}
// The following functions interpret image data as gamma-corrected sRGB.
// Specify ALPHA_CHANNEL_NONE if you have no alpha channel,
// or otherwise provide the index of the alpha channel. Flags value
// of 0 will probably do the right thing if you're not sure what
// the flags mean.
ALPHA_CHANNEL_NONE :: -1
// Set this flag if your texture has premultiplied alpha. Otherwise, stbir will
// use alpha-weighted resampling (effectively premultiplying, resampling,
// then unpremultiplying).
FLAG_ALPHA_PREMULTIPLIED :: (1 << 0)
// The specified alpha channel should be handled as gamma-corrected value even
// when doing sRGB operations.
FLAG_ALPHA_USES_COLORSPACE :: (1 << 1)
edge :: enum c.int {
CLAMP = 1,
REFLECT = 2,
WRAP = 3,
ZERO = 4,
}
@(default_calling_convention="c", link_prefix="stbir_")
foreign lib {
resize_uint8_srgb :: proc(input_pixels: [^]u8, input_w, input_h, input_stride_in_bytes: c.int,
output_pixels: [^]u8, output_w, output_h, output_stride_in_bytes: c.int,
num_channels: c.int, alpha_channel: b32, flags: c.int) -> c.int ---
// This function adds the ability to specify how requests to sample off the edge of the image are handled.
resize_uint8_srgb_edgemode :: proc(input_pixels: [^]u8, input_w, input_h, input_stride_in_bytes: c.int,
output_pixels: [^]u8, output_w, output_h, output_stride_in_bytes: c.int,
num_channels: c.int, alpha_channel: b32, flags: c.int,
edge_wrap_mode: edge) -> c.int ---
}
//////////////////////////////////////////////////////////////////////////////
//
// Medium-complexity API
//
// This extends the easy-to-use API as follows:
//
// * Alpha-channel can be processed separately
// * If alpha_channel is not STBIR_ALPHA_CHANNEL_NONE
// * Alpha channel will not be gamma corrected (unless flags&STBIR_FLAG_GAMMA_CORRECT)
// * Filters will be weighted by alpha channel (unless flags&STBIR_FLAG_ALPHA_PREMULTIPLIED)
// * Filter can be selected explicitly
// * uint16 image type
// * sRGB colorspace available for all types
// * context parameter for passing to STBIR_MALLOC
filter :: enum c.int {
DEFAULT = 0, // use same filter type that easy-to-use API chooses
BOX = 1, // A trapezoid w/1-pixel wide ramps, same result as box for integer scale ratios
TRIANGLE = 2, // On upsampling, produces same results as bilinear texture filtering
CUBICBSPLINE = 3, // The cubic b-spline (aka Mitchell-Netrevalli with B=1,C=0), gaussian-esque
CATMULLROM = 4, // An interpolating cubic spline
MITCHELL = 5, // Mitchell-Netrevalli filter with B=1/3, C=1/3
}
colorspace :: enum c.int {
LINEAR,
SRGB,
MAX_COLORSPACES,
}
@(default_calling_convention="c", link_prefix="stbir_")
foreign lib {
// The following functions are all identical except for the type of the image data
resize_uint8_generic :: proc(input_pixels: [^]u8, input_w, input_h, input_stride_in_bytes: c.int,
output_pixels: [^]u8, output_w, output_h, output_stride_in_bytes: c.int,
num_channels: c.int, alpha_channel: b32, flags: c.int,
edge_wrap_mode: edge, filter: filter, space: colorspace,
alloc_context: rawptr) -> c.int ---
resize_uint16_generic :: proc(input_pixels: [^]u16, input_w, input_h, input_stride_in_bytes: c.int,
output_pixels: [^]u16, output_w, output_h, output_stride_in_bytes: c.int,
num_channels: c.int, alpha_channel: b32, flags: c.int,
edge_wrap_mode: edge, filter: filter, space: colorspace,
alloc_context: rawptr) -> c.int ---
resize_float_generic :: proc(input_pixels: [^]f32, input_w, input_h, input_stride_in_bytes: c.int,
output_pixels: [^]f32, output_w, output_h, output_stride_in_bytes: c.int,
num_channels: c.int, alpha_channel: b32, flags: c.int,
edge_wrap_mode: edge, filter: filter, space: colorspace,
alloc_context: rawptr) -> c.int ---
}
//////////////////////////////////////////////////////////////////////////////
//
// Full-complexity API
//
// This extends the medium API as follows:
//
// * uint32 image type
// * not typesafe
// * separate filter types for each axis
// * separate edge modes for each axis
// * can specify scale explicitly for subpixel correctness
// * can specify image source tile using texture coordinates
datatype :: enum c.int {
UINT8,
UINT16,
UINT32,
FLOAT,
MAX_TYPES,
}
@(default_calling_convention="c", link_prefix="stbir_")
foreign lib {
// (s0, t0) & (s1, t1) are the top-left and bottom right corner (uv addressing style: [0, 1]x[0, 1]) of a region of the input image to use.
resize :: proc(input_pixels: rawptr, input_w, input_h, input_stride_in_bytes: c.int,
output_pixels: rawptr, output_w, output_h, output_stride_in_bytes: c.int,
datatype: datatype,
num_channels: c.int, alpha_channel: b32, flags: c.int,
edge_mode_horizontal, edge_mode_vertical: edge,
filter_horizontal, filter_vertical: filter,
space: colorspace, alloc_context: rawptr) -> c.int ---
resize_subpixel :: proc(input_pixels: rawptr, input_w, input_h, input_stride_in_bytes: c.int,
output_pixels: rawptr, output_w, output_h, output_stride_in_bytes: c.int,
datatype: datatype,
num_channels: c.int, alpha_channel: b32, flags: c.int,
edge_mode_horizontal, edge_mode_vertical: edge,
filter_horizontal, filter_vertical: filter,
space: colorspace, alloc_context: rawptr,
x_scale, y_scale: f32,
x_offset, y_offset: f32) -> c.int ---
resize_region :: proc(input_pixels: rawptr, input_w, input_h, input_stride_in_bytes: c.int,
output_pixels: rawptr, output_w, output_h, output_stride_in_bytes: c.int,
datatype: datatype,
num_channels: c.int, alpha_channel: b32, flags: c.int,
edge_mode_horizontal, edge_mode_vertical: edge,
filter_horizontal, filter_vertical: filter,
space: colorspace, alloc_context: rawptr,
s0, t0, s1, t1: f32) -> c.int ---
}
+26
View File
@@ -0,0 +1,26 @@
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" }
write_func :: proc "c" (ctx: rawptr, data: rawptr, size: c.int)
@(default_calling_convention="c", link_prefix="stbi_")
foreign stbiw {
write_png :: proc(filename: cstring, w, h, comp: c.int, data: rawptr, stride_in_bytes: c.int) -> c.int ---
write_bmp :: proc(filename: cstring, w, h, comp: c.int, data: rawptr) -> c.int ---
write_tga :: proc(filename: cstring, w, h, comp: c.int, data: rawptr) -> c.int ---
write_hdr :: proc(filename: cstring, w, h, comp: c.int, data: [^]f32) -> c.int ---
write_jpg :: proc(filename: cstring, w, h, comp: c.int, data: rawptr, quality: c.int /*0..=100*/) -> c.int ---
write_png_to_func :: proc(func: write_func, ctx: rawptr, w, h, comp: c.int, data: rawptr, stride_in_bytes: c.int) -> c.int ---
write_bmp_to_func :: proc(func: write_func, ctx: rawptr, w, h, comp: c.int, data: rawptr) -> c.int ---
write_tga_to_func :: proc(func: write_func, ctx: rawptr, w, h, comp: c.int, data: rawptr) -> c.int ---
write_hdr_to_func :: proc(func: write_func, ctx: rawptr, w, h, comp: c.int, data: [^]f32) -> c.int ---
write_jpg_to_func :: proc(func: write_func, ctx: rawptr, x, y, comp: c.int, data: rawptr, quality: c.int /*0..=100*/) -> c.int ---
flip_vertically_on_write :: proc(flip_boolean: b32) ---
}
View File
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+112
View File
@@ -0,0 +1,112 @@
package stb_rect_pack
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" }
Coord :: distinct c.int
_MAXVAL :: max(Coord)
Rect :: struct {
// reserved for your use:
id: c.int,
// input:
w, h: Coord,
// output:
x, y: Coord,
was_packed: b32, // non-zero if valid packing
}
Heuristic :: enum c.int {
Skyline_default = 0,
Skyline_BL_sortHeight = Skyline_default,
Skyline_BF_sortHeight,
}
//////////////////////////////////////////////////////////////////////////////
//
// the details of the following structures don't matter to you, but they must
// be visible so you can handle the memory allocations for them
Node :: struct {
x, y: Coord,
next: ^Node,
}
Context :: struct {
width: c.int,
height: c.int,
align: c.int,
init_mode: c.int,
heuristic: Heuristic,
num_nodes: c.int,
active_head: ^Node,
free_head: ^Node,
extra: [2]Node, // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
}
@(default_calling_convention="c", link_prefix="stbrp_")
foreign lib {
// Assign packed locations to rectangles. The rectangles are of type
// 'Rect' defined below, stored in the array 'rects', and there
// are 'num_rects' many of them.
//
// Rectangles which are successfully packed have the 'was_packed' flag
// set to a non-zero value and 'x' and 'y' store the minimum location
// on each axis (i.e. bottom-left in cartesian coordinates, top-left
// if you imagine y increasing downwards). Rectangles which do not fit
// have the 'was_packed' flag set to 0.
//
// You should not try to access the 'rects' array from another thread
// while this function is running, as the function temporarily reorders
// the array while it executes.
//
// To pack into another rectangle, you need to call init_target
// again. To continue packing into the same rectangle, you can call
// this function again. Calling this multiple times with multiple rect
// arrays will probably produce worse packing results than calling it
// a single time with the full rectangle array, but the option is
// available.
//
// The function returns 1 if all of the rectangles were successfully
// packed and 0 otherwise.
pack_rects :: proc(ctx: ^Context, rects: [^]Rect, num_rects: c.int) -> c.int ---
// Initialize a rectangle packer to:
// pack a rectangle that is 'width' by 'height' in dimensions
// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
//
// You must call this function every time you start packing into a new target.
//
// There is no "shutdown" function. The 'nodes' memory must stay valid for
// the following pack_rects() call (or calls), but can be freed after
// the call (or calls) finish.
//
// Note: to guarantee best results, either:
// 1. make sure 'num_nodes' >= 'width'
// or 2. call setup_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
//
// If you don't do either of the above things, widths will be quantized to multiples
// of small integers to guarantee the algorithm doesn't run out of temporary storage.
//
// If you do #2, then the non-quantized algorithm will be used, but the algorithm
// may run out of temporary storage and be unable to pack some rectangles.
init_target :: proc(ctx: ^Context, width, height: c.int, nodes: [^]Node, num_nodes: c.int) ---
// Optionally call this function after init but before doing any packing to
// change the handling of the out-of-temp-memory scenario, described above.
// If you call init again, this will be reset to the default (false).
setup_allow_out_of_mem :: proc(ctx: ^Context, allow_out_of_mem: b32) ---
// Optionally select which packing heuristic the library should use. Different
// heuristics will produce better/worse results for different data sets.
// If you call init again, this will be reset to the default.
setup_heuristic :: proc(ctx: ^Context, heuristic: Heuristic) ---
}
+16
View File
@@ -0,0 +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
rm *.o
+13
View File
@@ -0,0 +1,13 @@
@echo off
if not exist "..\lib" mkdir ..\lib
cl -nologo -MT -TC -O2 -c stb_image.c stb_image_write.c stb_image_resize.c stb_truetype.c stb_rect_pack.c stb_vorbis.c
lib -nologo stb_image.obj -out:..\lib\stb_image.lib
lib -nologo stb_image_write.obj -out:..\lib\stb_image_write.lib
lib -nologo stb_image_resize.obj -out:..\lib\stb_image_resize.lib
lib -nologo stb_truetype.obj -out:..\lib\stb_truetype.lib
lib -nologo stb_rect_pack.obj -out:..\lib\stb_rect_pack.lib
lib -nologo stb_vorbis.obj -out:..\lib\stb_vorbis.lib
del *.obj
+2
View File
@@ -0,0 +1,2 @@
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
+7897
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -0,0 +1,2 @@
#define STB_IMAGE_RESIZE_IMPLEMENTATION
#include "stb_image_resize.h"
+2634
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -0,0 +1,2 @@
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
+1724
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -0,0 +1,2 @@
#define STB_RECT_PACK_IMPLEMENTATION
#include "stb_rect_pack.h"
+623
View File
@@ -0,0 +1,623 @@
// stb_rect_pack.h - v1.01 - public domain - rectangle packing
// Sean Barrett 2014
//
// Useful for e.g. packing rectangular textures into an atlas.
// Does not do rotation.
//
// Before #including,
//
// #define STB_RECT_PACK_IMPLEMENTATION
//
// in the file that you want to have the implementation.
//
// Not necessarily the awesomest packing method, but better than
// the totally naive one in stb_truetype (which is primarily what
// this is meant to replace).
//
// Has only had a few tests run, may have issues.
//
// More docs to come.
//
// No memory allocations; uses qsort() and assert() from stdlib.
// Can override those by defining STBRP_SORT and STBRP_ASSERT.
//
// This library currently uses the Skyline Bottom-Left algorithm.
//
// Please note: better rectangle packers are welcome! Please
// implement them to the same API, but with a different init
// function.
//
// Credits
//
// Library
// Sean Barrett
// Minor features
// Martins Mozeiko
// github:IntellectualKitty
//
// Bugfixes / warning fixes
// Jeremy Jaussaud
// Fabian Giesen
//
// Version history:
//
// 1.01 (2021-07-11) always use large rect mode, expose STBRP__MAXVAL in public section
// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
// 0.99 (2019-02-07) warning fixes
// 0.11 (2017-03-03) return packing success/fail result
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
// 0.09 (2016-08-27) fix compiler warnings
// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
// 0.05: added STBRP_ASSERT to allow replacing assert
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
// 0.01: initial release
//
// LICENSE
//
// See end of file for license information.
//////////////////////////////////////////////////////////////////////////////
//
// INCLUDE SECTION
//
#ifndef STB_INCLUDE_STB_RECT_PACK_H
#define STB_INCLUDE_STB_RECT_PACK_H
#define STB_RECT_PACK_VERSION 1
#ifdef STBRP_STATIC
#define STBRP_DEF static
#else
#define STBRP_DEF extern
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct stbrp_context stbrp_context;
typedef struct stbrp_node stbrp_node;
typedef struct stbrp_rect stbrp_rect;
typedef int stbrp_coord;
#define STBRP__MAXVAL 0x7fffffff
// Mostly for internal use, but this is the maximum supported coordinate value.
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
// Assign packed locations to rectangles. The rectangles are of type
// 'stbrp_rect' defined below, stored in the array 'rects', and there
// are 'num_rects' many of them.
//
// Rectangles which are successfully packed have the 'was_packed' flag
// set to a non-zero value and 'x' and 'y' store the minimum location
// on each axis (i.e. bottom-left in cartesian coordinates, top-left
// if you imagine y increasing downwards). Rectangles which do not fit
// have the 'was_packed' flag set to 0.
//
// You should not try to access the 'rects' array from another thread
// while this function is running, as the function temporarily reorders
// the array while it executes.
//
// To pack into another rectangle, you need to call stbrp_init_target
// again. To continue packing into the same rectangle, you can call
// this function again. Calling this multiple times with multiple rect
// arrays will probably produce worse packing results than calling it
// a single time with the full rectangle array, but the option is
// available.
//
// The function returns 1 if all of the rectangles were successfully
// packed and 0 otherwise.
struct stbrp_rect
{
// reserved for your use:
int id;
// input:
stbrp_coord w, h;
// output:
stbrp_coord x, y;
int was_packed; // non-zero if valid packing
}; // 16 bytes, nominally
STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
// Initialize a rectangle packer to:
// pack a rectangle that is 'width' by 'height' in dimensions
// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
//
// You must call this function every time you start packing into a new target.
//
// There is no "shutdown" function. The 'nodes' memory must stay valid for
// the following stbrp_pack_rects() call (or calls), but can be freed after
// the call (or calls) finish.
//
// Note: to guarantee best results, either:
// 1. make sure 'num_nodes' >= 'width'
// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
//
// If you don't do either of the above things, widths will be quantized to multiples
// of small integers to guarantee the algorithm doesn't run out of temporary storage.
//
// If you do #2, then the non-quantized algorithm will be used, but the algorithm
// may run out of temporary storage and be unable to pack some rectangles.
STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
// Optionally call this function after init but before doing any packing to
// change the handling of the out-of-temp-memory scenario, described above.
// If you call init again, this will be reset to the default (false).
STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
// Optionally select which packing heuristic the library should use. Different
// heuristics will produce better/worse results for different data sets.
// If you call init again, this will be reset to the default.
enum
{
STBRP_HEURISTIC_Skyline_default=0,
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
STBRP_HEURISTIC_Skyline_BF_sortHeight
};
//////////////////////////////////////////////////////////////////////////////
//
// the details of the following structures don't matter to you, but they must
// be visible so you can handle the memory allocations for them
struct stbrp_node
{
stbrp_coord x,y;
stbrp_node *next;
};
struct stbrp_context
{
int width;
int height;
int align;
int init_mode;
int heuristic;
int num_nodes;
stbrp_node *active_head;
stbrp_node *free_head;
stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
};
#ifdef __cplusplus
}
#endif
#endif
//////////////////////////////////////////////////////////////////////////////
//
// IMPLEMENTATION SECTION
//
#ifdef STB_RECT_PACK_IMPLEMENTATION
#ifndef STBRP_SORT
#include <stdlib.h>
#define STBRP_SORT qsort
#endif
#ifndef STBRP_ASSERT
#include <assert.h>
#define STBRP_ASSERT assert
#endif
#ifdef _MSC_VER
#define STBRP__NOTUSED(v) (void)(v)
#define STBRP__CDECL __cdecl
#else
#define STBRP__NOTUSED(v) (void)sizeof(v)
#define STBRP__CDECL
#endif
enum
{
STBRP__INIT_skyline = 1
};
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
{
switch (context->init_mode) {
case STBRP__INIT_skyline:
STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
context->heuristic = heuristic;
break;
default:
STBRP_ASSERT(0);
}
}
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
{
if (allow_out_of_mem)
// if it's ok to run out of memory, then don't bother aligning them;
// this gives better packing, but may fail due to OOM (even though
// the rectangles easily fit). @TODO a smarter approach would be to only
// quantize once we've hit OOM, then we could get rid of this parameter.
context->align = 1;
else {
// if it's not ok to run out of memory, then quantize the widths
// so that num_nodes is always enough nodes.
//
// I.e. num_nodes * align >= width
// align >= width / num_nodes
// align = ceil(width/num_nodes)
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
}
}
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
{
int i;
for (i=0; i < num_nodes-1; ++i)
nodes[i].next = &nodes[i+1];
nodes[i].next = NULL;
context->init_mode = STBRP__INIT_skyline;
context->heuristic = STBRP_HEURISTIC_Skyline_default;
context->free_head = &nodes[0];
context->active_head = &context->extra[0];
context->width = width;
context->height = height;
context->num_nodes = num_nodes;
stbrp_setup_allow_out_of_mem(context, 0);
// node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
context->extra[0].x = 0;
context->extra[0].y = 0;
context->extra[0].next = &context->extra[1];
context->extra[1].x = (stbrp_coord) width;
context->extra[1].y = (1<<30);
context->extra[1].next = NULL;
}
// find minimum y position if it starts at x1
static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
{
stbrp_node *node = first;
int x1 = x0 + width;
int min_y, visited_width, waste_area;
STBRP__NOTUSED(c);
STBRP_ASSERT(first->x <= x0);
#if 0
// skip in case we're past the node
while (node->next->x <= x0)
++node;
#else
STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
#endif
STBRP_ASSERT(node->x <= x0);
min_y = 0;
waste_area = 0;
visited_width = 0;
while (node->x < x1) {
if (node->y > min_y) {
// raise min_y higher.
// we've accounted for all waste up to min_y,
// but we'll now add more waste for everything we've visted
waste_area += visited_width * (node->y - min_y);
min_y = node->y;
// the first time through, visited_width might be reduced
if (node->x < x0)
visited_width += node->next->x - x0;
else
visited_width += node->next->x - node->x;
} else {
// add waste area
int under_width = node->next->x - node->x;
if (under_width + visited_width > width)
under_width = width - visited_width;
waste_area += under_width * (min_y - node->y);
visited_width += under_width;
}
node = node->next;
}
*pwaste = waste_area;
return min_y;
}
typedef struct
{
int x,y;
stbrp_node **prev_link;
} stbrp__findresult;
static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
{
int best_waste = (1<<30), best_x, best_y = (1 << 30);
stbrp__findresult fr;
stbrp_node **prev, *node, *tail, **best = NULL;
// align to multiple of c->align
width = (width + c->align - 1);
width -= width % c->align;
STBRP_ASSERT(width % c->align == 0);
// if it can't possibly fit, bail immediately
if (width > c->width || height > c->height) {
fr.prev_link = NULL;
fr.x = fr.y = 0;
return fr;
}
node = c->active_head;
prev = &c->active_head;
while (node->x + width <= c->width) {
int y,waste;
y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
// bottom left
if (y < best_y) {
best_y = y;
best = prev;
}
} else {
// best-fit
if (y + height <= c->height) {
// can only use it if it first vertically
if (y < best_y || (y == best_y && waste < best_waste)) {
best_y = y;
best_waste = waste;
best = prev;
}
}
}
prev = &node->next;
node = node->next;
}
best_x = (best == NULL) ? 0 : (*best)->x;
// if doing best-fit (BF), we also have to try aligning right edge to each node position
//
// e.g, if fitting
//
// ____________________
// |____________________|
//
// into
//
// | |
// | ____________|
// |____________|
//
// then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
//
// This makes BF take about 2x the time
if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
tail = c->active_head;
node = c->active_head;
prev = &c->active_head;
// find first node that's admissible
while (tail->x < width)
tail = tail->next;
while (tail) {
int xpos = tail->x - width;
int y,waste;
STBRP_ASSERT(xpos >= 0);
// find the left position that matches this
while (node->next->x <= xpos) {
prev = &node->next;
node = node->next;
}
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
if (y + height <= c->height) {
if (y <= best_y) {
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
best_x = xpos;
STBRP_ASSERT(y <= best_y);
best_y = y;
best_waste = waste;
best = prev;
}
}
}
tail = tail->next;
}
}
fr.prev_link = best;
fr.x = best_x;
fr.y = best_y;
return fr;
}
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
{
// find best position according to heuristic
stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
stbrp_node *node, *cur;
// bail if:
// 1. it failed
// 2. the best node doesn't fit (we don't always check this)
// 3. we're out of memory
if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
res.prev_link = NULL;
return res;
}
// on success, create new node
node = context->free_head;
node->x = (stbrp_coord) res.x;
node->y = (stbrp_coord) (res.y + height);
context->free_head = node->next;
// insert the new node into the right starting point, and
// let 'cur' point to the remaining nodes needing to be
// stiched back in
cur = *res.prev_link;
if (cur->x < res.x) {
// preserve the existing one, so start testing with the next one
stbrp_node *next = cur->next;
cur->next = node;
cur = next;
} else {
*res.prev_link = node;
}
// from here, traverse cur and free the nodes, until we get to one
// that shouldn't be freed
while (cur->next && cur->next->x <= res.x + width) {
stbrp_node *next = cur->next;
// move the current node to the free list
cur->next = context->free_head;
context->free_head = cur;
cur = next;
}
// stitch the list back in
node->next = cur;
if (cur->x < res.x + width)
cur->x = (stbrp_coord) (res.x + width);
#ifdef _DEBUG
cur = context->active_head;
while (cur->x < context->width) {
STBRP_ASSERT(cur->x < cur->next->x);
cur = cur->next;
}
STBRP_ASSERT(cur->next == NULL);
{
int count=0;
cur = context->active_head;
while (cur) {
cur = cur->next;
++count;
}
cur = context->free_head;
while (cur) {
cur = cur->next;
++count;
}
STBRP_ASSERT(count == context->num_nodes+2);
}
#endif
return res;
}
static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
{
const stbrp_rect *p = (const stbrp_rect *) a;
const stbrp_rect *q = (const stbrp_rect *) b;
if (p->h > q->h)
return -1;
if (p->h < q->h)
return 1;
return (p->w > q->w) ? -1 : (p->w < q->w);
}
static int STBRP__CDECL rect_original_order(const void *a, const void *b)
{
const stbrp_rect *p = (const stbrp_rect *) a;
const stbrp_rect *q = (const stbrp_rect *) b;
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
}
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
{
int i, all_rects_packed = 1;
// we use the 'was_packed' field internally to allow sorting/unsorting
for (i=0; i < num_rects; ++i) {
rects[i].was_packed = i;
}
// sort according to heuristic
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
for (i=0; i < num_rects; ++i) {
if (rects[i].w == 0 || rects[i].h == 0) {
rects[i].x = rects[i].y = 0; // empty rect needs no space
} else {
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
if (fr.prev_link) {
rects[i].x = (stbrp_coord) fr.x;
rects[i].y = (stbrp_coord) fr.y;
} else {
rects[i].x = rects[i].y = STBRP__MAXVAL;
}
}
}
// unsort
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
// set was_packed flags and all_rects_packed status
for (i=0; i < num_rects; ++i) {
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
if (!rects[i].was_packed)
all_rects_packed = 0;
}
// return the all_rects_packed status
return all_rects_packed;
}
#endif
/*
------------------------------------------------------------------------------
This software is available under 2 licenses -- choose whichever you prefer.
------------------------------------------------------------------------------
ALTERNATIVE A - MIT License
Copyright (c) 2017 Sean Barrett
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
------------------------------------------------------------------------------
ALTERNATIVE B - Public Domain (www.unlicense.org)
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
software, either in source code form or as a compiled binary, for any purpose,
commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and to
the detriment of our heirs and successors. We intend this dedication to be an
overt act of relinquishment in perpetuity of all present and future rights to
this software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------
*/
+5
View File
@@ -0,0 +1,5 @@
#define STB_RECT_PACK_IMPLEMENTATION
#include "stb_rect_pack.h"
#define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h"
+5077
View File
File diff suppressed because it is too large Load Diff
+5584
View File
File diff suppressed because it is too large Load Diff
+609
View File
@@ -0,0 +1,609 @@
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" }
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
////
//// INTERFACE
////
////
#assert(size_of(c.int) == size_of(rune))
#assert(size_of(c.int) == size_of(b32))
//////////////////////////////////////////////////////////////////////////////
//
// TEXTURE BAKING API
//
// If you use this API, you only have to call two functions ever.
//
bakedchar :: struct {
x0, y0, x1, y1: u16, // coordinates of bbox in bitmap
xoff, yoff, xadvance: f32,
}
aligned_quad :: struct {
x0, y0, s0, t0: f32, // top-left
x1, y1, s1, t1: f32, // bottom-right
}
// bindings
@(default_calling_convention="c", link_prefix="stbtt_")
foreign stbtt {
// if return is positive, the first unused row of the bitmap
// if return is negative, returns the negative of the number of characters that fit
// if return is 0, no characters fit and no rows were used
// This uses a very crappy packing.
BakeFontBitmap :: proc(data: [^]byte, offset: c.int, // font location (use offset=0 for plain .ttf)
pixel_height: f32, // height of font in pixels
pixels: [^]byte, pw, ph: c.int, // bitmap to be filled in
first_char, num_chars: c.int, // characters to bake
chardata: [^]bakedchar, // you allocate this, it's num_chars long
) -> c.int ---
// Call GetBakedQuad with char_index = 'character - first_char', and it
// creates the quad you need to draw and advances the current position.
//
// The coordinate system used assumes y increases downwards.
//
// Characters will extend both above and below the current position;
// see discussion of "BASELINE" above.
//
// It's inefficient; you might want to c&p it and optimize it.
GetBakedQuad :: proc(chardata: ^bakedchar, pw, ph: c.int, // same data as above
char_index: c.int, // character to display
xpos, ypos: ^f32, // pointers to current position in screen pixel space
q: ^aligned_quad, // output: quad to draw
opengl_fillrule: b32, // true if opengl fill rule; false if DX9 or earlier
) ---
// Query the font vertical metrics without having to create a font first.
GetScaledFontVMetrics :: proc(fontdata: [^]byte, index: c.int, size: f32, ascent, descent, lineGap: ^f32) ---
}
//////////////////////////////////////////////////////////////////////////////
//
// NEW TEXTURE BAKING API
//
// This provides options for packing multiple fonts into one atlas, not
// perfectly but better than nothing.
packedchar :: struct {
x0, y0, x1, y1: u16,
xoff, yoff, xadvance: f32,
xoff2, yoff2: f32,
}
pack_range :: struct {
font_size: f32,
first_unicode_codepoint_in_range: c.int,
array_of_unicode_codepoints: [^]rune,
num_chars: c.int,
chardata_for_range: ^packedchar,
_, _: u8, // used internally to store oversample info
}
pack_context :: struct {
user_allocator_context, pack_info: rawptr,
width, height, stride_in_bytes, padding: c.int,
h_oversample, v_oversample: u32,
pixels: [^]byte,
nodes: rawptr,
}
POINT_SIZE :: #force_inline proc(x: $T) -> T { return -x } // @NOTE: this was a macro
// bindings
@(default_calling_convention="c", link_prefix="stbtt_")
foreign stbtt {
// Initializes a packing context stored in the passed-in stbtt_pack_context.
// Future calls using this context will pack characters into the bitmap passed
// in here: a 1-channel bitmap that is width * height. stride_in_bytes is
// the distance from one row to the next (or 0 to mean they are packed tightly
// together). "padding" is the amount of padding to leave between each
// character (normally you want '1' for bitmaps you'll use as textures with
// bilinear filtering).
//
// Returns 0 on failure, 1 on success.
PackBegin :: proc(spc: ^pack_context, pixels: [^]byte, width, height, stride_in_bytes, padding: c.int, alloc_context: rawptr) -> c.int ---
// Cleans up the packing context and frees all memory.
PackEnd :: proc(spc: ^pack_context) ---
// Creates character bitmaps from the font_index'th font found in fontdata (use
// font_index=0 if you don't know what that is). It creates num_chars_in_range
// bitmaps for characters with unicode values starting at first_unicode_char_in_range
// and increasing. Data for how to render them is stored in chardata_for_range;
// pass these to stbtt_GetPackedQuad to get back renderable quads.
//
// font_size is the full height of the character from ascender to descender,
// as computed by stbtt_ScaleForPixelHeight. To use a point size as computed
// by stbtt_ScaleForMappingEmToPixels, wrap the point size in POINT_SIZE()
// and pass that result as 'font_size':
// ..., 20 , ... // font max minus min y is 20 pixels tall
// ..., POINT_SIZE(20), ... // 'M' is 20 pixels tall
PackFontRange :: proc(spc: ^pack_context, fontdata: [^]byte, font_index: c.int, font_size: f32, first_unicode_char_in_range, num_chars_in_range: c.int, chardata_for_range: ^packedchar) -> c.int ---
// Creates character bitmaps from multiple ranges of characters stored in
// ranges. This will usually create a better-packed bitmap than multiple
// calls to stbtt_PackFontRange. Note that you can call this multiple
// times within a single PackBegin/PackEnd.
PackFontRanges :: proc(spc: ^pack_context, fontdata: [^]byte, font_index: c.int, ranges: [^]pack_range, num_ranges: c.int) -> c.int ---
// Oversampling a font increases the quality by allowing higher-quality subpixel
// positioning, and is especially valuable at smaller text sizes.
//
// This function sets the amount of oversampling for all following calls to
// stbtt_PackFontRange(s) or stbtt_PackFontRangesGatherRects for a given
// pack context. The default (no oversampling) is achieved by h_oversample=1
// and v_oversample=1. The total number of pixels required is
// h_oversample*v_oversample larger than the default; for example, 2x2
// oversampling requires 4x the storage of 1x1. For best results, render
// oversampled textures with bilinear filtering. Look at the readme in
// stb/tests/oversample for information about oversampled fonts
//
// To use with PackFontRangesGather etc., you must set it before calls
// call to PackFontRangesGatherRects.
PackSetOversampling :: proc(spc: ^pack_context, h_oversample, v_oversample: c.uint) ---
// If skip != false, this tells stb_truetype to skip any codepoints for which
// there is no corresponding glyph. If skip=false, which is the default, then
// codepoints without a glyph recived the font's "missing character" glyph,
// typically an empty box by convention.
PackSetSkipMissingCodepoints :: proc(spc: ^pack_context, skip: b32) ---
GetPackedQuad :: proc(chardata: ^packedchar, pw, ph: c.int, // same data as above
char_index: c.int, // character to display
xpos, ypos: ^f32, // pointers to current position in screen pixel space
q: ^aligned_quad, // output: quad to draw
align_to_integer: b32,
) ---
// Calling these functions in sequence is roughly equivalent to calling
// stbtt_PackFontRanges(). If you more control over the packing of multiple
// fonts, or if you want to pack custom data into a font texture, take a look
// at the source to of stbtt_PackFontRanges() and create a custom version
// using these functions, e.g. call GatherRects multiple times,
// building up a single array of rects, then call PackRects once,
// then call RenderIntoRects repeatedly. This may result in a
// better packing than calling PackFontRanges multiple times
// (or it may not).
PackFontRangesGatherRects :: proc(spc: ^pack_context, info: ^fontinfo, ranges: ^pack_range, num_ranges: c.int, rects: [^]stbrp.Rect) -> c.int ---
PackFontRangesPackRects :: proc(spc: ^pack_context, rects: [^]stbrp.Rect, num_rects: c.int) ---
PackFontRangesRenderIntoRects :: proc(spc: ^pack_context, info: ^fontinfo, ranges: ^pack_range, num_ranges: c.int, rects: [^]stbrp.Rect) -> c.int ---
}
//////////////////////////////////////////////////////////////////////////////
//
// FONT LOADING
//
//
fontinfo :: struct {
userdata: rawptr,
data: [^]byte,
fontstart: c.int,
numGlyphs: c.int,
loca, head, glyf, hhea, hmtx, kern: c.int,
index_map: c.int,
indexToLocFormat: c.int,
cff: _buf,
charstrings: _buf,
gsubrs: _buf,
subrs: _buf,
fontdicts: _buf,
fdselect: _buf,
}
@(default_calling_convention="c", link_prefix="stbtt_")
foreign stbtt {
// Given an offset into the file that defines a font, this function builds
// the necessary cached info for the rest of the system. You must allocate
// the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't
// need to do anything special to free it, because the contents are pure
// value data with no additional data structures. Returns 0 on failure.
InitFont :: proc(info: ^fontinfo, data: [^]byte, offset: c.int) -> b32 ---
// This function will determine the number of fonts in a font file. TrueType
// collection (.ttc) files may contain multiple fonts, while TrueType font
// (.ttf) files only contain one font. The number of fonts can be used for
// indexing with the previous function where the index is between zero and one
// less than the total fonts. If an error occurs, -1 is returned.
GetNumberOfFonts :: proc(data: [^]byte) -> b32 ---
// Each .ttf/.ttc file may have more than one font. Each font has a sequential
// index number starting from 0. Call this function to get the font offset for
// a given index; it returns -1 if the index is out of range. A regular .ttf
// file will only define one font and it always be at offset 0, so it will
// return '0' for index 0, and -1 for all other indices.
GetFontOffsetForIndex :: proc(data: [^]byte, index: c.int) -> c.int ---
}
//////////////////////////////////////////////////////////////////////////////
//
// CHARACTER TO GLYPH-INDEX CONVERSION
@(default_calling_convention="c", link_prefix="stbtt_")
foreign stbtt {
// If you're going to perform multiple operations on the same character
// and you want a speed-up, call this function with the character you're
// going to process, then use glyph-based functions instead of the
// codepoint-based functions.
// Returns 0 if the character codepoint is not defined in the font.
FindGlyphIndex :: proc(info: ^fontinfo, unicode_codepoint: rune) -> c.int ---
}
//////////////////////////////////////////////////////////////////////////////
//
// CHARACTER PROPERTIES
//
@(default_calling_convention="c", link_prefix="stbtt_")
foreign stbtt {
// computes a scale factor to produce a font whose "height" is 'pixels' tall.
// Height is measured as the distance from the highest ascender to the lowest
// descender; in other words, it's equivalent to calling stbtt_GetFontVMetrics
// and computing:
// scale = pixels / (ascent - descent)
// so if you prefer to measure height by the ascent only, use a similar calculation.
ScaleForPixelHeight :: proc(info: ^fontinfo, pixels: f32) -> f32 ---
// computes a scale factor to produce a font whose EM size is mapped to
// 'pixels' tall. This is probably what traditional APIs compute, but
// I'm not positive.
ScaleForMappingEmToPixels :: proc(info: ^fontinfo, pixels: f32) -> f32 ---
// ascent is the coordinate above the baseline the font extends; descent
// is the coordinate below the baseline the font extends (i.e. it is typically negative)
// lineGap is the spacing between one row's descent and the next row's ascent...
// so you should advance the vertical position by "*ascent - *descent + *lineGap"
// these are expressed in unscaled coordinates, so you must multiply by
// the scale factor for a given size
GetFontVMetrics :: proc(info: ^fontinfo, ascent, descent, lineGap: ^c.int) ---
// analogous to GetFontVMetrics, but returns the "typographic" values from the OS/2
// table (specific to MS/Windows TTF files).
//
// Returns 1 on success (table present), 0 on failure.
GetFontVMetricsOS2 :: proc(info: ^fontinfo, typoAscent, typoDescent, typoLineGap: ^c.int) -> b32 ---
// the bounding box around all possible characters
GetFontBoundingBox :: proc(info: ^fontinfo, x0, y0, x1, y1: ^c.int) ---
// leftSideBearing is the offset from the current horizontal position to the left edge of the character
// advanceWidth is the offset from the current horizontal position to the next horizontal position
// these are expressed in unscaled coordinates
GetCodepointHMetrics :: proc(info: ^fontinfo, codepoint: rune, advanceWidth, leftSideBearing: ^c.int) ---
// an additional amount to add to the 'advance' value between ch1 and ch2
GetCodepointKernAdvance :: proc(info: ^fontinfo, ch1, ch2: rune) -> (advance: c.int) ---
// Gets the bounding box of the visible part of the glyph, in unscaled coordinates
GetCodepointBox :: proc(info: ^fontinfo, codepoint: rune, x0, y0, x1, y1: ^c.int) -> c.int ---
// as above, but takes one or more glyph indices for greater efficiency
GetGlyphHMetrics :: proc(info: ^fontinfo, glyph_index: c.int, advanceWidth, leftSideBearing: ^c.int) ---
GetGlyphKernAdvance :: proc(info: ^fontinfo, glyph1, glyph2: c.int) -> c.int ---
GetGlyphBox :: proc(info: ^fontinfo, glyph_index: c.int, x0, y0, x1, y1: ^c.int) -> c.int ---
}
kerningentry :: struct {
glyph1: rune, // use FindGlyphIndex
glyph2: rune,
advance: c.int,
}
@(default_calling_convention="c", link_prefix="stbtt_")
foreign stbtt {
// Retrieves a complete list of all of the kerning pairs provided by the font
// stbtt_GetKerningTable never writes more than table_length entries and returns how many entries it did write.
// The table will be sorted by (a.glyph1 == b.glyph1)?(a.glyph2 < b.glyph2):(a.glyph1 < b.glyph1)
GetKerningTableLength :: proc(info: ^fontinfo) -> c.int ---
GetKerningTable :: proc(info: ^fontinfo, table: [^]kerningentry, table_length: c.int) -> c.int ---
}
//////////////////////////////////////////////////////////////////////////////
//
// GLYPH SHAPES (you probably don't need these, but they have to go before
// the bitmaps for C declaration-order reasons)
//
vmove :: enum c.int {
none,
vmove=1,
vline,
vcurve,
vcubic,
}
vertex_type :: distinct c.short // can't use stbtt_int16 because that's not visible in the header file
vertex :: struct {
x, y, cx, cy, cx1, cy1: vertex_type,
type, padding: byte,
}
@(default_calling_convention="c", link_prefix="stbtt_")
foreign stbtt {
// returns true if nothing is drawn for this glyph
IsGlyphEmpty :: proc(info: ^fontinfo, glyph_index: c.int) -> b32 ---
// returns # of vertices and fills *vertices with the pointer to them
// these are expressed in "unscaled" coordinates
//
// The shape is a series of contours. Each one starts with
// a STBTT_moveto, then consists of a series of mixed
// STBTT_lineto and STBTT_curveto segments. A lineto
// draws a line from previous endpoint to its x,y; a curveto
// draws a quadratic bezier from previous endpoint to
// its x,y, using cx,cy as the bezier control point.
GetCodepointShape :: proc(info: ^fontinfo, unicode_codepoint: rune, vertices: ^[^]vertex) -> c.int ---
GetGlyphShape :: proc(info: ^fontinfo, glyph_index: c.int, vertices: ^[^]vertex) -> c.int ---
// frees the data allocated above
FreeShape :: proc(info: ^fontinfo, vertices: [^]vertex) ---
// fills svg with the character's SVG data.
// returns data size or 0 if SVG not found.
FindSVGDoc :: proc(info: ^fontinfo, gl: b32) -> [^]byte ---
GetCodepointSVG :: proc(info: ^fontinfo, unicode_codepoint: rune, svg: ^cstring) -> c.int ---
GetGlyphSVG :: proc(info: ^fontinfo, gl: b32, svg: ^cstring) -> c.int ---
}
//////////////////////////////////////////////////////////////////////////////
//
// BITMAP RENDERING
//
_bitmap :: struct {
w, h, stride: c.int,
pixels: [^]byte,
}
@(default_calling_convention="c", link_prefix="stbtt_")
foreign stbtt {
// frees the bitmap allocated below
FreeBitmap :: proc(bitmap: [^]byte, userdata: rawptr) ---
// allocates a large-enough single-channel 8bpp bitmap and renders the
// specified character/glyph at the specified scale into it, with
// antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque).
// *width & *height are filled out with the width & height of the bitmap,
// which is stored left-to-right, top-to-bottom.
//
// xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap
GetCodepointBitmap :: proc(info: ^fontinfo, scale_x, scale_y: f32, codepoint: rune, width, height, xoff, yoff: ^c.int) -> [^]byte ---
// the same as stbtt_GetCodepoitnBitmap, but you can specify a subpixel
// shift for the character
GetCodepointBitmapSubpixel :: proc(info: ^fontinfo, scale_x, scale_y, shift_x, shift_y: f32, codepoint: rune, width, height, xoff, yoff: ^c.int) -> [^]byte ---
// the same as stbtt_GetCodepointBitmap, but you pass in storage for the bitmap
// in the form of 'output', with row spacing of 'out_stride' bytes. the bitmap
// is clipped to out_w/out_h bytes. Call stbtt_GetCodepointBitmapBox to get the
// width and height and positioning info for it first.
MakeCodepointBitmap :: proc(info: ^fontinfo, output: [^]byte, out_w, out_h, out_stride: c.int, scale_x, scale_y: f32, codepoint: rune) ---
// same as stbtt_MakeCodepointBitmap, but you can specify a subpixel
// shift for the character
MakeCodepointBitmapSubpixel :: proc(info: ^fontinfo, output: [^]byte, out_w, out_h, out_stride: c.int, scale_x, scale_y, shift_x, shift_y: f32, codepoint: rune) ---
// same as stbtt_MakeCodepointBitmapSubpixel, but prefiltering
// is performed (see stbtt_PackSetOversampling)
MakeCodepointBitmapSubpixelPrefilter :: proc(info: ^fontinfo, output: [^]byte, out_w, out_h, out_stride: c.int, scale_x, scale_y, shift_x, shift_y: f32, oversample_x, oversample_y: b32, sub_x, sub_y: ^f32, codepoint: rune) ---
// get the bbox of the bitmap centered around the glyph origin; so the
// bitmap width is ix1-ix0, height is iy1-iy0, and location to place
// the bitmap top left is (leftSideBearing*scale,iy0).
// (Note that the bitmap uses y-increases-down, but the shape uses
// y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.)
GetCodepointBitmapBox :: proc(font: ^fontinfo, codepoint: rune, scale_x, scale_y: f32, ix0, iy0, ix1, iy1: ^c.int) ---
// same as stbtt_GetCodepointBitmapBox, but you can specify a subpixel
// shift for the character
GetCodepointBitmapBoxSubpixel :: proc(font: ^fontinfo, codepoint: rune, scale_x, scale_y, shift_x, shift_y: f32, ix0, iy0, ix1, iy1: ^c.int) ---
// the following functions are equivalent to the above functions, but operate
// on glyph indices instead of Unicode codepoints (for efficiency)
GetGlyphBitmap :: proc(info: ^fontinfo, scale_x, scale_y: f32, glyph: c.int, width, height, xoff, yoff: ^c.int) -> [^]byte ---
GetGlyphBitmapSubpixel :: proc(info: ^fontinfo, scale_x, scale_y, shift_x, shift_y: f32, glyph: c.int, width, height, xoff, yoff: ^c.int) -> [^]byte ---
MakeGlyphBitmap :: proc(info: ^fontinfo, output: [^]byte, out_w, out_h, out_stride: c.int, scale_x, scale_y: f32, glyph: c.int) ---
MakeGlyphBitmapSubpixel :: proc(info: ^fontinfo, output: [^]byte, out_w, out_h, out_stride: c.int, scale_x, scale_y, shift_x, shift_y: f32, glyph: c.int) ---
MakeGlyphBitmapSubpixelPrefilter :: proc(info: ^fontinfo, output: [^]byte, out_w, out_h, out_stride: c.int, scale_x, scale_y, shift_x, shift_y: f32, oversample_x, oversample_y: c.int, sub_x, sub_y: ^f32, glyph: c.int) ---
GetGlyphBitmapBox :: proc(font: ^fontinfo, glyph: c.int, scale_x, scale_y: f32, ix0, iy0, ix1, iy1: ^c.int) ---
GetGlyphBitmapBoxSubpixel :: proc(font: ^fontinfo, glyph: c.int, scale_x, scale_y, shift_x, shift_y: f32, ix0, iy0, ix1, iy1: ^c.int) ---
// rasterize a shape with quadratic beziers into a bitmap
Rasterize :: proc(result: ^_bitmap, // 1-channel bitmap to draw into
flatness_in_pixels: f32, // allowable error of curve in pixels
vertices: [^]vertex, // array of vertices defining shape
num_verts: c.int, // number of vertices in above array
scale_x, scale_y: f32, // scale applied to input vertices
shift_x, shift_y: f32, // translation applied to input vertices
x_off, y_off: c.int, // another translation applied to input
invert: b32, // if non-zero, vertically flip shape
userdata: rawptr, // context for to STBTT_MALLOC
) ---
}
//////////////////////////////////////////////////////////////////////////////
//
// Signed Distance Function (or Field) rendering
//
@(default_calling_convention="c", link_prefix="stbtt_")
foreign stbtt {
// frees the SDF bitmap allocated below
FreeSDF :: proc(bitmap: [^]byte, userdata: rawptr) ---
// These functions compute a discretized SDF field for a single character, suitable for storing
// in a single-channel texture, sampling with bilinear filtering, and testing against
// larger than some threshold to produce scalable fonts.
// info -- the font
// scale -- controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap
// glyph/codepoint -- the character to generate the SDF for
// padding -- extra "pixels" around the character which are filled with the distance to the character (not 0),
// which allows effects like bit outlines
// onedge_value -- value 0-255 to test the SDF against to reconstruct the character (i.e. the isocontour of the character)
// pixel_dist_scale -- what value the SDF should increase by when moving one SDF "pixel" away from the edge (on the 0..255 scale)
// if positive, > onedge_value is inside; if negative, < onedge_value is inside
// width,height -- output height & width of the SDF bitmap (including padding)
// xoff,yoff -- output origin of the character
// return value -- a 2D array of bytes 0..255, width*height in size
//
// pixel_dist_scale & onedge_value are a scale & bias that allows you to make
// optimal use of the limited 0..255 for your application, trading off precision
// and special effects. SDF values outside the range 0..255 are clamped to 0..255.
//
// Example:
// scale = stbtt_ScaleForPixelHeight(22)
// padding = 5
// onedge_value = 180
// pixel_dist_scale = 180/5.0 = 36.0
//
// This will create an SDF bitmap in which the character is about 22 pixels
// high but the whole bitmap is about 22+5+5=32 pixels high. To produce a filled
// shape, sample the SDF at each pixel and fill the pixel if the SDF value
// is greater than or equal to 180/255. (You'll actually want to antialias,
// which is beyond the scope of this example.) Additionally, you can compute
// offset outlines (e.g. to stroke the character border inside & outside,
// or only outside). For example, to fill outside the character up to 3 SDF
// pixels, you would compare against (180-36.0*3)/255 = 72/255. The above
// choice of variables maps a range from 5 pixels outside the shape to
// 2 pixels inside the shape to 0..255; this is intended primarily for apply
// outside effects only (the interior range is needed to allow proper
// antialiasing of the font at *smaller* sizes)
//
// The function computes the SDF analytically at each SDF pixel, not by e.g.
// building a higher-res bitmap and approximating it. In theory the quality
// should be as high as possible for an SDF of this size & representation, but
// unclear if this is true in practice (perhaps building a higher-res bitmap
// and computing from that can allow drop-out prevention).
//
// The algorithm has not been optimized at all, so expect it to be slow
// if computing lots of characters or very large sizes.
GetGlyphSDF :: proc(info: ^fontinfo, scale: f32, glyph, padding: c.int, onedge_value: u8, pixel_dist_scale: f32, width, height, xoff, yoff: ^c.int) -> [^]byte ---
GetCodepointSDF :: proc(info: ^fontinfo, scale: f32, codepoint, padding: c.int, onedge_value: u8, pixel_dist_scale: f32, width, height, xoff, yoff: ^c.int) -> [^]byte ---
}
//////////////////////////////////////////////////////////////////////////////
//
// Finding the right font...
//
// You should really just solve this offline, keep your own tables
// of what font is what, and don't try to get it out of the .ttf file.
// That's because getting it out of the .ttf file is really hard, because
// the names in the file can appear in many possible encodings, in many
// possible languages, and e.g. if you need a case-insensitive comparison,
// the details of that depend on the encoding & language in a complex way
// (actually underspecified in truetype, but also gigantic).
//
// But you can use the provided functions in two possible ways:
// stbtt_FindMatchingFont() will use *case-sensitive* comparisons on
// unicode-encoded names to try to find the font you want;
// you can run this before calling stbtt_InitFont()
//
// stbtt_GetFontNameString() lets you get any of the various strings
// from the file yourself and do your own comparisons on them.
// You have to have called stbtt_InitFont() first.
MACSTYLE_DONTCARE :: 0
MACSTYLE_BOLD :: 1
MACSTYLE_ITALIC :: 2
MACSTYLE_UNDERSCORE :: 4
MACSTYLE_NONE :: 8 // <= not same as 0, this makes us check the bitfield is 0
@(default_calling_convention="c", link_prefix="stbtt_")
foreign stbtt {
// returns the offset (not index) of the font that matches, or -1 if none
// if you use STBTT_MACSTYLE_DONTCARE, use a font name like "Arial Bold".
// if you use any other flag, use a font name like "Arial"; this checks
// the 'macStyle' header field; i don't know if fonts set this consistently
FindMatchingFont :: proc(fontdata: [^]byte, name: cstring, flags: c.int) -> c.int ---
// returns 1/0 whether the first string interpreted as utf8 is identical to
// the second string interpreted as big-endian utf16... useful for strings from next func
CompareUTF8toUTF16_bigendian :: proc(s1: cstring, len1: c.int, s2: cstring, len2: c.int) -> c.int ---
// returns the string (which may be big-endian double byte, e.g. for unicode)
// and puts the length in bytes in *length.
//
// some of the values for the IDs are below; for more see the truetype spec:
// http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html
// http://www.microsoft.com/typography/otspec/name.htm
GetFontNameString :: proc(font: ^fontinfo, length: c.int, platformID: PLATFORM_ID, encodingID, languageID, nameID: c.int) -> cstring ---
}
PLATFORM_ID :: enum c.int { // platformID
PLATFORM_ID_UNICODE = 0,
PLATFORM_ID_MAC = 1,
PLATFORM_ID_ISO = 2,
PLATFORM_ID_MICROSOFT = 3,
}
// encodingID for PLATFORM_ID_UNICODE
UNICODE_EID_UNICODE_1_0 :: 0
UNICODE_EID_UNICODE_1_1 :: 1
UNICODE_EID_ISO_10646 :: 2
UNICODE_EID_UNICODE_2_0_BMP :: 3
UNICODE_EID_UNICODE_2_0_FULL :: 4
// encodingID for PLATFORM_ID_MICROSOFT
MS_EID_SYMBOL :: 0
MS_EID_UNICODE_BMP :: 1
MS_EID_SHIFTJIS :: 2
MS_EID_UNICODE_FULL :: 10
// encodingID for PLATFORM_ID_MAC; same as Script Manager codes
MAC_EID_ROMAN, MAC_EID_ARABIC :: 0, 4
MAC_EID_JAPANESE, MAC_EID_HEBREW :: 1, 5
MAC_EID_CHINESE_TRAD, MAC_EID_GREEK :: 2, 6
MAC_EID_KOREAN, MAC_EID_RUSSIAN :: 3, 7
// languageID for PLATFORM_ID_MICROSOFT; same as LCID...
// problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs
MS_LANG_ENGLISH, MS_LANG_ITALIAN :: 0x0409, 0x0410
MS_LANG_CHINESE, MS_LANG_JAPANESE :: 0x0804, 0x0411
MS_LANG_DUTCH, MS_LANG_KOREAN :: 0x0413, 0x0412
MS_LANG_FRENCH, MS_LANG_RUSSIAN :: 0x040c, 0x0419
MS_LANG_GERMAN, MS_LANG_SPANISH :: 0x0407, 0x0409
MS_LANG_HEBREW, MS_LANG_SWEDISH :: 0x040d, 0x041D
// languageID for PLATFORM_ID_MAC
MAC_LANG_ENGLISH, MAC_LANG_JAPANESE :: 0, 11
MAC_LANG_ARABIC, MAC_LANG_KOREAN :: 12, 23
MAC_LANG_DUTCH, MAC_LANG_RUSSIAN :: 4, 32
MAC_LANG_FRENCH, MAC_LANG_SPANISH :: 1, 6
MAC_LANG_GERMAN, MAC_LANG_SWEDISH :: 2, 5
MAC_LANG_HEBREW, MAC_LANG_CHINESE_SIMPLIFIED :: 10, 33
MAC_LANG_ITALIAN, MAC_LANG_CHINESE_TRAD :: 3, 19
// private structure
_buf :: struct {
data: [^]byte,
cursor: c.int,
size: c.int,
}
+352
View File
@@ -0,0 +1,352 @@
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" }
/////////// THREAD SAFETY
// Individual stb_vorbis* handles are not thread-safe; you cannot decode from
// them from multiple threads at the same time. However, you can have multiple
// stb_vorbis* handles and decode from them independently in multiple thrads.
/////////// MEMORY ALLOCATION
// normally stb_vorbis uses malloc() to allocate memory at startup,
// and alloca() to allocate temporary memory during a frame on the
// stack. (Memory consumption will depend on the amount of setup
// data in the file and how you set the compile flags for speed
// vs. size. In my test files the maximal-size usage is ~150KB.)
//
// You can modify the wrapper functions in the source (setup_malloc,
// setup_temp_malloc, temp_malloc) to change this behavior, or you
// can use a simpler allocation model: you pass in a buffer from
// which stb_vorbis will allocate _all_ its memory (including the
// temp memory). "open" may fail with a VORBIS_outofmem if you
// do not pass in enough data; there is no way to determine how
// much you do need except to succeed (at which point you can
// query get_info to find the exact amount required. yes I know
// this is lame).
//
// If you pass in a non-NULL buffer of the type below, allocation
// will occur from it as described above. Otherwise just pass NULL
// to use malloc()/alloca()
vorbis_alloc :: struct {
alloc_buffer: [^]byte,
alloc_buffer_length_in_bytes: c.int,
}
vorbis :: struct {}
vorbis_info :: struct {
sample_rate: c.uint,
channels: c.int,
setup_memory_required: c.uint,
setup_temp_memory_required: c.uint,
temp_memory_required: c.uint,
max_frame_size: c.int,
}
vorbis_comment :: struct {
vendor: cstring,
comment_list_length: c.int,
comment_list: [^]cstring,
}
@(default_calling_convention="c", link_prefix="stb_vorbis_")
foreign lib {
// get general information about the file
get_info :: proc(f: ^vorbis) -> vorbis_info ---
// get ogg comments
get_comment :: proc(f: ^vorbis) -> vorbis_comment ---
// get the last error detected (clears it, too)
get_error :: proc(f: ^vorbis) -> c.int ---
// close an ogg vorbis file and free all memory in use
close :: proc(f: ^vorbis) ---
// this function returns the offset (in samples) from the beginning of the
// file that will be returned by the next decode, if it is known, or -1
// otherwise. after a flush_pushdata() call, this may take a while before
// it becomes valid again.
// NOT WORKING YET after a seek with PULLDATA API
get_sample_offset :: proc(f: ^vorbis) -> c.int ---
// returns the current seek point within the file, or offset from the beginning
// of the memory buffer. In pushdata mode it returns 0.
get_file_offset :: proc(f: ^vorbis) -> c.uint ---
}
/////////// PUSHDATA API
// this API allows you to get blocks of data from any source and hand
// them to stb_vorbis. you have to buffer them; stb_vorbis will tell
// you how much it used, and you have to give it the rest next time;
// and stb_vorbis may not have enough data to work with and you will
// need to give it the same data again PLUS more. Note that the Vorbis
// specification does not bound the size of an individual frame.
@(default_calling_convention="c", link_prefix="stb_vorbis_")
foreign lib {
// create a vorbis decoder by passing in the initial data block containing
// the ogg&vorbis headers (you don't need to do parse them, just provide
// the first N bytes of the file--you're told if it's not enough, see below)
// on success, returns an stb_vorbis *, does not set error, returns the amount of
// data parsed/consumed on this call in *datablock_memory_consumed_in_bytes;
// on failure, returns NULL on error and sets *error, does not change *datablock_memory_consumed
// if returns NULL and *error is VORBIS_need_more_data, then the input block was
// incomplete and you need to pass in a larger block from the start of the file
open_pushdata :: proc(
datablock: [^]byte, datablock_length_in_bytes: c.int,
datablock_memory_consumed_in_bytes: ^c.int,
error: ^Error,
alloc_buffer: ^vorbis_alloc,
) -> ^vorbis ---
// decode a frame of audio sample data if possible from the passed-in data block
//
// return value: number of bytes we used from datablock
//
// possible cases:
// 0 bytes used, 0 samples output (need more data)
// N bytes used, 0 samples output (resynching the stream, keep going)
// N bytes used, M samples output (one frame of data)
// note that after opening a file, you will ALWAYS get one N-bytes,0-sample
// frame, because Vorbis always "discards" the first frame.
//
// Note that on resynch, stb_vorbis will rarely consume all of the buffer,
// instead only datablock_length_in_bytes-3 or less. This is because it wants
// to avoid missing parts of a page header if they cross a datablock boundary,
// without writing state-machiney code to record a partial detection.
//
// The number of channels returned are stored in *channels (which can be
// NULL--it is always the same as the number of channels reported by
// get_info). *output will contain an array of float* buffers, one per
// channel. In other words, (*output)[0][0] contains the first sample from
// the first channel, and (*output)[1][0] contains the first sample from
// the second channel.
//
// *output points into stb_vorbis's internal output buffer storage; these
// buffers are owned by stb_vorbis and application code should not free
// them or modify their contents. They are transient and will be overwritten
// once you ask for more data to get decoded, so be sure to grab any data
// you need before then.
decode_frame_pushdata :: proc(
f: ^vorbis,
datablock: [^]byte, datablock_length_in_bytes: c.int,
channels: ^c.int, // place to write number of float * buffers
output: ^[^]^f32, // place to write float ** array of float * buffers
samples: ^c.int, // place to write number of output samples
) -> c.int ---
// inform stb_vorbis that your next datablock will not be contiguous with
// previous ones (e.g. you've seeked in the data); future attempts to decode
// frames will cause stb_vorbis to resynchronize (as noted above), and
// once it sees a valid Ogg page (typically 4-8KB, as large as 64KB), it
// will begin decoding the _next_ frame.
//
// if you want to seek using pushdata, you need to seek in your file, then
// call stb_vorbis_flush_pushdata(), then start calling decoding, then once
// decoding is returning you data, call stb_vorbis_get_sample_offset, and
// if you don't like the result, seek your file again and repeat.
flush_pushdata :: proc(f: ^vorbis) ---
}
////////// PULLING INPUT API
// This API assumes stb_vorbis is allowed to pull data from a source--
// either a block of memory containing the _entire_ vorbis stream, or a
// FILE * that you or it create, or possibly some other reading mechanism
// if you go modify the source to replace the FILE * case with some kind
// of callback to your code. (But if you don't support seeking, you may
// just want to go ahead and use pushdata.)
@(default_calling_convention="c", link_prefix="stb_vorbis_")
foreign lib {
// decode an entire file and output the data interleaved into a malloc()ed
// buffer stored in *output. The return value is the number of samples
// decoded, or -1 if the file could not be opened or was not an ogg vorbis file.
// When you're done with it, just free() the pointer returned in *output.
decode_filename :: proc(filename: cstring, channels, sample_rate: ^c.int, output: ^[^]c.short) -> c.int ---
decode_memory :: proc(mem: [^]byte, len: c.int, channels, sample_rate: ^c.int, output: ^[^]c.short) -> c.int ---
// create an ogg vorbis decoder from an ogg vorbis stream in memory (note
// this must be the entire stream!). on failure, returns NULL and sets *error
open_memory :: proc(data: [^]byte, len: c.int,
error: ^Error, alloc_buffer: ^vorbis_alloc) -> ^vorbis ---
// create an ogg vorbis decoder from a filename via fopen(). on failure,
// returns NULL and sets *error (possibly to VORBIS_file_open_failure).
open_filename :: proc(filename: cstring,
error: ^Error, alloc_buffer: ^vorbis_alloc) -> ^vorbis ---
// create an ogg vorbis decoder from an open FILE *, looking for a stream at
// the _current_ seek point (ftell). on failure, returns NULL and sets *error.
// note that stb_vorbis must "own" this stream; if you seek it in between
// calls to stb_vorbis, it will become confused. Moreover, if you attempt to
// perform stb_vorbis_seek_*() operations on this file, it will assume it
// owns the _entire_ rest of the file after the start point. Use the next
// function, stb_vorbis_open_file_section(), to limit it.
open_file :: proc(f: ^c.FILE, close_handle_on_close: b32,
error: ^Error, alloc_buffer: ^vorbis_alloc) -> ^vorbis ---
// create an ogg vorbis decoder from an open FILE *, looking for a stream at
// the _current_ seek point (ftell); the stream will be of length 'len' bytes.
// on failure, returns NULL and sets *error. note that stb_vorbis must "own"
// this stream; if you seek it in between calls to stb_vorbis, it will become
// confused.
open_file_section :: proc(f: ^c.FILE, close_handle_on_close: b32,
error: ^Error, alloc_buffer: ^vorbis_alloc, len: c.uint) -> ^vorbis ---
// these functions seek in the Vorbis file to (approximately) 'sample_number'.
// after calling seek_frame(), the next call to get_frame_*() will include
// the specified sample. after calling stb_vorbis_seek(), the next call to
// stb_vorbis_get_samples_* will start with the specified sample. If you
// do not need to seek to EXACTLY the target sample when using get_samples_*,
// you can also use seek_frame().
seek_frame :: proc(f: ^vorbis, sample_number: c.uint) -> c.int ---
seek :: proc(f: ^vorbis, sample_number: c.uint) -> c.int ---
// this function is equivalent to stb_vorbis_seek(f,0)
seek_start :: proc(f: ^vorbis) -> c.int ---
// these functions return the total length of the vorbis stream
stream_length_in_samples :: proc(f: ^vorbis) -> c.uint ---
stream_length_in_seconds :: proc(f: ^vorbis) -> f32 ---
// decode the next frame and return the number of samples. the number of
// channels returned are stored in *channels (which can be NULL--it is always
// the same as the number of channels reported by get_info). *output will
// contain an array of float* buffers, one per channel. These outputs will
// be overwritten on the next call to stb_vorbis_get_frame_*.
//
// You generally should not intermix calls to stb_vorbis_get_frame_*()
// and stb_vorbis_get_samples_*(), since the latter calls the former.
get_frame_float :: proc(f: ^vorbis, channels: ^c.int, output: ^[^]^f32) -> c.int ---
// decode the next frame and return the number of *samples* per channel.
// Note that for interleaved data, you pass in the number of shorts (the
// size of your array), but the return value is the number of samples per
// channel, not the total number of samples.
//
// The data is coerced to the number of channels you request according to the
// channel coercion rules (see below). You must pass in the size of your
// buffer(s) so that stb_vorbis will not overwrite the end of the buffer.
// The maximum buffer size needed can be gotten from get_info(); however,
// the Vorbis I specification implies an absolute maximum of 4096 samples
// per channel.
get_frame_short_interleaved :: proc(f: ^vorbis, num_c: c.int, buffer: [^]c.short, num_shorts: c.int) -> c.int ---
get_frame_short :: proc(f: ^vorbis, num_c: c.int, buffer: ^[^]c.short, num_samples: c.int) -> c.int ---
// Channel coercion rules:
// Let M be the number of channels requested, and N the number of channels present,
// and Cn be the nth channel; let stereo L be the sum of all L and center channels,
// and stereo R be the sum of all R and center channels (channel assignment from the
// vorbis spec).
// M N output
// 1 k sum(Ck) for all k
// 2 * stereo L, stereo R
// k l k > l, the first l channels, then 0s
// k l k <= l, the first k channels
// Note that this is not _good_ surround etc. mixing at all! It's just so
// you get something useful.
// gets num_samples samples, not necessarily on a frame boundary--this requires
// buffering so you have to supply the buffers. DOES NOT APPLY THE COERCION RULES.
// Returns the number of samples stored per channel; it may be less than requested
// at the end of the file. If there are no more samples in the file, returns 0.
get_samples_float_interleaved :: proc(f: ^vorbis, channels: c.int, buffer: [^]f32, num_floats: c.int) -> c.int ---
get_samples_float :: proc(f: ^vorbis, channels: c.int, buffer: ^[^]f32, num_samples: c.int) -> c.int ---
// gets num_samples samples, not necessarily on a frame boundary--this requires
// buffering so you have to supply the buffers. Applies the coercion rules above
// to produce 'channels' channels. Returns the number of samples stored per channel;
// it may be less than requested at the end of the file. If there are no more
// samples in the file, returns 0.
get_samples_short_interleaved :: proc(f: ^vorbis, channels: c.int, buffer: [^]c.short, num_shorts: c.int) -> c.int ---
get_samples_short :: proc(f: ^vorbis, channels: c.int, buffer: ^[^]c.short, num_samples: c.int) -> c.int ---
}
Error :: enum c.int {
none = 0,
need_more_data=1, // not a real error
invalid_api_mixing, // can't mix API modes
outofmem, // not enough memory
feature_not_supported, // uses floor 0
too_many_channels, // MAX_CHANNELS is too small
file_open_failure, // fopen() failed
seek_without_length, // can't seek in unknown-length file
unexpected_eof=10, // file is truncated?
seek_invalid, // seek past EOF
// decoding errors (corrupt/invalid stream) -- you probably
// don't care about the exact details of these
// vorbis errors:
invalid_setup=20,
invalid_stream,
// ogg errors:
missing_capture_pattern=30,
invalid_stream_structure_version,
continued_packet_flag_invalid,
incorrect_stream_serial_number,
invalid_first_page,
bad_packet_type,
cant_find_last_page,
seek_failed,
ogg_skeleton_not_supported,
}
// MAX_CHANNELS [number]
// globally define this to the maximum number of channels you need.
// The spec does not put a restriction on channels except that
// the count is stored in a byte, so 255 is the hard limit.
// Reducing this saves about 16 bytes per value, so using 16 saves
// (255-16)*16 or around 4KB. Plus anything other memory usage
// I forgot to account for. Can probably go as low as 8 (7.1 audio),
// 6 (5.1 audio), or 2 (stereo only).
MAX_CHANNELS :: 16 // enough for anyone?
// PUSHDATA_CRC_COUNT [number]
// after a flush_pushdata(), stb_vorbis begins scanning for the
// next valid page, without backtracking. when it finds something
// that looks like a page, it streams through it and verifies its
// CRC32. Should that validation fail, it keeps scanning. But it's
// possible that _while_ streaming through to check the CRC32 of
// one candidate page, it sees another candidate page. This #define
// determines how many "overlapping" candidate pages it can search
// at once. Note that "real" pages are typically ~4KB to ~8KB, whereas
// garbage pages could be as big as 64KB, but probably average ~16KB.
// So don't hose ourselves by scanning an apparent 64KB page and
// missing a ton of real ones in the interim; so minimum of 2
PUSHDATA_CRC_COUNT :: 4
// FAST_HUFFMAN_LENGTH [number]
// sets the log size of the huffman-acceleration table. Maximum
// supported value is 24. with larger numbers, more decodings are O(1),
// but the table size is larger so worse cache missing, so you'll have
// to probe (and try multiple ogg vorbis files) to find the sweet spot.
FAST_HUFFMAN_LENGTH :: 10
+43 -14
View File
@@ -38,7 +38,7 @@ def no_vk(t):
t = t.replace('VK_', '')
return t
def convert_type(t):
def convert_type(t, prev_name, curr_name):
table = {
"Bool32": 'b32',
"float": 'f32',
@@ -56,14 +56,14 @@ def convert_type(t):
"void*": "rawptr",
"void *": "rawptr",
"char*": 'cstring',
"const uint32_t* const*": "^^u32",
"const uint32_t* const*": "^[^]u32",
"const void*": 'rawptr',
"const char*": 'cstring',
"const char* const*": 'cstring_array',
"const char* const*": '[^]cstring',
"const ObjectTableEntryNVX* const*": "^^ObjectTableEntryNVX",
"const void* const *": "^rawptr",
"const AccelerationStructureGeometryKHR* const*": "^^AccelerationStructureGeometryKHR",
"const AccelerationStructureBuildRangeInfoKHR* const*": "^^AccelerationStructureBuildRangeInfoKHR",
"const void* const *": "[^]rawptr",
"const AccelerationStructureGeometryKHR* const*": "^[^]AccelerationStructureGeometryKHR",
"const AccelerationStructureBuildRangeInfoKHR* const*": "^[^]AccelerationStructureBuildRangeInfoKHR",
"struct BaseOutStructure": "BaseOutStructure",
"struct BaseInStructure": "BaseInStructure",
'v': '',
@@ -74,13 +74,32 @@ def convert_type(t):
if t == "":
return t
elif t.endswith("*"):
elem = ""
pointer = "^"
if t.startswith("const"):
ttype = t[6:len(t)-1]
return "^{}".format(convert_type(ttype))
elem = convert_type(ttype, prev_name, curr_name)
else:
ttype = t[:len(t)-1]
return "^{}".format(convert_type(ttype))
elem = convert_type(ttype, prev_name, curr_name)
if curr_name.endswith("s") or curr_name.endswith("Table"):
if prev_name.endswith("Count") or prev_name.endswith("Counts"):
pointer = "[^]"
elif curr_name.startswith("pp"):
if elem.startswith("[^]"):
pass
else:
pointer = "[^]"
elif curr_name.startswith("p"):
pointer = "[^]"
if curr_name and elem.endswith("Flags"):
pointer = "[^]"
return "{}{}".format(pointer, elem)
elif t[0].isupper():
return t
@@ -154,8 +173,8 @@ def fix_enum_arg(name, is_flag_bit=False):
name = name.replace("_BIT", "")
return name
def do_type(t):
return convert_type(no_vk(t)).replace("FlagBits", "Flags")
def do_type(t, prev_name="", name=""):
return convert_type(no_vk(t), prev_name, name).replace("FlagBits", "Flags")
def parse_handles_def(f):
f.write("// Handles types\n")
@@ -246,6 +265,8 @@ def parse_enums(f):
f.write("// Enums\n")
data = re.findall(r"typedef enum Vk(\w+) {(.+?)} \w+;", src, re.S)
data.sort(key=lambda x: x[0])
generated_flags = set()
@@ -354,6 +375,7 @@ def parse_enums(f):
unused_flags = [flag for flag in flags_defs if flag not in generated_flags]
unused_flags.sort()
max_len = max(len(flag) for flag in unused_flags)
for flag in unused_flags:
@@ -373,6 +395,7 @@ def parse_structs(f):
f.write("#raw_union ")
f.write("{\n")
prev_name = ""
ffields = []
for type_, fname in fields:
if '[' in fname:
@@ -381,11 +404,12 @@ def parse_structs(f):
n = fix_arg(fname)
if "Flag_Bits" in type_:
comment = " // only single bit set"
t = do_type(type_)
t = do_type(type_, prev_name, fname)
if t == "Structure_Type" and n == "type":
n = "s_type"
ffields.append(tuple([n, t, comment]))
prev_name = fname
max_len = max(len(n) for n, _, _ in ffields)
@@ -423,7 +447,14 @@ def parse_procedures(f):
for rt, name, fields in data:
proc_name = no_vk(name)
pf = [(do_type(t), fix_arg(n)) for t, n in re.findall(r"(?:\s*|)(.+?)\s*(\w+)(?:,|$)", fields)]
pf = []
prev_name = ""
for type_, fname in re.findall(r"(?:\s*|)(.+?)\s*(\w+)(?:,|$)", fields):
curr_name = fix_arg(fname)
pf.append((do_type(type_, prev_name, curr_name), curr_name))
prev_name = curr_name
data_fields = ', '.join(["{}: {}".format(n, t) for t, n in pf if t != ""])
ts = "proc \"c\" ({})".format(data_fields)
@@ -517,8 +548,6 @@ NonDispatchableHandle :: distinct u64
SetProcAddressType :: #type proc(p: rawptr, name: cstring)
cstring_array :: ^cstring // Helper Type
RemoteAddressNV :: distinct rawptr // Declared inline before MemoryGetRemoteAddressInfoNV
// Base constants
-2
View File
@@ -23,8 +23,6 @@ NonDispatchableHandle :: distinct u64
SetProcAddressType :: #type proc(p: rawptr, name: cstring)
cstring_array :: ^cstring // Helper Type
RemoteAddressNV :: distinct rawptr // Declared inline before MemoryGetRemoteAddressInfoNV
// Base constants
+2110 -2110
View File
File diff suppressed because it is too large Load Diff
+156 -156
View File
@@ -15,44 +15,44 @@ ProcReallocationFunction :: #type pro
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)
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
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
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)
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)
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
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
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
@@ -77,9 +77,9 @@ ProcDestroyShaderModule :: #type pro
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
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)
@@ -90,25 +90,25 @@ ProcDestroyDescriptorSetLayout :: #type pro
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)
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
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)
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)
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)
@@ -116,30 +116,30 @@ ProcCmdSetDepthBounds :: #type pro
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)
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)
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)
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)
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)
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)
@@ -149,24 +149,24 @@ ProcCmdPushConstants :: #type pro
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)
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)
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)
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
@@ -174,13 +174,13 @@ ProcDestroySamplerYcbcrConversion :: #type pro
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)
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
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)
@@ -193,81 +193,81 @@ ProcGetBufferOpaqueCaptureAddress :: #type pro
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
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
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
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
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
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)
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)
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)
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)
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
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)
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)
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)
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
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
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
@@ -278,15 +278,15 @@ ProcDestroyDeferredOperationKHR :: #type pro
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
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)
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
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)
@@ -304,9 +304,9 @@ ProcDebugMarkerSetObjectNameEXT :: #type pro
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)
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)
@@ -316,24 +316,24 @@ ProcDestroyCuModuleNVX :: #type pro
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
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
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)
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
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)
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
@@ -347,36 +347,36 @@ ProcCreateDebugUtilsMessengerEXT :: #type pro
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
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
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)
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
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
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)
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
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
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)
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
@@ -390,25 +390,25 @@ ProcQueueSetPerformanceConfigurationINTEL :: #type pro
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
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)
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)
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)
@@ -424,11 +424,11 @@ ProcGetPrivateDataEXT :: #type pro
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)
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
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)
@@ -439,39 +439,39 @@ ProcCmdDrawMultiIndexedEXT :: #type pro
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
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
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)
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
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)
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
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
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
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
ProcCreateIOSSurfaceMVK :: #type proc "system" (instance: Instance, pCreateInfo: ^IOSSurfaceCreateInfoMVK, pAllocator: ^AllocationCallbacks, pSurface: ^SurfaceKHR) -> Result
+163 -163
View File
@@ -181,9 +181,9 @@ InstanceCreateInfo :: struct {
flags: InstanceCreateFlags,
pApplicationInfo: ^ApplicationInfo,
enabledLayerCount: u32,
ppEnabledLayerNames: cstring_array,
ppEnabledLayerNames: [^]cstring,
enabledExtensionCount: u32,
ppEnabledExtensionNames: cstring_array,
ppEnabledExtensionNames: [^]cstring,
}
MemoryHeap :: struct {
@@ -403,7 +403,7 @@ DeviceQueueCreateInfo :: struct {
flags: DeviceQueueCreateFlags,
queueFamilyIndex: u32,
queueCount: u32,
pQueuePriorities: ^f32,
pQueuePriorities: [^]f32,
}
DeviceCreateInfo :: struct {
@@ -411,12 +411,12 @@ DeviceCreateInfo :: struct {
pNext: rawptr,
flags: DeviceCreateFlags,
queueCreateInfoCount: u32,
pQueueCreateInfos: ^DeviceQueueCreateInfo,
pQueueCreateInfos: [^]DeviceQueueCreateInfo,
enabledLayerCount: u32,
ppEnabledLayerNames: cstring_array,
ppEnabledLayerNames: [^]cstring,
enabledExtensionCount: u32,
ppEnabledExtensionNames: cstring_array,
pEnabledFeatures: ^PhysicalDeviceFeatures,
ppEnabledExtensionNames: [^]cstring,
pEnabledFeatures: [^]PhysicalDeviceFeatures,
}
ExtensionProperties :: struct {
@@ -435,12 +435,12 @@ SubmitInfo :: struct {
sType: StructureType,
pNext: rawptr,
waitSemaphoreCount: u32,
pWaitSemaphores: ^Semaphore,
pWaitDstStageMask: ^PipelineStageFlags,
pWaitSemaphores: [^]Semaphore,
pWaitDstStageMask: [^]PipelineStageFlags,
commandBufferCount: u32,
pCommandBuffers: ^CommandBuffer,
pCommandBuffers: [^]CommandBuffer,
signalSemaphoreCount: u32,
pSignalSemaphores: ^Semaphore,
pSignalSemaphores: [^]Semaphore,
}
MappedMemoryRange :: struct {
@@ -475,13 +475,13 @@ SparseMemoryBind :: struct {
SparseBufferMemoryBindInfo :: struct {
buffer: Buffer,
bindCount: u32,
pBinds: ^SparseMemoryBind,
pBinds: [^]SparseMemoryBind,
}
SparseImageOpaqueMemoryBindInfo :: struct {
image: Image,
bindCount: u32,
pBinds: ^SparseMemoryBind,
pBinds: [^]SparseMemoryBind,
}
ImageSubresource :: struct {
@@ -502,22 +502,22 @@ SparseImageMemoryBind :: struct {
SparseImageMemoryBindInfo :: struct {
image: Image,
bindCount: u32,
pBinds: ^SparseImageMemoryBind,
pBinds: [^]SparseImageMemoryBind,
}
BindSparseInfo :: struct {
sType: StructureType,
pNext: rawptr,
waitSemaphoreCount: u32,
pWaitSemaphores: ^Semaphore,
pWaitSemaphores: [^]Semaphore,
bufferBindCount: u32,
pBufferBinds: ^SparseBufferMemoryBindInfo,
pBufferBinds: [^]SparseBufferMemoryBindInfo,
imageOpaqueBindCount: u32,
pImageOpaqueBinds: ^SparseImageOpaqueMemoryBindInfo,
pImageOpaqueBinds: [^]SparseImageOpaqueMemoryBindInfo,
imageBindCount: u32,
pImageBinds: ^SparseImageMemoryBindInfo,
pImageBinds: [^]SparseImageMemoryBindInfo,
signalSemaphoreCount: u32,
pSignalSemaphores: ^Semaphore,
pSignalSemaphores: [^]Semaphore,
}
SparseImageFormatProperties :: struct {
@@ -569,7 +569,7 @@ BufferCreateInfo :: struct {
usage: BufferUsageFlags,
sharingMode: SharingMode,
queueFamilyIndexCount: u32,
pQueueFamilyIndices: ^u32,
pQueueFamilyIndices: [^]u32,
}
BufferViewCreateInfo :: struct {
@@ -596,7 +596,7 @@ ImageCreateInfo :: struct {
usage: ImageUsageFlags,
sharingMode: SharingMode,
queueFamilyIndexCount: u32,
pQueueFamilyIndices: ^u32,
pQueueFamilyIndices: [^]u32,
initialLayout: ImageLayout,
}
@@ -650,7 +650,7 @@ SpecializationMapEntry :: struct {
SpecializationInfo :: struct {
mapEntryCount: u32,
pMapEntries: ^SpecializationMapEntry,
pMapEntries: [^]SpecializationMapEntry,
dataSize: int,
pData: rawptr,
}
@@ -693,9 +693,9 @@ PipelineVertexInputStateCreateInfo :: struct {
pNext: rawptr,
flags: PipelineVertexInputStateCreateFlags,
vertexBindingDescriptionCount: u32,
pVertexBindingDescriptions: ^VertexInputBindingDescription,
pVertexBindingDescriptions: [^]VertexInputBindingDescription,
vertexAttributeDescriptionCount: u32,
pVertexAttributeDescriptions: ^VertexInputAttributeDescription,
pVertexAttributeDescriptions: [^]VertexInputAttributeDescription,
}
PipelineInputAssemblyStateCreateInfo :: struct {
@@ -727,9 +727,9 @@ PipelineViewportStateCreateInfo :: struct {
pNext: rawptr,
flags: PipelineViewportStateCreateFlags,
viewportCount: u32,
pViewports: ^Viewport,
pViewports: [^]Viewport,
scissorCount: u32,
pScissors: ^Rect2D,
pScissors: [^]Rect2D,
}
PipelineRasterizationStateCreateInfo :: struct {
@@ -803,7 +803,7 @@ PipelineColorBlendStateCreateInfo :: struct {
logicOpEnable: b32,
logicOp: LogicOp,
attachmentCount: u32,
pAttachments: ^PipelineColorBlendAttachmentState,
pAttachments: [^]PipelineColorBlendAttachmentState,
blendConstants: [4]f32,
}
@@ -812,7 +812,7 @@ PipelineDynamicStateCreateInfo :: struct {
pNext: rawptr,
flags: PipelineDynamicStateCreateFlags,
dynamicStateCount: u32,
pDynamicStates: ^DynamicState,
pDynamicStates: [^]DynamicState,
}
GraphicsPipelineCreateInfo :: struct {
@@ -820,7 +820,7 @@ GraphicsPipelineCreateInfo :: struct {
pNext: rawptr,
flags: PipelineCreateFlags,
stageCount: u32,
pStages: ^PipelineShaderStageCreateInfo,
pStages: [^]PipelineShaderStageCreateInfo,
pVertexInputState: ^PipelineVertexInputStateCreateInfo,
pInputAssemblyState: ^PipelineInputAssemblyStateCreateInfo,
pTessellationState: ^PipelineTessellationStateCreateInfo,
@@ -848,9 +848,9 @@ PipelineLayoutCreateInfo :: struct {
pNext: rawptr,
flags: PipelineLayoutCreateFlags,
setLayoutCount: u32,
pSetLayouts: ^DescriptorSetLayout,
pSetLayouts: [^]DescriptorSetLayout,
pushConstantRangeCount: u32,
pPushConstantRanges: ^PushConstantRange,
pPushConstantRanges: [^]PushConstantRange,
}
SamplerCreateInfo :: struct {
@@ -909,7 +909,7 @@ DescriptorPoolCreateInfo :: struct {
flags: DescriptorPoolCreateFlags,
maxSets: u32,
poolSizeCount: u32,
pPoolSizes: ^DescriptorPoolSize,
pPoolSizes: [^]DescriptorPoolSize,
}
DescriptorSetAllocateInfo :: struct {
@@ -917,7 +917,7 @@ DescriptorSetAllocateInfo :: struct {
pNext: rawptr,
descriptorPool: DescriptorPool,
descriptorSetCount: u32,
pSetLayouts: ^DescriptorSetLayout,
pSetLayouts: [^]DescriptorSetLayout,
}
DescriptorSetLayoutBinding :: struct {
@@ -925,7 +925,7 @@ DescriptorSetLayoutBinding :: struct {
descriptorType: DescriptorType,
descriptorCount: u32,
stageFlags: ShaderStageFlags,
pImmutableSamplers: ^Sampler,
pImmutableSamplers: [^]Sampler,
}
DescriptorSetLayoutCreateInfo :: struct {
@@ -933,7 +933,7 @@ DescriptorSetLayoutCreateInfo :: struct {
pNext: rawptr,
flags: DescriptorSetLayoutCreateFlags,
bindingCount: u32,
pBindings: ^DescriptorSetLayoutBinding,
pBindings: [^]DescriptorSetLayoutBinding,
}
WriteDescriptorSet :: struct {
@@ -972,7 +972,7 @@ FramebufferCreateInfo :: struct {
flags: FramebufferCreateFlags,
renderPass: RenderPass,
attachmentCount: u32,
pAttachments: ^ImageView,
pAttachments: [^]ImageView,
width: u32,
height: u32,
layers: u32,
@@ -982,13 +982,13 @@ SubpassDescription :: struct {
flags: SubpassDescriptionFlags,
pipelineBindPoint: PipelineBindPoint,
inputAttachmentCount: u32,
pInputAttachments: ^AttachmentReference,
pInputAttachments: [^]AttachmentReference,
colorAttachmentCount: u32,
pColorAttachments: ^AttachmentReference,
pResolveAttachments: ^AttachmentReference,
pColorAttachments: [^]AttachmentReference,
pResolveAttachments: [^]AttachmentReference,
pDepthStencilAttachment: ^AttachmentReference,
preserveAttachmentCount: u32,
pPreserveAttachments: ^u32,
pPreserveAttachments: [^]u32,
}
SubpassDependency :: struct {
@@ -1006,11 +1006,11 @@ RenderPassCreateInfo :: struct {
pNext: rawptr,
flags: RenderPassCreateFlags,
attachmentCount: u32,
pAttachments: ^AttachmentDescription,
pAttachments: [^]AttachmentDescription,
subpassCount: u32,
pSubpasses: ^SubpassDescription,
pSubpasses: [^]SubpassDescription,
dependencyCount: u32,
pDependencies: ^SubpassDependency,
pDependencies: [^]SubpassDependency,
}
CommandPoolCreateInfo :: struct {
@@ -1126,7 +1126,7 @@ RenderPassBeginInfo :: struct {
framebuffer: Framebuffer,
renderArea: Rect2D,
clearValueCount: u32,
pClearValues: ^ClearValue,
pClearValues: [^]ClearValue,
}
PhysicalDeviceSubgroupProperties :: struct {
@@ -1189,7 +1189,7 @@ DeviceGroupRenderPassBeginInfo :: struct {
pNext: rawptr,
deviceMask: u32,
deviceRenderAreaCount: u32,
pDeviceRenderAreas: ^Rect2D,
pDeviceRenderAreas: [^]Rect2D,
}
DeviceGroupCommandBufferBeginInfo :: struct {
@@ -1202,11 +1202,11 @@ DeviceGroupSubmitInfo :: struct {
sType: StructureType,
pNext: rawptr,
waitSemaphoreCount: u32,
pWaitSemaphoreDeviceIndices: ^u32,
pWaitSemaphoreDeviceIndices: [^]u32,
commandBufferCount: u32,
pCommandBufferDeviceMasks: ^u32,
pCommandBufferDeviceMasks: [^]u32,
signalSemaphoreCount: u32,
pSignalSemaphoreDeviceIndices: ^u32,
pSignalSemaphoreDeviceIndices: [^]u32,
}
DeviceGroupBindSparseInfo :: struct {
@@ -1220,16 +1220,16 @@ BindBufferMemoryDeviceGroupInfo :: struct {
sType: StructureType,
pNext: rawptr,
deviceIndexCount: u32,
pDeviceIndices: ^u32,
pDeviceIndices: [^]u32,
}
BindImageMemoryDeviceGroupInfo :: struct {
sType: StructureType,
pNext: rawptr,
deviceIndexCount: u32,
pDeviceIndices: ^u32,
pDeviceIndices: [^]u32,
splitInstanceBindRegionCount: u32,
pSplitInstanceBindRegions: ^Rect2D,
pSplitInstanceBindRegions: [^]Rect2D,
}
PhysicalDeviceGroupProperties :: struct {
@@ -1244,7 +1244,7 @@ DeviceGroupDeviceCreateInfo :: struct {
sType: StructureType,
pNext: rawptr,
physicalDeviceCount: u32,
pPhysicalDevices: ^PhysicalDevice,
pPhysicalDevices: [^]PhysicalDevice,
}
BufferMemoryRequirementsInfo2 :: struct {
@@ -1355,7 +1355,7 @@ RenderPassInputAttachmentAspectCreateInfo :: struct {
sType: StructureType,
pNext: rawptr,
aspectReferenceCount: u32,
pAspectReferences: ^InputAttachmentAspectReference,
pAspectReferences: [^]InputAttachmentAspectReference,
}
ImageViewUsageCreateInfo :: struct {
@@ -1374,11 +1374,11 @@ RenderPassMultiviewCreateInfo :: struct {
sType: StructureType,
pNext: rawptr,
subpassCount: u32,
pViewMasks: ^u32,
pViewMasks: [^]u32,
dependencyCount: u32,
pViewOffsets: ^i32,
pViewOffsets: [^]i32,
correlationMaskCount: u32,
pCorrelationMasks: ^u32,
pCorrelationMasks: [^]u32,
}
PhysicalDeviceMultiviewFeatures :: struct {
@@ -1486,7 +1486,7 @@ DescriptorUpdateTemplateCreateInfo :: struct {
pNext: rawptr,
flags: DescriptorUpdateTemplateCreateFlags,
descriptorUpdateEntryCount: u32,
pDescriptorUpdateEntries: ^DescriptorUpdateTemplateEntry,
pDescriptorUpdateEntries: [^]DescriptorUpdateTemplateEntry,
templateType: DescriptorUpdateTemplateType,
descriptorSetLayout: DescriptorSetLayout,
pipelineBindPoint: PipelineBindPoint,
@@ -1770,7 +1770,7 @@ ImageFormatListCreateInfo :: struct {
sType: StructureType,
pNext: rawptr,
viewFormatCount: u32,
pViewFormats: ^Format,
pViewFormats: [^]Format,
}
AttachmentDescription2 :: struct {
@@ -1802,13 +1802,13 @@ SubpassDescription2 :: struct {
pipelineBindPoint: PipelineBindPoint,
viewMask: u32,
inputAttachmentCount: u32,
pInputAttachments: ^AttachmentReference2,
pInputAttachments: [^]AttachmentReference2,
colorAttachmentCount: u32,
pColorAttachments: ^AttachmentReference2,
pResolveAttachments: ^AttachmentReference2,
pColorAttachments: [^]AttachmentReference2,
pResolveAttachments: [^]AttachmentReference2,
pDepthStencilAttachment: ^AttachmentReference2,
preserveAttachmentCount: u32,
pPreserveAttachments: ^u32,
pPreserveAttachments: [^]u32,
}
SubpassDependency2 :: struct {
@@ -1829,13 +1829,13 @@ RenderPassCreateInfo2 :: struct {
pNext: rawptr,
flags: RenderPassCreateFlags,
attachmentCount: u32,
pAttachments: ^AttachmentDescription2,
pAttachments: [^]AttachmentDescription2,
subpassCount: u32,
pSubpasses: ^SubpassDescription2,
pSubpasses: [^]SubpassDescription2,
dependencyCount: u32,
pDependencies: ^SubpassDependency2,
pDependencies: [^]SubpassDependency2,
correlatedViewMaskCount: u32,
pCorrelatedViewMasks: ^u32,
pCorrelatedViewMasks: [^]u32,
}
SubpassBeginInfo :: struct {
@@ -1906,7 +1906,7 @@ DescriptorSetLayoutBindingFlagsCreateInfo :: struct {
sType: StructureType,
pNext: rawptr,
bindingCount: u32,
pBindingFlags: ^DescriptorBindingFlags,
pBindingFlags: [^]DescriptorBindingFlags,
}
PhysicalDeviceDescriptorIndexingFeatures :: struct {
@@ -1966,7 +1966,7 @@ DescriptorSetVariableDescriptorCountAllocateInfo :: struct {
sType: StructureType,
pNext: rawptr,
descriptorSetCount: u32,
pDescriptorCounts: ^u32,
pDescriptorCounts: [^]u32,
}
DescriptorSetVariableDescriptorCountLayoutSupport :: struct {
@@ -2040,21 +2040,21 @@ FramebufferAttachmentImageInfo :: struct {
height: u32,
layerCount: u32,
viewFormatCount: u32,
pViewFormats: ^Format,
pViewFormats: [^]Format,
}
FramebufferAttachmentsCreateInfo :: struct {
sType: StructureType,
pNext: rawptr,
attachmentImageInfoCount: u32,
pAttachmentImageInfos: ^FramebufferAttachmentImageInfo,
pAttachmentImageInfos: [^]FramebufferAttachmentImageInfo,
}
RenderPassAttachmentBeginInfo :: struct {
sType: StructureType,
pNext: rawptr,
attachmentCount: u32,
pAttachments: ^ImageView,
pAttachments: [^]ImageView,
}
PhysicalDeviceUniformBufferStandardLayoutFeatures :: struct {
@@ -2117,9 +2117,9 @@ TimelineSemaphoreSubmitInfo :: struct {
sType: StructureType,
pNext: rawptr,
waitSemaphoreValueCount: u32,
pWaitSemaphoreValues: ^u64,
pWaitSemaphoreValues: [^]u64,
signalSemaphoreValueCount: u32,
pSignalSemaphoreValues: ^u64,
pSignalSemaphoreValues: [^]u64,
}
SemaphoreWaitInfo :: struct {
@@ -2127,8 +2127,8 @@ SemaphoreWaitInfo :: struct {
pNext: rawptr,
flags: SemaphoreWaitFlags,
semaphoreCount: u32,
pSemaphores: ^Semaphore,
pValues: ^u64,
pSemaphores: [^]Semaphore,
pValues: [^]u64,
}
SemaphoreSignalInfo :: struct {
@@ -2201,7 +2201,7 @@ SwapchainCreateInfoKHR :: struct {
imageUsage: ImageUsageFlags,
imageSharingMode: SharingMode,
queueFamilyIndexCount: u32,
pQueueFamilyIndices: ^u32,
pQueueFamilyIndices: [^]u32,
preTransform: SurfaceTransformFlagsKHR,
compositeAlpha: CompositeAlphaFlagsKHR,
presentMode: PresentModeKHR,
@@ -2213,11 +2213,11 @@ PresentInfoKHR :: struct {
sType: StructureType,
pNext: rawptr,
waitSemaphoreCount: u32,
pWaitSemaphores: ^Semaphore,
pWaitSemaphores: [^]Semaphore,
swapchainCount: u32,
pSwapchains: ^SwapchainKHR,
pImageIndices: ^u32,
pResults: ^Result,
pSwapchains: [^]SwapchainKHR,
pImageIndices: [^]u32,
pResults: [^]Result,
}
ImageSwapchainCreateInfoKHR :: struct {
@@ -2254,7 +2254,7 @@ DeviceGroupPresentInfoKHR :: struct {
sType: StructureType,
pNext: rawptr,
swapchainCount: u32,
pDeviceMasks: ^u32,
pDeviceMasks: [^]u32,
mode: DeviceGroupPresentModeFlagsKHR,
}
@@ -2379,14 +2379,14 @@ RectLayerKHR :: struct {
PresentRegionKHR :: struct {
rectangleCount: u32,
pRectangles: ^RectLayerKHR,
pRectangles: [^]RectLayerKHR,
}
PresentRegionsKHR :: struct {
sType: StructureType,
pNext: rawptr,
swapchainCount: u32,
pRegions: ^PresentRegionKHR,
pRegions: [^]PresentRegionKHR,
}
SharedPresentSurfaceCapabilitiesKHR :: struct {
@@ -2447,7 +2447,7 @@ QueryPoolPerformanceCreateInfoKHR :: struct {
pNext: rawptr,
queueFamilyIndex: u32,
counterIndexCount: u32,
pCounterIndices: ^u32,
pCounterIndices: [^]u32,
}
PerformanceCounterResultKHR :: struct #raw_union {
@@ -2696,14 +2696,14 @@ PipelineLibraryCreateInfoKHR :: struct {
sType: StructureType,
pNext: rawptr,
libraryCount: u32,
pLibraries: ^Pipeline,
pLibraries: [^]Pipeline,
}
PresentIdKHR :: struct {
sType: StructureType,
pNext: rawptr,
swapchainCount: u32,
pPresentIds: ^u64,
pPresentIds: [^]u64,
}
PhysicalDevicePresentIdFeaturesKHR :: struct {
@@ -2755,11 +2755,11 @@ DependencyInfoKHR :: struct {
pNext: rawptr,
dependencyFlags: DependencyFlags,
memoryBarrierCount: u32,
pMemoryBarriers: ^MemoryBarrier2KHR,
pMemoryBarriers: [^]MemoryBarrier2KHR,
bufferMemoryBarrierCount: u32,
pBufferMemoryBarriers: ^BufferMemoryBarrier2KHR,
pBufferMemoryBarriers: [^]BufferMemoryBarrier2KHR,
imageMemoryBarrierCount: u32,
pImageMemoryBarriers: ^ImageMemoryBarrier2KHR,
pImageMemoryBarriers: [^]ImageMemoryBarrier2KHR,
}
SemaphoreSubmitInfoKHR :: struct {
@@ -2783,11 +2783,11 @@ SubmitInfo2KHR :: struct {
pNext: rawptr,
flags: SubmitFlagsKHR,
waitSemaphoreInfoCount: u32,
pWaitSemaphoreInfos: ^SemaphoreSubmitInfoKHR,
pWaitSemaphoreInfos: [^]SemaphoreSubmitInfoKHR,
commandBufferInfoCount: u32,
pCommandBufferInfos: ^CommandBufferSubmitInfoKHR,
pCommandBufferInfos: [^]CommandBufferSubmitInfoKHR,
signalSemaphoreInfoCount: u32,
pSignalSemaphoreInfos: ^SemaphoreSubmitInfoKHR,
pSignalSemaphoreInfos: [^]SemaphoreSubmitInfoKHR,
}
PhysicalDeviceSynchronization2FeaturesKHR :: struct {
@@ -2844,7 +2844,7 @@ CopyBufferInfo2KHR :: struct {
srcBuffer: Buffer,
dstBuffer: Buffer,
regionCount: u32,
pRegions: ^BufferCopy2KHR,
pRegions: [^]BufferCopy2KHR,
}
ImageCopy2KHR :: struct {
@@ -2865,7 +2865,7 @@ CopyImageInfo2KHR :: struct {
dstImage: Image,
dstImageLayout: ImageLayout,
regionCount: u32,
pRegions: ^ImageCopy2KHR,
pRegions: [^]ImageCopy2KHR,
}
BufferImageCopy2KHR :: struct {
@@ -2886,7 +2886,7 @@ CopyBufferToImageInfo2KHR :: struct {
dstImage: Image,
dstImageLayout: ImageLayout,
regionCount: u32,
pRegions: ^BufferImageCopy2KHR,
pRegions: [^]BufferImageCopy2KHR,
}
CopyImageToBufferInfo2KHR :: struct {
@@ -2896,7 +2896,7 @@ CopyImageToBufferInfo2KHR :: struct {
srcImageLayout: ImageLayout,
dstBuffer: Buffer,
regionCount: u32,
pRegions: ^BufferImageCopy2KHR,
pRegions: [^]BufferImageCopy2KHR,
}
ImageBlit2KHR :: struct {
@@ -2916,7 +2916,7 @@ BlitImageInfo2KHR :: struct {
dstImage: Image,
dstImageLayout: ImageLayout,
regionCount: u32,
pRegions: ^ImageBlit2KHR,
pRegions: [^]ImageBlit2KHR,
filter: Filter,
}
@@ -2938,7 +2938,7 @@ ResolveImageInfo2KHR :: struct {
dstImage: Image,
dstImageLayout: ImageLayout,
regionCount: u32,
pRegions: ^ImageResolve2KHR,
pRegions: [^]ImageResolve2KHR,
}
DebugReportCallbackCreateInfoEXT :: struct {
@@ -3054,9 +3054,9 @@ CuLaunchInfoNVX :: struct {
blockDimZ: u32,
sharedMemBytes: u32,
paramCount: int,
pParams: ^rawptr,
pParams: [^]rawptr,
extraCount: int,
pExtras: ^rawptr,
pExtras: [^]rawptr,
}
ImageViewHandleInfoNVX :: struct {
@@ -3127,7 +3127,7 @@ ValidationFlagsEXT :: struct {
sType: StructureType,
pNext: rawptr,
disabledValidationCheckCount: u32,
pDisabledValidationChecks: ^ValidationCheckEXT,
pDisabledValidationChecks: [^]ValidationCheckEXT,
}
PhysicalDeviceTextureCompressionASTCHDRFeaturesEXT :: struct {
@@ -3179,7 +3179,7 @@ PipelineViewportWScalingStateCreateInfoNV :: struct {
pNext: rawptr,
viewportWScalingEnable: b32,
viewportCount: u32,
pViewportWScalings: ^ViewportWScalingNV,
pViewportWScalings: [^]ViewportWScalingNV,
}
SurfaceCapabilities2EXT :: struct {
@@ -3243,7 +3243,7 @@ PresentTimesInfoGOOGLE :: struct {
sType: StructureType,
pNext: rawptr,
swapchainCount: u32,
pTimes: ^PresentTimeGOOGLE,
pTimes: [^]PresentTimeGOOGLE,
}
PhysicalDeviceMultiviewPerViewAttributesPropertiesNVX :: struct {
@@ -3264,7 +3264,7 @@ PipelineViewportSwizzleStateCreateInfoNV :: struct {
pNext: rawptr,
flags: PipelineViewportSwizzleStateCreateFlagsNV,
viewportCount: u32,
pViewportSwizzles: ^ViewportSwizzleNV,
pViewportSwizzles: [^]ViewportSwizzleNV,
}
PhysicalDeviceDiscardRectanglePropertiesEXT :: struct {
@@ -3279,7 +3279,7 @@ PipelineDiscardRectangleStateCreateInfoEXT :: struct {
flags: PipelineDiscardRectangleStateCreateFlagsEXT,
discardRectangleMode: DiscardRectangleModeEXT,
discardRectangleCount: u32,
pDiscardRectangles: ^Rect2D,
pDiscardRectangles: [^]Rect2D,
}
PhysicalDeviceConservativeRasterizationPropertiesEXT :: struct {
@@ -3358,11 +3358,11 @@ DebugUtilsMessengerCallbackDataEXT :: struct {
messageIdNumber: i32,
pMessage: cstring,
queueLabelCount: u32,
pQueueLabels: ^DebugUtilsLabelEXT,
pQueueLabels: [^]DebugUtilsLabelEXT,
cmdBufLabelCount: u32,
pCmdBufLabels: ^DebugUtilsLabelEXT,
pCmdBufLabels: [^]DebugUtilsLabelEXT,
objectCount: u32,
pObjects: ^DebugUtilsObjectNameInfoEXT,
pObjects: [^]DebugUtilsObjectNameInfoEXT,
}
DebugUtilsMessengerCreateInfoEXT :: struct {
@@ -3426,7 +3426,7 @@ SampleLocationsInfoEXT :: struct {
sampleLocationsPerPixel: SampleCountFlags,
sampleLocationGridSize: Extent2D,
sampleLocationsCount: u32,
pSampleLocations: ^SampleLocationEXT,
pSampleLocations: [^]SampleLocationEXT,
}
AttachmentSampleLocationsEXT :: struct {
@@ -3443,9 +3443,9 @@ RenderPassSampleLocationsBeginInfoEXT :: struct {
sType: StructureType,
pNext: rawptr,
attachmentInitialSampleLocationsCount: u32,
pAttachmentInitialSampleLocations: ^AttachmentSampleLocationsEXT,
pAttachmentInitialSampleLocations: [^]AttachmentSampleLocationsEXT,
postSubpassSampleLocationsCount: u32,
pPostSubpassSampleLocations: ^SubpassSampleLocationsEXT,
pPostSubpassSampleLocations: [^]SubpassSampleLocationsEXT,
}
PipelineSampleLocationsStateCreateInfoEXT :: struct {
@@ -3511,7 +3511,7 @@ PipelineCoverageModulationStateCreateInfoNV :: struct {
coverageModulationMode: CoverageModulationModeNV,
coverageModulationTableEnable: b32,
coverageModulationTableCount: u32,
pCoverageModulationTable: ^f32,
pCoverageModulationTable: [^]f32,
}
PhysicalDeviceShaderSMBuiltinsPropertiesNV :: struct {
@@ -3537,7 +3537,7 @@ DrmFormatModifierPropertiesListEXT :: struct {
sType: StructureType,
pNext: rawptr,
drmFormatModifierCount: u32,
pDrmFormatModifierProperties: ^DrmFormatModifierPropertiesEXT,
pDrmFormatModifierProperties: [^]DrmFormatModifierPropertiesEXT,
}
PhysicalDeviceImageDrmFormatModifierInfoEXT :: struct {
@@ -3546,14 +3546,14 @@ PhysicalDeviceImageDrmFormatModifierInfoEXT :: struct {
drmFormatModifier: u64,
sharingMode: SharingMode,
queueFamilyIndexCount: u32,
pQueueFamilyIndices: ^u32,
pQueueFamilyIndices: [^]u32,
}
ImageDrmFormatModifierListCreateInfoEXT :: struct {
sType: StructureType,
pNext: rawptr,
drmFormatModifierCount: u32,
pDrmFormatModifiers: ^u64,
pDrmFormatModifiers: [^]u64,
}
ImageDrmFormatModifierExplicitCreateInfoEXT :: struct {
@@ -3561,7 +3561,7 @@ ImageDrmFormatModifierExplicitCreateInfoEXT :: struct {
pNext: rawptr,
drmFormatModifier: u64,
drmFormatModifierPlaneCount: u32,
pPlaneLayouts: ^SubresourceLayout,
pPlaneLayouts: [^]SubresourceLayout,
}
ImageDrmFormatModifierPropertiesEXT :: struct {
@@ -3586,7 +3586,7 @@ ShaderModuleValidationCacheCreateInfoEXT :: struct {
ShadingRatePaletteNV :: struct {
shadingRatePaletteEntryCount: u32,
pShadingRatePaletteEntries: ^ShadingRatePaletteEntryNV,
pShadingRatePaletteEntries: [^]ShadingRatePaletteEntryNV,
}
PipelineViewportShadingRateImageStateCreateInfoNV :: struct {
@@ -3594,7 +3594,7 @@ PipelineViewportShadingRateImageStateCreateInfoNV :: struct {
pNext: rawptr,
shadingRateImageEnable: b32,
viewportCount: u32,
pShadingRatePalettes: ^ShadingRatePaletteNV,
pShadingRatePalettes: [^]ShadingRatePaletteNV,
}
PhysicalDeviceShadingRateImageFeaturesNV :: struct {
@@ -3622,7 +3622,7 @@ CoarseSampleOrderCustomNV :: struct {
shadingRate: ShadingRatePaletteEntryNV,
sampleCount: u32,
sampleLocationCount: u32,
pSampleLocations: ^CoarseSampleLocationNV,
pSampleLocations: [^]CoarseSampleLocationNV,
}
PipelineViewportCoarseSampleOrderStateCreateInfoNV :: struct {
@@ -3630,7 +3630,7 @@ PipelineViewportCoarseSampleOrderStateCreateInfoNV :: struct {
pNext: rawptr,
sampleOrderType: CoarseSampleOrderTypeNV,
customSampleOrderCount: u32,
pCustomSampleOrders: ^CoarseSampleOrderCustomNV,
pCustomSampleOrders: [^]CoarseSampleOrderCustomNV,
}
RayTracingShaderGroupCreateInfoNV :: struct {
@@ -3648,9 +3648,9 @@ RayTracingPipelineCreateInfoNV :: struct {
pNext: rawptr,
flags: PipelineCreateFlags,
stageCount: u32,
pStages: ^PipelineShaderStageCreateInfo,
pStages: [^]PipelineShaderStageCreateInfo,
groupCount: u32,
pGroups: ^RayTracingShaderGroupCreateInfoNV,
pGroups: [^]RayTracingShaderGroupCreateInfoNV,
maxRecursionDepth: u32,
layout: PipelineLayout,
basePipelineHandle: Pipeline,
@@ -3702,7 +3702,7 @@ AccelerationStructureInfoNV :: struct {
flags: BuildAccelerationStructureFlagsNV,
instanceCount: u32,
geometryCount: u32,
pGeometries: ^GeometryNV,
pGeometries: [^]GeometryNV,
}
AccelerationStructureCreateInfoNV :: struct {
@@ -3719,14 +3719,14 @@ BindAccelerationStructureMemoryInfoNV :: struct {
memory: DeviceMemory,
memoryOffset: DeviceSize,
deviceIndexCount: u32,
pDeviceIndices: ^u32,
pDeviceIndices: [^]u32,
}
WriteDescriptorSetAccelerationStructureNV :: struct {
sType: StructureType,
pNext: rawptr,
accelerationStructureCount: u32,
pAccelerationStructures: ^AccelerationStructureNV,
pAccelerationStructures: [^]AccelerationStructureNV,
}
AccelerationStructureMemoryRequirementsInfoNV :: struct {
@@ -3869,7 +3869,7 @@ PipelineVertexInputDivisorStateCreateInfoEXT :: struct {
sType: StructureType,
pNext: rawptr,
vertexBindingDivisorCount: u32,
pVertexBindingDivisors: ^VertexInputBindingDivisorDescriptionEXT,
pVertexBindingDivisors: [^]VertexInputBindingDivisorDescriptionEXT,
}
PhysicalDeviceVertexAttributeDivisorFeaturesEXT :: struct {
@@ -3889,7 +3889,7 @@ PipelineCreationFeedbackCreateInfoEXT :: struct {
pNext: rawptr,
pPipelineCreationFeedback: ^PipelineCreationFeedbackEXT,
pipelineStageCreationFeedbackCount: u32,
pPipelineStageCreationFeedbacks: ^PipelineCreationFeedbackEXT,
pPipelineStageCreationFeedbacks: [^]PipelineCreationFeedbackEXT,
}
PhysicalDeviceComputeShaderDerivativesFeaturesNV :: struct {
@@ -3945,7 +3945,7 @@ PipelineViewportExclusiveScissorStateCreateInfoNV :: struct {
sType: StructureType,
pNext: rawptr,
exclusiveScissorCount: u32,
pExclusiveScissors: ^Rect2D,
pExclusiveScissors: [^]Rect2D,
}
PhysicalDeviceExclusiveScissorFeaturesNV :: struct {
@@ -4162,9 +4162,9 @@ ValidationFeaturesEXT :: struct {
sType: StructureType,
pNext: rawptr,
enabledValidationFeatureCount: u32,
pEnabledValidationFeatures: ^ValidationFeatureEnableEXT,
pEnabledValidationFeatures: [^]ValidationFeatureEnableEXT,
disabledValidationFeatureCount: u32,
pDisabledValidationFeatures: ^ValidationFeatureDisableEXT,
pDisabledValidationFeatures: [^]ValidationFeatureDisableEXT,
}
CooperativeMatrixPropertiesNV :: struct {
@@ -4357,7 +4357,7 @@ GraphicsShaderGroupCreateInfoNV :: struct {
sType: StructureType,
pNext: rawptr,
stageCount: u32,
pStages: ^PipelineShaderStageCreateInfo,
pStages: [^]PipelineShaderStageCreateInfo,
pVertexInputState: ^PipelineVertexInputStateCreateInfo,
pTessellationState: ^PipelineTessellationStateCreateInfo,
}
@@ -4366,9 +4366,9 @@ GraphicsPipelineShaderGroupsCreateInfoNV :: struct {
sType: StructureType,
pNext: rawptr,
groupCount: u32,
pGroups: ^GraphicsShaderGroupCreateInfoNV,
pGroups: [^]GraphicsShaderGroupCreateInfoNV,
pipelineCount: u32,
pPipelines: ^Pipeline,
pPipelines: [^]Pipeline,
}
BindShaderGroupIndirectCommandNV :: struct {
@@ -4410,8 +4410,8 @@ IndirectCommandsLayoutTokenNV :: struct {
pushconstantSize: u32,
indirectStateFlags: IndirectStateFlagsNV,
indexTypeCount: u32,
pIndexTypes: ^IndexType,
pIndexTypeValues: ^u32,
pIndexTypes: [^]IndexType,
pIndexTypeValues: [^]u32,
}
IndirectCommandsLayoutCreateInfoNV :: struct {
@@ -4420,9 +4420,9 @@ IndirectCommandsLayoutCreateInfoNV :: struct {
flags: IndirectCommandsLayoutUsageFlagsNV,
pipelineBindPoint: PipelineBindPoint,
tokenCount: u32,
pTokens: ^IndirectCommandsLayoutTokenNV,
pTokens: [^]IndirectCommandsLayoutTokenNV,
streamCount: u32,
pStreamStrides: ^u32,
pStreamStrides: [^]u32,
}
GeneratedCommandsInfoNV :: struct {
@@ -4432,7 +4432,7 @@ GeneratedCommandsInfoNV :: struct {
pipeline: Pipeline,
indirectCommandsLayout: IndirectCommandsLayoutNV,
streamCount: u32,
pStreams: ^IndirectCommandsStreamNV,
pStreams: [^]IndirectCommandsStreamNV,
sequencesCount: u32,
preprocessBuffer: Buffer,
preprocessOffset: DeviceSize,
@@ -4463,7 +4463,7 @@ CommandBufferInheritanceViewportScissorInfoNV :: struct {
pNext: rawptr,
viewportScissor2D: b32,
viewportDepthCount: u32,
pViewportDepths: ^Viewport,
pViewportDepths: [^]Viewport,
}
PhysicalDeviceTexelBufferAlignmentFeaturesEXT :: struct {
@@ -4729,14 +4729,14 @@ PhysicalDeviceMutableDescriptorTypeFeaturesVALVE :: struct {
MutableDescriptorTypeListVALVE :: struct {
descriptorTypeCount: u32,
pDescriptorTypes: ^DescriptorType,
pDescriptorTypes: [^]DescriptorType,
}
MutableDescriptorTypeCreateInfoVALVE :: struct {
sType: StructureType,
pNext: rawptr,
mutableDescriptorTypeListCount: u32,
pMutableDescriptorTypeLists: ^MutableDescriptorTypeListVALVE,
pMutableDescriptorTypeLists: [^]MutableDescriptorTypeListVALVE,
}
PhysicalDeviceVertexInputDynamicStateFeaturesEXT :: struct {
@@ -4837,7 +4837,7 @@ PipelineColorWriteCreateInfoEXT :: struct {
sType: StructureType,
pNext: rawptr,
attachmentCount: u32,
pColorWriteEnables: ^b32,
pColorWriteEnables: [^]b32,
}
PhysicalDeviceGlobalPriorityQueryFeaturesEXT :: struct {
@@ -4943,8 +4943,8 @@ AccelerationStructureBuildGeometryInfoKHR :: struct {
srcAccelerationStructure: AccelerationStructureKHR,
dstAccelerationStructure: AccelerationStructureKHR,
geometryCount: u32,
pGeometries: ^AccelerationStructureGeometryKHR,
ppGeometries: ^^AccelerationStructureGeometryKHR,
pGeometries: [^]AccelerationStructureGeometryKHR,
ppGeometries: ^[^]AccelerationStructureGeometryKHR,
scratchData: DeviceOrHostAddressKHR,
}
@@ -4963,7 +4963,7 @@ WriteDescriptorSetAccelerationStructureKHR :: struct {
sType: StructureType,
pNext: rawptr,
accelerationStructureCount: u32,
pAccelerationStructures: ^AccelerationStructureKHR,
pAccelerationStructures: [^]AccelerationStructureKHR,
}
PhysicalDeviceAccelerationStructureFeaturesKHR :: struct {
@@ -5056,9 +5056,9 @@ RayTracingPipelineCreateInfoKHR :: struct {
pNext: rawptr,
flags: PipelineCreateFlags,
stageCount: u32,
pStages: ^PipelineShaderStageCreateInfo,
pStages: [^]PipelineShaderStageCreateInfo,
groupCount: u32,
pGroups: ^RayTracingShaderGroupCreateInfoKHR,
pGroups: [^]RayTracingShaderGroupCreateInfoKHR,
maxPipelineRayRecursionDepth: u32,
pLibraryInfo: ^PipelineLibraryCreateInfoKHR,
pLibraryInterface: ^RayTracingPipelineInterfaceCreateInfoKHR,
@@ -5128,7 +5128,7 @@ ImportMemoryWin32HandleInfoKHR :: struct {
ExportMemoryWin32HandleInfoKHR :: struct {
sType: StructureType,
pNext: rawptr,
pAttributes: ^SECURITY_ATTRIBUTES,
pAttributes: [^]SECURITY_ATTRIBUTES,
dwAccess: DWORD,
name: LPCWSTR,
}
@@ -5150,12 +5150,12 @@ Win32KeyedMutexAcquireReleaseInfoKHR :: struct {
sType: StructureType,
pNext: rawptr,
acquireCount: u32,
pAcquireSyncs: ^DeviceMemory,
pAcquireKeys: ^u64,
pAcquireTimeouts: ^u32,
pAcquireSyncs: [^]DeviceMemory,
pAcquireKeys: [^]u64,
pAcquireTimeouts: [^]u32,
releaseCount: u32,
pReleaseSyncs: ^DeviceMemory,
pReleaseKeys: ^u64,
pReleaseSyncs: [^]DeviceMemory,
pReleaseKeys: [^]u64,
}
ImportSemaphoreWin32HandleInfoKHR :: struct {
@@ -5171,7 +5171,7 @@ ImportSemaphoreWin32HandleInfoKHR :: struct {
ExportSemaphoreWin32HandleInfoKHR :: struct {
sType: StructureType,
pNext: rawptr,
pAttributes: ^SECURITY_ATTRIBUTES,
pAttributes: [^]SECURITY_ATTRIBUTES,
dwAccess: DWORD,
name: LPCWSTR,
}
@@ -5180,9 +5180,9 @@ D3D12FenceSubmitInfoKHR :: struct {
sType: StructureType,
pNext: rawptr,
waitSemaphoreValuesCount: u32,
pWaitSemaphoreValues: ^u64,
pWaitSemaphoreValues: [^]u64,
signalSemaphoreValuesCount: u32,
pSignalSemaphoreValues: ^u64,
pSignalSemaphoreValues: [^]u64,
}
SemaphoreGetWin32HandleInfoKHR :: struct {
@@ -5205,7 +5205,7 @@ ImportFenceWin32HandleInfoKHR :: struct {
ExportFenceWin32HandleInfoKHR :: struct {
sType: StructureType,
pNext: rawptr,
pAttributes: ^SECURITY_ATTRIBUTES,
pAttributes: [^]SECURITY_ATTRIBUTES,
dwAccess: DWORD,
name: LPCWSTR,
}
@@ -5227,7 +5227,7 @@ ImportMemoryWin32HandleInfoNV :: struct {
ExportMemoryWin32HandleInfoNV :: struct {
sType: StructureType,
pNext: rawptr,
pAttributes: ^SECURITY_ATTRIBUTES,
pAttributes: [^]SECURITY_ATTRIBUTES,
dwAccess: DWORD,
}
@@ -5235,12 +5235,12 @@ Win32KeyedMutexAcquireReleaseInfoNV :: struct {
sType: StructureType,
pNext: rawptr,
acquireCount: u32,
pAcquireSyncs: ^DeviceMemory,
pAcquireKeys: ^u64,
pAcquireTimeoutMilliseconds: ^u32,
pAcquireSyncs: [^]DeviceMemory,
pAcquireKeys: [^]u64,
pAcquireTimeoutMilliseconds: [^]u32,
releaseCount: u32,
pReleaseSyncs: ^DeviceMemory,
pReleaseKeys: ^u64,
pReleaseSyncs: [^]DeviceMemory,
pReleaseKeys: [^]u64,
}
SurfaceFullScreenExclusiveInfoEXT :: struct {