mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-13 01:21:38 -07:00
Merge branch 'master' into llvm-12.0.1-windows
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
)
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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 }
|
||||
@@ -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) {
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,3 +1,4 @@
|
||||
//+build darwin
|
||||
package unix
|
||||
|
||||
import "core:c"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
package unix;
|
||||
//+build freebsd
|
||||
package unix
|
||||
|
||||
import "core:c";
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//+build linux
|
||||
package unix
|
||||
|
||||
import "core:c"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//+build linux, darwin, freebsd
|
||||
package unix
|
||||
|
||||
foreign import "system:pthread"
|
||||
|
||||
@@ -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 ---
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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(¶ms->Tuple.variables, heap_allocator(), param_types.count);
|
||||
slice_init(¶ms->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
@@ -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 ¶ms,
|
||||
void check_struct_fields(CheckerContext *ctx, Ast *node, Slice<Entity *> *fields, String **tags, Slice<Ast *> const ¶ms,
|
||||
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 ®_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++) {
|
||||
|
||||
@@ -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(¶ms->Tuple.variables, permanent_allocator(), 3);
|
||||
slice_init(¶ms->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(¶ms->Tuple.variables, permanent_allocator(), 2);
|
||||
slice_init(¶ms->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;
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
+6706
-1550
File diff suppressed because it is too large
Load Diff
@@ -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%
|
||||
@@ -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
Vendored
+9
-9
@@ -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)
|
||||
|
||||
Vendored
+16
-16
@@ -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) }
|
||||
|
||||
Vendored
+36
@@ -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.
|
||||
|
||||
Vendored
+433
@@ -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
@@ -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 ---
|
||||
}
|
||||
|
||||
Vendored
+167
@@ -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 ---
|
||||
}
|
||||
+1477
File diff suppressed because it is too large
Load Diff
+1144
File diff suppressed because it is too large
Load Diff
Vendored
+1490
File diff suppressed because it is too large
Load Diff
Vendored
+52
@@ -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 ---
|
||||
}
|
||||
Vendored
+352
@@ -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 ---
|
||||
}
|
||||
Vendored
+85
@@ -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 ---
|
||||
}
|
||||
Vendored
BIN
Binary file not shown.
Vendored
+35
@@ -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 ---
|
||||
}
|
||||
Vendored
+6
@@ -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
|
||||
Vendored
+8
@@ -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
|
||||
Vendored
+9
@@ -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"
|
||||
Vendored
+70273
File diff suppressed because it is too large
Load Diff
Vendored
+231
@@ -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 ---
|
||||
}
|
||||
Vendored
+79
@@ -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,
|
||||
}
|
||||
Vendored
+8
-2
@@ -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
@@ -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.
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
Vendored
+107
@@ -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
@@ -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
@@ -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) ---
|
||||
}
|
||||
Vendored
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
+112
@@ -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) ---
|
||||
}
|
||||
Vendored
+16
@@ -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
|
||||
Vendored
+13
@@ -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
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
Vendored
+7897
File diff suppressed because it is too large
Load Diff
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
#define STB_IMAGE_RESIZE_IMPLEMENTATION
|
||||
#include "stb_image_resize.h"
|
||||
Vendored
+2634
File diff suppressed because it is too large
Load Diff
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include "stb_image_write.h"
|
||||
Vendored
+1724
File diff suppressed because it is too large
Load Diff
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
#define STB_RECT_PACK_IMPLEMENTATION
|
||||
#include "stb_rect_pack.h"
|
||||
Vendored
+623
@@ -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.
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
#define STB_RECT_PACK_IMPLEMENTATION
|
||||
#include "stb_rect_pack.h"
|
||||
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#include "stb_truetype.h"
|
||||
Vendored
+5077
File diff suppressed because it is too large
Load Diff
Vendored
+5584
File diff suppressed because it is too large
Load Diff
+609
@@ -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,
|
||||
}
|
||||
Vendored
+352
@@ -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
@@ -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
|
||||
|
||||
Vendored
-2
@@ -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
|
||||
|
||||
Vendored
+2110
-2110
File diff suppressed because it is too large
Load Diff
Vendored
+156
-156
@@ -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
|
||||
|
||||
Vendored
+163
-163
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user