mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-17 10:07:00 +00:00
Merge branch 'master' into windows-llvm-13.0.0
This commit is contained in:
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
@@ -38,6 +38,10 @@ jobs:
|
||||
cd tests/vendor
|
||||
make
|
||||
timeout-minutes: 10
|
||||
- name: Odin issues tests
|
||||
run: |
|
||||
cd tests/issues
|
||||
./run.sh
|
||||
- name: Odin check examples/all for Linux i386
|
||||
run: ./odin check examples/all -vet -strict-style -target:linux_i386
|
||||
timeout-minutes: 10
|
||||
@@ -151,6 +155,10 @@ jobs:
|
||||
cd tests\vendor
|
||||
call build.bat
|
||||
timeout-minutes: 10
|
||||
- name: Odin issues tests
|
||||
run: |
|
||||
cd tests/issues
|
||||
./run.bat
|
||||
- name: core:math/big tests
|
||||
shell: cmd
|
||||
run: |
|
||||
|
||||
@@ -134,6 +134,14 @@ run_demo() {
|
||||
./odin run examples/demo/demo.odin -file
|
||||
}
|
||||
|
||||
have_which() {
|
||||
if ! which which > /dev/null 2>&1; then
|
||||
panic "Could not find \`which\`"
|
||||
fi
|
||||
}
|
||||
|
||||
have_which
|
||||
|
||||
case $OS in
|
||||
Linux)
|
||||
config_linux
|
||||
|
||||
@@ -14,11 +14,24 @@ when ODIN_OS == .Windows {
|
||||
// EDOM,
|
||||
// EILSEQ
|
||||
// ERANGE
|
||||
when ODIN_OS == .Linux || ODIN_OS == .FreeBSD {
|
||||
when ODIN_OS == .Linux {
|
||||
@(private="file")
|
||||
@(default_calling_convention="c")
|
||||
foreign libc {
|
||||
@(link_name="__libc_errno_location")
|
||||
@(link_name="__errno_location")
|
||||
_get_errno :: proc() -> ^int ---
|
||||
}
|
||||
|
||||
EDOM :: 33
|
||||
EILSEQ :: 84
|
||||
ERANGE :: 34
|
||||
}
|
||||
|
||||
when ODIN_OS == .FreeBSD {
|
||||
@(private="file")
|
||||
@(default_calling_convention="c")
|
||||
foreign libc {
|
||||
@(link_name="__error")
|
||||
_get_errno :: proc() -> ^int ---
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ fprintln :: proc(fd: os.Handle, args: ..any, sep := " ") -> int {
|
||||
w := io.to_writer(os.stream_from_handle(fd))
|
||||
return wprintln(w=w, args=args, sep=sep)
|
||||
}
|
||||
// fprintf formats according to the specififed format string and writes to fd
|
||||
// fprintf formats according to the specified format string and writes to fd
|
||||
fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int {
|
||||
w := io.to_writer(os.stream_from_handle(fd))
|
||||
return wprintf(w, fmt, ..args)
|
||||
@@ -34,12 +34,12 @@ fprint_typeid :: proc(fd: os.Handle, id: typeid) -> (n: int, err: io.Error) {
|
||||
print :: proc(args: ..any, sep := " ") -> int { return fprint(fd=os.stdout, args=args, sep=sep) }
|
||||
// println formats using the default print settings and writes to os.stdout
|
||||
println :: proc(args: ..any, sep := " ") -> int { return fprintln(fd=os.stdout, args=args, sep=sep) }
|
||||
// printf formats according to the specififed format string and writes to os.stdout
|
||||
// printf formats according to the specified format string and writes to os.stdout
|
||||
printf :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stdout, fmt, ..args) }
|
||||
|
||||
// eprint formats using the default print settings and writes to os.stderr
|
||||
eprint :: proc(args: ..any, sep := " ") -> int { return fprint(fd=os.stderr, args=args, sep=sep) }
|
||||
// eprintln formats using the default print settings and writes to os.stderr
|
||||
eprintln :: proc(args: ..any, sep := " ") -> int { return fprintln(fd=os.stderr, args=args, sep=sep) }
|
||||
// eprintf formats according to the specififed format string and writes to os.stderr
|
||||
// eprintf formats according to the specified format string and writes to os.stderr
|
||||
eprintf :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stderr, fmt, ..args) }
|
||||
|
||||
@@ -182,3 +182,12 @@ shuffle :: proc(array: $T/[]$E, r: ^Rand = nil) {
|
||||
array[i], array[j] = array[j], array[i]
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a random element from the given slice
|
||||
choice :: proc(array: $T/[]$E, r: ^Rand = nil) -> (res: E) {
|
||||
n := i64(len(array))
|
||||
if n < 1 {
|
||||
return E{}
|
||||
}
|
||||
return array[int63_max(n, r)]
|
||||
}
|
||||
331
core/mem/virtual/arena.odin
Normal file
331
core/mem/virtual/arena.odin
Normal file
@@ -0,0 +1,331 @@
|
||||
package mem_virtual
|
||||
|
||||
import "core:mem"
|
||||
|
||||
Arena_Kind :: enum uint {
|
||||
Growing = 0, // Chained memory blocks (singly linked list).
|
||||
Static = 1, // Fixed reservation sized.
|
||||
Buffer = 2, // Uses a fixed sized buffer.
|
||||
}
|
||||
|
||||
Arena :: struct {
|
||||
kind: Arena_Kind,
|
||||
curr_block: ^Memory_Block,
|
||||
total_used: uint,
|
||||
total_reserved: uint,
|
||||
minimum_block_size: uint,
|
||||
temp_count: uint,
|
||||
}
|
||||
|
||||
|
||||
// 1 MiB should be enough to start with
|
||||
DEFAULT_ARENA_STATIC_COMMIT_SIZE :: 1<<20
|
||||
DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE :: DEFAULT_ARENA_STATIC_COMMIT_SIZE
|
||||
|
||||
// 1 GiB on 64-bit systems, 128 MiB on 32-bit systems by default
|
||||
DEFAULT_ARENA_STATIC_RESERVE_SIZE :: 1<<30 when size_of(uintptr) == 8 else 1<<27
|
||||
|
||||
|
||||
|
||||
@(require_results)
|
||||
arena_init_growing :: proc(arena: ^Arena, reserved: uint = DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE) -> (err: Allocator_Error) {
|
||||
arena.kind = .Growing
|
||||
arena.curr_block = memory_block_alloc(0, reserved, {}) or_return
|
||||
arena.total_used = 0
|
||||
arena.total_reserved = arena.curr_block.reserved
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@(require_results)
|
||||
arena_init_static :: proc(arena: ^Arena, reserved: uint, commit_size: uint = DEFAULT_ARENA_STATIC_COMMIT_SIZE) -> (err: Allocator_Error) {
|
||||
arena.kind = .Static
|
||||
arena.curr_block = memory_block_alloc(commit_size, reserved, {}) or_return
|
||||
arena.total_used = 0
|
||||
arena.total_reserved = arena.curr_block.reserved
|
||||
return
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
arena_init_buffer :: proc(arena: ^Arena, buffer: []byte) -> (err: Allocator_Error) {
|
||||
if len(buffer) < size_of(Memory_Block) {
|
||||
return .Out_Of_Memory
|
||||
}
|
||||
|
||||
arena.kind = .Buffer
|
||||
|
||||
mem.zero_slice(buffer)
|
||||
|
||||
block_base := raw_data(buffer)
|
||||
block := (^Memory_Block)(block_base)
|
||||
block.base = block_base[size_of(Memory_Block):]
|
||||
block.reserved = len(buffer) - size_of(Memory_Block)
|
||||
block.committed = block.reserved
|
||||
block.used = 0
|
||||
|
||||
arena.curr_block = block
|
||||
arena.total_used = 0
|
||||
arena.total_reserved = arena.curr_block.reserved
|
||||
return
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
arena_alloc :: proc(arena: ^Arena, size: uint, alignment: uint, loc := #caller_location) -> (data: []byte, err: Allocator_Error) {
|
||||
assert(alignment & (alignment-1) == 0, "non-power of two alignment", loc)
|
||||
|
||||
size := size
|
||||
if size == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
switch arena.kind {
|
||||
case .Growing:
|
||||
if arena.curr_block == nil || (safe_add(arena.curr_block.used, size) or_else 0) > arena.curr_block.reserved {
|
||||
size = mem.align_forward_uint(size, alignment)
|
||||
if arena.minimum_block_size == 0 {
|
||||
arena.minimum_block_size = DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE
|
||||
}
|
||||
|
||||
block_size := max(size, arena.minimum_block_size)
|
||||
|
||||
new_block := memory_block_alloc(size, block_size, {}) or_return
|
||||
new_block.prev = arena.curr_block
|
||||
arena.curr_block = new_block
|
||||
arena.total_reserved += new_block.reserved
|
||||
}
|
||||
|
||||
prev_used := arena.curr_block.used
|
||||
data, err = alloc_from_memory_block(arena.curr_block, size, alignment)
|
||||
arena.total_used += arena.curr_block.used - prev_used
|
||||
case .Static:
|
||||
if arena.curr_block == nil {
|
||||
if arena.minimum_block_size == 0 {
|
||||
arena.minimum_block_size = DEFAULT_ARENA_STATIC_RESERVE_SIZE
|
||||
}
|
||||
arena_init_static(arena=arena, reserved=arena.minimum_block_size, commit_size=DEFAULT_ARENA_STATIC_COMMIT_SIZE) or_return
|
||||
}
|
||||
fallthrough
|
||||
case .Buffer:
|
||||
if arena.curr_block == nil {
|
||||
return nil, .Out_Of_Memory
|
||||
}
|
||||
data, err = alloc_from_memory_block(arena.curr_block, size, alignment)
|
||||
arena.total_used = arena.curr_block.used
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
arena_static_reset_to :: proc(arena: ^Arena, pos: uint, loc := #caller_location) -> bool {
|
||||
if arena.curr_block != nil {
|
||||
assert(arena.kind != .Growing, "expected a non .Growing arena", loc)
|
||||
|
||||
prev_pos := arena.curr_block.used
|
||||
arena.curr_block.used = clamp(pos, 0, arena.curr_block.reserved)
|
||||
|
||||
if prev_pos < pos {
|
||||
mem.zero_slice(arena.curr_block.base[arena.curr_block.used:][:pos-prev_pos])
|
||||
}
|
||||
arena.total_used = arena.curr_block.used
|
||||
return true
|
||||
} else if pos == 0 {
|
||||
arena.total_used = 0
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
arena_growing_free_last_memory_block :: proc(arena: ^Arena, loc := #caller_location) {
|
||||
if free_block := arena.curr_block; free_block != nil {
|
||||
assert(arena.kind == .Growing, "expected a .Growing arena", loc)
|
||||
arena.curr_block = free_block.prev
|
||||
memory_block_dealloc(free_block)
|
||||
}
|
||||
}
|
||||
|
||||
arena_free_all :: proc(arena: ^Arena) {
|
||||
switch arena.kind {
|
||||
case .Growing:
|
||||
for arena.curr_block != nil {
|
||||
arena_growing_free_last_memory_block(arena)
|
||||
}
|
||||
arena.total_reserved = 0
|
||||
case .Static, .Buffer:
|
||||
arena_static_reset_to(arena, 0)
|
||||
}
|
||||
arena.total_used = 0
|
||||
}
|
||||
|
||||
arena_destroy :: proc(arena: ^Arena) {
|
||||
arena_free_all(arena)
|
||||
if arena.kind != .Buffer {
|
||||
memory_block_dealloc(arena.curr_block)
|
||||
}
|
||||
arena.curr_block = nil
|
||||
arena.total_used = 0
|
||||
arena.total_reserved = 0
|
||||
arena.temp_count = 0
|
||||
}
|
||||
|
||||
arena_growing_bootstrap_new :: proc{
|
||||
arena_growing_bootstrap_new_by_offset,
|
||||
arena_growing_bootstrap_new_by_name,
|
||||
}
|
||||
|
||||
arena_static_bootstrap_new :: proc{
|
||||
arena_static_bootstrap_new_by_offset,
|
||||
arena_static_bootstrap_new_by_name,
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
arena_growing_bootstrap_new_by_offset :: proc($T: typeid, offset_to_arena: uintptr, minimum_block_size: uint = DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE) -> (ptr: ^T, err: Allocator_Error) {
|
||||
bootstrap: Arena
|
||||
bootstrap.kind = .Growing
|
||||
bootstrap.minimum_block_size = minimum_block_size
|
||||
|
||||
data := arena_alloc(&bootstrap, size_of(T), align_of(T)) or_return
|
||||
|
||||
ptr = (^T)(raw_data(data))
|
||||
|
||||
(^Arena)(uintptr(ptr) + offset_to_arena)^ = bootstrap
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
arena_growing_bootstrap_new_by_name :: proc($T: typeid, $field_name: string, minimum_block_size: uint = DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE) -> (ptr: ^T, err: Allocator_Error) {
|
||||
return arena_growing_bootstrap_new_by_offset(T, offset_of_by_string(T, field_name), minimum_block_size)
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
arena_static_bootstrap_new_by_offset :: proc($T: typeid, offset_to_arena: uintptr, reserved: uint) -> (ptr: ^T, err: Allocator_Error) {
|
||||
bootstrap: Arena
|
||||
bootstrap.kind = .Static
|
||||
bootstrap.minimum_block_size = reserved
|
||||
|
||||
data := arena_alloc(&bootstrap, size_of(T), align_of(T)) or_return
|
||||
|
||||
ptr = (^T)(raw_data(data))
|
||||
|
||||
(^Arena)(uintptr(ptr) + offset_to_arena)^ = bootstrap
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
arena_static_bootstrap_new_by_name :: proc($T: typeid, $field_name: string, reserved: uint) -> (ptr: ^T, err: Allocator_Error) {
|
||||
return arena_static_bootstrap_new_by_offset(T, offset_of_by_string(T, field_name), reserved)
|
||||
}
|
||||
|
||||
|
||||
@(require_results)
|
||||
arena_allocator :: proc(arena: ^Arena) -> mem.Allocator {
|
||||
return mem.Allocator{arena_allocator_proc, arena}
|
||||
}
|
||||
|
||||
arena_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr, old_size: int,
|
||||
location := #caller_location) -> (data: []byte, err: Allocator_Error) {
|
||||
arena := (^Arena)(allocator_data)
|
||||
|
||||
size, alignment := uint(size), uint(alignment)
|
||||
old_size := uint(old_size)
|
||||
|
||||
switch mode {
|
||||
case .Alloc:
|
||||
return arena_alloc(arena, size, alignment)
|
||||
case .Free:
|
||||
err = .Mode_Not_Implemented
|
||||
case .Free_All:
|
||||
arena_free_all(arena)
|
||||
case .Resize:
|
||||
old_data := ([^]byte)(old_memory)
|
||||
|
||||
switch {
|
||||
case old_data == nil:
|
||||
return arena_alloc(arena, size, alignment)
|
||||
case size == old_size:
|
||||
// return old memory
|
||||
data = old_data[:size]
|
||||
return
|
||||
case size == 0:
|
||||
err = .Mode_Not_Implemented
|
||||
return
|
||||
case (uintptr(old_data) & uintptr(alignment-1) == 0) && size < old_size:
|
||||
// shrink data in-place
|
||||
data = old_data[:size]
|
||||
return
|
||||
}
|
||||
|
||||
new_memory := arena_alloc(arena, size, alignment) or_return
|
||||
if new_memory == nil {
|
||||
return
|
||||
}
|
||||
copy(new_memory, old_data[:old_size])
|
||||
return new_memory, nil
|
||||
case .Query_Features:
|
||||
set := (^mem.Allocator_Mode_Set)(old_memory)
|
||||
if set != nil {
|
||||
set^ = {.Alloc, .Free_All, .Resize, .Query_Features}
|
||||
}
|
||||
case .Query_Info:
|
||||
err = .Mode_Not_Implemented
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Arena_Temp :: struct {
|
||||
arena: ^Arena,
|
||||
block: ^Memory_Block,
|
||||
used: uint,
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
arena_temp_begin :: proc(arena: ^Arena, loc := #caller_location) -> (temp: Arena_Temp) {
|
||||
assert(arena != nil, "nil arena", loc)
|
||||
temp.arena = arena
|
||||
temp.block = arena.curr_block
|
||||
if arena.curr_block != nil {
|
||||
temp.used = arena.curr_block.used
|
||||
}
|
||||
arena.temp_count += 1
|
||||
return
|
||||
}
|
||||
|
||||
arena_temp_end :: proc(temp: Arena_Temp, loc := #caller_location) {
|
||||
assert(temp.arena != nil, "nil arena", loc)
|
||||
arena := temp.arena
|
||||
|
||||
memory_block_found := false
|
||||
for block := arena.curr_block; block != nil; block = block.prev {
|
||||
if block == temp.block {
|
||||
memory_block_found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !memory_block_found {
|
||||
assert(arena.curr_block == temp.block, "memory block stored within Arena_Temp not owned by Arena", loc)
|
||||
}
|
||||
|
||||
for arena.curr_block != temp.block {
|
||||
arena_growing_free_last_memory_block(arena)
|
||||
}
|
||||
|
||||
if block := arena.curr_block; block != nil {
|
||||
assert(block.used >= temp.used, "out of order use of arena_temp_end", loc)
|
||||
amount_to_zero := min(block.used-temp.used, block.reserved-block.used)
|
||||
mem.zero_slice(block.base[temp.used:][:amount_to_zero])
|
||||
block.used = temp.used
|
||||
}
|
||||
|
||||
assert(arena.temp_count > 0, "double-use of arena_temp_end", loc)
|
||||
arena.temp_count -= 1
|
||||
}
|
||||
|
||||
arena_check_temp :: proc(arena: ^Arena, loc := #caller_location) {
|
||||
assert(arena.temp_count == 0, "Arena_Temp not been ended", loc)
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package mem_virtual
|
||||
|
||||
arena_init :: proc{
|
||||
static_arena_init,
|
||||
growing_arena_init,
|
||||
}
|
||||
|
||||
arena_temp_begin :: proc{
|
||||
static_arena_temp_begin,
|
||||
growing_arena_temp_begin,
|
||||
}
|
||||
|
||||
arena_temp_end :: proc{
|
||||
static_arena_temp_end,
|
||||
growing_arena_temp_end,
|
||||
}
|
||||
|
||||
arena_check_temp :: proc{
|
||||
static_arena_check_temp,
|
||||
growing_arena_check_temp,
|
||||
}
|
||||
|
||||
arena_allocator :: proc{
|
||||
static_arena_allocator,
|
||||
growing_arena_allocator,
|
||||
}
|
||||
|
||||
arena_alloc :: proc{
|
||||
static_arena_alloc,
|
||||
growing_arena_alloc,
|
||||
}
|
||||
|
||||
arena_free_all :: proc{
|
||||
static_arena_free_all,
|
||||
growing_arena_free_all,
|
||||
}
|
||||
|
||||
arena_destroy :: proc{
|
||||
static_arena_destroy,
|
||||
growing_arena_destroy,
|
||||
}
|
||||
@@ -1,170 +0,0 @@
|
||||
package mem_virtual
|
||||
|
||||
import "core:mem"
|
||||
|
||||
Growing_Arena :: struct {
|
||||
curr_block: ^Memory_Block,
|
||||
total_used: uint,
|
||||
total_reserved: uint,
|
||||
|
||||
minimum_block_size: uint,
|
||||
temp_count: int,
|
||||
}
|
||||
|
||||
DEFAULT_MINIMUM_BLOCK_SIZE :: 1<<20 // 1 MiB should be enough
|
||||
|
||||
growing_arena_init :: proc(arena: ^Growing_Arena, reserved: uint = DEFAULT_MINIMUM_BLOCK_SIZE) -> (err: Allocator_Error) {
|
||||
arena.curr_block = memory_block_alloc(0, reserved, {}) or_return
|
||||
arena.total_used = 0
|
||||
arena.total_reserved = arena.curr_block.reserved
|
||||
return
|
||||
}
|
||||
|
||||
growing_arena_alloc :: proc(arena: ^Growing_Arena, min_size: int, alignment: int) -> (data: []byte, err: Allocator_Error) {
|
||||
align_forward_offset :: proc "contextless" (arena: ^Growing_Arena, alignment: int) -> uint #no_bounds_check {
|
||||
alignment_offset := uint(0)
|
||||
ptr := uintptr(arena.curr_block.base[arena.curr_block.used:])
|
||||
mask := uintptr(alignment-1)
|
||||
if ptr & mask != 0 {
|
||||
alignment_offset = uint(alignment) - uint(ptr & mask)
|
||||
}
|
||||
return alignment_offset
|
||||
}
|
||||
|
||||
assert(mem.is_power_of_two(uintptr(alignment)))
|
||||
|
||||
size := uint(0)
|
||||
if arena.curr_block != nil {
|
||||
size = uint(min_size) + align_forward_offset(arena, alignment)
|
||||
}
|
||||
|
||||
if arena.curr_block == nil || arena.curr_block.used + size > arena.curr_block.reserved {
|
||||
size = uint(mem.align_forward_int(min_size, alignment))
|
||||
arena.minimum_block_size = max(DEFAULT_MINIMUM_BLOCK_SIZE, arena.minimum_block_size)
|
||||
|
||||
block_size := max(size, arena.minimum_block_size)
|
||||
|
||||
new_block := memory_block_alloc(size, block_size, {}) or_return
|
||||
new_block.prev = arena.curr_block
|
||||
arena.curr_block = new_block
|
||||
arena.total_reserved += new_block.reserved
|
||||
}
|
||||
|
||||
|
||||
data, err = alloc_from_memory_block(arena.curr_block, int(size), alignment)
|
||||
if err == nil {
|
||||
arena.total_used += size
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
growing_arena_free_last_memory_block :: proc(arena: ^Growing_Arena) {
|
||||
free_block := arena.curr_block
|
||||
arena.curr_block = free_block.prev
|
||||
memory_block_dealloc(free_block)
|
||||
}
|
||||
|
||||
growing_arena_free_all :: proc(arena: ^Growing_Arena) {
|
||||
for arena.curr_block != nil {
|
||||
growing_arena_free_last_memory_block(arena)
|
||||
}
|
||||
arena.total_used = 0
|
||||
arena.total_reserved = 0
|
||||
}
|
||||
|
||||
growing_arena_destroy :: proc(arena: ^Growing_Arena) {
|
||||
growing_arena_free_all(arena)
|
||||
}
|
||||
|
||||
growing_arena_bootstrap_new_by_offset :: proc($T: typeid, offset_to_arena: uintptr, minimum_block_size: uint = DEFAULT_MINIMUM_BLOCK_SIZE) -> (ptr: ^T, err: Allocator_Error) { bootstrap: Growing_Arena
|
||||
bootstrap.minimum_block_size = minimum_block_size
|
||||
|
||||
data := growing_arena_alloc(&bootstrap, size_of(T), align_of(T)) or_return
|
||||
|
||||
ptr = (^T)(raw_data(data))
|
||||
|
||||
(^Growing_Arena)(uintptr(ptr) + offset_to_arena)^ = bootstrap
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
growing_arena_bootstrap_new_by_name :: proc($T: typeid, $field_name: string, minimum_block_size: uint = DEFAULT_MINIMUM_BLOCK_SIZE) -> (ptr: ^T, err: Allocator_Error) {
|
||||
return growing_arena_bootstrap_new_by_offset(T, offset_of_by_string(T, field_name), minimum_block_size)
|
||||
}
|
||||
growing_arena_bootstrap_new :: proc{
|
||||
growing_arena_bootstrap_new_by_offset,
|
||||
growing_arena_bootstrap_new_by_name,
|
||||
}
|
||||
|
||||
growing_arena_allocator :: proc(arena: ^Growing_Arena) -> mem.Allocator {
|
||||
return mem.Allocator{growing_arena_allocator_proc, arena}
|
||||
}
|
||||
|
||||
growing_arena_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr, old_size: int,
|
||||
location := #caller_location) -> (data: []byte, err: Allocator_Error) {
|
||||
arena := (^Growing_Arena)(allocator_data)
|
||||
|
||||
switch mode {
|
||||
case .Alloc:
|
||||
return growing_arena_alloc(arena, size, alignment)
|
||||
case .Free:
|
||||
err = .Mode_Not_Implemented
|
||||
return
|
||||
case .Free_All:
|
||||
growing_arena_free_all(arena)
|
||||
return
|
||||
case .Resize:
|
||||
return mem.default_resize_bytes_align(mem.byte_slice(old_memory, old_size), size, alignment, growing_arena_allocator(arena), location)
|
||||
|
||||
case .Query_Features, .Query_Info:
|
||||
err = .Mode_Not_Implemented
|
||||
return
|
||||
}
|
||||
|
||||
err = .Mode_Not_Implemented
|
||||
return
|
||||
}
|
||||
|
||||
Growing_Arena_Temp :: struct {
|
||||
arena: ^Growing_Arena,
|
||||
block: ^Memory_Block,
|
||||
used: uint,
|
||||
}
|
||||
|
||||
growing_arena_temp_begin :: proc(arena: ^Growing_Arena) -> (temp: Growing_Arena_Temp) {
|
||||
temp.arena = arena
|
||||
temp.block = arena.curr_block
|
||||
if arena.curr_block != nil {
|
||||
temp.used = arena.curr_block.used
|
||||
}
|
||||
arena.temp_count += 1
|
||||
return
|
||||
}
|
||||
|
||||
growing_arena_temp_end :: proc(temp: Growing_Arena_Temp, loc := #caller_location) {
|
||||
assert(temp.arena != nil, "nil arena", loc)
|
||||
arena := temp.arena
|
||||
|
||||
for arena.curr_block != temp.block {
|
||||
growing_arena_free_last_memory_block(arena)
|
||||
}
|
||||
|
||||
if block := arena.curr_block; block != nil {
|
||||
assert(block.used >= temp.used, "out of order use of growing_arena_temp_end", loc)
|
||||
amount_to_zero := min(block.used-temp.used, block.reserved-block.used)
|
||||
mem.zero_slice(block.base[temp.used:][:amount_to_zero])
|
||||
block.used = temp.used
|
||||
}
|
||||
|
||||
assert(arena.temp_count > 0, "double-use of growing_arena_temp_end", loc)
|
||||
arena.temp_count -= 1
|
||||
}
|
||||
|
||||
growing_arena_check_temp :: proc(arena: ^Growing_Arena, loc := #caller_location) {
|
||||
assert(arena.temp_count == 0, "Growing_Arena_Temp not been ended", loc)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
package mem_virtual
|
||||
|
||||
import "core:mem"
|
||||
|
||||
Static_Arena :: struct {
|
||||
block: ^Memory_Block,
|
||||
total_used: uint,
|
||||
total_reserved: uint,
|
||||
|
||||
minimum_block_size: uint,
|
||||
temp_count: int,
|
||||
}
|
||||
|
||||
STATIC_ARENA_DEFAULT_COMMIT_SIZE :: 1<<20 // 1 MiB should be enough to start with
|
||||
|
||||
// 1 GiB on 64-bit systems, 128 MiB on 32-bit systems by default
|
||||
STATIC_ARENA_DEFAULT_RESERVE_SIZE :: 1<<30 when size_of(uintptr) == 8 else 1<<27
|
||||
|
||||
static_arena_init :: proc(arena: ^Static_Arena, reserved: uint, commit_size: uint = STATIC_ARENA_DEFAULT_COMMIT_SIZE) -> (err: Allocator_Error) {
|
||||
arena.block = memory_block_alloc(commit_size, reserved, {}) or_return
|
||||
arena.total_used = 0
|
||||
arena.total_reserved = arena.block.reserved
|
||||
return
|
||||
}
|
||||
|
||||
static_arena_destroy :: proc(arena: ^Static_Arena) {
|
||||
memory_block_dealloc(arena.block)
|
||||
arena^ = {}
|
||||
}
|
||||
|
||||
|
||||
static_arena_alloc :: proc(arena: ^Static_Arena, size: int, alignment: int) -> (data: []byte, err: Allocator_Error) {
|
||||
align_forward :: #force_inline proc "contextless" (ptr: uint, align: uint) -> uint {
|
||||
mask := align-1
|
||||
return (ptr + mask) &~ mask
|
||||
}
|
||||
|
||||
if arena.block == nil {
|
||||
reserve_size := max(arena.minimum_block_size, STATIC_ARENA_DEFAULT_RESERVE_SIZE)
|
||||
static_arena_init(arena, reserve_size, STATIC_ARENA_DEFAULT_COMMIT_SIZE) or_return
|
||||
}
|
||||
|
||||
MINIMUM_ALIGN :: 2*align_of(uintptr)
|
||||
|
||||
defer arena.total_used = arena.block.used
|
||||
return alloc_from_memory_block(arena.block, size, max(MINIMUM_ALIGN, alignment))
|
||||
}
|
||||
|
||||
static_arena_reset_to :: proc(arena: ^Static_Arena, pos: uint) -> bool {
|
||||
if arena.block != nil {
|
||||
prev_pos := arena.block.used
|
||||
arena.block.used = clamp(pos, 0, arena.block.reserved)
|
||||
|
||||
if prev_pos < pos {
|
||||
mem.zero_slice(arena.block.base[arena.block.used:][:pos-prev_pos])
|
||||
}
|
||||
return true
|
||||
} else if pos == 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
static_arena_free_all :: proc(arena: ^Static_Arena) {
|
||||
static_arena_reset_to(arena, 0)
|
||||
}
|
||||
|
||||
|
||||
static_arena_bootstrap_new_by_offset :: proc($T: typeid, offset_to_arena: uintptr, reserved: uint) -> (ptr: ^T, err: Allocator_Error) {
|
||||
bootstrap: Static_Arena
|
||||
bootstrap.minimum_block_size = reserved
|
||||
|
||||
data := static_arena_alloc(&bootstrap, size_of(T), align_of(T)) or_return
|
||||
|
||||
ptr = (^T)(raw_data(data))
|
||||
|
||||
(^Static_Arena)(uintptr(ptr) + offset_to_arena)^ = bootstrap
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
static_arena_bootstrap_new_by_name :: proc($T: typeid, $field_name: string, reserved: uint) -> (ptr: ^T, err: Allocator_Error) {
|
||||
return static_arena_bootstrap_new_by_offset(T, offset_of_by_string(T, field_name), reserved)
|
||||
}
|
||||
static_arena_bootstrap_new :: proc{
|
||||
static_arena_bootstrap_new_by_offset,
|
||||
static_arena_bootstrap_new_by_name,
|
||||
}
|
||||
|
||||
|
||||
static_arena_allocator :: proc(arena: ^Static_Arena) -> mem.Allocator {
|
||||
return mem.Allocator{static_arena_allocator_proc, arena}
|
||||
}
|
||||
|
||||
static_arena_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr, old_size: int,
|
||||
location := #caller_location) -> (data: []byte, err: Allocator_Error) {
|
||||
arena := (^Static_Arena)(allocator_data)
|
||||
|
||||
switch mode {
|
||||
case .Alloc:
|
||||
return static_arena_alloc(arena, size, alignment)
|
||||
case .Free:
|
||||
err = .Mode_Not_Implemented
|
||||
return
|
||||
case .Free_All:
|
||||
static_arena_free_all(arena)
|
||||
return
|
||||
case .Resize:
|
||||
return mem.default_resize_bytes_align(mem.byte_slice(old_memory, old_size), size, alignment, static_arena_allocator(arena), location)
|
||||
|
||||
case .Query_Features, .Query_Info:
|
||||
err = .Mode_Not_Implemented
|
||||
return
|
||||
}
|
||||
|
||||
err = .Mode_Not_Implemented
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Static_Arena_Temp :: struct {
|
||||
arena: ^Static_Arena,
|
||||
used: uint,
|
||||
}
|
||||
|
||||
|
||||
static_arena_temp_begin :: proc(arena: ^Static_Arena) -> (temp: Static_Arena_Temp) {
|
||||
temp.arena = arena
|
||||
temp.used = arena.block.used if arena.block != nil else 0
|
||||
arena.temp_count += 1
|
||||
return
|
||||
}
|
||||
|
||||
static_arena_temp_end :: proc(temp: Static_Arena_Temp, loc := #caller_location) {
|
||||
assert(temp.arena != nil, "nil arena", loc)
|
||||
arena := temp.arena
|
||||
|
||||
used := arena.block.used if arena.block != nil else 0
|
||||
|
||||
assert(temp.used >= used, "invalid Static_Arena_Temp", loc)
|
||||
|
||||
static_arena_reset_to(arena, temp.used)
|
||||
|
||||
assert(arena.temp_count > 0, "double-use of static_arena_temp_end", loc)
|
||||
arena.temp_count -= 1
|
||||
}
|
||||
|
||||
|
||||
static_arena_check_temp :: proc(arena: ^Static_Arena, loc := #caller_location) {
|
||||
assert(arena.temp_count == 0, "Static_Arena_Temp not been ended", loc)
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package mem_virtual
|
||||
|
||||
import "core:mem"
|
||||
import "core:intrinsics"
|
||||
|
||||
DEFAULT_PAGE_SIZE := uint(4096)
|
||||
|
||||
@@ -95,18 +96,11 @@ memory_block_alloc :: proc(committed, reserved: uint, flags: Memory_Block_Flags)
|
||||
pmblock.block.committed = committed
|
||||
pmblock.block.reserved = reserved
|
||||
|
||||
sentinel := &global_platform_memory_block_sentinel
|
||||
platform_mutex_lock()
|
||||
pmblock.next = sentinel
|
||||
pmblock.prev = sentinel.prev
|
||||
pmblock.prev.next = pmblock
|
||||
pmblock.next.prev = pmblock
|
||||
platform_mutex_unlock()
|
||||
|
||||
return &pmblock.block, nil
|
||||
}
|
||||
|
||||
alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: int) -> (data: []byte, err: Allocator_Error) {
|
||||
alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: uint) -> (data: []byte, err: Allocator_Error) {
|
||||
calc_alignment_offset :: proc "contextless" (block: ^Memory_Block, alignment: uintptr) -> uint {
|
||||
alignment_offset := uint(0)
|
||||
ptr := uintptr(block.base[block.used:])
|
||||
@@ -134,11 +128,18 @@ alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: int)
|
||||
return nil
|
||||
}
|
||||
|
||||
if block == nil {
|
||||
return nil, .Out_Of_Memory
|
||||
}
|
||||
|
||||
alignment_offset := calc_alignment_offset(block, uintptr(alignment))
|
||||
size := uint(min_size) + alignment_offset
|
||||
size, size_ok := safe_add(min_size, alignment_offset)
|
||||
if !size_ok {
|
||||
err = .Out_Of_Memory
|
||||
return
|
||||
}
|
||||
|
||||
if block.used + size > block.reserved {
|
||||
if to_be_used, ok := safe_add(block.used, size); !ok || to_be_used > block.reserved {
|
||||
err = .Out_Of_Memory
|
||||
return
|
||||
}
|
||||
@@ -153,12 +154,14 @@ alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: int)
|
||||
|
||||
memory_block_dealloc :: proc(block_to_free: ^Memory_Block) {
|
||||
if block := (^Platform_Memory_Block)(block_to_free); block != nil {
|
||||
platform_mutex_lock()
|
||||
block.prev.next = block.next
|
||||
block.next.prev = block.prev
|
||||
platform_mutex_unlock()
|
||||
|
||||
platform_memory_free(block)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@(private)
|
||||
safe_add :: #force_inline proc "contextless" (x, y: uint) -> (uint, bool) {
|
||||
z, did_overflow := intrinsics.overflow_add(x, y)
|
||||
return z, !did_overflow
|
||||
}
|
||||
@@ -1,13 +1,10 @@
|
||||
//+private
|
||||
package mem_virtual
|
||||
|
||||
import "core:sync"
|
||||
|
||||
Platform_Memory_Block :: struct {
|
||||
block: Memory_Block,
|
||||
committed: uint,
|
||||
reserved: uint,
|
||||
prev, next: ^Platform_Memory_Block,
|
||||
}
|
||||
|
||||
platform_memory_alloc :: proc "contextless" (to_commit, to_reserve: uint) -> (block: ^Platform_Memory_Block, err: Allocator_Error) {
|
||||
@@ -33,28 +30,6 @@ platform_memory_free :: proc "contextless" (block: ^Platform_Memory_Block) {
|
||||
}
|
||||
}
|
||||
|
||||
platform_mutex_lock :: proc() {
|
||||
sync.mutex_lock(&global_memory_block_mutex)
|
||||
}
|
||||
|
||||
platform_mutex_unlock :: proc() {
|
||||
sync.mutex_unlock(&global_memory_block_mutex)
|
||||
}
|
||||
|
||||
global_memory_block_mutex: sync.Mutex
|
||||
global_platform_memory_block_sentinel: Platform_Memory_Block
|
||||
global_platform_memory_block_sentinel_set: bool
|
||||
|
||||
@(init)
|
||||
platform_memory_init :: proc() {
|
||||
if !global_platform_memory_block_sentinel_set {
|
||||
_platform_memory_init()
|
||||
global_platform_memory_block_sentinel.prev = &global_platform_memory_block_sentinel
|
||||
global_platform_memory_block_sentinel.next = &global_platform_memory_block_sentinel
|
||||
global_platform_memory_block_sentinel_set = true
|
||||
}
|
||||
}
|
||||
|
||||
platform_memory_commit :: proc "contextless" (block: ^Platform_Memory_Block, to_commit: uint) -> (err: Allocator_Error) {
|
||||
if to_commit < block.committed {
|
||||
return nil
|
||||
@@ -63,7 +38,6 @@ platform_memory_commit :: proc "contextless" (block: ^Platform_Memory_Block, to_
|
||||
return .Out_Of_Memory
|
||||
}
|
||||
|
||||
|
||||
commit(block, to_commit) or_return
|
||||
block.committed = to_commit
|
||||
return nil
|
||||
|
||||
@@ -2,7 +2,6 @@ package os
|
||||
|
||||
import win32 "core:sys/windows"
|
||||
import "core:strings"
|
||||
import "core:time"
|
||||
|
||||
read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []File_Info, err: Errno) {
|
||||
find_data_to_file_info :: proc(base_path: string, d: ^win32.WIN32_FIND_DATAW) -> (fi: File_Info) {
|
||||
@@ -41,9 +40,7 @@ read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []F
|
||||
// fi.mode |= file_type_mode(h);
|
||||
}
|
||||
|
||||
fi.creation_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime))
|
||||
fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime))
|
||||
fi.access_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime))
|
||||
windows_set_file_info_times(&fi, d)
|
||||
|
||||
fi.is_dir = fi.mode & File_Mode_Dir != 0
|
||||
return
|
||||
|
||||
@@ -130,7 +130,7 @@ _new_file :: proc(handle: uintptr, name: string) -> ^File {
|
||||
f := new(File, _file_allocator())
|
||||
|
||||
f.impl.allocator = _file_allocator()
|
||||
f.impl.fd = rawptr(fd)
|
||||
f.impl.fd = rawptr(handle)
|
||||
f.impl.name = strings.clone(name, f.impl.allocator)
|
||||
f.impl.wname = win32.utf8_to_wstring(name, f.impl.allocator)
|
||||
|
||||
|
||||
@@ -228,6 +228,13 @@ file_mode_from_file_attributes :: proc(FileAttributes: win32.DWORD, h: win32.HAN
|
||||
return
|
||||
}
|
||||
|
||||
@(private)
|
||||
windows_set_file_info_times :: proc(fi: ^File_Info, d: ^$T) {
|
||||
fi.creation_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime))
|
||||
fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime))
|
||||
fi.access_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime))
|
||||
}
|
||||
|
||||
@(private)
|
||||
file_info_from_win32_file_attribute_data :: proc(d: ^win32.WIN32_FILE_ATTRIBUTE_DATA, name: string) -> (fi: File_Info, e: Errno) {
|
||||
fi.size = i64(d.nFileSizeHigh)<<32 + i64(d.nFileSizeLow)
|
||||
@@ -235,9 +242,7 @@ file_info_from_win32_file_attribute_data :: proc(d: ^win32.WIN32_FILE_ATTRIBUTE_
|
||||
fi.mode |= file_mode_from_file_attributes(d.dwFileAttributes, nil, 0)
|
||||
fi.is_dir = fi.mode & File_Mode_Dir != 0
|
||||
|
||||
fi.creation_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime))
|
||||
fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime))
|
||||
fi.access_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime))
|
||||
windows_set_file_info_times(&fi, d)
|
||||
|
||||
fi.fullpath, e = full_path_from_name(name)
|
||||
fi.name = basename(fi.fullpath)
|
||||
@@ -252,9 +257,7 @@ file_info_from_win32_find_data :: proc(d: ^win32.WIN32_FIND_DATAW, name: string)
|
||||
fi.mode |= file_mode_from_file_attributes(d.dwFileAttributes, nil, 0)
|
||||
fi.is_dir = fi.mode & File_Mode_Dir != 0
|
||||
|
||||
fi.creation_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime))
|
||||
fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime))
|
||||
fi.access_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime))
|
||||
windows_set_file_info_times(&fi, d)
|
||||
|
||||
fi.fullpath, e = full_path_from_name(name)
|
||||
fi.name = basename(fi.fullpath)
|
||||
@@ -290,10 +293,7 @@ file_info_from_get_file_information_by_handle :: proc(path: string, h: win32.HAN
|
||||
fi.mode |= file_mode_from_file_attributes(ti.FileAttributes, h, ti.ReparseTag)
|
||||
fi.is_dir = fi.mode & File_Mode_Dir != 0
|
||||
|
||||
fi.creation_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime))
|
||||
fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime))
|
||||
fi.access_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime))
|
||||
|
||||
windows_set_file_info_times(&fi, &d)
|
||||
|
||||
return fi, ERROR_NONE
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ objc_SEL :: ^intrinsics.objc_selector
|
||||
foreign Foundation {
|
||||
objc_lookUpClass :: proc "c" (name: cstring) -> objc_Class ---
|
||||
sel_registerName :: proc "c" (name: cstring) -> objc_SEL ---
|
||||
objc_allocateClassPair :: proc "c" (superclass: objc_Class, name: cstring, extraBytes: uint) ---
|
||||
objc_allocateClassPair :: proc "c" (superclass: objc_Class, name: cstring, extraBytes: uint) -> objc_Class ---
|
||||
|
||||
objc_msgSend :: proc "c" (self: objc_id, op: objc_SEL, #c_vararg args: ..any) ---
|
||||
objc_msgSend_fpret :: proc "c" (self: objc_id, op: objc_SEL, #c_vararg args: ..any) -> f64 ---
|
||||
|
||||
@@ -177,7 +177,6 @@ _quick_sort_general :: proc(data: $T/[]$E, a, b, max_depth: int, call: $P, $KIND
|
||||
}
|
||||
|
||||
|
||||
// merge sort
|
||||
_stable_sort_general :: proc(data: $T/[]$E, call: $P, $KIND: Sort_Kind) where (ORD(E) && KIND == .Ordered) || (KIND != .Ordered) #no_bounds_check {
|
||||
less :: #force_inline proc(a, b: E, call: P) -> bool {
|
||||
when KIND == .Ordered {
|
||||
@@ -190,7 +189,9 @@ _stable_sort_general :: proc(data: $T/[]$E, call: $P, $KIND: Sort_Kind) where (O
|
||||
#panic("unhandled Sort_Kind")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// insertion sort
|
||||
// TODO(bill): use a different algorithm as insertion sort is O(n^2)
|
||||
n := len(data)
|
||||
for i in 1..<n {
|
||||
for j := i; j > 0 && less(data[j], data[j-1], call); j -= 1 {
|
||||
|
||||
@@ -575,9 +575,11 @@ parse_f64 :: proc(str: string, n: ^int = nil) -> (value: f64, ok: bool) {
|
||||
i := 0
|
||||
|
||||
sign: f64 = 1
|
||||
seen_sign := true
|
||||
switch s[i] {
|
||||
case '-': i += 1; sign = -1
|
||||
case '+': i += 1
|
||||
case: seen_sign = false
|
||||
}
|
||||
|
||||
for ; i < len(s); i += 1 {
|
||||
@@ -677,8 +679,13 @@ parse_f64 :: proc(str: string, n: ^int = nil) -> (value: f64, ok: bool) {
|
||||
for exp > 0 { scale *= 10; exp -= 1 }
|
||||
}
|
||||
}
|
||||
s = s[i:]
|
||||
|
||||
// If we only consumed a sign, return false
|
||||
if i == 1 && seen_sign {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
s = s[i:]
|
||||
if frac {
|
||||
value = sign * (value/scale)
|
||||
} else {
|
||||
|
||||
@@ -128,4 +128,34 @@ foreign advapi32 {
|
||||
lpData: LPCVOID,
|
||||
cbData: DWORD,
|
||||
) -> LSTATUS ---
|
||||
|
||||
GetFileSecurityW :: proc(
|
||||
lpFileName: LPCWSTR,
|
||||
RequestedInformation: SECURITY_INFORMATION,
|
||||
pSecurityDescriptor: PSECURITY_DESCRIPTOR,
|
||||
nLength: DWORD,
|
||||
lpnLengthNeeded: LPDWORD,
|
||||
) -> BOOL ---
|
||||
|
||||
DuplicateToken :: proc(
|
||||
ExistingTokenHandle: HANDLE,
|
||||
ImpersonationLevel: SECURITY_IMPERSONATION_LEVEL,
|
||||
DuplicateTokenHandle: PHANDLE,
|
||||
) -> BOOL ---
|
||||
|
||||
MapGenericMask :: proc(
|
||||
AccessMask: PDWORD,
|
||||
GenericMapping: PGENERIC_MAPPING,
|
||||
) ---
|
||||
|
||||
AccessCheck :: proc(
|
||||
pSecurityDescriptor: PSECURITY_DESCRIPTOR,
|
||||
ClientToken: HANDLE,
|
||||
DesiredAccess: DWORD,
|
||||
GenericMapping: PGENERIC_MAPPING,
|
||||
PrivilegeSet: PPRIVILEGE_SET,
|
||||
PrivilegeSetLength: LPDWORD,
|
||||
GrantedAccess: LPDWORD,
|
||||
AccessStatus: LPBOOL,
|
||||
) -> BOOL ---
|
||||
}
|
||||
|
||||
9
core/sys/windows/comctl32.odin
Normal file
9
core/sys/windows/comctl32.odin
Normal file
@@ -0,0 +1,9 @@
|
||||
// +build windows
|
||||
package sys_windows
|
||||
|
||||
foreign import "system:Comctl32.lib"
|
||||
|
||||
@(default_calling_convention="stdcall")
|
||||
foreign Comctl32 {
|
||||
LoadIconWithScaleDown :: proc(hinst: HINSTANCE, pszName: PCWSTR, cx: c_int, cy: c_int, phico: ^HICON) -> HRESULT ---
|
||||
}
|
||||
@@ -77,6 +77,7 @@ foreign gdi32 {
|
||||
) -> HFONT ---
|
||||
TextOutW :: proc(hdc: HDC, x, y: c_int, lpString: LPCWSTR, c: c_int) -> BOOL ---
|
||||
GetTextExtentPoint32W :: proc(hdc: HDC, lpString: LPCWSTR, c: c_int, psizl: LPSIZE) -> BOOL ---
|
||||
GetTextMetricsW :: proc(hdc: HDC, lptm: LPTEXTMETRICW) -> BOOL ---
|
||||
}
|
||||
|
||||
RGB :: #force_inline proc "contextless" (r, g, b: u8) -> COLORREF {
|
||||
|
||||
@@ -248,6 +248,17 @@ foreign kernel32 {
|
||||
GetModuleHandleW :: proc(lpModuleName: LPCWSTR) -> HMODULE ---
|
||||
GetModuleHandleA :: proc(lpModuleName: LPCSTR) -> HMODULE ---
|
||||
GetSystemTimeAsFileTime :: proc(lpSystemTimeAsFileTime: LPFILETIME) ---
|
||||
GetSystemTimePreciseAsFileTime :: proc(lpSystemTimeAsFileTime: LPFILETIME) ---
|
||||
FileTimeToSystemTime :: proc(lpFileTime: ^FILETIME, lpSystemTime: ^SYSTEMTIME) -> BOOL ---
|
||||
SystemTimeToTzSpecificLocalTime :: proc(
|
||||
lpTimeZoneInformation: ^TIME_ZONE_INFORMATION,
|
||||
lpUniversalTime: ^SYSTEMTIME,
|
||||
lpLocalTime: ^SYSTEMTIME,
|
||||
) -> BOOL ---
|
||||
SystemTimeToFileTime :: proc(
|
||||
lpSystemTime: ^SYSTEMTIME,
|
||||
lpFileTime: LPFILETIME,
|
||||
) -> BOOL ---
|
||||
CreateEventW :: proc(
|
||||
lpEventAttributes: LPSECURITY_ATTRIBUTES,
|
||||
bManualReset: BOOL,
|
||||
@@ -346,6 +357,13 @@ foreign kernel32 {
|
||||
GenerateConsoleCtrlEvent :: proc(dwCtrlEvent: DWORD, dwProcessGroupId: DWORD) -> BOOL ---
|
||||
FreeConsole :: proc() -> BOOL ---
|
||||
GetConsoleWindow :: proc() -> HWND ---
|
||||
|
||||
GetDiskFreeSpaceExW :: proc(
|
||||
lpDirectoryName: LPCWSTR,
|
||||
lpFreeBytesAvailableToCaller: PULARGE_INTEGER,
|
||||
lpTotalNumberOfBytes: PULARGE_INTEGER,
|
||||
lpTotalNumberOfFreeBytes: PULARGE_INTEGER,
|
||||
) -> BOOL ---
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -14,4 +14,10 @@ foreign shell32 {
|
||||
lpDirectory: LPCWSTR,
|
||||
nShowCmd: INT,
|
||||
) -> HINSTANCE ---
|
||||
SHCreateDirectoryExW :: proc(
|
||||
hwnd: HWND,
|
||||
pszPath: LPCWSTR,
|
||||
psa: ^SECURITY_ATTRIBUTES,
|
||||
) -> c_int ---
|
||||
SHFileOperationW :: proc(lpFileOp: LPSHFILEOPSTRUCTW) -> c_int ---
|
||||
}
|
||||
|
||||
@@ -8,4 +8,5 @@ foreign shlwapi {
|
||||
PathFileExistsW :: proc(pszPath: wstring) -> BOOL ---
|
||||
PathFindExtensionW :: proc(pszPath: wstring) -> wstring ---
|
||||
PathFindFileNameW :: proc(pszPath: wstring) -> wstring ---
|
||||
SHAutoComplete :: proc(hwndEdit: HWND, dwFlags: DWORD) -> LWSTDAPI ---
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ DWORD :: c_ulong
|
||||
DWORDLONG :: c.ulonglong
|
||||
QWORD :: c.ulonglong
|
||||
HANDLE :: distinct LPVOID
|
||||
PHANDLE :: ^HANDLE
|
||||
HINSTANCE :: HANDLE
|
||||
HMODULE :: distinct HINSTANCE
|
||||
HRESULT :: distinct LONG
|
||||
@@ -43,6 +44,7 @@ BOOLEAN :: distinct b8
|
||||
GROUP :: distinct c_uint
|
||||
LARGE_INTEGER :: distinct c_longlong
|
||||
ULARGE_INTEGER :: distinct c_ulonglong
|
||||
PULARGE_INTEGER :: ^ULARGE_INTEGER
|
||||
LONG :: c_long
|
||||
UINT :: c_uint
|
||||
INT :: c_int
|
||||
@@ -133,6 +135,11 @@ LPWSAOVERLAPPED :: distinct rawptr
|
||||
LPWSAOVERLAPPED_COMPLETION_ROUTINE :: distinct rawptr
|
||||
LPCVOID :: rawptr
|
||||
|
||||
PACCESS_TOKEN :: PVOID
|
||||
PSECURITY_DESCRIPTOR :: PVOID
|
||||
PSID :: PVOID
|
||||
PCLAIMS_BLOB :: PVOID
|
||||
|
||||
PCONDITION_VARIABLE :: ^CONDITION_VARIABLE
|
||||
PLARGE_INTEGER :: ^LARGE_INTEGER
|
||||
PSRWLOCK :: ^SRWLOCK
|
||||
@@ -175,6 +182,7 @@ FILE_SHARE_DELETE: DWORD : 0x00000004
|
||||
FILE_GENERIC_ALL: DWORD : 0x10000000
|
||||
FILE_GENERIC_EXECUTE: DWORD : 0x20000000
|
||||
FILE_GENERIC_READ: DWORD : 0x80000000
|
||||
FILE_ALL_ACCESS :: STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF
|
||||
|
||||
FILE_ACTION_ADDED :: 0x00000001
|
||||
FILE_ACTION_REMOVED :: 0x00000002
|
||||
@@ -230,6 +238,20 @@ SECURITY_SQOS_PRESENT: DWORD : 0x00100000
|
||||
|
||||
FIONBIO: c_ulong : 0x8004667e
|
||||
|
||||
OWNER_SECURITY_INFORMATION :: 0x00000001
|
||||
GROUP_SECURITY_INFORMATION :: 0x00000002
|
||||
DACL_SECURITY_INFORMATION :: 0x00000004
|
||||
SACL_SECURITY_INFORMATION :: 0x00000008
|
||||
LABEL_SECURITY_INFORMATION :: 0x00000010
|
||||
ATTRIBUTE_SECURITY_INFORMATION :: 0x00000020
|
||||
SCOPE_SECURITY_INFORMATION :: 0x00000040
|
||||
PROCESS_TRUST_LABEL_SECURITY_INFORMATION :: 0x00000080
|
||||
ACCESS_FILTER_SECURITY_INFORMATION :: 0x00000100
|
||||
BACKUP_SECURITY_INFORMATION :: 0x00010000
|
||||
PROTECTED_DACL_SECURITY_INFORMATION :: 0x80000000
|
||||
PROTECTED_SACL_SECURITY_INFORMATION :: 0x40000000
|
||||
UNPROTECTED_DACL_SECURITY_INFORMATION :: 0x20000000
|
||||
UNPROTECTED_SACL_SECURITY_INFORMATION :: 0x10000000
|
||||
|
||||
GET_FILEEX_INFO_LEVELS :: distinct i32
|
||||
GetFileExInfoStandard: GET_FILEEX_INFO_LEVELS : 0
|
||||
@@ -773,6 +795,30 @@ MSG :: struct {
|
||||
|
||||
LPMSG :: ^MSG
|
||||
|
||||
TEXTMETRICW :: struct {
|
||||
tmHeight: LONG,
|
||||
tmAscent: LONG,
|
||||
tmDescent: LONG,
|
||||
tmInternalLeading: LONG,
|
||||
tmExternalLeading: LONG,
|
||||
tmAveCharWidth: LONG,
|
||||
tmMaxCharWidth: LONG,
|
||||
tmWeight: LONG,
|
||||
tmOverhang: LONG,
|
||||
tmDigitizedAspectX: LONG,
|
||||
tmDigitizedAspectY: LONG,
|
||||
tmFirstChar: WCHAR,
|
||||
tmLastChar: WCHAR,
|
||||
tmDefaultChar: WCHAR,
|
||||
tmBreakChar: WCHAR,
|
||||
tmItalic: BYTE,
|
||||
tmUnderlined: BYTE,
|
||||
tmStruckOut: BYTE,
|
||||
tmPitchAndFamily: BYTE,
|
||||
tmCharSet: BYTE,
|
||||
}
|
||||
LPTEXTMETRICW :: ^TEXTMETRICW
|
||||
|
||||
PAINTSTRUCT :: struct {
|
||||
hdc: HDC,
|
||||
fErase: BOOL,
|
||||
@@ -879,6 +925,48 @@ NM_FONTCHANGED :: NM_OUTOFMEMORY-22
|
||||
NM_CUSTOMTEXT :: NM_OUTOFMEMORY-23 // uses NMCUSTOMTEXT struct
|
||||
NM_TVSTATEIMAGECHANGING :: NM_OUTOFMEMORY-23 // uses NMTVSTATEIMAGECHANGING struct, defined after HTREEITEM
|
||||
|
||||
PCZZWSTR :: ^WCHAR
|
||||
|
||||
SHFILEOPSTRUCTW :: struct {
|
||||
hwnd: HWND,
|
||||
wFunc: UINT,
|
||||
pFrom: PCZZWSTR,
|
||||
pTo: PCZZWSTR,
|
||||
fFlags: FILEOP_FLAGS,
|
||||
fAnyOperationsAborted: BOOL,
|
||||
hNameMappings: LPVOID,
|
||||
lpszProgressTitle: PCWSTR, // only used if FOF_SIMPLEPROGRESS
|
||||
}
|
||||
LPSHFILEOPSTRUCTW :: ^SHFILEOPSTRUCTW
|
||||
|
||||
// Shell File Operations
|
||||
FO_MOVE :: 0x0001
|
||||
FO_COPY :: 0x0002
|
||||
FO_DELETE :: 0x0003
|
||||
FO_RENAME :: 0x0004
|
||||
|
||||
// SHFILEOPSTRUCT.fFlags and IFileOperation::SetOperationFlags() flag values
|
||||
FOF_MULTIDESTFILES :: 0x0001
|
||||
FOF_CONFIRMMOUSE :: 0x0002
|
||||
FOF_SILENT :: 0x0004 // don't display progress UI (confirm prompts may be displayed still)
|
||||
FOF_RENAMEONCOLLISION :: 0x0008 // automatically rename the source files to avoid the collisions
|
||||
FOF_NOCONFIRMATION :: 0x0010 // don't display confirmation UI, assume "yes" for cases that can be bypassed, "no" for those that can not
|
||||
FOF_WANTMAPPINGHANDLE :: 0x0020 // Fill in SHFILEOPSTRUCT.hNameMappings
|
||||
// Must be freed using SHFreeNameMappings
|
||||
FOF_ALLOWUNDO :: 0x0040 // enable undo including Recycle behavior for IFileOperation::Delete()
|
||||
FOF_FILESONLY :: 0x0080 // only operate on the files (non folders), both files and folders are assumed without this
|
||||
FOF_SIMPLEPROGRESS :: 0x0100 // means don't show names of files
|
||||
FOF_NOCONFIRMMKDIR :: 0x0200 // don't dispplay confirmatino UI before making any needed directories, assume "Yes" in these cases
|
||||
FOF_NOERRORUI :: 0x0400 // don't put up error UI, other UI may be displayed, progress, confirmations
|
||||
FOF_NOCOPYSECURITYATTRIBS :: 0x0800 // dont copy file security attributes (ACLs)
|
||||
FOF_NORECURSION :: 0x1000 // don't recurse into directories for operations that would recurse
|
||||
FOF_NO_CONNECTED_ELEMENTS :: 0x2000 // don't operate on connected elements ("xxx_files" folders that go with .htm files)
|
||||
FOF_WANTNUKEWARNING :: 0x4000 // during delete operation, warn if object is being permanently destroyed instead of recycling (partially overrides FOF_NOCONFIRMATION)
|
||||
FOF_NORECURSEREPARSE :: 0x8000 // deprecated; the operations engine always does the right thing on FolderLink objects (symlinks, reparse points, folder shortcuts)
|
||||
FOF_NO_UI :: (FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR) // don't display any UI at all
|
||||
|
||||
FILEOP_FLAGS :: WORD
|
||||
|
||||
DEVMODEW :: struct {
|
||||
dmDeviceName: [32]wchar_t,
|
||||
dmSpecVersion: WORD,
|
||||
@@ -1066,8 +1154,14 @@ WS_EX_TOPMOST : UINT : 0x0000_0008
|
||||
WS_EX_TRANSPARENT : UINT : 0x0000_0020
|
||||
WS_EX_WINDOWEDGE : UINT : 0x0000_0100
|
||||
|
||||
PBS_SMOOTH :: 0x01
|
||||
PBS_VERTICAL :: 0x04
|
||||
PBS_SMOOTH :: 0x01
|
||||
PBS_VERTICAL :: 0x04
|
||||
PBS_MARQUEE :: 0x08
|
||||
PBS_SMOOTHREVERSE :: 0x10
|
||||
|
||||
PBST_NORMAL :: 0x0001
|
||||
PBST_ERROR :: 0x0002
|
||||
PBST_PAUSED :: 0x0003
|
||||
|
||||
QS_ALLEVENTS : UINT : QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY
|
||||
QS_ALLINPUT : UINT : QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY | QS_SENDMESSAGE
|
||||
@@ -1462,6 +1556,24 @@ IDI_WARNING := IDI_EXCLAMATION
|
||||
IDI_ERROR := IDI_HAND
|
||||
IDI_INFORMATION := IDI_ASTERISK
|
||||
|
||||
IMAGE_BITMAP :: 0
|
||||
IMAGE_ICON :: 1
|
||||
IMAGE_CURSOR :: 2
|
||||
IMAGE_ENHMETAFILE :: 3
|
||||
|
||||
LR_DEFAULTCOLOR :: 0x00000000
|
||||
LR_MONOCHROME :: 0x00000001
|
||||
LR_COLOR :: 0x00000002
|
||||
LR_COPYRETURNORG :: 0x00000004
|
||||
LR_COPYDELETEORG :: 0x00000008
|
||||
LR_LOADFROMFILE :: 0x00000010
|
||||
LR_LOADTRANSPARENT :: 0x00000020
|
||||
LR_DEFAULTSIZE :: 0x00000040
|
||||
LR_VGACOLOR :: 0x00000080
|
||||
LR_LOADMAP3DCOLORS :: 0x00001000
|
||||
LR_CREATEDIBSECTION :: 0x00002000
|
||||
LR_COPYFROMRESOURCE :: 0x00004000
|
||||
LR_SHARED :: 0x00008000
|
||||
|
||||
// DIB color table identifiers
|
||||
DIB_RGB_COLORS :: 0
|
||||
@@ -1774,12 +1886,15 @@ WAIT_FAILED: DWORD : 0xFFFFFFFF
|
||||
|
||||
PIPE_ACCESS_INBOUND: DWORD : 0x00000001
|
||||
PIPE_ACCESS_OUTBOUND: DWORD : 0x00000002
|
||||
PIPE_ACCESS_DUPLEX: DWORD : 0x00000003
|
||||
FILE_FLAG_FIRST_PIPE_INSTANCE: DWORD : 0x00080000
|
||||
FILE_FLAG_OVERLAPPED: DWORD : 0x40000000
|
||||
PIPE_WAIT: DWORD : 0x00000000
|
||||
PIPE_TYPE_BYTE: DWORD : 0x00000000
|
||||
PIPE_TYPE_MESSAGE: DWORD : 0x00000004
|
||||
PIPE_REJECT_REMOTE_CLIENTS: DWORD : 0x00000008
|
||||
PIPE_READMODE_BYTE: DWORD : 0x00000000
|
||||
PIPE_READMODE_MESSAGE: DWORD : 0x00000002
|
||||
PIPE_ACCEPT_REMOTE_CLIENTS: DWORD : 0x00000000
|
||||
|
||||
FD_SETSIZE :: 64
|
||||
@@ -1793,7 +1908,58 @@ HEAP_ZERO_MEMORY: DWORD : 0x00000008
|
||||
HANDLE_FLAG_INHERIT: DWORD : 0x00000001
|
||||
HANDLE_FLAG_PROTECT_FROM_CLOSE :: 0x00000002
|
||||
|
||||
TOKEN_READ: DWORD : 0x20008
|
||||
GENERIC_MAPPING :: struct {
|
||||
GenericRead: ACCESS_MASK,
|
||||
GenericWrite: ACCESS_MASK,
|
||||
GenericExecute: ACCESS_MASK,
|
||||
GenericAll: ACCESS_MASK,
|
||||
}
|
||||
PGENERIC_MAPPING :: ^GENERIC_MAPPING
|
||||
|
||||
SECURITY_IMPERSONATION_LEVEL :: enum {
|
||||
SecurityAnonymous,
|
||||
SecurityIdentification,
|
||||
SecurityImpersonation,
|
||||
SecurityDelegation,
|
||||
}
|
||||
|
||||
SECURITY_INFORMATION :: DWORD
|
||||
ANYSIZE_ARRAY :: 1
|
||||
|
||||
LUID_AND_ATTRIBUTES :: struct {
|
||||
Luid: LUID,
|
||||
Attributes: DWORD,
|
||||
}
|
||||
|
||||
PRIVILEGE_SET :: struct {
|
||||
PrivilegeCount: DWORD,
|
||||
Control: DWORD,
|
||||
Privilege: [ANYSIZE_ARRAY]LUID_AND_ATTRIBUTES,
|
||||
}
|
||||
PPRIVILEGE_SET :: ^PRIVILEGE_SET
|
||||
|
||||
// Token Specific Access Rights.
|
||||
TOKEN_ASSIGN_PRIMARY :: 0x0001
|
||||
TOKEN_DUPLICATE :: 0x0002
|
||||
TOKEN_IMPERSONATE :: 0x0004
|
||||
TOKEN_QUERY :: 0x0008
|
||||
TOKEN_QUERY_SOURCE :: 0x0010
|
||||
TOKEN_ADJUST_PRIVILEGES :: 0x0020
|
||||
TOKEN_ADJUST_GROUPS :: 0x0040
|
||||
TOKEN_ADJUST_DEFAULT :: 0x0080
|
||||
TOKEN_ADJUST_SESSIONID :: 0x0100
|
||||
|
||||
TOKEN_ALL_ACCESS_P :: STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY |\
|
||||
TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT
|
||||
|
||||
TOKEN_ALL_ACCESS :: TOKEN_ALL_ACCESS_P | TOKEN_ADJUST_SESSIONID
|
||||
TOKEN_READ :: STANDARD_RIGHTS_READ | TOKEN_QUERY
|
||||
TOKEN_WRITE :: STANDARD_RIGHTS_WRITE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT
|
||||
TOKEN_EXECUTE :: STANDARD_RIGHTS_EXECUTE
|
||||
TOKEN_TRUST_CONSTRAINT_MASK :: STANDARD_RIGHTS_READ | TOKEN_QUERY | TOKEN_QUERY_SOURCE
|
||||
TOKEN_ACCESS_PSEUDO_HANDLE_WIN8 :: TOKEN_QUERY | TOKEN_QUERY_SOURCE
|
||||
TOKEN_ACCESS_PSEUDO_HANDLE :: TOKEN_ACCESS_PSEUDO_HANDLE_WIN8
|
||||
|
||||
|
||||
CP_ACP :: 0 // default to ANSI code page
|
||||
CP_OEMCP :: 1 // default to OEM code page
|
||||
@@ -2101,9 +2267,10 @@ FILETIME :: struct {
|
||||
|
||||
FILETIME_as_unix_nanoseconds :: proc "contextless" (ft: FILETIME) -> i64 {
|
||||
t := i64(u64(ft.dwLowDateTime) | u64(ft.dwHighDateTime) << 32)
|
||||
return (t - 0x019db1ded53e8000) * 100
|
||||
return (t - 116444736000000000) * 100
|
||||
}
|
||||
|
||||
|
||||
OVERLAPPED :: struct {
|
||||
Internal: ^c_ulong,
|
||||
InternalHigh: ^c_ulong,
|
||||
@@ -2777,6 +2944,16 @@ SYSTEMTIME :: struct {
|
||||
milliseconds: WORD,
|
||||
}
|
||||
|
||||
TIME_ZONE_INFORMATION :: struct {
|
||||
Bias: LONG,
|
||||
StandardName: [32]WCHAR,
|
||||
StandardDate: SYSTEMTIME,
|
||||
StandardBias: LONG,
|
||||
DaylightName: [32]WCHAR,
|
||||
DaylightDate: SYSTEMTIME,
|
||||
DaylightBias: LONG,
|
||||
}
|
||||
|
||||
|
||||
@(private="file")
|
||||
IMAGE_DOS_HEADER :: struct {
|
||||
@@ -3048,12 +3225,32 @@ SHCONTF_FLATLIST :: 0x4000
|
||||
SHCONTF_ENABLE_ASYNC :: 0x8000
|
||||
SHCONTF_INCLUDESUPERHIDDEN :: 0x10000
|
||||
|
||||
SHACF_DEFAULT :: 0x00000000 // Currently (SHACF_FILESYSTEM | SHACF_URLALL)
|
||||
SHACF_FILESYSTEM :: 0x00000001 // This includes the File System as well as the rest of the shell (Desktop\My Computer\Control Panel\)
|
||||
SHACF_URLALL :: (SHACF_URLHISTORY | SHACF_URLMRU)
|
||||
SHACF_URLHISTORY :: 0x00000002 // URLs in the User's History
|
||||
SHACF_URLMRU :: 0x00000004 // URLs in the User's Recently Used list.
|
||||
SHACF_USETAB :: 0x00000008 // Use the tab to move thru the autocomplete possibilities instead of to the next dialog/window control.
|
||||
SHACF_FILESYS_ONLY :: 0x00000010 // This includes the File System
|
||||
SHACF_FILESYS_DIRS :: 0x00000020 // Same as SHACF_FILESYS_ONLY except it only includes directories, UNC servers, and UNC server shares.
|
||||
SHACF_VIRTUAL_NAMESPACE :: 0x00000040 // Also include the virtual namespace
|
||||
SHACF_AUTOSUGGEST_FORCE_ON :: 0x10000000 // Ignore the registry default and force the feature on.
|
||||
SHACF_AUTOSUGGEST_FORCE_OFF :: 0x20000000 // Ignore the registry default and force the feature off.
|
||||
SHACF_AUTOAPPEND_FORCE_ON :: 0x40000000 // Ignore the registry default and force the feature on. (Also know as AutoComplete)
|
||||
SHACF_AUTOAPPEND_FORCE_OFF :: 0x80000000 // Ignore the registry default and force the feature off. (Also know as AutoComplete)
|
||||
|
||||
LWSTDAPI :: HRESULT
|
||||
|
||||
CLSID_FileOpenDialog := &GUID{0xDC1C5A9C, 0xE88A, 0x4DDE, {0xA5, 0xA1, 0x60, 0xF8, 0x2A, 0x20, 0xAE, 0xF7}}
|
||||
CLSID_FileSaveDialog := &GUID{0xC0B4E2F3, 0xBA21, 0x4773, {0x8D, 0xBA, 0x33, 0x5E, 0xC9, 0x46, 0xEB, 0x8B}}
|
||||
CLSID_TaskbarList := &GUID{0x56FDF344, 0xFD6D, 0x11d0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}}
|
||||
|
||||
IID_IFileDialog := &GUID{0x42F85136, 0xDB7E, 0x439C, {0x85, 0xF1, 0xE4, 0x07, 0x5D, 0x13, 0x5F, 0xC8}}
|
||||
IID_IFileSaveDialog := &GUID{0x84BCCD23, 0x5FDE, 0x4CDB, {0xAE, 0xA4, 0xAF, 0x64, 0xB8, 0x3D, 0x78, 0xAB}}
|
||||
IID_IFileOpenDialog := &GUID{0xD57C7288, 0xD4AD, 0x4768, {0xBE, 0x02, 0x9D, 0x96, 0x95, 0x32, 0xD9, 0x60}}
|
||||
IID_ITaskbarList := &GUID{0x56FDF342, 0xFD6D, 0x11d0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}}
|
||||
IID_ITaskbarList2 := &GUID{0x602D4995, 0xB13A, 0x429b, {0xA6, 0x6E, 0x19, 0x35, 0xE4, 0x4F, 0x43, 0x17}}
|
||||
IID_ITaskbarList3 := &GUID{0xea1afb91, 0x9e28, 0x4b86, {0x90, 0xe9, 0x9e, 0x9f, 0x8a, 0x5e, 0xef, 0xaf}}
|
||||
|
||||
IModalWindow :: struct #raw_union {
|
||||
#subtype IUnknown: IUnknown,
|
||||
@@ -3358,6 +3555,84 @@ IFileSaveDialogVtbl :: struct {
|
||||
ApplyProperties: proc "stdcall" (this: ^IFileSaveDialog, psi: ^IShellItem, pStore: ^IPropertyStore, hwnd: HWND, pSink: ^IFileOperationProgressSink) -> HRESULT,
|
||||
}
|
||||
|
||||
ITaskbarList :: struct #raw_union {
|
||||
#subtype IUnknown: IUnknown,
|
||||
using Vtbl: ^ITaskbarListVtbl,
|
||||
}
|
||||
ITaskbarListVtbl :: struct {
|
||||
using IUnknownVtbl: IUnknownVtbl,
|
||||
HrInit: proc "stdcall" (this: ^ITaskbarList) -> HRESULT,
|
||||
AddTab: proc "stdcall" (this: ^ITaskbarList, hwnd: HWND) -> HRESULT,
|
||||
DeleteTab: proc "stdcall" (this: ^ITaskbarList, hwnd: HWND) -> HRESULT,
|
||||
ActivateTab: proc "stdcall" (this: ^ITaskbarList, hwnd: HWND) -> HRESULT,
|
||||
SetActiveAlt: proc "stdcall" (this: ^ITaskbarList, hwnd: HWND) -> HRESULT,
|
||||
}
|
||||
|
||||
ITaskbarList2 :: struct #raw_union {
|
||||
#subtype ITaskbarList: ITaskbarList,
|
||||
using Vtbl: ^ITaskbarList2Vtbl,
|
||||
}
|
||||
ITaskbarList2Vtbl :: struct {
|
||||
using ITaskbarListVtbl: ITaskbarListVtbl,
|
||||
MarkFullscreenWindow: proc "stdcall" (this: ^ITaskbarList2, hwnd: HWND, fFullscreen: BOOL) -> HRESULT,
|
||||
}
|
||||
|
||||
TBPFLAG :: enum c_int {
|
||||
NOPROGRESS = 0,
|
||||
INDETERMINATE = 0x1,
|
||||
NORMAL = 0x2,
|
||||
ERROR = 0x4,
|
||||
PAUSED = 0x8,
|
||||
}
|
||||
|
||||
THUMBBUTTONFLAGS :: enum c_int {
|
||||
ENABLED = 0,
|
||||
DISABLED = 0x1,
|
||||
DISMISSONCLICK = 0x2,
|
||||
NOBACKGROUND = 0x4,
|
||||
HIDDEN = 0x8,
|
||||
NONINTERACTIVE = 0x10,
|
||||
}
|
||||
|
||||
THUMBBUTTONMASK :: enum c_int {
|
||||
BITMAP = 0x1,
|
||||
ICON = 0x2,
|
||||
TOOLTIP = 0x4,
|
||||
FLAGS = 0x8,
|
||||
}
|
||||
|
||||
THUMBBUTTON :: struct {
|
||||
dwMask: THUMBBUTTONMASK,
|
||||
iId: UINT,
|
||||
iBitmap: UINT,
|
||||
hIcon: HICON,
|
||||
szTip: [260]WCHAR,
|
||||
dwFlags: THUMBBUTTONFLAGS,
|
||||
}
|
||||
LPTHUMBBUTTON :: ^THUMBBUTTON
|
||||
|
||||
HIMAGELIST :: ^IUnknown
|
||||
|
||||
ITaskbarList3 :: struct #raw_union {
|
||||
#subtype ITaskbarList2: ITaskbarList2,
|
||||
using Vtbl: ^ITaskbarList3Vtbl,
|
||||
}
|
||||
ITaskbarList3Vtbl :: struct {
|
||||
using ITaskbarList2Vtbl: ITaskbarList2Vtbl,
|
||||
SetProgressValue: proc "stdcall" (this: ^ITaskbarList3, hwnd: HWND, ullCompleted: ULONGLONG, ullTotal: ULONGLONG) -> HRESULT,
|
||||
SetProgressState: proc "stdcall" (this: ^ITaskbarList3, hwnd: HWND, tbpFlags: TBPFLAG) -> HRESULT,
|
||||
RegisterTab: proc "stdcall" (this: ^ITaskbarList3, hwndTab: HWND, hwndMDI: HWND) -> HRESULT,
|
||||
UnregisterTab: proc "stdcall" (this: ^ITaskbarList3, hwndTab: HWND) -> HRESULT,
|
||||
SetTabOrder: proc "stdcall" (this: ^ITaskbarList3, hwndTab: HWND, hwndInsertBefore: HWND) -> HRESULT,
|
||||
SetTabActive: proc "stdcall" (this: ^ITaskbarList3, hwndTab: HWND, hwndMDI: HWND, dwReserved: DWORD) -> HRESULT,
|
||||
ThumbBarAddButtons: proc "stdcall" (this: ^ITaskbarList3, hwnd: HWND, cButtons: UINT, pButton: LPTHUMBBUTTON) -> HRESULT,
|
||||
ThumbBarUpdateButtons: proc "stdcall" (this: ^ITaskbarList3, hwnd: HWND, cButtons: UINT, pButton: LPTHUMBBUTTON) -> HRESULT,
|
||||
ThumbBarSetImageList: proc "stdcall" (this: ^ITaskbarList3, hwnd: HWND, himl: HIMAGELIST) -> HRESULT,
|
||||
SetOverlayIcon: proc "stdcall" (this: ^ITaskbarList3, hwnd: HWND, hIcon: HICON, pszDescription: LPCWSTR) -> HRESULT,
|
||||
SetThumbnailTooltip: proc "stdcall" (this: ^ITaskbarList3, hwnd: HWND, pszTip: LPCWSTR) -> HRESULT,
|
||||
SetThumbnailClip: proc "stdcall" (this: ^ITaskbarList3, hwnd: HWND, prcClip: ^RECT) -> HRESULT,
|
||||
}
|
||||
|
||||
MEMORYSTATUSEX :: struct {
|
||||
dwLength: DWORD,
|
||||
dwMemoryLoad: DWORD,
|
||||
|
||||
@@ -78,6 +78,7 @@ foreign user32 {
|
||||
LoadIconW :: proc(hInstance: HINSTANCE, lpIconName: LPCWSTR) -> HICON ---
|
||||
LoadCursorA :: proc(hInstance: HINSTANCE, lpCursorName: LPCSTR) -> HCURSOR ---
|
||||
LoadCursorW :: proc(hInstance: HINSTANCE, lpCursorName: LPCWSTR) -> HCURSOR ---
|
||||
LoadImageW :: proc(hInst: HINSTANCE, name: LPCWSTR, type: UINT, cx: c_int, cy: c_int, fuLoad: UINT) -> HANDLE ---
|
||||
|
||||
GetWindowRect :: proc(hWnd: HWND, lpRect: LPRECT) -> BOOL ---
|
||||
GetClientRect :: proc(hWnd: HWND, lpRect: LPRECT) -> BOOL ---
|
||||
|
||||
@@ -62,19 +62,19 @@ utf8_to_wstring :: proc(s: string, allocator := context.temp_allocator) -> wstri
|
||||
wstring_to_utf8 :: proc(s: wstring, N: int, allocator := context.temp_allocator) -> (res: string, err: runtime.Allocator_Error) {
|
||||
context.allocator = allocator
|
||||
|
||||
if N <= 0 {
|
||||
if N == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
n := WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, s, i32(N), nil, 0, nil, nil)
|
||||
n := WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, s, i32(N) if N > 0 else -1, nil, 0, nil, nil)
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// If N == -1 the call to WideCharToMultiByte assume the wide string is null terminated
|
||||
// If N < 0 the call to WideCharToMultiByte assume the wide string is null terminated
|
||||
// and will scan it to find the first null terminated character. The resulting string will
|
||||
// also be null terminated.
|
||||
// If N != -1 it assumes the wide string is not null terminated and the resulting string
|
||||
// If N > 0 it assumes the wide string is not null terminated and the resulting string
|
||||
// will not be null terminated.
|
||||
text := make([]byte, n) or_return
|
||||
|
||||
|
||||
@@ -454,6 +454,7 @@ TB_ISBUTTONENABLED :: 0x0409
|
||||
TBM_CLEARTICS :: 0x0409
|
||||
TTM_SETTOOLINFOA :: 0x0409
|
||||
CBEM_HASEDITCHANGED :: 0x040a
|
||||
PBM_SETMARQUEE :: 0x040a
|
||||
RB_INSERTBANDW :: 0x040a
|
||||
SB_GETRECT :: 0x040a
|
||||
TB_ISBUTTONCHECKED :: 0x040a
|
||||
@@ -488,10 +489,12 @@ TTM_ENUMTOOLSA :: 0x040e
|
||||
SB_SETICON :: 0x040f
|
||||
TBM_GETTICPOS :: 0x040f
|
||||
TTM_GETCURRENTTOOLA :: 0x040f
|
||||
PBM_SETSTATE :: 0x0410
|
||||
RB_IDTOINDEX :: 0x0410
|
||||
SB_SETTIPTEXTA :: 0x0410
|
||||
TBM_GETNUMTICS :: 0x0410
|
||||
TTM_WINDOWFROMPOINT :: 0x0410
|
||||
PBM_GETSTATE :: 0x0411
|
||||
RB_GETTOOLTIPS :: 0x0411
|
||||
SB_SETTIPTEXTW :: 0x0411
|
||||
TBM_GETSELSTART :: 0x0411
|
||||
|
||||
@@ -17,7 +17,7 @@ MAX_DURATION :: Duration(1<<63 - 1)
|
||||
IS_SUPPORTED :: _IS_SUPPORTED
|
||||
|
||||
Time :: struct {
|
||||
_nsec: i64, // zero is 1970-01-01 00:00:00
|
||||
_nsec: i64, // Measured in UNIX nanonseconds
|
||||
}
|
||||
|
||||
Month :: enum int {
|
||||
@@ -59,36 +59,36 @@ sleep :: proc "contextless" (d: Duration) {
|
||||
_sleep(d)
|
||||
}
|
||||
|
||||
stopwatch_start :: proc(using stopwatch: ^Stopwatch) {
|
||||
stopwatch_start :: proc "contextless" (using stopwatch: ^Stopwatch) {
|
||||
if !running {
|
||||
_start_time = tick_now()
|
||||
running = true
|
||||
}
|
||||
}
|
||||
|
||||
stopwatch_stop :: proc(using stopwatch: ^Stopwatch) {
|
||||
stopwatch_stop :: proc "contextless" (using stopwatch: ^Stopwatch) {
|
||||
if running {
|
||||
_accumulation += tick_diff(_start_time, tick_now())
|
||||
running = false
|
||||
}
|
||||
}
|
||||
|
||||
stopwatch_reset :: proc(using stopwatch: ^Stopwatch) {
|
||||
stopwatch_reset :: proc "contextless" (using stopwatch: ^Stopwatch) {
|
||||
_accumulation = {}
|
||||
running = false
|
||||
}
|
||||
|
||||
stopwatch_duration :: proc(using stopwatch: Stopwatch) -> Duration {
|
||||
stopwatch_duration :: proc "contextless" (using stopwatch: Stopwatch) -> Duration {
|
||||
if !running { return _accumulation }
|
||||
return _accumulation + tick_diff(_start_time, tick_now())
|
||||
}
|
||||
|
||||
diff :: proc(start, end: Time) -> Duration {
|
||||
diff :: proc "contextless" (start, end: Time) -> Duration {
|
||||
d := end._nsec - start._nsec
|
||||
return Duration(d)
|
||||
}
|
||||
|
||||
since :: proc(start: Time) -> Duration {
|
||||
since :: proc "contextless" (start: Time) -> Duration {
|
||||
return diff(start, now())
|
||||
}
|
||||
|
||||
@@ -117,8 +117,8 @@ duration_hours :: proc "contextless" (d: Duration) -> f64 {
|
||||
return f64(hour) + f64(nsec)/(60*60*1e9)
|
||||
}
|
||||
|
||||
duration_round :: proc(d, m: Duration) -> Duration {
|
||||
_less_than_half :: #force_inline proc(x, y: Duration) -> bool {
|
||||
duration_round :: proc "contextless" (d, m: Duration) -> Duration {
|
||||
_less_than_half :: #force_inline proc "contextless" (x, y: Duration) -> bool {
|
||||
return u64(x)+u64(x) < u64(y)
|
||||
}
|
||||
|
||||
@@ -146,45 +146,45 @@ duration_round :: proc(d, m: Duration) -> Duration {
|
||||
return MAX_DURATION
|
||||
}
|
||||
|
||||
duration_truncate :: proc(d, m: Duration) -> Duration {
|
||||
duration_truncate :: proc "contextless" (d, m: Duration) -> Duration {
|
||||
return d if m <= 0 else d - d%m
|
||||
}
|
||||
|
||||
date :: proc(t: Time) -> (year: int, month: Month, day: int) {
|
||||
date :: proc "contextless" (t: Time) -> (year: int, month: Month, day: int) {
|
||||
year, month, day, _ = _abs_date(_time_abs(t), true)
|
||||
return
|
||||
}
|
||||
|
||||
year :: proc(t: Time) -> (year: int) {
|
||||
year :: proc "contextless" (t: Time) -> (year: int) {
|
||||
year, _, _, _ = _date(t, true)
|
||||
return
|
||||
}
|
||||
|
||||
month :: proc(t: Time) -> (month: Month) {
|
||||
month :: proc "contextless" (t: Time) -> (month: Month) {
|
||||
_, month, _, _ = _date(t, true)
|
||||
return
|
||||
}
|
||||
|
||||
day :: proc(t: Time) -> (day: int) {
|
||||
day :: proc "contextless" (t: Time) -> (day: int) {
|
||||
_, _, day, _ = _date(t, true)
|
||||
return
|
||||
}
|
||||
|
||||
clock :: proc { clock_from_time, clock_from_duration, clock_from_stopwatch }
|
||||
|
||||
clock_from_time :: proc(t: Time) -> (hour, min, sec: int) {
|
||||
clock_from_time :: proc "contextless" (t: Time) -> (hour, min, sec: int) {
|
||||
return clock_from_seconds(_time_abs(t))
|
||||
}
|
||||
|
||||
clock_from_duration :: proc(d: Duration) -> (hour, min, sec: int) {
|
||||
clock_from_duration :: proc "contextless" (d: Duration) -> (hour, min, sec: int) {
|
||||
return clock_from_seconds(u64(d/1e9))
|
||||
}
|
||||
|
||||
clock_from_stopwatch :: proc(s: Stopwatch) -> (hour, min, sec: int) {
|
||||
clock_from_stopwatch :: proc "contextless" (s: Stopwatch) -> (hour, min, sec: int) {
|
||||
return clock_from_duration(stopwatch_duration(s))
|
||||
}
|
||||
|
||||
clock_from_seconds :: proc(nsec: u64) -> (hour, min, sec: int) {
|
||||
clock_from_seconds :: proc "contextless" (nsec: u64) -> (hour, min, sec: int) {
|
||||
sec = int(nsec % SECONDS_PER_DAY)
|
||||
hour = sec / SECONDS_PER_HOUR
|
||||
sec -= hour * SECONDS_PER_HOUR
|
||||
@@ -193,11 +193,11 @@ clock_from_seconds :: proc(nsec: u64) -> (hour, min, sec: int) {
|
||||
return
|
||||
}
|
||||
|
||||
read_cycle_counter :: proc() -> u64 {
|
||||
read_cycle_counter :: proc "contextless" () -> u64 {
|
||||
return u64(intrinsics.read_cycle_counter())
|
||||
}
|
||||
|
||||
unix :: proc(sec: i64, nsec: i64) -> Time {
|
||||
unix :: proc "contextless" (sec: i64, nsec: i64) -> Time {
|
||||
sec, nsec := sec, nsec
|
||||
if nsec < 0 || nsec >= 1e9 {
|
||||
n := nsec / 1e9
|
||||
@@ -208,20 +208,20 @@ unix :: proc(sec: i64, nsec: i64) -> Time {
|
||||
sec -= 1
|
||||
}
|
||||
}
|
||||
return Time{(sec*1e9 + nsec) + UNIX_TO_INTERNAL}
|
||||
return Time{(sec*1e9 + nsec)}
|
||||
}
|
||||
|
||||
to_unix_seconds :: time_to_unix
|
||||
time_to_unix :: proc(t: Time) -> i64 {
|
||||
time_to_unix :: proc "contextless" (t: Time) -> i64 {
|
||||
return t._nsec/1e9
|
||||
}
|
||||
|
||||
to_unix_nanoseconds :: time_to_unix_nano
|
||||
time_to_unix_nano :: proc(t: Time) -> i64 {
|
||||
time_to_unix_nano :: proc "contextless" (t: Time) -> i64 {
|
||||
return t._nsec
|
||||
}
|
||||
|
||||
time_add :: proc(t: Time, d: Duration) -> Time {
|
||||
time_add :: proc "contextless" (t: Time, d: Duration) -> Time {
|
||||
return Time{t._nsec + i64(d)}
|
||||
}
|
||||
|
||||
@@ -231,7 +231,7 @@ time_add :: proc(t: Time, d: Duration) -> Time {
|
||||
// On Windows it depends but is comparable with regular sleep in the worst case.
|
||||
// To get the same kind of accuracy as on Linux, have your program call `win32.time_begin_period(1)` to
|
||||
// tell Windows to use a more accurate timer for your process.
|
||||
accurate_sleep :: proc(d: Duration) {
|
||||
accurate_sleep :: proc "contextless" (d: Duration) {
|
||||
to_sleep, estimate, mean, m2, count: Duration
|
||||
|
||||
to_sleep = d
|
||||
@@ -279,19 +279,19 @@ ABSOLUTE_TO_UNIX :: -UNIX_TO_ABSOLUTE
|
||||
|
||||
|
||||
@(private)
|
||||
_date :: proc(t: Time, full: bool) -> (year: int, month: Month, day: int, yday: int) {
|
||||
_date :: proc "contextless" (t: Time, full: bool) -> (year: int, month: Month, day: int, yday: int) {
|
||||
year, month, day, yday = _abs_date(_time_abs(t), full)
|
||||
return
|
||||
}
|
||||
|
||||
@(private)
|
||||
_time_abs :: proc(t: Time) -> u64 {
|
||||
_time_abs :: proc "contextless" (t: Time) -> u64 {
|
||||
return u64(t._nsec/1e9 + UNIX_TO_ABSOLUTE)
|
||||
}
|
||||
|
||||
@(private)
|
||||
_abs_date :: proc(abs: u64, full: bool) -> (year: int, month: Month, day: int, yday: int) {
|
||||
_is_leap_year :: proc(year: int) -> bool {
|
||||
_abs_date :: proc "contextless" (abs: u64, full: bool) -> (year: int, month: Month, day: int, yday: int) {
|
||||
_is_leap_year :: proc "contextless" (year: int) -> bool {
|
||||
return year%4 == 0 && (year%100 != 0 || year%400 == 0)
|
||||
}
|
||||
|
||||
@@ -352,9 +352,11 @@ _abs_date :: proc(abs: u64, full: bool) -> (year: int, month: Month, day: int, y
|
||||
return
|
||||
}
|
||||
|
||||
datetime_to_time :: proc(year, month, day, hour, minute, second: int, nsec := int(0)) -> (t: Time, ok: bool) {
|
||||
divmod :: proc(year: int, divisor: int) -> (div: int, mod: int) {
|
||||
assert(divisor > 0)
|
||||
datetime_to_time :: proc "contextless" (year, month, day, hour, minute, second: int, nsec := int(0)) -> (t: Time, ok: bool) {
|
||||
divmod :: proc "contextless" (year: int, divisor: int) -> (div: int, mod: int) {
|
||||
if divisor <= 0 {
|
||||
intrinsics.debug_trap()
|
||||
}
|
||||
div = int(year / divisor)
|
||||
mod = year % divisor
|
||||
return
|
||||
|
||||
@@ -7,9 +7,16 @@ _IS_SUPPORTED :: true
|
||||
|
||||
_now :: proc "contextless" () -> Time {
|
||||
file_time: win32.FILETIME
|
||||
win32.GetSystemTimeAsFileTime(&file_time)
|
||||
ns := win32.FILETIME_as_unix_nanoseconds(file_time)
|
||||
return Time{_nsec=ns}
|
||||
|
||||
ns: i64
|
||||
|
||||
// monotonic
|
||||
win32.GetSystemTimePreciseAsFileTime(&file_time)
|
||||
|
||||
dt := u64(transmute(u64le)file_time) // in 100ns units
|
||||
ns = i64((dt - 116444736000000000) * 100) // convert to ns
|
||||
|
||||
return unix(0, ns)
|
||||
}
|
||||
|
||||
_sleep :: proc "contextless" (d: Duration) {
|
||||
|
||||
@@ -71,7 +71,7 @@ void big_int_and (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_and_not(BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_xor (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_or (BigInt *dst, BigInt const *x, BigInt const *y);
|
||||
void big_int_not (BigInt *dst, BigInt const *x, u64 bit_count, bool is_signed);
|
||||
void big_int_not (BigInt *dst, BigInt const *x, i32 bit_count, bool is_signed);
|
||||
|
||||
|
||||
void big_int_add_eq(BigInt *dst, BigInt const *x);
|
||||
|
||||
@@ -1533,10 +1533,10 @@ bool check_builtin_procedure_directive(CheckerContext *c, Operand *operand, Ast
|
||||
}
|
||||
|
||||
bool is_defined = check_identifier_exists(c->scope, arg);
|
||||
gb_unused(is_defined);
|
||||
// gb_unused(is_defined);
|
||||
operand->type = t_untyped_bool;
|
||||
operand->mode = Addressing_Constant;
|
||||
operand->value = exact_value_bool(false);
|
||||
operand->value = exact_value_bool(is_defined);
|
||||
|
||||
} else if (name == "config") {
|
||||
if (ce->args.count != 2) {
|
||||
|
||||
@@ -1488,6 +1488,11 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty
|
||||
if (!(e->flags & EntityFlag_Using)) {
|
||||
continue;
|
||||
}
|
||||
if (is_blank_ident(e->token)) {
|
||||
error(e->token, "'using' a procedure parameter requires a non blank identifier");
|
||||
break;
|
||||
}
|
||||
|
||||
bool is_value = (e->flags & EntityFlag_Value) != 0 && !is_type_pointer(e->type);
|
||||
String name = e->token.string;
|
||||
Type *t = base_type(type_deref(e->type));
|
||||
|
||||
@@ -821,11 +821,12 @@ i64 check_distance_between_types(CheckerContext *c, Operand *operand, Type *type
|
||||
if (are_types_identical(src, dst)) {
|
||||
return 5;
|
||||
}
|
||||
|
||||
Type *dst_elem = base_array_type(dst);
|
||||
i64 distance = check_distance_between_types(c, operand, dst_elem);
|
||||
if (distance >= 0) {
|
||||
return distance + 7;
|
||||
if (dst->Matrix.row_count == dst->Matrix.column_count) {
|
||||
Type *dst_elem = base_array_type(dst);
|
||||
i64 distance = check_distance_between_types(c, operand, dst_elem);
|
||||
if (distance >= 0) {
|
||||
return distance + 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2916,7 +2917,12 @@ bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type *t) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
if (is_type_untyped(o->type)) {
|
||||
Type *src_t = o->type;
|
||||
Type *dst_t = t;
|
||||
Type *src_bt = base_type(src_t);
|
||||
Type *dst_bt = base_type(dst_t);
|
||||
|
||||
if (is_type_untyped(src_t)) {
|
||||
gbString expr_str = expr_to_string(o->expr);
|
||||
error(o->expr, "Cannot transmute untyped expression: '%s'", expr_str);
|
||||
gb_string_free(expr_str);
|
||||
@@ -2925,7 +2931,6 @@ bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type *t) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Type *dst_bt = base_type(t);
|
||||
if (dst_bt == nullptr || dst_bt == t_invalid) {
|
||||
GB_ASSERT(global_error_collector.count != 0);
|
||||
|
||||
@@ -2934,21 +2939,21 @@ bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type *t) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Type *src_bt = base_type(o->type);
|
||||
if (src_bt == nullptr || src_bt == t_invalid) {
|
||||
// NOTE(bill): this should be an error
|
||||
GB_ASSERT(global_error_collector.count != 0);
|
||||
o->mode = Addressing_Value;
|
||||
o->expr = node;
|
||||
o->type = t;
|
||||
o->type = dst_t;
|
||||
return true;
|
||||
}
|
||||
|
||||
i64 srcz = type_size_of(o->type);
|
||||
i64 dstz = type_size_of(t);
|
||||
|
||||
i64 srcz = type_size_of(src_t);
|
||||
i64 dstz = type_size_of(dst_t);
|
||||
if (srcz != dstz) {
|
||||
gbString expr_str = expr_to_string(o->expr);
|
||||
gbString type_str = type_to_string(t);
|
||||
gbString type_str = type_to_string(dst_t);
|
||||
error(o->expr, "Cannot transmute '%s' to '%s', %lld vs %lld bytes", expr_str, type_str, srcz, dstz);
|
||||
gb_string_free(type_str);
|
||||
gb_string_free(expr_str);
|
||||
@@ -2958,16 +2963,53 @@ bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type *t) {
|
||||
}
|
||||
|
||||
if (build_context.vet_extra) {
|
||||
if (are_types_identical(o->type, t)) {
|
||||
gbString str = type_to_string(t);
|
||||
if (are_types_identical(o->type, dst_t)) {
|
||||
gbString str = type_to_string(dst_t);
|
||||
warning(o->expr, "Unneeded transmute to the same type '%s'", str);
|
||||
gb_string_free(str);
|
||||
}
|
||||
}
|
||||
|
||||
o->expr = node;
|
||||
o->type = dst_t;
|
||||
if (o->mode == Addressing_Constant) {
|
||||
if (are_types_identical(src_bt, dst_bt)) {
|
||||
return true;
|
||||
}
|
||||
if (is_type_integer(src_t) && is_type_integer(dst_t)) {
|
||||
if (types_have_same_internal_endian(src_t, dst_t)) {
|
||||
ExactValue src_v = exact_value_to_integer(o->value);
|
||||
GB_ASSERT(src_v.kind == ExactValue_Integer);
|
||||
BigInt v = src_v.value_integer;
|
||||
|
||||
BigInt smax = {};
|
||||
BigInt umax = {};
|
||||
|
||||
big_int_from_u64(&smax, 0);
|
||||
big_int_not(&smax, &smax, cast(i32)(srcz*8 - 1), false);
|
||||
|
||||
big_int_from_u64(&umax, 1);
|
||||
BigInt sz_in_bits = big_int_make_i64(srcz*8);
|
||||
big_int_shl_eq(&umax, &sz_in_bits);
|
||||
|
||||
if (is_type_unsigned(src_t) && !is_type_unsigned(dst_t)) {
|
||||
if (big_int_cmp(&v, &smax) >= 0) {
|
||||
big_int_sub_eq(&v, &umax);
|
||||
}
|
||||
} else if (!is_type_unsigned(src_t) && is_type_unsigned(dst_t)) {
|
||||
if (big_int_is_neg(&v)) {
|
||||
big_int_add_eq(&v, &umax);
|
||||
}
|
||||
}
|
||||
|
||||
o->value.kind = ExactValue_Integer;
|
||||
o->value.value_integer = v;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
o->mode = Addressing_Value;
|
||||
o->type = t;
|
||||
o->value = {};
|
||||
return true;
|
||||
}
|
||||
@@ -6413,7 +6455,9 @@ CallArgumentError check_polymorphic_record_type(CheckerContext *c, Operand *oper
|
||||
if (e->kind == Entity_TypeName) {
|
||||
if (o->mode != Addressing_Type) {
|
||||
if (show_error) {
|
||||
error(o->expr, "Expected a type for the argument '%.*s'", LIT(e->token.string));
|
||||
gbString expr = expr_to_string(o->expr);
|
||||
error(o->expr, "Expected a type for the argument '%.*s', got %s", LIT(e->token.string), expr);
|
||||
gb_string_free(expr);
|
||||
}
|
||||
err = CallArgumentError_WrongTypes;
|
||||
}
|
||||
@@ -6456,6 +6500,10 @@ CallArgumentError check_polymorphic_record_type(CheckerContext *c, Operand *oper
|
||||
// add_type_info_type(c, o->type);
|
||||
}
|
||||
|
||||
if (show_error && err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
{
|
||||
bool failure = false;
|
||||
Entity *found_entity = find_polymorphic_record_entity(c, original_type, param_count, ordered_operands, &failure);
|
||||
|
||||
@@ -584,7 +584,11 @@ void check_label(CheckerContext *ctx, Ast *label, Ast *parent) {
|
||||
// Returns 'true' for 'continue', 'false' for 'return'
|
||||
bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, Ast *expr, bool is_selector, Entity *e) {
|
||||
if (e == nullptr) {
|
||||
error(us->token, "'using' applied to an unknown entity");
|
||||
if (is_blank_ident(expr)) {
|
||||
error(us->token, "'using' in a statement is not allowed with the blank identifier '_'");
|
||||
} else {
|
||||
error(us->token, "'using' applied to an unknown entity");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -550,10 +550,10 @@ namespace lbAbiAmd64SysV {
|
||||
if (is_mem_cls(cls, attribute_kind)) {
|
||||
LLVMAttributeRef attribute = nullptr;
|
||||
if (attribute_kind == Amd64TypeAttribute_ByVal) {
|
||||
if (!is_calling_convention_odin(calling_convention)) {
|
||||
// if (!is_calling_convention_odin(calling_convention)) {
|
||||
return lb_arg_type_indirect_byval(c, type);
|
||||
}
|
||||
attribute = nullptr;
|
||||
// }
|
||||
// attribute = nullptr;
|
||||
} else if (attribute_kind == Amd64TypeAttribute_StructRect) {
|
||||
attribute = lb_create_enum_attribute_with_type(c, "sret", type);
|
||||
}
|
||||
@@ -982,13 +982,13 @@ namespace lbAbiArm64 {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned is_homogenous_aggregate_small_enough(LLVMTypeRef *base_type_, unsigned member_count_) {
|
||||
return (member_count_ <= 4);
|
||||
}
|
||||
|
||||
unsigned is_homogenous_aggregate_small_enough(LLVMTypeRef base_type, unsigned member_count) {
|
||||
return (member_count <= 4);
|
||||
}
|
||||
|
||||
lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef type, bool return_is_defined) {
|
||||
LLVMTypeRef homo_base_type = {};
|
||||
LLVMTypeRef homo_base_type = nullptr;
|
||||
unsigned homo_member_count = 0;
|
||||
|
||||
if (!return_is_defined) {
|
||||
@@ -996,16 +996,16 @@ namespace lbAbiArm64 {
|
||||
} else if (is_register(type)) {
|
||||
return non_struct(c, type);
|
||||
} else if (is_homogenous_aggregate(c, type, &homo_base_type, &homo_member_count)) {
|
||||
if(is_homogenous_aggregate_small_enough(&homo_base_type, homo_member_count)) {
|
||||
return lb_arg_type_direct(type, LLVMArrayType(homo_base_type, homo_member_count), nullptr, nullptr);
|
||||
} else {
|
||||
//TODO(Platin): do i need to create stuff that can handle the diffrent return type?
|
||||
// else this needs a fix in llvm_backend_proc as we would need to cast it to the correct array type
|
||||
|
||||
//LLVMTypeRef array_type = LLVMArrayType(homo_base_type, homo_member_count);
|
||||
LLVMAttributeRef attr = lb_create_enum_attribute_with_type(c, "sret", type);
|
||||
return lb_arg_type_indirect(type, attr);
|
||||
}
|
||||
if (is_homogenous_aggregate_small_enough(homo_base_type, homo_member_count)) {
|
||||
return lb_arg_type_direct(type, LLVMArrayType(homo_base_type, homo_member_count), nullptr, nullptr);
|
||||
} else {
|
||||
//TODO(Platin): do i need to create stuff that can handle the diffrent return type?
|
||||
// else this needs a fix in llvm_backend_proc as we would need to cast it to the correct array type
|
||||
|
||||
//LLVMTypeRef array_type = LLVMArrayType(homo_base_type, homo_member_count);
|
||||
LLVMAttributeRef attr = lb_create_enum_attribute_with_type(c, "sret", type);
|
||||
return lb_arg_type_indirect(type, attr);
|
||||
}
|
||||
} else {
|
||||
i64 size = lb_sizeof(type);
|
||||
if (size <= 16) {
|
||||
|
||||
@@ -293,6 +293,7 @@ LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
|
||||
case Type_Named:
|
||||
GB_PANIC("Type_Named should be handled in lb_debug_type separately");
|
||||
|
||||
case Type_SoaPointer:
|
||||
case Type_Pointer:
|
||||
return LLVMDIBuilderCreatePointerType(m->debug_builder, lb_debug_type(m, type->Pointer.elem), word_bits, word_bits, 0, nullptr, 0);
|
||||
case Type_MultiPointer:
|
||||
|
||||
@@ -753,12 +753,16 @@ lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr,
|
||||
}
|
||||
GB_ASSERT_MSG(lb_is_type_kind(fnp, LLVMFunctionTypeKind), "%s", LLVMPrintTypeToString(fnp));
|
||||
|
||||
lbFunctionType *ft = map_must_get(&p->module->function_type_map, base_type(value.type));
|
||||
|
||||
{
|
||||
unsigned param_count = LLVMCountParamTypes(fnp);
|
||||
GB_ASSERT(arg_count >= param_count);
|
||||
|
||||
LLVMTypeRef *param_types = gb_alloc_array(temporary_allocator(), LLVMTypeRef, param_count);
|
||||
LLVMGetParamTypes(fnp, param_types);
|
||||
|
||||
|
||||
for (unsigned i = 0; i < param_count; i++) {
|
||||
LLVMTypeRef param_type = param_types[i];
|
||||
LLVMTypeRef arg_type = LLVMTypeOf(args[i]);
|
||||
@@ -776,10 +780,20 @@ lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr,
|
||||
|
||||
LLVMValueRef ret = LLVMBuildCall2(p->builder, fnp, fn, args, arg_count, "");
|
||||
|
||||
LLVMAttributeIndex param_offset = LLVMAttributeIndex_FirstArgIndex;
|
||||
if (return_ptr.value != nullptr) {
|
||||
param_offset += 1;
|
||||
|
||||
LLVMAddCallSiteAttribute(ret, 1, lb_create_enum_attribute_with_type(p->module->ctx, "sret", LLVMTypeOf(args[0])));
|
||||
}
|
||||
|
||||
for_array(i, ft->args) {
|
||||
LLVMAttributeRef attribute = ft->args[i].attribute;
|
||||
if (attribute != nullptr) {
|
||||
LLVMAddCallSiteAttribute(ret, param_offset + cast(LLVMAttributeIndex)i, attribute);
|
||||
}
|
||||
}
|
||||
|
||||
switch (inlining) {
|
||||
case ProcInlining_none:
|
||||
break;
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
@echo off
|
||||
|
||||
if not exist "build\" mkdir build
|
||||
pushd build
|
||||
|
||||
set COMMON=-collection:tests=..
|
||||
set COMMON=-collection:tests=..\..
|
||||
|
||||
set ERROR_DID_OCCUR=0
|
||||
|
||||
@echo on
|
||||
|
||||
..\..\odin test test_issue_829.odin %COMMON% -file
|
||||
..\..\odin test test_issue_1592.odin %COMMON% -file
|
||||
..\..\odin test test_issue_2087.odin %COMMON% -file
|
||||
..\..\..\odin test ..\test_issue_829.odin %COMMON% -file
|
||||
..\..\..\odin test ..\test_issue_1592.odin %COMMON% -file
|
||||
..\..\..\odin test ..\test_issue_2087.odin %COMMON% -file
|
||||
..\..\..\odin build ..\test_issue_2113.odin %COMMON% -file -debug
|
||||
|
||||
@echo off
|
||||
|
||||
if %ERRORLEVEL% NEQ 0 set ERROR_DID_OCCUR=1
|
||||
|
||||
popd
|
||||
rmdir /S /Q build
|
||||
if %ERROR_DID_OCCUR% NEQ 0 EXIT /B 1
|
||||
|
||||
@@ -2,15 +2,18 @@
|
||||
set -eu
|
||||
|
||||
mkdir -p build
|
||||
ODIN=../../odin
|
||||
COMMON="-collection:tests=.."
|
||||
pushd build
|
||||
ODIN=../../../odin
|
||||
COMMON="-collection:tests=../.."
|
||||
|
||||
set -x
|
||||
|
||||
$ODIN test test_issue_829.odin $COMMON -file
|
||||
$ODIN test test_issue_1592.odin $COMMON -file
|
||||
$ODIN test test_issue_2087.odin $COMMON -file
|
||||
$ODIN test ../test_issue_829.odin $COMMON -file
|
||||
$ODIN test ../test_issue_1592.odin $COMMON -file
|
||||
$ODIN test ../test_issue_2087.odin $COMMON -file
|
||||
$ODIN build ../test_issue_2113.odin $COMMON -file -debug
|
||||
|
||||
set +x
|
||||
|
||||
popd
|
||||
rm -rf build
|
||||
|
||||
@@ -10,9 +10,13 @@ test_parse_float :: proc(t: ^testing.T) {
|
||||
{
|
||||
f, ok := strconv.parse_f64("1.2")
|
||||
testing.expect(t, ok && f == 1.2, "expected f64(1.2), fully consumed")
|
||||
|
||||
f, ok = strconv.parse_f64("1.2a")
|
||||
testing.expect(t, !ok && f == 1.2, "expected f64(1.2), partially consumed")
|
||||
f, ok = strconv.parse_f64("+")
|
||||
testing.expect(t, !ok && f == 0.0, "expected f64(0.0), with ok=false")
|
||||
f, ok = strconv.parse_f64("-")
|
||||
testing.expect(t, !ok && f == 0.0, "expected f64(0.0), with ok=false")
|
||||
|
||||
|
||||
f, ok = strconv.parse_f64("inf")
|
||||
testing.expect(t, ok && math.classify(f) == math.Float_Class.Inf, "expected f64(+inf), fully consumed")
|
||||
|
||||
13
tests/issues/test_issue_2113.odin
Normal file
13
tests/issues/test_issue_2113.odin
Normal file
@@ -0,0 +1,13 @@
|
||||
// Tests issue #2113 https://github.com/odin-lang/Odin/issues/2113
|
||||
// Causes a panic on compilation
|
||||
package test_issues
|
||||
|
||||
T :: struct {
|
||||
a: int,
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
array: #soa[1]T
|
||||
a := &array[0]
|
||||
_ = a
|
||||
}
|
||||
6
vendor/darwin/Foundation/NSApplication.odin
vendored
6
vendor/darwin/Foundation/NSApplication.odin
vendored
@@ -11,7 +11,7 @@ ActivationPolicy :: enum UInteger {
|
||||
ApplicationDelegate :: struct {
|
||||
willFinishLaunching: proc "c" (self: ^ApplicationDelegate, notification: ^Notification),
|
||||
didFinishLaunching: proc "c" (self: ^ApplicationDelegate, notification: ^Notification),
|
||||
shouldTerminateAfterLastWindowClosed: proc "c" (self: ^ApplicationDelegate, sender: ^Application),
|
||||
shouldTerminateAfterLastWindowClosed: proc "c" (self: ^ApplicationDelegate, sender: ^Application) -> BOOL,
|
||||
|
||||
user_data: rawptr,
|
||||
}
|
||||
@@ -34,9 +34,9 @@ Application_setDelegate :: proc(self: ^Application, delegate: ^ApplicationDelega
|
||||
del := (^ApplicationDelegate)(self->pointerValue())
|
||||
del->didFinishLaunching(notification)
|
||||
}
|
||||
shouldTerminateAfterLastWindowClosed :: proc "c" (self: ^Value, _: SEL, application: ^Application) {
|
||||
shouldTerminateAfterLastWindowClosed :: proc "c" (self: ^Value, _: SEL, application: ^Application) -> BOOL {
|
||||
del := (^ApplicationDelegate)(self->pointerValue())
|
||||
del->shouldTerminateAfterLastWindowClosed(application)
|
||||
return del->shouldTerminateAfterLastWindowClosed(application)
|
||||
}
|
||||
|
||||
wrapper := Value.valueWithPointer(delegate)
|
||||
|
||||
16
vendor/darwin/Foundation/NSWindow.odin
vendored
16
vendor/darwin/Foundation/NSWindow.odin
vendored
@@ -156,6 +156,22 @@ Window_makeKeyAndOrderFront :: proc(self: ^Window, key: ^NS.Object) {
|
||||
Window_setTitle :: proc(self: ^Window, title: ^NS.String) {
|
||||
msgSend(nil, self, "setTitle:", title)
|
||||
}
|
||||
@(objc_type=Window, objc_name="setTitlebarAppearsTransparent")
|
||||
Window_setTitlebarAppearsTransparent :: proc(self: ^Window, ok: NS.BOOL) {
|
||||
msgSend(nil, self, "setTitlebarAppearsTransparent:", ok)
|
||||
}
|
||||
@(objc_type=Window, objc_name="setMovable")
|
||||
Window_setMovable :: proc(self: ^Window, ok: NS.BOOL) {
|
||||
msgSend(nil, self, "setMovable:", ok)
|
||||
}
|
||||
@(objc_type=Window, objc_name="setMovableByWindowBackground")
|
||||
Window_setMovableByWindowBackground :: proc(self: ^Window, ok: NS.BOOL) {
|
||||
msgSend(nil, self, "setMovableByWindowBackground:", ok)
|
||||
}
|
||||
@(objc_type=Window, objc_name="setStyleMask")
|
||||
Window_setStyleMask :: proc(self: ^Window, style_mask: WindowStyleMask) {
|
||||
msgSend(nil, self, "setStyleMask:", style_mask)
|
||||
}
|
||||
@(objc_type=Window, objc_name="close")
|
||||
Window_close :: proc(self: ^Window) {
|
||||
msgSend(nil, self, "close")
|
||||
|
||||
6
vendor/darwin/Foundation/objc.odin
vendored
6
vendor/darwin/Foundation/objc.odin
vendored
@@ -10,9 +10,13 @@ IMP :: proc "c" (object: id, sel: SEL, #c_vararg args: ..any) -> id
|
||||
foreign Foundation {
|
||||
objc_lookUpClass :: proc "c" (name: cstring) -> Class ---
|
||||
sel_registerName :: proc "c" (name: cstring) -> SEL ---
|
||||
objc_allocateClassPair :: proc "c" (superclass: Class, name: cstring, extraBytes: uint) ---
|
||||
objc_allocateClassPair :: proc "c" (superclass : Class, name : cstring, extraBytes : c.size_t) -> Class ---
|
||||
objc_registerClassPair :: proc "c" (cls : Class) ---
|
||||
|
||||
class_addMethod :: proc "c" (cls: Class, name: SEL, imp: IMP, types: cstring) -> BOOL ---
|
||||
class_getInstanceMethod :: proc "c" (cls: Class, name: SEL) -> Method ---
|
||||
|
||||
method_setImplementation :: proc "c" (method: Method, imp: IMP) ---
|
||||
}
|
||||
|
||||
|
||||
|
||||
312
vendor/directx/d3d11/d3d11.odin
vendored
312
vendor/directx/d3d11/d3d11.odin
vendored
@@ -30,7 +30,7 @@ foreign d3d11 {
|
||||
DriverType: DRIVER_TYPE,
|
||||
Software: HMODULE,
|
||||
Flags: CREATE_DEVICE_FLAGS,
|
||||
pFeatureLevels: ^FEATURE_LEVEL,
|
||||
pFeatureLevels: [^]FEATURE_LEVEL,
|
||||
FeatureLevels: u32,
|
||||
SDKVersion: u32,
|
||||
ppDevice: ^^IDevice,
|
||||
@@ -41,8 +41,8 @@ foreign d3d11 {
|
||||
pAdapter: ^dxgi.IAdapter,
|
||||
DriverType: DRIVER_TYPE,
|
||||
Software: HMODULE,
|
||||
Flags: u32,
|
||||
pFeatureLevels: ^FEATURE_LEVEL,
|
||||
Flags: CREATE_DEVICE_FLAGS,
|
||||
pFeatureLevels: [^]FEATURE_LEVEL,
|
||||
FeatureLevels: u32,
|
||||
SDKVersion: u32,
|
||||
pSwapChainDesc: ^dxgi.SWAP_CHAIN_DESC,
|
||||
@@ -539,25 +539,37 @@ ANISOTROPIC_FILTERING_BIT :: 0x40
|
||||
SDK_VERSION :: 7
|
||||
RETURN_PARAMETER_INDEX :: -1
|
||||
|
||||
COMPONENT_MASK :: enum u32 { // TODO: make bit_set
|
||||
COMPONENT_MASK :: distinct bit_set[COMPONENT_MASK_ELEMENT; u32]
|
||||
COMPONENT_MASK_ELEMENT :: enum u32 {
|
||||
X = 1,
|
||||
Y = 2,
|
||||
Z = 4,
|
||||
W = 8,
|
||||
}
|
||||
|
||||
SHADER_REQUIRES :: enum u32 { // TODO: make bit_set
|
||||
DOUBLES = 0x00000001,
|
||||
EARLY_DEPTH_STENCIL = 0x00000002,
|
||||
UAVS_AT_EVERY_STAGE = 0x00000004,
|
||||
_64_UAVS = 0x00000008,
|
||||
MINIMUM_PRECISION = 0x00000010,
|
||||
_11_1_DOUBLE_EXTENSIONS = 0x00000020,
|
||||
_11_1_SHADER_EXTENSIONS = 0x00000040,
|
||||
LEVEL_9_COMPARISON_FILTERING = 0x00000080,
|
||||
TILED_RESOURCES = 0x00000100,
|
||||
SHADER_REQUIRES_FLAGS :: distinct bit_set[SHADER_REQUIRES_FLAG; u64]
|
||||
SHADER_REQUIRES_FLAG :: enum u64 {
|
||||
DOUBLES = 0,
|
||||
EARLY_DEPTH_STENCIL = 1,
|
||||
UAVS_AT_EVERY_STAGE = 2,
|
||||
_64_UAVS = 3,
|
||||
MINIMUM_PRECISION = 4,
|
||||
_11_1_DOUBLE_EXTENSIONS = 5,
|
||||
_11_1_SHADER_EXTENSIONS = 6,
|
||||
LEVEL_9_COMPARISON_FILTERING = 7,
|
||||
TILED_RESOURCES = 8,
|
||||
}
|
||||
|
||||
SHADER_REQUIRES_DOUBLES :: SHADER_REQUIRES_FLAGS{.DOUBLES}
|
||||
SHADER_REQUIRES_EARLY_DEPTH_STENCIL :: SHADER_REQUIRES_FLAGS{.EARLY_DEPTH_STENCIL}
|
||||
SHADER_REQUIRES_UAVS_AT_EVERY_STAGE :: SHADER_REQUIRES_FLAGS{.UAVS_AT_EVERY_STAGE}
|
||||
SHADER_REQUIRES_64_UAVS :: SHADER_REQUIRES_FLAGS{._64_UAVS}
|
||||
SHADER_REQUIRES_MINIMUM_PRECISION :: SHADER_REQUIRES_FLAGS{.MINIMUM_PRECISION}
|
||||
SHADER_REQUIRES_11_1_DOUBLE_EXTENSIONS :: SHADER_REQUIRES_FLAGS{._11_1_DOUBLE_EXTENSIONS}
|
||||
SHADER_REQUIRES_11_1_SHADER_EXTENSIONS :: SHADER_REQUIRES_FLAGS{._11_1_SHADER_EXTENSIONS}
|
||||
SHADER_REQUIRES_LEVEL_9_COMPARISON_FILTERING :: SHADER_REQUIRES_FLAGS{.LEVEL_9_COMPARISON_FILTERING}
|
||||
SHADER_REQUIRES_TILED_RESOURCES :: SHADER_REQUIRES_FLAGS{.TILED_RESOURCES}
|
||||
|
||||
DRIVER_TYPE :: enum i32 {
|
||||
UNKNOWN = 0,
|
||||
HARDWARE = 1,
|
||||
@@ -708,11 +720,12 @@ SHADER_VARIABLE_CLASS :: enum i32 {
|
||||
INTERFACE_POINTER = 7,
|
||||
}
|
||||
|
||||
SHADER_VARIABLE_FLAGS :: enum u32 { // TODO: make bit_set
|
||||
USERPACKED = 0x1,
|
||||
USED = 0x2,
|
||||
INTERFACE_POINTER = 0x4,
|
||||
INTERFACE_PARAMETER = 0x8,
|
||||
SHADER_VARIABLE_FLAGS :: distinct bit_set[SHADER_VARIABLE_FLAG; u32]
|
||||
SHADER_VARIABLE_FLAG :: enum u32 {
|
||||
USERPACKED = 0,
|
||||
USED = 1,
|
||||
INTERFACE_POINTER = 2,
|
||||
INTERFACE_PARAMETER = 3,
|
||||
}
|
||||
|
||||
SHADER_VARIABLE_TYPE :: enum i32 {
|
||||
@@ -776,14 +789,21 @@ SHADER_VARIABLE_TYPE :: enum i32 {
|
||||
MIN16UINT = 57,
|
||||
}
|
||||
|
||||
SHADER_INPUT_FLAGS :: enum u32 { // TODO: make bit_set
|
||||
USERPACKED = 0x1,
|
||||
COMPARISON_SAMPLER = 0x2,
|
||||
TEXTURE_COMPONENT_0 = 0x4,
|
||||
TEXTURE_COMPONENT_1 = 0x8,
|
||||
SHADER_INPUT_FLAGS :: distinct bit_set[SHADER_INPUT_FLAG; u32]
|
||||
SHADER_INPUT_FLAG :: enum u32 {
|
||||
USERPACKED = 0,
|
||||
COMPARISON_SAMPLER = 1,
|
||||
TEXTURE_COMPONENT_0 = 2,
|
||||
TEXTURE_COMPONENT_1 = 3,
|
||||
TEXTURE_COMPONENTS = 0xc,
|
||||
UNUSED = 0x10,
|
||||
UNUSED = 4,
|
||||
}
|
||||
SHADER_INPUT_FLAG_USERPACKED :: SHADER_INPUT_FLAGS{.USERPACKED}
|
||||
SHADER_INPUT_FLAG_COMPARISON_SAMPLER :: SHADER_INPUT_FLAGS{.COMPARISON_SAMPLER}
|
||||
SHADER_INPUT_FLAG_TEXTURE_COMPONENT_0 :: SHADER_INPUT_FLAGS{.TEXTURE_COMPONENT_0}
|
||||
SHADER_INPUT_FLAG_TEXTURE_COMPONENT_1 :: SHADER_INPUT_FLAGS{.TEXTURE_COMPONENT_1}
|
||||
SHADER_INPUT_FLAG_TEXTURE_COMPONENTS :: SHADER_INPUT_FLAGS{.TEXTURE_COMPONENT_0, .TEXTURE_COMPONENT_1}
|
||||
SHADER_INPUT_FLAG_UNUSED :: SHADER_INPUT_FLAGS{.UNUSED}
|
||||
|
||||
SHADER_INPUT_TYPE :: enum i32 {
|
||||
CBUFFER = 0,
|
||||
@@ -802,8 +822,9 @@ SHADER_INPUT_TYPE :: enum i32 {
|
||||
UAV_FEEDBACKTEXTURE = 13,
|
||||
}
|
||||
|
||||
SHADER_CBUFFER_FLAGS :: enum u32 { // TODO: make bit_set
|
||||
USERPACKED = 0x1,
|
||||
SHADER_CBUFFER_FLAGS :: distinct bit_set[SHADER_CBUFFER_FLAG; u32]
|
||||
SHADER_CBUFFER_FLAG :: enum u32 {
|
||||
USERPACKED = 0,
|
||||
}
|
||||
|
||||
CBUFFER_TYPE :: enum i32 {
|
||||
@@ -906,10 +927,10 @@ INTERPOLATION_MODE :: enum i32 {
|
||||
LINEAR_NOPERSPECTIVE_SAMPLE = 7,
|
||||
}
|
||||
|
||||
PARAMETER_FLAGS :: enum u32 { // TODO: make bit_set
|
||||
NONE = 0x0,
|
||||
IN = 0x1,
|
||||
OUT = 0x2,
|
||||
PARAMETER_FLAGS :: distinct bit_set[PARAMETER_FLAG; u32]
|
||||
PARAMETER_FLAG :: enum u32 {
|
||||
IN = 0,
|
||||
OUT = 1,
|
||||
}
|
||||
|
||||
CDEFAULT :: struct {
|
||||
@@ -1022,43 +1043,46 @@ USAGE :: enum i32 {
|
||||
STAGING = 3,
|
||||
}
|
||||
|
||||
BIND_FLAG :: enum u32 { // TODO: make bit_set
|
||||
VERTEX_BUFFER = 0x1,
|
||||
INDEX_BUFFER = 0x2,
|
||||
CONSTANT_BUFFER = 0x4,
|
||||
SHADER_RESOURCE = 0x8,
|
||||
STREAM_OUTPUT = 0x10,
|
||||
RENDER_TARGET = 0x20,
|
||||
DEPTH_STENCIL = 0x40,
|
||||
UNORDERED_ACCESS = 0x80,
|
||||
DECODER = 0x200,
|
||||
VIDEO_ENCODER = 0x400,
|
||||
BIND_FLAGS :: distinct bit_set[BIND_FLAG; u32]
|
||||
BIND_FLAG :: enum u32 {
|
||||
VERTEX_BUFFER = 0,
|
||||
INDEX_BUFFER = 1,
|
||||
CONSTANT_BUFFER = 2,
|
||||
SHADER_RESOURCE = 3,
|
||||
STREAM_OUTPUT = 4,
|
||||
RENDER_TARGET = 5,
|
||||
DEPTH_STENCIL = 6,
|
||||
UNORDERED_ACCESS = 7,
|
||||
DECODER = 9,
|
||||
VIDEO_ENCODER = 10,
|
||||
}
|
||||
|
||||
CPU_ACCESS_FLAG :: enum u32 { // TODO: make bit_set
|
||||
WRITE = 0x10000,
|
||||
READ = 0x20000,
|
||||
CPU_ACCESS_FLAGS :: distinct bit_set[CPU_ACCESS_FLAG; u32]
|
||||
CPU_ACCESS_FLAG :: enum u32 {
|
||||
WRITE = 16,
|
||||
READ = 17,
|
||||
|
||||
}
|
||||
|
||||
RESOURCE_MISC_FLAG :: enum u32 { // TODO: make bit_set
|
||||
GENERATE_MIPS = 0x1,
|
||||
SHARED = 0x2,
|
||||
TEXTURECUBE = 0x4,
|
||||
DRAWINDIRECT_ARGS = 0x10,
|
||||
BUFFER_ALLOW_RAW_VIEWS = 0x20,
|
||||
BUFFER_STRUCTURED = 0x40,
|
||||
RESOURCE_CLAMP = 0x80,
|
||||
SHARED_KEYEDMUTEX = 0x100,
|
||||
GDI_COMPATIBLE = 0x200,
|
||||
SHARED_NTHANDLE = 0x800,
|
||||
RESTRICTED_CONTENT = 0x1000,
|
||||
RESTRICT_SHARED_RESOURCE = 0x2000,
|
||||
RESTRICT_SHARED_RESOURCE_DRIVER = 0x4000,
|
||||
GUARDED = 0x8000,
|
||||
TILE_POOL = 0x20000,
|
||||
TILED = 0x40000,
|
||||
HW_PROTECTED = 0x80000,
|
||||
RESOURCE_MISC_FLAGS :: distinct bit_set[RESOURCE_MISC_FLAG; u32]
|
||||
RESOURCE_MISC_FLAG :: enum u32 {
|
||||
GENERATE_MIPS = 0,
|
||||
SHARED = 1,
|
||||
TEXTURECUBE = 2,
|
||||
DRAWINDIRECT_ARGS = 4,
|
||||
BUFFER_ALLOW_RAW_VIEWS = 5,
|
||||
BUFFER_STRUCTURED = 6,
|
||||
RESOURCE_CLAMP = 7,
|
||||
SHARED_KEYEDMUTEX = 8,
|
||||
GDI_COMPATIBLE = 9,
|
||||
SHARED_NTHANDLE = 11,
|
||||
RESTRICTED_CONTENT = 12,
|
||||
RESTRICT_SHARED_RESOURCE = 13,
|
||||
RESTRICT_SHARED_RESOURCE_DRIVER = 14,
|
||||
GUARDED = 15,
|
||||
TILE_POOL = 17,
|
||||
TILED = 18,
|
||||
HW_PROTECTED = 19,
|
||||
}
|
||||
|
||||
MAP :: enum i32 {
|
||||
@@ -1069,17 +1093,20 @@ MAP :: enum i32 {
|
||||
WRITE_NO_OVERWRITE = 5,
|
||||
}
|
||||
|
||||
MAP_FLAG :: enum u32 { // TODO: make bit_set
|
||||
DO_NOT_WAIT = 0x100000,
|
||||
MAP_FLAGS :: distinct bit_set[MAP_FLAG; u32]
|
||||
MAP_FLAG :: enum u32 {
|
||||
DO_NOT_WAIT = 20,
|
||||
}
|
||||
|
||||
RAISE_FLAG :: enum u32 { // TODO: make bit_set
|
||||
DRIVER_INTERNAL_ERROR = 0x1,
|
||||
RAISE_FLAGS :: distinct bit_set[RAISE_FLAG; u32]
|
||||
RAISE_FLAG :: enum u32 {
|
||||
DRIVER_INTERNAL_ERROR = 0,
|
||||
}
|
||||
|
||||
CLEAR_FLAG :: enum u32 { // TODO: make bit_set
|
||||
DEPTH = 0x1,
|
||||
STENCIL = 0x2,
|
||||
CLEAR_FLAGS :: distinct bit_set[CLEAR_FLAG; u32]
|
||||
CLEAR_FLAG :: enum u32 {
|
||||
DEPTH = 0,
|
||||
STENCIL = 1,
|
||||
}
|
||||
|
||||
|
||||
@@ -1206,7 +1233,15 @@ BLEND_OP :: enum i32 {
|
||||
MAX = 5,
|
||||
}
|
||||
|
||||
COLOR_WRITE_ENABLE :: enum i32 { // TODO: make bit_set
|
||||
COLOR_WRITE_ENABLE_MASK :: distinct bit_set[COLOR_WRITE_ENABLE; u32]
|
||||
|
||||
COLOR_WRITE_ENABLE_RED :: COLOR_WRITE_ENABLE_MASK{.RED}
|
||||
COLOR_WRITE_ENABLE_GREEN :: COLOR_WRITE_ENABLE_MASK{.GREEN}
|
||||
COLOR_WRITE_ENABLE_BLUE :: COLOR_WRITE_ENABLE_MASK{.BLUE}
|
||||
COLOR_WRITE_ENABLE_ALPHA :: COLOR_WRITE_ENABLE_MASK{.ALPHA}
|
||||
COLOR_WRITE_ENABLE_ALL :: COLOR_WRITE_ENABLE_MASK{.RED, .GREEN, .BLUE, .ALPHA}
|
||||
|
||||
COLOR_WRITE_ENABLE :: enum i32 {
|
||||
RED = 1,
|
||||
GREEN = 2,
|
||||
BLUE = 4,
|
||||
@@ -1308,9 +1343,9 @@ IResource_VTable :: struct {
|
||||
BUFFER_DESC :: struct {
|
||||
ByteWidth: u32,
|
||||
Usage: USAGE,
|
||||
BindFlags: BIND_FLAG,
|
||||
CPUAccessFlags: CPU_ACCESS_FLAG,
|
||||
MiscFlags: RESOURCE_MISC_FLAG,
|
||||
BindFlags: BIND_FLAGS,
|
||||
CPUAccessFlags: CPU_ACCESS_FLAGS,
|
||||
MiscFlags: RESOURCE_MISC_FLAGS,
|
||||
StructureByteStride: u32,
|
||||
}
|
||||
|
||||
@@ -1337,9 +1372,9 @@ TEXTURE1D_DESC :: struct {
|
||||
ArraySize: u32,
|
||||
Format: dxgi.FORMAT,
|
||||
Usage: USAGE,
|
||||
BindFlags: BIND_FLAG,
|
||||
CPUAccessFlags: CPU_ACCESS_FLAG,
|
||||
MiscFlags: RESOURCE_MISC_FLAG,
|
||||
BindFlags: BIND_FLAGS,
|
||||
CPUAccessFlags: CPU_ACCESS_FLAGS,
|
||||
MiscFlags: RESOURCE_MISC_FLAGS,
|
||||
}
|
||||
|
||||
CTEXTURE1D_DESC :: struct {
|
||||
@@ -1367,9 +1402,9 @@ TEXTURE2D_DESC :: struct {
|
||||
Format: dxgi.FORMAT,
|
||||
SampleDesc: dxgi.SAMPLE_DESC,
|
||||
Usage: USAGE,
|
||||
BindFlags: BIND_FLAG,
|
||||
CPUAccessFlags: CPU_ACCESS_FLAG,
|
||||
MiscFlags: RESOURCE_MISC_FLAG,
|
||||
BindFlags: BIND_FLAGS,
|
||||
CPUAccessFlags: CPU_ACCESS_FLAGS,
|
||||
MiscFlags: RESOURCE_MISC_FLAGS,
|
||||
}
|
||||
|
||||
CTEXTURE2D_DESC :: struct {
|
||||
@@ -1396,9 +1431,9 @@ TEXTURE3D_DESC :: struct {
|
||||
MipLevels: u32,
|
||||
Format: dxgi.FORMAT,
|
||||
Usage: USAGE,
|
||||
BindFlags: BIND_FLAG,
|
||||
CPUAccessFlags: CPU_ACCESS_FLAG,
|
||||
MiscFlags: RESOURCE_MISC_FLAG,
|
||||
BindFlags: BIND_FLAGS,
|
||||
CPUAccessFlags: CPU_ACCESS_FLAGS,
|
||||
MiscFlags: RESOURCE_MISC_FLAGS,
|
||||
}
|
||||
|
||||
CTEXTURE3D_DESC :: struct {
|
||||
@@ -1451,14 +1486,15 @@ BUFFER_SRV :: struct {
|
||||
},
|
||||
}
|
||||
|
||||
BUFFEREX_SRV_FLAG :: enum u32 { // TODO: make bit_set
|
||||
RAW = 0x1,
|
||||
BUFFEREX_SRV_FLAGS :: distinct bit_set[BUFFEREX_SRV_FLAG; u32]
|
||||
BUFFEREX_SRV_FLAG :: enum u32 {
|
||||
RAW = 0,
|
||||
}
|
||||
|
||||
BUFFEREX_SRV :: struct {
|
||||
FirstElement: u32,
|
||||
NumElements: u32,
|
||||
Flags: u32,
|
||||
Flags: BUFFEREX_SRV_FLAGS,
|
||||
}
|
||||
|
||||
TEX1D_SRV :: struct {
|
||||
@@ -1657,15 +1693,16 @@ TEX2DMS_ARRAY_DSV :: struct {
|
||||
ArraySize: u32,
|
||||
}
|
||||
|
||||
DSV_FLAG :: enum u32 { // TODO: make bit_set
|
||||
DEPTH = 0x1,
|
||||
STENCIL = 0x2,
|
||||
DSV_FLAGS :: distinct bit_set[DSV_FLAG; u32]
|
||||
DSV_FLAG :: enum u32 {
|
||||
DEPTH = 0,
|
||||
STENCIL = 1,
|
||||
}
|
||||
|
||||
DEPTH_STENCIL_VIEW_DESC :: struct {
|
||||
Format: dxgi.FORMAT,
|
||||
ViewDimension: DSV_DIMENSION,
|
||||
Flags: u32,
|
||||
Flags: DSV_FLAGS,
|
||||
using _: struct #raw_union {
|
||||
Texture1D: TEX1D_DSV,
|
||||
Texture1DArray: TEX1D_ARRAY_DSV,
|
||||
@@ -1693,16 +1730,17 @@ IDepthStencilView_VTable :: struct {
|
||||
}
|
||||
|
||||
|
||||
BUFFER_UAV_FLAG :: enum u32 { // TODO: make bit_set
|
||||
RAW = 0x1,
|
||||
APPEND = 0x2,
|
||||
COUNTER = 0x4,
|
||||
BUFFER_UAV_FLAGS :: distinct bit_set[BUFFER_UAV_FLAG; u32]
|
||||
BUFFER_UAV_FLAG :: enum u32 {
|
||||
RAW = 0,
|
||||
APPEND = 1,
|
||||
COUNTER = 2,
|
||||
}
|
||||
|
||||
BUFFER_UAV :: struct {
|
||||
FirstElement: u32,
|
||||
NumElements: u32,
|
||||
Flags: u32,
|
||||
Flags: BUFFER_UAV_FLAGS,
|
||||
}
|
||||
|
||||
TEX1D_UAV :: struct {
|
||||
@@ -1961,8 +1999,9 @@ IAsynchronous_VTable :: struct {
|
||||
}
|
||||
|
||||
|
||||
ASYNC_GETDATA_FLAG :: enum u32 { // TODO: make bit_set
|
||||
DONOTFLUSH = 0x1,
|
||||
ASYNC_GETDATA_FLAGS :: distinct bit_set[ASYNC_GETDATA_FLAG; u32]
|
||||
ASYNC_GETDATA_FLAG :: enum u32 {
|
||||
DONOTFLUSH = 0,
|
||||
}
|
||||
|
||||
QUERY :: enum i32 {
|
||||
@@ -1984,13 +2023,14 @@ QUERY :: enum i32 {
|
||||
SO_OVERFLOW_PREDICATE_STREAM3 = 15,
|
||||
}
|
||||
|
||||
QUERY_MISC_FLAG :: enum u32 { // TODO: make bit_set
|
||||
QUERY_MISC_PREDICATEHINT = 0x1,
|
||||
QUERY_MISC_FLAGS :: distinct bit_set[QUERY_MISC_FLAG; u32]
|
||||
QUERY_MISC_FLAG :: enum u32 {
|
||||
PREDICATEHINT = 0,
|
||||
}
|
||||
|
||||
QUERY_DESC :: struct {
|
||||
Query: QUERY,
|
||||
MiscFlags: RESOURCE_MISC_FLAG,
|
||||
MiscFlags: QUERY_MISC_FLAGS,
|
||||
}
|
||||
|
||||
CQUERY_DESC :: struct {
|
||||
@@ -2054,7 +2094,7 @@ COUNTER_TYPE :: enum i32 {
|
||||
|
||||
COUNTER_DESC :: struct {
|
||||
Counter: COUNTER,
|
||||
MiscFlags: RESOURCE_MISC_FLAG,
|
||||
MiscFlags: RESOURCE_MISC_FLAGS,
|
||||
}
|
||||
|
||||
CCOUNTER_DESC :: struct {
|
||||
@@ -2150,21 +2190,21 @@ FEATURE :: enum i32 {
|
||||
FORMAT_SUPPORT = 2,
|
||||
FORMAT_SUPPORT2 = 3,
|
||||
D3D10_X_HARDWARE_OPTIONS = 4,
|
||||
OPTIONS = 5,
|
||||
OPTIONS = 5,
|
||||
ARCHITECTURE_INFO = 6,
|
||||
D3D9_OPTIONS = 7,
|
||||
SHADER_MIN_PRECISION_SUPPORT = 8,
|
||||
D3D9_SHADOW_SUPPORT = 9,
|
||||
OPTIONS1 = 10,
|
||||
OPTIONS1 = 10,
|
||||
D3D9_SIMPLE_INSTANCING_SUPPORT = 11,
|
||||
MARKER_SUPPORT = 12,
|
||||
D3D9_OPTIONS1 = 13,
|
||||
OPTIONS2 = 14,
|
||||
OPTIONS3 = 15,
|
||||
OPTIONS2 = 14,
|
||||
OPTIONS3 = 15,
|
||||
GPU_VIRTUAL_ADDRESS_SUPPORT = 16,
|
||||
OPTIONS4 = 17,
|
||||
OPTIONS4 = 17,
|
||||
SHADER_CACHE = 18,
|
||||
OPTIONS5 = 19,
|
||||
OPTIONS5 = 19,
|
||||
}
|
||||
|
||||
FEATURE_DATA_THREADING :: struct {
|
||||
@@ -2285,14 +2325,14 @@ FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT :: struct {
|
||||
MaxGPUVirtualAddressBitsPerProcess: u32,
|
||||
}
|
||||
|
||||
SHADER_CACHE_SUPPORT_FLAGS :: enum u32 { // TODO: make bit_set
|
||||
NONE = 0x0,
|
||||
AUTOMATIC_INPROC_CACHE = 0x1,
|
||||
AUTOMATIC_DISK_CACHE = 0x2,
|
||||
SHADER_CACHE_SUPPORT_FLAGS :: distinct bit_set[SHADER_CACHE_SUPPORT_FLAG; u32]
|
||||
SHADER_CACHE_SUPPORT_FLAG :: enum u32 {
|
||||
AUTOMATIC_INPROC_CACHE = 0,
|
||||
AUTOMATIC_DISK_CACHE = 1,
|
||||
}
|
||||
|
||||
FEATURE_DATA_SHADER_CACHE :: struct {
|
||||
SupportFlags: u32,
|
||||
SupportFlags: SHADER_CACHE_SUPPORT_FLAGS,
|
||||
}
|
||||
|
||||
SHARED_RESOURCE_TIER :: enum i32 {
|
||||
@@ -2322,7 +2362,7 @@ IDeviceContext_VTable :: struct {
|
||||
VSSetShader: proc "stdcall" (this: ^IDeviceContext, pVertexShader: ^IVertexShader, ppClassInstances: ^^IClassInstance, NumClassInstances: u32),
|
||||
DrawIndexed: proc "stdcall" (this: ^IDeviceContext, IndexCount: u32, StartIndexLocation: u32, BaseVertexLocation: i32),
|
||||
Draw: proc "stdcall" (this: ^IDeviceContext, VertexCount: u32, StartVertexLocation: u32),
|
||||
Map: proc "stdcall" (this: ^IDeviceContext, pResource: ^IResource, Subresource: u32, MapType: MAP, MapFlags: u32, pMappedResource: ^MAPPED_SUBRESOURCE) -> HRESULT,
|
||||
Map: proc "stdcall" (this: ^IDeviceContext, pResource: ^IResource, Subresource: u32, MapType: MAP, MapFlags: MAP_FLAGS, pMappedResource: ^MAPPED_SUBRESOURCE) -> HRESULT,
|
||||
Unmap: proc "stdcall" (this: ^IDeviceContext, pResource: ^IResource, Subresource: u32),
|
||||
PSSetConstantBuffers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumBuffers: u32, ppConstantBuffers: ^^IBuffer),
|
||||
IASetInputLayout: proc "stdcall" (this: ^IDeviceContext, pInputLayout: ^IInputLayout),
|
||||
@@ -2343,7 +2383,7 @@ IDeviceContext_VTable :: struct {
|
||||
GSSetSamplers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumSamplers: u32, ppSamplers: ^^ISamplerState),
|
||||
OMSetRenderTargets: proc "stdcall" (this: ^IDeviceContext, NumViews: u32, ppRenderTargetViews: ^^IRenderTargetView, pDepthStencilView: ^IDepthStencilView),
|
||||
OMSetRenderTargetsAndUnorderedAccessViews: proc "stdcall" (this: ^IDeviceContext, NumRTVs: u32, ppRenderTargetViews: ^^IRenderTargetView, pDepthStencilView: ^IDepthStencilView, UAVStartSlot: u32, NumUAVs: u32, ppUnorderedAccessViews: ^^IUnorderedAccessView, pUAVInitialCounts: ^u32),
|
||||
OMSetBlendState: proc "stdcall" (this: ^IDeviceContext, pBlendState: ^IBlendState, BlendFactor: ^[4]f32, SampleMask: u32),
|
||||
OMSetBlendState: proc "stdcall" (this: ^IDeviceContext, pBlendState: ^IBlendState, BlendFactor: ^[4]f32, SampleMask: COLOR_WRITE_ENABLE_MASK),
|
||||
OMSetDepthStencilState: proc "stdcall" (this: ^IDeviceContext, pDepthStencilState: ^IDepthStencilState, StencilRef: u32),
|
||||
SOSetTargets: proc "stdcall" (this: ^IDeviceContext, NumBuffers: u32, ppSOTargets: ^^IBuffer, pOffsets: ^u32),
|
||||
DrawAuto: proc "stdcall" (this: ^IDeviceContext),
|
||||
@@ -2399,7 +2439,7 @@ IDeviceContext_VTable :: struct {
|
||||
GSGetSamplers: proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumSamplers: u32, ppSamplers: ^^ISamplerState),
|
||||
OMGetRenderTargets: proc "stdcall" (this: ^IDeviceContext, NumViews: u32, ppRenderTargetViews: ^^IRenderTargetView, ppDepthStencilView: ^^IDepthStencilView),
|
||||
OMGetRenderTargetsAndUnorderedAccessViews: proc "stdcall" (this: ^IDeviceContext, NumRTVs: u32, ppRenderTargetViews: ^^IRenderTargetView, ppDepthStencilView: ^^IDepthStencilView, UAVStartSlot: u32, NumUAVs: u32, ppUnorderedAccessViews: ^^IUnorderedAccessView),
|
||||
OMGetBlendState: proc "stdcall" (this: ^IDeviceContext, ppBlendState: ^^IBlendState, BlendFactor: ^[4]f32, pSampleMask: ^u32),
|
||||
OMGetBlendState: proc "stdcall" (this: ^IDeviceContext, ppBlendState: ^^IBlendState, BlendFactor: ^[4]f32, pSampleMask: ^COLOR_WRITE_ENABLE_MASK),
|
||||
OMGetDepthStencilState: proc "stdcall" (this: ^IDeviceContext, ppDepthStencilState: ^^IDepthStencilState, pStencilRef: ^u32),
|
||||
SOGetTargets: proc "stdcall" (this: ^IDeviceContext, NumBuffers: u32, ppSOTargets: ^^IBuffer),
|
||||
RSGetState: proc "stdcall" (this: ^IDeviceContext, ppRasterizerState: ^^IRasterizerState),
|
||||
@@ -3315,13 +3355,13 @@ IDevice_VTable :: struct {
|
||||
GetCreationFlags: proc "stdcall" (this: ^IDevice) -> u32,
|
||||
GetDeviceRemovedReason: proc "stdcall" (this: ^IDevice) -> HRESULT,
|
||||
GetImmediateContext: proc "stdcall" (this: ^IDevice, ppImmediateContext: ^^IDeviceContext),
|
||||
SetExceptionMode: proc "stdcall" (this: ^IDevice, RaiseFlags: u32) -> HRESULT,
|
||||
SetExceptionMode: proc "stdcall" (this: ^IDevice, RaiseFlags: RAISE_FLAGS) -> HRESULT,
|
||||
GetExceptionMode: proc "stdcall" (this: ^IDevice) -> u32,
|
||||
}
|
||||
|
||||
|
||||
CREATE_DEVICE_FLAGS :: distinct bit_set[CREATE_DEVICE_FLAG; u32]
|
||||
CREATE_DEVICE_FLAG :: enum u32 { // TODO: make bit_set
|
||||
CREATE_DEVICE_FLAG :: enum u32 {
|
||||
SINGLETHREADED = 0,
|
||||
DEBUG = 1,
|
||||
SWITCH_TO_REF = 2,
|
||||
@@ -3367,14 +3407,14 @@ SHADER_BUFFER_DESC :: struct {
|
||||
Type: CBUFFER_TYPE,
|
||||
Variables: u32,
|
||||
Size: u32,
|
||||
uFlags: u32,
|
||||
uFlags: SHADER_CBUFFER_FLAGS,
|
||||
}
|
||||
|
||||
SHADER_VARIABLE_DESC :: struct {
|
||||
Name: cstring,
|
||||
StartOffset: u32,
|
||||
Size: u32,
|
||||
uFlags: u32,
|
||||
uFlags: SHADER_VARIABLE_FLAGS,
|
||||
DefaultValue: rawptr,
|
||||
StartTexture: u32,
|
||||
TextureSize: u32,
|
||||
@@ -3443,7 +3483,7 @@ SHADER_INPUT_BIND_DESC :: struct {
|
||||
BindPoint: u32,
|
||||
BindCount: u32,
|
||||
|
||||
uFlags: u32,
|
||||
uFlags: SHADER_INPUT_FLAGS,
|
||||
ReturnType: RESOURCE_RETURN_TYPE,
|
||||
Dimension: SRV_DIMENSION,
|
||||
NumSamples: u32,
|
||||
@@ -3485,7 +3525,7 @@ FUNCTION_DESC :: struct {
|
||||
ConversionInstructionCount: u32,
|
||||
BitwiseInstructionCount: u32,
|
||||
MinFeatureLevel: FEATURE_LEVEL,
|
||||
RequiredFeatureFlags: u64,
|
||||
RequiredFeatureFlags: SHADER_REQUIRES_FLAGS,
|
||||
|
||||
Name: cstring,
|
||||
FunctionParameterCount: i32,
|
||||
@@ -3571,7 +3611,7 @@ IShaderReflection_VTable :: struct {
|
||||
GetNumInterfaceSlots: proc "stdcall" (this: ^IShaderReflection) -> u32,
|
||||
GetMinFeatureLevel: proc "stdcall" (this: ^IShaderReflection, pLevel: ^FEATURE_LEVEL) -> HRESULT,
|
||||
GetThreadGroupSize: proc "stdcall" (this: ^IShaderReflection, pSizeX: ^u32, pSizeY: ^u32, pSizeZ: ^u32) -> u32,
|
||||
GetRequiresFlags: proc "stdcall" (this: ^IShaderReflection) -> u64,
|
||||
GetRequiresFlags: proc "stdcall" (this: ^IShaderReflection) -> SHADER_REQUIRES_FLAGS,
|
||||
}
|
||||
|
||||
|
||||
@@ -3634,22 +3674,24 @@ IDebug :: struct #raw_union {
|
||||
using id3d11debug_vtable: ^IDebug_VTable,
|
||||
}
|
||||
|
||||
RLDO_FLAGS :: enum u32 { // TODO: make bit_set
|
||||
SUMMARY = 0x1,
|
||||
DETAIL = 0x2,
|
||||
IGNORE_INTERNAL = 0x4,
|
||||
RLDO_FLAGS :: distinct bit_set[RLDO_FLAG; u32]
|
||||
RLDO_FLAG :: enum u32 {
|
||||
SUMMARY = 0,
|
||||
DETAIL = 1,
|
||||
IGNORE_INTERNAL = 2,
|
||||
}
|
||||
|
||||
DEBUG_FEATURE :: enum u32 { // TODO: make bit_set
|
||||
FLUSH_PER_RENDER_OP = 0x1,
|
||||
FINISH_PER_RENDER_OP = 0x2,
|
||||
FEATURE_PRESENT_PER_RENDER_OP = 0x4,
|
||||
DEBUG_FEATURES :: distinct bit_set[DEBUG_FEATURE; u32]
|
||||
DEBUG_FEATURE :: enum u32 {
|
||||
FLUSH_PER_RENDER_OP = 0,
|
||||
FINISH_PER_RENDER_OP = 1,
|
||||
FEATURE_PRESENT_PER_RENDER_OP = 2,
|
||||
}
|
||||
|
||||
IDebug_VTable :: struct {
|
||||
using iunkown_vtable: IUnknown_VTable,
|
||||
SetFeatureMask: proc "stdcall" (this: ^IDebug, mask: DEBUG_FEATURE) -> HRESULT,
|
||||
GetFeatureMask: proc "stdcall" (this: ^IDebug) -> DEBUG_FEATURE,
|
||||
SetFeatureMask: proc "stdcall" (this: ^IDebug, mask: DEBUG_FEATURES) -> HRESULT,
|
||||
GetFeatureMask: proc "stdcall" (this: ^IDebug) -> DEBUG_FEATURES,
|
||||
SetPresentPerRenderOpDelay: proc "stdcall" (this: ^IDebug, Milliseconds: u32) -> HRESULT,
|
||||
GetPresentPerRenderOpDelay: proc "stdcall" (this: ^IDebug) -> u32,
|
||||
SetSwapChain: proc "stdcall" (this: ^IDebug, pSwapChain: ^dxgi.ISwapChain) -> HRESULT,
|
||||
@@ -3667,7 +3709,7 @@ IInfoQueue :: struct #raw_union {
|
||||
using id3d11infoqueue_vtable: ^IInfoQueue_VTable,
|
||||
}
|
||||
|
||||
MESSAGE_SEVERITY :: enum u32 { // TODO: make bit_set
|
||||
MESSAGE_SEVERITY :: enum u32 {
|
||||
CORRUPTION = 0,
|
||||
ERROR,
|
||||
WARNING,
|
||||
@@ -3675,7 +3717,7 @@ MESSAGE_SEVERITY :: enum u32 { // TODO: make bit_set
|
||||
MESSAGE, // Not supported until D3D 11.1
|
||||
}
|
||||
|
||||
MESSAGE_CATEGORY :: enum u32 { // TODO: make bit_set
|
||||
MESSAGE_CATEGORY :: enum u32 {
|
||||
APPLICATION_DEFINED = 0,
|
||||
MISCELLANEOUS,
|
||||
INITIALIZATION,
|
||||
@@ -3750,7 +3792,7 @@ IInfoQueue_VTable :: struct {
|
||||
SetMuteDebugOutput: proc "stdcall" (this: ^IInfoQueue, bMute: BOOL),
|
||||
}
|
||||
|
||||
MESSAGE_ID :: enum u32 { // TODO: make bit_set
|
||||
MESSAGE_ID :: enum u32 {
|
||||
UNKNOWN = 0,
|
||||
DEVICE_IASETVERTEXBUFFERS_HAZARD,
|
||||
DEVICE_IASETINDEXBUFFER_HAZARD,
|
||||
|
||||
1
vendor/glfw/bindings/bindings.odin
vendored
1
vendor/glfw/bindings/bindings.odin
vendored
@@ -110,6 +110,7 @@ foreign glfw {
|
||||
WaitEventsTimeout :: proc(timeout: f64) ---
|
||||
PostEmptyEvent :: proc() ---
|
||||
|
||||
RawMouseMotionSupported :: proc() -> b32 ---
|
||||
GetInputMode :: proc(window: WindowHandle, mode: c.int) -> c.int ---
|
||||
SetInputMode :: proc(window: WindowHandle, mode, value: c.int) ---
|
||||
|
||||
|
||||
3
vendor/glfw/constants.odin
vendored
3
vendor/glfw/constants.odin
vendored
@@ -339,6 +339,9 @@ CURSOR_NORMAL :: 0x00034001
|
||||
CURSOR_HIDDEN :: 0x00034002
|
||||
CURSOR_DISABLED :: 0x00034003
|
||||
|
||||
/* Mouse motion */
|
||||
RAW_MOUSE_MOTION :: 0x00033005
|
||||
|
||||
/* Behavior? */
|
||||
ANY_RELEASE_BEHAVIOR :: 0
|
||||
RELEASE_BEHAVIOR_FLUSH :: 0x00035001
|
||||
|
||||
33
vendor/glfw/native.odin
vendored
33
vendor/glfw/native.odin
vendored
@@ -1,33 +0,0 @@
|
||||
package glfw
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
import win32 "core:sys/windows"
|
||||
|
||||
foreign import glfw { "lib/glfw3_mt.lib", "system:user32.lib", "system:gdi32.lib", "system:shell32.lib" }
|
||||
|
||||
@(default_calling_convention="c", link_prefix="glfw")
|
||||
foreign glfw {
|
||||
GetWin32Adapter :: proc(monitor: MonitorHandle) -> cstring ---
|
||||
GetWin32Monitor :: proc(monitor: MonitorHandle) -> cstring ---
|
||||
GetWin32Window :: proc(window: WindowHandle) -> win32.HWND ---
|
||||
GetWGLContext :: proc(window: WindowHandle) -> rawptr ---
|
||||
}
|
||||
} else when ODIN_OS == .Linux {
|
||||
// TODO: Native Linux
|
||||
// Display* glfwGetX11Display(void);
|
||||
// RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
|
||||
// RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
|
||||
// Window glfwGetX11Window(GLFWwindow* window);
|
||||
// void glfwSetX11SelectionString(const char* string);
|
||||
// const char* glfwGetX11SelectionString(void);
|
||||
|
||||
// struct wl_display* glfwGetWaylandDisplay(void);
|
||||
// struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
|
||||
// struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
|
||||
} else when ODIN_OS == .Darwin {
|
||||
// TODO: Native Darwin
|
||||
// CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
|
||||
// id glfwGetCocoaWindow(GLFWwindow* window);
|
||||
// id glfwGetNSGLContext(GLFWwindow* window);
|
||||
}
|
||||
|
||||
16
vendor/glfw/native_darwin.odin
vendored
Normal file
16
vendor/glfw/native_darwin.odin
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
//+build darwin
|
||||
|
||||
package glfw
|
||||
|
||||
import NS "vendor:darwin/foundation"
|
||||
|
||||
foreign import glfw { "lib/darwin/libglfw3.a" }
|
||||
|
||||
@(default_calling_convention="c", link_prefix="glfw")
|
||||
foreign glfw {
|
||||
GetCocoaWindow :: proc(window: WindowHandle) -> ^NS.Window ---
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
|
||||
// id glfwGetNSGLContext(GLFWwindow* window);
|
||||
15
vendor/glfw/native_linux.odin
vendored
Normal file
15
vendor/glfw/native_linux.odin
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
//+build linux
|
||||
|
||||
package glfw
|
||||
|
||||
// TODO: Native Linux
|
||||
// Display* glfwGetX11Display(void);
|
||||
// RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
|
||||
// RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
|
||||
// Window glfwGetX11Window(GLFWwindow* window);
|
||||
// void glfwSetX11SelectionString(const char* string);
|
||||
// const char* glfwGetX11SelectionString(void);
|
||||
|
||||
// struct wl_display* glfwGetWaylandDisplay(void);
|
||||
// struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
|
||||
// struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
|
||||
15
vendor/glfw/native_windows.odin
vendored
Normal file
15
vendor/glfw/native_windows.odin
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
//+build windows
|
||||
|
||||
package glfw
|
||||
|
||||
import win32 "core:sys/windows"
|
||||
|
||||
foreign import glfw { "lib/glfw3_mt.lib", "system:user32.lib", "system:gdi32.lib", "system:shell32.lib" }
|
||||
|
||||
@(default_calling_convention="c", link_prefix="glfw")
|
||||
foreign glfw {
|
||||
GetWin32Adapter :: proc(monitor: MonitorHandle) -> cstring ---
|
||||
GetWin32Monitor :: proc(monitor: MonitorHandle) -> cstring ---
|
||||
GetWin32Window :: proc(window: WindowHandle) -> win32.HWND ---
|
||||
GetWGLContext :: proc(window: WindowHandle) -> rawptr ---
|
||||
}
|
||||
14
vendor/vulkan/_gen/create_vulkan_odin_wrapper.py
vendored
14
vendor/vulkan/_gen/create_vulkan_odin_wrapper.py
vendored
@@ -84,7 +84,7 @@ def convert_type(t, prev_name, curr_name):
|
||||
else:
|
||||
ttype = t[:len(t)-1]
|
||||
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 = "[^]"
|
||||
@@ -95,10 +95,10 @@ def convert_type(t, prev_name, curr_name):
|
||||
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
|
||||
@@ -276,7 +276,7 @@ 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()
|
||||
@@ -458,14 +458,14 @@ def parse_procedures(f):
|
||||
|
||||
for rt, name, fields in data:
|
||||
proc_name = no_vk(name)
|
||||
|
||||
|
||||
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)
|
||||
@@ -510,7 +510,7 @@ def group_functions(f):
|
||||
|
||||
if table_name in ('Device', 'Queue', 'CommandBuffer') and name != 'GetDeviceProcAddr':
|
||||
group_map["Device"].append(nn)
|
||||
elif table_name in ('Instance', 'PhysicalDevice') or name == 'GetDeviceProcAddr':
|
||||
elif table_name in ('Instance', 'PhysicalDevice') and name != 'ProcGetInstanceProcAddr' or name == 'GetDeviceProcAddr':
|
||||
group_map["Instance"].append(nn)
|
||||
elif table_name in ('rawptr', '', 'DebugReportFlagsEXT') or name == 'GetInstanceProcAddr':
|
||||
# Skip the allocation function and the dll entry point
|
||||
|
||||
6
vendor/vulkan/procedures.odin
vendored
6
vendor/vulkan/procedures.odin
vendored
@@ -533,6 +533,7 @@ DeviceMemoryReportCallbackEXT: ProcDeviceMemoryReportCallbackEXT
|
||||
EnumerateInstanceExtensionProperties: ProcEnumerateInstanceExtensionProperties
|
||||
EnumerateInstanceLayerProperties: ProcEnumerateInstanceLayerProperties
|
||||
EnumerateInstanceVersion: ProcEnumerateInstanceVersion
|
||||
GetInstanceProcAddr: ProcGetInstanceProcAddr
|
||||
|
||||
// Instance Procedures
|
||||
AcquireDrmDisplayEXT: ProcAcquireDrmDisplayEXT
|
||||
@@ -564,7 +565,6 @@ GetDisplayPlaneCapabilities2KHR: ProcGetDisplayP
|
||||
GetDisplayPlaneCapabilitiesKHR: ProcGetDisplayPlaneCapabilitiesKHR
|
||||
GetDisplayPlaneSupportedDisplaysKHR: ProcGetDisplayPlaneSupportedDisplaysKHR
|
||||
GetDrmDisplayEXT: ProcGetDrmDisplayEXT
|
||||
GetInstanceProcAddr: ProcGetInstanceProcAddr
|
||||
GetPhysicalDeviceCalibrateableTimeDomainsEXT: ProcGetPhysicalDeviceCalibrateableTimeDomainsEXT
|
||||
GetPhysicalDeviceCooperativeMatrixPropertiesNV: ProcGetPhysicalDeviceCooperativeMatrixPropertiesNV
|
||||
GetPhysicalDeviceDisplayPlaneProperties2KHR: ProcGetPhysicalDeviceDisplayPlaneProperties2KHR
|
||||
@@ -1045,6 +1045,7 @@ load_proc_addresses_custom :: proc(set_proc_address: SetProcAddressType) {
|
||||
set_proc_address(&EnumerateInstanceExtensionProperties, "vkEnumerateInstanceExtensionProperties")
|
||||
set_proc_address(&EnumerateInstanceLayerProperties, "vkEnumerateInstanceLayerProperties")
|
||||
set_proc_address(&EnumerateInstanceVersion, "vkEnumerateInstanceVersion")
|
||||
set_proc_address(&GetInstanceProcAddr, "vkGetInstanceProcAddr")
|
||||
|
||||
// Instance Procedures
|
||||
set_proc_address(&AcquireDrmDisplayEXT, "vkAcquireDrmDisplayEXT")
|
||||
@@ -1076,7 +1077,6 @@ load_proc_addresses_custom :: proc(set_proc_address: SetProcAddressType) {
|
||||
set_proc_address(&GetDisplayPlaneCapabilitiesKHR, "vkGetDisplayPlaneCapabilitiesKHR")
|
||||
set_proc_address(&GetDisplayPlaneSupportedDisplaysKHR, "vkGetDisplayPlaneSupportedDisplaysKHR")
|
||||
set_proc_address(&GetDrmDisplayEXT, "vkGetDrmDisplayEXT")
|
||||
set_proc_address(&GetInstanceProcAddr, "vkGetInstanceProcAddr")
|
||||
set_proc_address(&GetPhysicalDeviceCalibrateableTimeDomainsEXT, "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT")
|
||||
set_proc_address(&GetPhysicalDeviceCooperativeMatrixPropertiesNV, "vkGetPhysicalDeviceCooperativeMatrixPropertiesNV")
|
||||
set_proc_address(&GetPhysicalDeviceDisplayPlaneProperties2KHR, "vkGetPhysicalDeviceDisplayPlaneProperties2KHR")
|
||||
@@ -2839,7 +2839,6 @@ load_proc_addresses_instance :: proc(instance: Instance) {
|
||||
GetDisplayPlaneCapabilitiesKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDisplayPlaneCapabilitiesKHR")
|
||||
GetDisplayPlaneSupportedDisplaysKHR = auto_cast GetInstanceProcAddr(instance, "vkGetDisplayPlaneSupportedDisplaysKHR")
|
||||
GetDrmDisplayEXT = auto_cast GetInstanceProcAddr(instance, "vkGetDrmDisplayEXT")
|
||||
GetInstanceProcAddr = auto_cast GetInstanceProcAddr(instance, "vkGetInstanceProcAddr")
|
||||
GetPhysicalDeviceCalibrateableTimeDomainsEXT = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT")
|
||||
GetPhysicalDeviceCooperativeMatrixPropertiesNV = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceCooperativeMatrixPropertiesNV")
|
||||
GetPhysicalDeviceDisplayPlaneProperties2KHR = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPlaneProperties2KHR")
|
||||
@@ -3322,6 +3321,7 @@ load_proc_addresses_global :: proc(vk_get_instance_proc_addr: rawptr) {
|
||||
EnumerateInstanceExtensionProperties = auto_cast GetInstanceProcAddr(nil, "vkEnumerateInstanceExtensionProperties")
|
||||
EnumerateInstanceLayerProperties = auto_cast GetInstanceProcAddr(nil, "vkEnumerateInstanceLayerProperties")
|
||||
EnumerateInstanceVersion = auto_cast GetInstanceProcAddr(nil, "vkEnumerateInstanceVersion")
|
||||
GetInstanceProcAddr = auto_cast GetInstanceProcAddr(nil, "vkGetInstanceProcAddr")
|
||||
}
|
||||
|
||||
load_proc_addresses :: proc{
|
||||
|
||||
Reference in New Issue
Block a user