Merge remote-tracking branch 'offical/master'

This commit is contained in:
ed
2024-05-10 11:10:02 -04:00
11 changed files with 779 additions and 236 deletions
+8 -8
View File
@@ -273,14 +273,14 @@ Typeid_Kind :: enum u8 {
} }
#assert(len(Typeid_Kind) < 32) #assert(len(Typeid_Kind) < 32)
// Typeid_Bit_Field :: bit_field #align(align_of(uintptr)) { Typeid_Bit_Field :: bit_field uintptr {
// index: 8*size_of(uintptr) - 8, index: uintptr | 8*size_of(uintptr) - 8,
// kind: 5, // Typeid_Kind kind: Typeid_Kind | 5, // Typeid_Kind
// named: 1, named: bool | 1,
// special: 1, // signed, cstring, etc special: bool | 1, // signed, cstring, etc
// reserved: 1, reserved: bool | 1,
// } }
// #assert(size_of(Typeid_Bit_Field) == size_of(uintptr)); #assert(size_of(Typeid_Bit_Field) == size_of(uintptr))
// NOTE(bill): only the ones that are needed (not all types) // NOTE(bill): only the ones that are needed (not all types)
// This will be set by the compiler // This will be set by the compiler
+18 -15
View File
@@ -1,5 +1,5 @@
/* /*
package fmt implemented formatted I/O with procedures similar to C's printf and Python's format. package fmt implements formatted I/O with procedures similar to C's printf and Python's format.
The format 'verbs' are derived from C's but simpler. The format 'verbs' are derived from C's but simpler.
Printing Printing
@@ -33,6 +33,8 @@ Floating-point, complex numbers, and quaternions:
%E scientific notation, e.g. -1.23456E+78 %E scientific notation, e.g. -1.23456E+78
%f decimal point but no exponent, e.g. 123.456 %f decimal point but no exponent, e.g. 123.456
%F synonym for %f %F synonym for %f
%g synonym for %f with default maximum precision
%G synonym for %g
%h hexadecimal (lower-case) representation with 0h prefix (0h01234abcd) %h hexadecimal (lower-case) representation with 0h prefix (0h01234abcd)
%H hexadecimal (upper-case) representation with 0H prefix (0h01234ABCD) %H hexadecimal (upper-case) representation with 0H prefix (0h01234ABCD)
%m number of bytes in the best unit of measurement, e.g. 123.45mib %m number of bytes in the best unit of measurement, e.g. 123.45mib
@@ -61,9 +63,9 @@ For compound values, the elements are printed using these rules recursively; lai
bit sets {key0 = elem0, key1 = elem1, ...} bit sets {key0 = elem0, key1 = elem1, ...}
pointer to above: &{}, &[], &map[] pointer to above: &{}, &[], &map[]
Width is specified by an optional decimal number immediately preceding the verb. Width is specified by an optional decimal number immediately after the '%'.
If not present, the width is whatever is necessary to represent the value. If not present, the width is whatever is necessary to represent the value.
Precision is specified after the (optional) width followed by a period followed by a decimal number. Precision is specified after the (optional) width by a period followed by a decimal number.
If no period is present, a default precision is used. If no period is present, a default precision is used.
A period with no following number specifies a precision of 0. A period with no following number specifies a precision of 0.
@@ -75,7 +77,7 @@ Examples:
%8.f width 8, precision 0 %8.f width 8, precision 0
Width and precision are measured in units of Unicode code points (runes). Width and precision are measured in units of Unicode code points (runes).
n.b. C's printf uses units of bytes n.b. C's printf uses units of bytes.
Other flags: Other flags:
@@ -92,7 +94,7 @@ Other flags:
0 pad with leading zeros rather than spaces 0 pad with leading zeros rather than spaces
Flags are ignored by verbs that don't expect them Flags are ignored by verbs that don't expect them.
For each printf-like procedure, there is a print function that takes no For each printf-like procedure, there is a print function that takes no
@@ -105,19 +107,20 @@ Explicit argument indices:
In printf-like procedures, the default behaviour is for each formatting verb to format successive In printf-like procedures, the default behaviour is for each formatting verb to format successive
arguments passed in the call. However, the notation [n] immediately before the verb indicates that arguments passed in the call. However, the notation [n] immediately before the verb indicates that
the nth zero-index argument is to be formatted instead. the nth zero-index argument is to be formatted instead.
The same notation before an '*' for a width or precision selecting the argument index holding the value. The same notation before an '*' for a width or precision specifier selects the argument index
Python-like syntax with argument indices differs for the selecting the argument index: {N:v} holding the value.
Python-like syntax with argument indices differs for selecting the argument index: {n:v}
Examples: Examples:
fmt.printf("%[1]d %[0]d\n", 13, 37); // C-like syntax fmt.printfln("%[1]d %[0]d", 13, 37) // C-like syntax
fmt.printf("{1:d} {0:d}\n", 13, 37); // Python-like syntax fmt.printfln("{1:d} {0:d}", 13, 37) // Python-like syntax
prints "37 13", whilst: prints "37 13", whilst:
fmt.printf("%[2]*.[1]*[0]f\n", 17.0, 2, 6); // C-like syntax fmt.printfln("%*[2].*[1][0]f", 17.0, 2, 6) // C-like syntax
fmt.printf("%{0:[2]*.[1]*f}\n", 17.0, 2, 6); // Python-like syntax fmt.printfln("{0:*[2].*[1]f}", 17.0, 2, 6) // Python-like syntax
equivalent to: is equivalent to:
fmt.printf("%6.2f\n", 17.0, 2, 6); // C-like syntax fmt.printfln("%6.2f", 17.0) // C-like syntax
fmt.printf("{:6.2f}\n", 17.0, 2, 6); // Python-like syntax fmt.printfln("{:6.2f}", 17.0) // Python-like syntax
prints "17.00" and prints "17.00".
Format errors: Format errors:
+156 -191
View File
@@ -25,8 +25,6 @@ Info :: struct {
prec: int, prec: int,
indent: int, indent: int,
reordered: bool,
good_arg_index: bool,
ignore_user_formatters: bool, ignore_user_formatters: bool,
in_bad: bool, in_bad: bool,
@@ -527,13 +525,107 @@ wprintln :: proc(w: io.Writer, args: ..any, sep := " ", flush := true) -> int {
// Returns: The number of bytes written // Returns: The number of bytes written
// //
wprintf :: proc(w: io.Writer, fmt: string, args: ..any, flush := true, newline := false) -> int { wprintf :: proc(w: io.Writer, fmt: string, args: ..any, flush := true, newline := false) -> int {
MAX_CHECKED_ARGS :: 64
assert(len(args) <= MAX_CHECKED_ARGS, "number of args > 64 is unsupported")
parse_options :: proc(fi: ^Info, fmt: string, index, end: int, unused_args: ^bit_set[0 ..< MAX_CHECKED_ARGS], args: ..any) -> int {
i := index
// Prefix
prefix_loop: for ; i < end; i += 1 {
switch fmt[i] {
case '+':
fi.plus = true
case '-':
fi.minus = true
fi.zero = false
case ' ':
fi.space = true
case '#':
fi.hash = true
case '0':
fi.zero = !fi.minus
case:
break prefix_loop
}
}
// Width
if i < end && fmt[i] == '*' {
i += 1
width_index, _, index_ok := _arg_number(fmt, &i, len(args))
if index_ok {
unused_args^ -= {width_index}
fi.width, _, fi.width_set = int_from_arg(args, width_index)
if !fi.width_set {
io.write_string(fi.writer, "%!(BAD WIDTH)", &fi.n)
}
if fi.width < 0 {
fi.width = -fi.width
fi.minus = true
fi.zero = false
}
}
} else {
fi.width, i, fi.width_set = _parse_int(fmt, i)
}
// Precision
if i < end && fmt[i] == '.' {
i += 1
if i < end && fmt[i] == '*' {
i += 1
precision_index, _, index_ok := _arg_number(fmt, &i, len(args))
if index_ok {
unused_args^ -= {precision_index}
fi.prec, _, fi.prec_set = int_from_arg(args, precision_index)
if fi.prec < 0 {
fi.prec = 0
fi.prec_set = false
}
if !fi.prec_set {
io.write_string(fi.writer, "%!(BAD PRECISION)", &fi.n)
}
}
} else {
prev_i := i
fi.prec, i, fi.prec_set = _parse_int(fmt, i)
if i == prev_i {
fi.prec = 0
fi.prec_set = true
}
}
}
return i
}
error_check_arg :: proc(fi: ^Info, arg_parsed: bool, unused_args: bit_set[0 ..< MAX_CHECKED_ARGS]) -> (int, bool) {
if !arg_parsed {
for index in unused_args {
return index, true
}
io.write_string(fi.writer, "%!(MISSING ARGUMENT)", &fi.n)
} else {
io.write_string(fi.writer, "%!(BAD ARGUMENT NUMBER)", &fi.n)
}
return 0, false
}
fi: Info fi: Info
arg_index: int = 0
end := len(fmt) end := len(fmt)
was_prev_index := false unused_args: bit_set[0 ..< MAX_CHECKED_ARGS]
for i in 0 ..< len(args) {
unused_args += {i}
}
loop: for i := 0; i < end; /**/ { loop: for i := 0; i < end; /**/ {
fi = Info{writer = w, good_arg_index = true, reordered = fi.reordered, n = fi.n} fi = Info{writer = w, n = fi.n}
prev_i := i prev_i := i
for i < end && !(fmt[i] == '%' || fmt[i] == '{' || fmt[i] == '}') { for i < end && !(fmt[i] == '%' || fmt[i] == '{' || fmt[i] == '}') {
@@ -567,191 +659,65 @@ wprintf :: proc(w: io.Writer, fmt: string, args: ..any, flush := true, newline :
} }
if char == '%' { if char == '%' {
prefix_loop: for ; i < end; i += 1 { if i < end && fmt[i] == '%' {
switch fmt[i] { io.write_byte(fi.writer, '%', &fi.n)
case '+':
fi.plus = true
case '-':
fi.minus = true
fi.zero = false
case ' ':
fi.space = true
case '#':
fi.hash = true
case '0':
fi.zero = !fi.minus
case:
break prefix_loop
}
}
arg_index, i, was_prev_index = _arg_number(&fi, arg_index, fmt, i, len(args))
// Width
if i < end && fmt[i] == '*' {
i += 1 i += 1
fi.width, arg_index, fi.width_set = int_from_arg(args, arg_index) continue loop
if !fi.width_set {
io.write_string(w, "%!(BAD WIDTH)", &fi.n)
}
if fi.width < 0 {
fi.width = -fi.width
fi.minus = true
fi.zero = false
}
was_prev_index = false
} else {
fi.width, i, fi.width_set = _parse_int(fmt, i)
if was_prev_index && fi.width_set { // %[6]2d
fi.good_arg_index = false
}
} }
// Precision i = parse_options(&fi, fmt, i, end, &unused_args, ..args)
if i < end && fmt[i] == '.' {
i += 1
if was_prev_index { // %[6].2d
fi.good_arg_index = false
}
if i < end && fmt[i] == '*' {
arg_index, i, was_prev_index = _arg_number(&fi, arg_index, fmt, i, len(args))
i += 1
fi.prec, arg_index, fi.prec_set = int_from_arg(args, arg_index)
if fi.prec < 0 {
fi.prec = 0
fi.prec_set = false
}
if !fi.prec_set {
io.write_string(fi.writer, "%!(BAD PRECISION)", &fi.n)
}
was_prev_index = false
} else {
fi.prec, i, fi.prec_set = _parse_int(fmt, i)
}
}
if !was_prev_index { arg_index, arg_parsed, index_ok := _arg_number(fmt, &i, len(args))
arg_index, i, was_prev_index = _arg_number(&fi, arg_index, fmt, i, len(args))
if !index_ok {
arg_index, index_ok = error_check_arg(&fi, arg_parsed, unused_args)
} }
if i >= end { if i >= end {
io.write_string(fi.writer, "%!(NO VERB)", &fi.n) io.write_string(fi.writer, "%!(NO VERB)", &fi.n)
break loop break loop
} else if fmt[i] == ' ' {
io.write_string(fi.writer, "%!(NO VERB)", &fi.n)
continue loop
} }
verb, w := utf8.decode_rune_in_string(fmt[i:]) verb, w := utf8.decode_rune_in_string(fmt[i:])
i += w i += w
switch { if index_ok {
case verb == '%': unused_args -= {arg_index}
io.write_byte(fi.writer, '%', &fi.n)
case !fi.good_arg_index:
io.write_string(fi.writer, "%!(BAD ARGUMENT NUMBER)", &fi.n)
case arg_index >= len(args):
io.write_string(fi.writer, "%!(MISSING ARGUMENT)", &fi.n)
case:
fmt_arg(&fi, args[arg_index], verb) fmt_arg(&fi, args[arg_index], verb)
arg_index += 1
} }
} else if char == '{' { } else if char == '{' {
arg_index: int
arg_parsed, index_ok: bool
if i < end && fmt[i] != '}' && fmt[i] != ':' { if i < end && fmt[i] != '}' && fmt[i] != ':' {
new_arg_index, new_i, ok := _parse_int(fmt, i) arg_index, i, arg_parsed = _parse_int(fmt, i)
if ok { if arg_parsed {
fi.reordered = true index_ok = 0 <= arg_index && arg_index < len(args)
was_prev_index = true
arg_index = new_arg_index
i = new_i
} else {
io.write_string(fi.writer, "%!(BAD ARGUMENT NUMBER ", &fi.n)
// Skip over the bad argument
start_index := i
for i < end && fmt[i] != '}' && fmt[i] != ':' {
i += 1
}
fmt_arg(&fi, fmt[start_index:i], 'v')
io.write_string(fi.writer, ")", &fi.n)
} }
} }
if !index_ok {
arg_index, index_ok = error_check_arg(&fi, arg_parsed, unused_args)
}
verb: rune = 'v' verb: rune = 'v'
if i < end && fmt[i] == ':' { if i < end && fmt[i] == ':' {
i += 1 i += 1
prefix_loop_percent: for ; i < end; i += 1 { i = parse_options(&fi, fmt, i, end, &unused_args, ..args)
switch fmt[i] {
case '+':
fi.plus = true
case '-':
fi.minus = true
fi.zero = false
case ' ':
fi.space = true
case '#':
fi.hash = true
case '0':
fi.zero = !fi.minus
case:
break prefix_loop_percent
}
}
arg_index, i, was_prev_index = _arg_number(&fi, arg_index, fmt, i, len(args))
// Width
if i < end && fmt[i] == '*' {
i += 1
fi.width, arg_index, fi.width_set = int_from_arg(args, arg_index)
if !fi.width_set {
io.write_string(fi.writer, "%!(BAD WIDTH)", &fi.n)
}
if fi.width < 0 {
fi.width = -fi.width
fi.minus = true
fi.zero = false
}
was_prev_index = false
} else {
fi.width, i, fi.width_set = _parse_int(fmt, i)
if was_prev_index && fi.width_set { // %[6]2d
fi.good_arg_index = false
}
}
// Precision
if i < end && fmt[i] == '.' {
i += 1
if was_prev_index { // %[6].2d
fi.good_arg_index = false
}
if i < end && fmt[i] == '*' {
arg_index, i, was_prev_index = _arg_number(&fi, arg_index, fmt, i, len(args))
i += 1
fi.prec, arg_index, fi.prec_set = int_from_arg(args, arg_index)
if fi.prec < 0 {
fi.prec = 0
fi.prec_set = false
}
if !fi.prec_set {
io.write_string(fi.writer, "%!(BAD PRECISION)", &fi.n)
}
was_prev_index = false
} else {
fi.prec, i, fi.prec_set = _parse_int(fmt, i)
}
}
if !was_prev_index {
arg_index, i, was_prev_index = _arg_number(&fi, arg_index, fmt, i, len(args))
}
if i >= end { if i >= end {
io.write_string(fi.writer, "%!(NO VERB)", &fi.n) io.write_string(fi.writer, "%!(NO VERB)", &fi.n)
break loop break loop
} else if fmt[i] == '}' {
i += 1
io.write_string(fi.writer, "%!(NO VERB)", &fi.n)
continue
} }
w: int = 1 w: int = 1
@@ -770,31 +736,35 @@ wprintf :: proc(w: io.Writer, fmt: string, args: ..any, flush := true, newline :
switch { switch {
case brace != '}': case brace != '}':
io.write_string(fi.writer, "%!(MISSING CLOSE BRACE)", &fi.n) io.write_string(fi.writer, "%!(MISSING CLOSE BRACE)", &fi.n)
case !fi.good_arg_index: case index_ok:
io.write_string(fi.writer, "%!(BAD ARGUMENT NUMBER)", &fi.n)
case arg_index >= len(args):
io.write_string(fi.writer, "%!(MISSING ARGUMENT)", &fi.n)
case:
fmt_arg(&fi, args[arg_index], verb) fmt_arg(&fi, args[arg_index], verb)
arg_index += 1 unused_args -= {arg_index}
} }
} }
} }
if !fi.reordered && arg_index < len(args) { if unused_args != {} {
io.write_string(fi.writer, "%!(EXTRA ", &fi.n) // Use default options when formatting extra arguments.
for arg, index in args[arg_index:] { extra_fi := Info { writer = fi.writer, n = fi.n }
if index > 0 {
io.write_string(fi.writer, ", ", &fi.n) io.write_string(extra_fi.writer, "%!(EXTRA ", &extra_fi.n)
first_printed := false
for index in unused_args {
if first_printed {
io.write_string(extra_fi.writer, ", ", &extra_fi.n)
} }
arg := args[index]
if arg == nil { if arg == nil {
io.write_string(fi.writer, "<nil>", &fi.n) io.write_string(extra_fi.writer, "<nil>", &extra_fi.n)
} else { } else {
fmt_arg(&fi, args[index], 'v') fmt_arg(&extra_fi, arg, 'v')
} }
first_printed = true
} }
io.write_string(fi.writer, ")", &fi.n) io.write_byte(extra_fi.writer, ')', &extra_fi.n)
fi.n = extra_fi.n
} }
if newline { if newline {
@@ -877,18 +847,16 @@ _parse_int :: proc(s: string, offset: int) -> (result: int, new_offset: int, ok:
// Parses an argument number from a format string and determines if it's valid // Parses an argument number from a format string and determines if it's valid
// //
// Inputs: // Inputs:
// - fi: A pointer to an Info structure
// - arg_index: The current argument index
// - format: The format string to parse // - format: The format string to parse
// - offset: The current position in the format string // - offset: A pointer to the current position in the format string
// - arg_count: The total number of arguments // - arg_count: The total number of arguments
// //
// Returns: // Returns:
// - index: The parsed argument index // - index: The parsed argument index
// - new_offset: The new position in the format string // - parsed: A boolean indicating if an argument number was parsed
// - ok: A boolean indicating if the parsed argument number is valid // - ok: A boolean indicating if the parsed argument number is within arg_count
// //
_arg_number :: proc(fi: ^Info, arg_index: int, format: string, offset, arg_count: int) -> (index, new_offset: int, ok: bool) { _arg_number :: proc(format: string, offset: ^int, arg_count: int) -> (index: int, parsed, ok: bool) {
parse_arg_number :: proc(format: string) -> (int, int, bool) { parse_arg_number :: proc(format: string) -> (int, int, bool) {
if len(format) < 3 { if len(format) < 3 {
return 0, 1, false return 0, 1, false
@@ -896,30 +864,28 @@ _arg_number :: proc(fi: ^Info, arg_index: int, format: string, offset, arg_count
for i in 1..<len(format) { for i in 1..<len(format) {
if format[i] == ']' { if format[i] == ']' {
width, new_index, ok := _parse_int(format, 1) value, new_index, ok := _parse_int(format, 1)
if !ok || new_index != i { if !ok || new_index != i {
return 0, i+1, false return 0, i+1, false
} }
return width-1, i+1, true return value, i+1, true
} }
} }
return 0, 1, false return 0, 1, false
} }
i := offset^
if len(format) <= offset || format[offset] != '[' { if len(format) <= i || format[i] != '[' {
return arg_index, offset, false return 0, false, false
} }
fi.reordered = true
width: int width: int
index, width, ok = parse_arg_number(format[offset:]) index, width, parsed = parse_arg_number(format[i:])
if ok && 0 <= index && index < arg_count { offset^ = i + width
return index, offset+width, true ok = parsed && 0 <= index && index < arg_count
} return
fi.good_arg_index = false
return arg_index, offset+width, false
} }
// Retrieves an integer from a list of any type at the specified index // Retrieves an integer from a list of any type at the specified index
// //
@@ -2570,7 +2536,6 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
if _user_formatters != nil && !fi.ignore_user_formatters { if _user_formatters != nil && !fi.ignore_user_formatters {
formatter := _user_formatters[v.id] formatter := _user_formatters[v.id]
if formatter != nil { if formatter != nil {
fi.ignore_user_formatters = false
if ok := formatter(fi, v, verb); !ok { if ok := formatter(fi, v, verb); !ok {
fi.ignore_user_formatters = true fi.ignore_user_formatters = true
fmt_bad_verb(fi, verb) fmt_bad_verb(fi, verb)
+2
View File
@@ -2117,7 +2117,9 @@ parse_proc_type :: proc(p: ^Parser, tok: tokenizer.Token) -> ^ast.Proc_Type {
} }
expect_token(p, .Open_Paren) expect_token(p, .Open_Paren)
p.expr_level += 1
params, _ := parse_field_list(p, .Close_Paren, ast.Field_Flags_Signature_Params) params, _ := parse_field_list(p, .Close_Paren, ast.Field_Flags_Signature_Params)
p.expr_level -= 1
expect_closing_parentheses_of_field_list(p) expect_closing_parentheses_of_field_list(p)
results, diverging := parse_results(p) results, diverging := parse_results(p)
+1 -2
View File
@@ -104,8 +104,7 @@ generic_ftoa :: proc(buf: []byte, val: f64, fmt: byte, precision, bit_size: int)
} else { } else {
switch fmt { switch fmt {
case 'e', 'E': case 'e', 'E':
prec += 1 decimal.round(d, prec + 1)
decimal.round(d, prec)
case 'f', 'F': case 'f', 'F':
decimal.round(d, d.decimal_point+prec) decimal.round(d, d.decimal_point+prec)
case 'g', 'G': case 'g', 'G':
+2
View File
@@ -429,6 +429,8 @@ foreign kernel32 {
DisconnectNamedPipe :: proc(hNamedPipe: HANDLE) -> BOOL --- DisconnectNamedPipe :: proc(hNamedPipe: HANDLE) -> BOOL ---
WaitNamedPipeW :: proc(lpNamedPipeName: LPCWSTR, nTimeOut: DWORD) -> BOOL --- WaitNamedPipeW :: proc(lpNamedPipeName: LPCWSTR, nTimeOut: DWORD) -> BOOL ---
AllocConsole :: proc() -> BOOL ---
AttachConsole :: proc(dwProcessId: DWORD) -> BOOL ---
SetConsoleCtrlHandler :: proc(HandlerRoutine: PHANDLER_ROUTINE, Add: BOOL) -> BOOL --- SetConsoleCtrlHandler :: proc(HandlerRoutine: PHANDLER_ROUTINE, Add: BOOL) -> BOOL ---
GenerateConsoleCtrlEvent :: proc(dwCtrlEvent: DWORD, dwProcessGroupId: DWORD) -> BOOL --- GenerateConsoleCtrlEvent :: proc(dwCtrlEvent: DWORD, dwProcessGroupId: DWORD) -> BOOL ---
FreeConsole :: proc() -> BOOL --- FreeConsole :: proc() -> BOOL ---
+32 -2
View File
@@ -161,8 +161,7 @@ gb_internal bool check_is_terminating_list(Slice<Ast *> const &stmts, String con
} }
gb_internal bool check_has_break_list(Slice<Ast *> const &stmts, String const &label, bool implicit) { gb_internal bool check_has_break_list(Slice<Ast *> const &stmts, String const &label, bool implicit) {
for_array(i, stmts) { for (Ast *stmt : stmts) {
Ast *stmt = stmts[i];
if (check_has_break(stmt, label, implicit)) { if (check_has_break(stmt, label, implicit)) {
return true; return true;
} }
@@ -170,6 +169,14 @@ gb_internal bool check_has_break_list(Slice<Ast *> const &stmts, String const &l
return false; return false;
} }
gb_internal bool check_has_break_expr_list(Slice<Ast *> const &exprs, String const &label) {
for (Ast *expr : exprs) {
if (expr && expr->viral_state_flags & ViralStateFlag_ContainsOrBreak) {
return true;
}
}
return false;
}
gb_internal bool check_has_break(Ast *stmt, String const &label, bool implicit) { gb_internal bool check_has_break(Ast *stmt, String const &label, bool implicit) {
switch (stmt->kind) { switch (stmt->kind) {
@@ -227,6 +234,20 @@ gb_internal bool check_has_break(Ast *stmt, String const &label, bool implicit)
return true; return true;
} }
break; break;
case Ast_ValueDecl:
if (stmt->ValueDecl.is_mutable && check_has_break_expr_list(stmt->ValueDecl.values, label)) {
return true;
}
break;
case Ast_AssignStmt:
if (check_has_break_expr_list(stmt->AssignStmt.lhs, label)) {
return true;
}
if (check_has_break_expr_list(stmt->AssignStmt.rhs, label)) {
return true;
}
break;
} }
return false; return false;
@@ -250,6 +271,15 @@ gb_internal bool check_is_terminating(Ast *node, String const &label) {
return check_is_terminating(unparen_expr(es->expr), label); return check_is_terminating(unparen_expr(es->expr), label);
case_end; case_end;
case_ast_node(vd, ValueDecl, node);
return check_has_break_expr_list(vd->values, label);
case_end;
case_ast_node(as, AssignStmt, node);
return check_has_break_expr_list(as->lhs, label) ||
check_has_break_expr_list(as->rhs, label);
case_end;
case_ast_node(bs, BranchStmt, node); case_ast_node(bs, BranchStmt, node);
return bs->token.kind == Token_fallthrough; return bs->token.kind == Token_fallthrough;
case_end; case_end;
+2
View File
@@ -3883,10 +3883,12 @@ gb_internal Ast *parse_proc_type(AstFile *f, Token proc_token) {
expect_token(f, Token_OpenParen); expect_token(f, Token_OpenParen);
f->expr_level += 1;
params = parse_field_list(f, nullptr, FieldFlag_Signature, Token_CloseParen, true, true); params = parse_field_list(f, nullptr, FieldFlag_Signature, Token_CloseParen, true, true);
if (file_allow_newline(f)) { if (file_allow_newline(f)) {
skip_possible_newline(f); skip_possible_newline(f);
} }
f->expr_level -= 1;
expect_token_after(f, Token_CloseParen, "parameter list"); expect_token_after(f, Token_CloseParen, "parameter list");
results = parse_results(f, &diverging); results = parse_results(f, &diverging);
+130 -6
View File
@@ -29,6 +29,8 @@ when ODIN_TEST {
main :: proc() { main :: proc() {
t := testing.T{} t := testing.T{}
test_fmt_memory(&t) test_fmt_memory(&t)
test_fmt_doc_examples(&t)
test_fmt_options(&t)
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
if TEST_fail > 0 { if TEST_fail > 0 {
@@ -36,12 +38,13 @@ main :: proc() {
} }
} }
test_fmt_memory :: proc(t: ^testing.T) { check :: proc(t: ^testing.T, exp: string, format: string, args: ..any, loc := #caller_location) {
check :: proc(t: ^testing.T, exp: string, format: string, args: ..any, loc := #caller_location) { got := fmt.tprintf(format, ..args)
got := fmt.tprintf(format, ..args) expect(t, got == exp, fmt.tprintf("(%q, %v): %q != %q", format, args, got, exp), loc)
expect(t, got == exp, fmt.tprintf("(%q, %v): %q != %q", format, args, got, exp), loc) }
}
@(test)
test_fmt_memory :: proc(t: ^testing.T) {
check(t, "5b", "%m", 5) check(t, "5b", "%m", 5)
check(t, "5B", "%M", 5) check(t, "5B", "%M", 5)
check(t, "-5B", "%M", -5) check(t, "-5B", "%M", -5)
@@ -52,8 +55,129 @@ test_fmt_memory :: proc(t: ^testing.T) {
check(t, "3.50 gib", "%#m", u32(mem.Gigabyte * 3.5)) check(t, "3.50 gib", "%#m", u32(mem.Gigabyte * 3.5))
check(t, "01tib", "%5.0m", mem.Terabyte) check(t, "01tib", "%5.0m", mem.Terabyte)
check(t, "-1tib", "%5.0m", -mem.Terabyte) check(t, "-1tib", "%5.0m", -mem.Terabyte)
check(t, "2.50 pib", "%#5.m", uint(mem.Petabyte * 2.5)) check(t, "2 pib", "%#5.m", uint(mem.Petabyte * 2.5))
check(t, "1.00 EiB", "%#M", mem.Exabyte) check(t, "1.00 EiB", "%#M", mem.Exabyte)
check(t, "255 B", "%#M", u8(255)) check(t, "255 B", "%#M", u8(255))
check(t, "0b", "%m", u8(0)) check(t, "0b", "%m", u8(0))
} }
@(test)
test_fmt_doc_examples :: proc(t: ^testing.T) {
// C-like syntax
check(t, "37 13", "%[1]d %[0]d", 13, 37)
check(t, "017.00", "%*[2].*[1][0]f", 17.0, 2, 6)
check(t, "017.00", "%6.2f", 17.0)
// Python-like syntax
check(t, "37 13", "{1:d} {0:d}", 13, 37)
check(t, "017.00", "{0:*[2].*[1]f}", 17.0, 2, 6)
check(t, "017.00", "{:6.2f}", 17.0)
}
@(test)
test_fmt_options :: proc(t: ^testing.T) {
// Escaping
check(t, "% { } 0 { } } {", "%% {{ }} {} {{ }} }} {{", 0 )
// Prefixes
check(t, "+3.000", "%+f", 3.0 )
check(t, "0003", "%04i", 3 )
check(t, "3 ", "% -4i", 3 )
check(t, "+3", "%+i", 3 )
check(t, "0b11", "%#b", 3 )
check(t, "0xA", "%#X", 10 )
// Specific index formatting
check(t, "1 2 3", "%i %i %i", 1, 2, 3)
check(t, "1 2 3", "%[0]i %[1]i %[2]i", 1, 2, 3)
check(t, "3 2 1", "%[2]i %[1]i %[0]i", 1, 2, 3)
check(t, "3 1 2", "%[2]i %i %i", 1, 2, 3)
check(t, "1 2 3", "%i %[1]i %i", 1, 2, 3)
check(t, "1 3 2", "%i %[2]i %i", 1, 2, 3)
check(t, "1 1 1", "%[0]i %[0]i %[0]i", 1)
// Width
check(t, "3.140", "%f", 3.14)
check(t, "3.140", "%4f", 3.14)
check(t, "3.140", "%5f", 3.14)
check(t, "03.140", "%6f", 3.14)
// Precision
check(t, "3", "%.f", 3.14)
check(t, "3", "%.0f", 3.14)
check(t, "3.1", "%.1f", 3.14)
check(t, "3.140", "%.3f", 3.14)
check(t, "3.14000", "%.5f", 3.14)
check(t, "3.1415", "%g", 3.1415)
// Scientific notation
check(t, "3.000000e+00", "%e", 3.0)
check(t, "3e+02", "%.e", 300.0)
check(t, "3e+02", "%.0e", 300.0)
check(t, "3.0e+02", "%.1e", 300.0)
check(t, "3.00e+02", "%.2e", 300.0)
check(t, "3.000e+02", "%.3e", 300.0)
check(t, "3e+01", "%.e", 30.56)
check(t, "3e+01", "%.0e", 30.56)
check(t, "3.1e+01", "%.1e", 30.56)
check(t, "3.06e+01", "%.2e", 30.56)
check(t, "3.056e+01", "%.3e", 30.56)
// Width and precision
check(t, "3.140", "%5.3f", 3.14)
check(t, "3.140", "%*[1].3f", 3.14, 5)
check(t, "3.140", "%*[1].*[2]f", 3.14, 5, 3)
check(t, "3.140", "%*[1].*[2][0]f", 3.14, 5, 3)
check(t, "3.140", "%*[2].*[1]f", 3.14, 3, 5)
check(t, "3.140", "%5.*[1]f", 3.14, 3)
// Error checking
check(t, "%!(MISSING ARGUMENT)%!(NO VERB)", "%" )
check(t, "1%!(EXTRA 2, 3)", "%i", 1, 2, 3)
check(t, "2%!(EXTRA 1, 3)", "%[1]i", 1, 2, 3)
check(t, "%!(BAD ARGUMENT NUMBER)%!(EXTRA 0)", "%[1]i", 0)
check(t, "%!(MISSING ARGUMENT)", "%f")
check(t, "%!(BAD ARGUMENT NUMBER)%!(NO VERB)", "%[0]")
check(t, "%!(BAD ARGUMENT NUMBER)", "%[0]f")
check(t, "%!(BAD ARGUMENT NUMBER)%!(NO VERB) %!(MISSING ARGUMENT)", "%[0] %i")
check(t, "%!(NO VERB) 1%!(EXTRA 2)", "%[0] %i", 1, 2)
check(t, "1 2 %!(MISSING ARGUMENT)", "%i %i %i", 1, 2)
check(t, "1 2 %!(BAD ARGUMENT NUMBER)", "%i %i %[2]i", 1, 2)
check(t, "%!(BAD ARGUMENT NUMBER)%!(NO VERB)%!(EXTRA 0)", "%[1]", 0)
check(t, "3.1%!(EXTRA 3.14)", "%.1f", 3.14, 3.14)
// Python-like syntax
check(t, "1 2 3", "{} {} {}", 1, 2, 3)
check(t, "3 2 1", "{2} {1} {0}", 1, 2, 3)
check(t, "1 2 3", "{:i} {:i} {:i}", 1, 2, 3)
check(t, "1 2 3", "{0:i} {1:i} {2:i}", 1, 2, 3)
check(t, "3 2 1", "{2:i} {1:i} {0:i}", 1, 2, 3)
check(t, "3 1 2", "{2:i} {0:i} {1:i}", 1, 2, 3)
check(t, "1 2 3", "{:i} {1:i} {:i}", 1, 2, 3)
check(t, "1 3 2", "{:i} {2:i} {:i}", 1, 2, 3)
check(t, "1 1 1", "{0:i} {0:i} {0:i}", 1)
check(t, "1 1%!(EXTRA 2)", "{} {0}", 1, 2)
check(t, "2 1", "{1} {}", 1, 2)
check(t, "%!(BAD ARGUMENT NUMBER) 1%!(EXTRA 2)", "{2} {}", 1, 2)
check(t, "%!(BAD ARGUMENT NUMBER)", "{1}")
check(t, "%!(BAD ARGUMENT NUMBER)%!(NO VERB)", "{1:}")
check(t, "%!(BAD ARGUMENT NUMBER)%!(NO VERB)%!(EXTRA 0)", "{1:}", 0)
check(t, "%!(MISSING ARGUMENT)", "{}" )
check(t, "%!(MISSING ARGUMENT)%!(MISSING CLOSE BRACE)", "{" )
check(t, "%!(MISSING CLOSE BRACE)%!(EXTRA 1)", "{", 1)
check(t, "%!(MISSING CLOSE BRACE)%!(EXTRA 1)", "{0", 1 )
}
+220
View File
@@ -82,6 +82,7 @@ FEATURE_LEVEL :: enum i32 {
_11_1 = 45312, _11_1 = 45312,
_12_0 = 49152, _12_0 = 49152,
_12_1 = 49408, _12_1 = 49408,
_12_2 = 49664,
} }
PRIMITIVE_TOPOLOGY :: enum i32 { PRIMITIVE_TOPOLOGY :: enum i32 {
@@ -833,6 +834,9 @@ FEATURE :: enum i32 {
OPTIONS7 = 32, OPTIONS7 = 32,
PROTECTED_RESOURCE_SESSION_TYPE_COUNT = 33, PROTECTED_RESOURCE_SESSION_TYPE_COUNT = 33,
PROTECTED_RESOURCE_SESSION_TYPES = 34, PROTECTED_RESOURCE_SESSION_TYPES = 34,
OPTIONS8 = 36,
OPTIONS9 = 37,
WAVE_MMA = 38,
} }
SHADER_MIN_PRECISION_SUPPORT :: enum i32 { SHADER_MIN_PRECISION_SUPPORT :: enum i32 {
@@ -1017,6 +1021,7 @@ SHADER_MODEL :: enum i32 {
_6_4 = 100, _6_4 = 100,
_6_5 = 101, _6_5 = 101,
_6_6 = 102, _6_6 = 102,
_6_7 = 103,
} }
FEATURE_DATA_SHADER_MODEL :: struct { FEATURE_DATA_SHADER_MODEL :: struct {
@@ -1052,6 +1057,7 @@ SHADER_CACHE_SUPPORT_FLAG :: enum u32 {
LIBRARY = 1, LIBRARY = 1,
AUTOMATIC_INPROC_CACHE = 2, AUTOMATIC_INPROC_CACHE = 2,
AUTOMATIC_DISK_CACHE = 3, AUTOMATIC_DISK_CACHE = 3,
DRIVER_MANAGED_CACHE = 4,
} }
FEATURE_DATA_SHADER_CACHE :: struct { FEATURE_DATA_SHADER_CACHE :: struct {
@@ -1171,6 +1177,55 @@ FEATURE_DATA_QUERY_META_COMMAND :: struct {
QueryOutputDataSizeInBytes: SIZE_T, QueryOutputDataSizeInBytes: SIZE_T,
} }
FEATURE_DATA_OPTIONS8 :: struct {
UnalignedBlockTexturesSupported: BOOL,
}
WAVE_MMA_TIER :: enum i32 {
NOT_SUPPORTED = 0,
_1_0 = 10,
}
FEATURE_DATA_OPTIONS9 :: struct {
MeshShaderPipelineStatsSupported: BOOL,
MeshShaderSupportsFullRangeRenderTargetArrayIndex: BOOL,
AtomicInt64OnTypedResourceSupported: BOOL,
AtomicInt64OnGroupSharedSupported: BOOL,
DerivativesInMeshAndAmplificationShadersSupported: BOOL,
WaveMMATier: WAVE_MMA_TIER,
}
WAVE_MMA_INPUT_DATATYPE :: enum i32 {
INVALID = 0,
BYTE = 1,
FLOAT16 = 2,
FLOAT = 3,
}
WAVE_MMA_DIMENSION :: enum i32 {
INVALID = 0,
_16 = 1,
_64 = 2,
}
WAVE_MMA_ACCUM_DATATYPE :: enum i32 {
NONE = 0,
INT32 = 1,
FLOAT16 = 2,
FLOAT = 4,
}
FEATURE_DATA_WAVE_MMA :: struct {
InputDataType: WAVE_MMA_INPUT_DATATYPE,
M: WAVE_MMA_DIMENSION,
N: WAVE_MMA_DIMENSION,
Supported: BOOL,
K: u32,
AccumDataTypes: WAVE_MMA_ACCUM_DATATYPE,
RequiredWaveLaneCountMin: u32,
RequiredWaveLaneCountMax: u32,
}
RESOURCE_ALLOCATION_INFO :: struct { RESOURCE_ALLOCATION_INFO :: struct {
SizeInBytes: u64, SizeInBytes: u64,
Alignment: u64, Alignment: u64,
@@ -1261,6 +1316,7 @@ RESOURCE_FLAG :: enum u32 {
ALLOW_CROSS_ADAPTER = 4, ALLOW_CROSS_ADAPTER = 4,
ALLOW_SIMULTANEOUS_ACCESS = 5, ALLOW_SIMULTANEOUS_ACCESS = 5,
VIDEO_DECODE_REFERENCE_ONLY = 6, VIDEO_DECODE_REFERENCE_ONLY = 6,
VIDEO_ENCODE_REFERENCE_ONLY = 7,
} }
MIP_REGION :: struct { MIP_REGION :: struct {
@@ -2140,6 +2196,7 @@ QUERY_HEAP_TYPE :: enum i32 {
SO_STATISTICS = 3, SO_STATISTICS = 3,
VIDEO_DECODE_STATISTICS = 4, VIDEO_DECODE_STATISTICS = 4,
COPY_QUEUE_TIMESTAMP = 5, COPY_QUEUE_TIMESTAMP = 5,
PIPELINE_STATISTICS1 = 7,
} }
QUERY_HEAP_DESC :: struct { QUERY_HEAP_DESC :: struct {
@@ -2158,6 +2215,7 @@ QUERY_TYPE :: enum i32 {
SO_STATISTICS_STREAM2 = 6, SO_STATISTICS_STREAM2 = 6,
SO_STATISTICS_STREAM3 = 7, SO_STATISTICS_STREAM3 = 7,
VIDEO_DECODE_STATISTICS = 8, VIDEO_DECODE_STATISTICS = 8,
PIPELINE_STATISTICS1 = 10,
} }
PREDICATION_OP :: enum i32 { PREDICATION_OP :: enum i32 {
@@ -2179,6 +2237,23 @@ QUERY_DATA_PIPELINE_STATISTICS :: struct {
CSInvocations: u64, CSInvocations: u64,
} }
QUERY_DATA_PIPELINE_STATISTICS1 :: struct {
IAVertices: u64,
IAPrimitives: u64,
VSInvocations: u64,
GSInvocations: u64,
GSPrimitives: u64,
CInvocations: u64,
CPrimitives: u64,
PSInvocations: u64,
HSInvocations: u64,
DSInvocations: u64,
CSInvocations: u64,
ASInvocations: u64,
MSInvocations: u64,
MSPrimitives: u64,
}
QUERY_DATA_SO_STATISTICS :: struct { QUERY_DATA_SO_STATISTICS :: struct {
NumPrimitivesWritten: u64, NumPrimitivesWritten: u64,
PrimitivesStorageNeeded: u64, PrimitivesStorageNeeded: u64,
@@ -3244,6 +3319,8 @@ AUTO_BREADCRUMB_OP :: enum i32 {
INITIALIZEEXTENSIONCOMMAND = 40, INITIALIZEEXTENSIONCOMMAND = 40,
EXECUTEEXTENSIONCOMMAND = 41, EXECUTEEXTENSIONCOMMAND = 41,
DISPATCHMESH = 42, DISPATCHMESH = 42,
ENCODEFRAME = 43,
RESOLVEENCODEROUTPUTMETADATA = 44,
} }
AUTO_BREADCRUMB_NODE :: struct { AUTO_BREADCRUMB_NODE :: struct {
@@ -3283,6 +3360,7 @@ DRED_VERSION :: enum i32 {
_1_0 = 1, _1_0 = 1,
_1_1 = 2, _1_1 = 2,
_1_2 = 3, _1_2 = 3,
_1_3 = 4,
} }
DRED_FLAGS :: distinct bit_set[DRED_FLAG; u32] DRED_FLAGS :: distinct bit_set[DRED_FLAG; u32]
@@ -3329,6 +3407,8 @@ DRED_ALLOCATION_TYPE :: enum i32 {
VIDEO_MOTION_ESTIMATOR = 45, VIDEO_MOTION_ESTIMATOR = 45,
VIDEO_MOTION_VECTOR_HEAP = 46, VIDEO_MOTION_VECTOR_HEAP = 46,
VIDEO_EXTENSION_COMMAND = 47, VIDEO_EXTENSION_COMMAND = 47,
VIDEO_ENCODER = 48,
VIDEO_ENCODER_HEAP = 49,
INVALID = -1, INVALID = -1,
} }
@@ -3367,6 +3447,24 @@ DRED_PAGE_FAULT_OUTPUT1 :: struct {
pHeadRecentFreedAllocationNode: ^DRED_ALLOCATION_NODE1, pHeadRecentFreedAllocationNode: ^DRED_ALLOCATION_NODE1,
} }
DRED_PAGE_FAULT_FLAGS :: bit_set[DRED_PAGE_FAULT_FLAG;u32]
DRED_PAGE_FAULT_FLAG :: enum u32 {
}
DRED_DEVICE_STATE :: enum i32 {
UNKNOWN = 0,
HUNG = 3,
FAULT = 6,
PAGEFAULT = 7,
}
DRED_PAGE_FAULT_OUTPUT2 :: struct {
PageFaultVA: GPU_VIRTUAL_ADDRESS,
pHeadExistingAllocationNode: ^DRED_ALLOCATION_NODE1,
pHeadRecentFreedAllocationNode: ^DRED_ALLOCATION_NODE1,
PageFaultFlags: DRED_PAGE_FAULT_FLAGS,
}
DEVICE_REMOVED_EXTENDED_DATA1 :: struct { DEVICE_REMOVED_EXTENDED_DATA1 :: struct {
DeviceRemovedReason: HRESULT, DeviceRemovedReason: HRESULT,
AutoBreadcrumbsOutput: DRED_AUTO_BREADCRUMBS_OUTPUT, AutoBreadcrumbsOutput: DRED_AUTO_BREADCRUMBS_OUTPUT,
@@ -3379,12 +3477,20 @@ DEVICE_REMOVED_EXTENDED_DATA2 :: struct {
PageFaultOutput: DRED_PAGE_FAULT_OUTPUT1, PageFaultOutput: DRED_PAGE_FAULT_OUTPUT1,
} }
DEVICE_REMOVED_EXTENDED_DATA3 :: struct {
DeviceRemovedReason: HRESULT,
AutoBreadcrumbsOutput: DRED_AUTO_BREADCRUMBS_OUTPUT1,
PageFaultOutput: DRED_PAGE_FAULT_OUTPUT2,
DeviceState: DRED_DEVICE_STATE,
}
VERSIONED_DEVICE_REMOVED_EXTENDED_DATA :: struct { VERSIONED_DEVICE_REMOVED_EXTENDED_DATA :: struct {
Version: DRED_VERSION, Version: DRED_VERSION,
using _: struct #raw_union { using _: struct #raw_union {
Dred_1_0: DEVICE_REMOVED_EXTENDED_DATA, Dred_1_0: DEVICE_REMOVED_EXTENDED_DATA,
Dred_1_1: DEVICE_REMOVED_EXTENDED_DATA1, Dred_1_1: DEVICE_REMOVED_EXTENDED_DATA1,
Dred_1_2: DEVICE_REMOVED_EXTENDED_DATA2, Dred_1_2: DEVICE_REMOVED_EXTENDED_DATA2,
Dred_1_3: DEVICE_REMOVED_EXTENDED_DATA3,
}, },
} }
@@ -3440,6 +3546,18 @@ IDeviceRemovedExtendedData1_VTable :: struct {
GetPageFaultAllocationOutput1: proc "system" (this: ^IDeviceRemovedExtendedData1, pOutput: ^DRED_PAGE_FAULT_OUTPUT1) -> HRESULT, GetPageFaultAllocationOutput1: proc "system" (this: ^IDeviceRemovedExtendedData1, pOutput: ^DRED_PAGE_FAULT_OUTPUT1) -> HRESULT,
} }
IDeviceRemovedExtendedData2_UUID_STRING :: "67FC5816-E4CA-4915-BF18-42541272DA54"
IDeviceRemovedExtendedData2_UUID := &IID{0x67FC5816, 0xE4CA, 0x4915, {0xBF, 0x18, 0x42, 0x54, 0x12, 0x72, 0xDA, 0x54}}
IDeviceRemovedExtendedData2 :: struct #raw_union {
#subtype id3d12deviceremovedextendeddata1: IDeviceRemovedExtendedData1,
using id3d12deviceremovedextendeddata2_vtable: ^IDeviceRemovedExtendedData2_VTable,
}
IDeviceRemovedExtendedData2_VTable :: struct {
using id3d12deviceremovedextendeddata1_vtable: IDeviceRemovedExtendedData1_VTable,
GetPageFaultAllocationOutput2: proc "system" (this: ^IDeviceRemovedExtendedData2, pOutput: ^DRED_PAGE_FAULT_OUTPUT2) -> HRESULT,
GetDeviceState: proc "system" (this: ^IDeviceRemovedExtendedData2) -> DRED_DEVICE_STATE,
}
BACKGROUND_PROCESSING_MODE :: enum i32 { BACKGROUND_PROCESSING_MODE :: enum i32 {
ALLOWED = 0, ALLOWED = 0,
ALLOW_INTRUSIVE_MEASUREMENTS = 1, ALLOW_INTRUSIVE_MEASUREMENTS = 1,
@@ -3686,6 +3804,71 @@ IGraphicsCommandList4_VTable :: struct {
} }
SHADER_CACHE_MODE :: enum i32 {
MEMORY = 0,
DISK = 1,
}
SHADER_CACHE_FLAGS :: bit_set[SHADER_CACHE_FLAG;u32]
SHADER_CACHE_FLAG :: enum u32 {
DRIVER_VERSIONED = 0,
USE_WORKING_DIR = 1,
}
SHADER_CACHE_SESSION_DESC :: struct {
Identifier: GUID,
Mode: SHADER_CACHE_MODE,
Flags: SHADER_CACHE_FLAGS,
MaximumInMemoryCacheSizeBytes: u32,
MaximumInMemoryCacheEntries: u32,
MaximumValueFileSizeBytes: u32,
Version: u64,
}
IShaderCacheSession_UUID_STRING :: "28E2495D-0F64-4AE4-A6EC-129255DC49A8"
IShaderCacheSession_UUID := &IID{0x28E2495D, 0x0F64, 0x4AE4, {0xA6, 0xEC, 0x12, 0x92, 0x55, 0xDC, 0x49, 0xA8}}
IShaderCacheSession :: struct #raw_union {
#subtype idevicechild: IDeviceChild,
using id3d12shadercachesession_vtable: ^IShaderCacheSession_VTable,
}
IShaderCacheSession_VTable :: struct {
using idevicechild_vtable: IDeviceChild_VTable,
FindValue: proc "system" (this: ^IShaderCacheSession, pKey: rawptr, KeySize: u32, pValue: rawptr, pValueSize: ^u32) -> HRESULT,
StoreValue: proc "system" (this: ^IShaderCacheSession, pKey: rawptr, KeySize: u32, pValue: rawptr, ValueSize: u32) -> HRESULT,
SetDeleteOnDestroy: proc "system" (this: ^IShaderCacheSession),
GetDesc: proc "system" (this: ^IShaderCacheSession, pRetValue: ^SHADER_CACHE_SESSION_DESC) -> ^SHADER_CACHE_SESSION_DESC,
}
SHADER_CACHE_KIND_FLAGS :: bit_set[SHADER_CACHE_KIND_FLAG;u32]
SHADER_CACHE_KIND_FLAG :: enum u32 {
IMPLICIT_D3D_CACHE_FOR_DRIVER = 0,
IMPLICIT_D3D_CONVERSIONS = 1,
IMPLICIT_DRIVER_MANAGED = 2,
APPLICATION_MANAGED = 3,
}
SHADER_CACHE_CONTROL_FLAGS :: bit_set[SHADER_CACHE_CONTROL_FLAG;u32]
SHADER_CACHE_CONTROL_FLAG :: enum u32 {
DISABLE = 0,
ENABLE = 1,
CLEAR = 2,
}
IDevice9_UUID_STRING :: "4C80E962-F032-4F60-BC9E-EBC2CFA1D83C"
IDevice9_UUID := &IID{0x4C80E962, 0xF032, 0x4F60, {0xBC, 0x9E, 0xEB, 0xC2, 0xCF, 0xA1, 0xD8, 0x3C}}
IDevice9 :: struct #raw_union {
#subtype id3d12device8: IDevice8,
using id3d12device9_vtable: ^IDevice9_VTable,
}
IDevice9_VTable :: struct {
using id3d12device8_vtable: IDevice8_VTable,
CreateShaderCacheSession: proc "system" (this: ^IDevice9, pDesc: ^SHADER_CACHE_SESSION_DESC , riid: ^IID, ppvSession: ^rawptr) -> HRESULT,
ShaderCacheControl: proc "system" (this: ^IDevice9, Kinds: SHADER_CACHE_KIND_FLAGS, Control: SHADER_CACHE_CONTROL_FLAGS) -> HRESULT,
CreateCommandQueue1: proc "system" (this: ^IDevice9, pDesc: ^COMMAND_QUEUE_DESC, CreatorID: ^IID, riid: ^IID, ppCommandQueue: ^rawptr) -> HRESULT,
}
ITools_UUID_STRING :: "7071e1f0-e84b-4b33-974f-12fa49de65c5" ITools_UUID_STRING :: "7071e1f0-e84b-4b33-974f-12fa49de65c5"
ITools_UUID := &IID{0x7071e1f0, 0xe84b, 0x4b33, {0x97, 0x4f, 0x12, 0xfa, 0x49, 0xde, 0x65, 0xc5}} ITools_UUID := &IID{0x7071e1f0, 0xe84b, 0x4b33, {0x97, 0x4f, 0x12, 0xfa, 0x49, 0xde, 0x65, 0xc5}}
ITools :: struct #raw_union { ITools :: struct #raw_union {
@@ -3766,6 +3949,30 @@ IDebug3_VTable :: struct {
SetGPUBasedValidationFlags: proc "system" (this: ^IDebug3, Flags: GPU_BASED_VALIDATION_FLAGS), SetGPUBasedValidationFlags: proc "system" (this: ^IDebug3, Flags: GPU_BASED_VALIDATION_FLAGS),
} }
IDebug4_UUID_STRING :: "014B816E-9EC5-4A2F-A845-FFBE441CE13A"
IDebug4_UUID := &IID{0x014B816E, 0x9EC5, 0x4A2F, {0xA8, 0x45, 0xFF, 0xBE, 0x44, 0x1C, 0xE1, 0x3A}}
IDebug4 :: struct #raw_union {
#subtype id3d12debug3: IDebug3,
using id3d12debug4_vtable: ^IDebug4_VTable,
}
IDebug4_VTable :: struct {
using id3d12debug3_vtable: IDebug3_VTable,
DisableDebugLayer: proc "system" (this: ^IDebug4),
}
IDebug5_UUID_STRING :: "548D6B12-09FA-40E0-9069-5DCD589A52C9"
IDebug5_UUID := &IID{0x548D6B12, 0x09FA, 0x40E0, {0x90, 0x69, 0x5D, 0xCD, 0x58, 0x9A, 0x52, 0xC9}}
IDebug5 :: struct #raw_union {
#subtype id3d12debug4: IDebug4,
using id3d12debug5_vtable: ^IDebug5_VTable,
}
IDebug5_VTable :: struct {
using id3d12debug4_vtable: IDebug4_VTable,
SetEnableAutoName: proc "system" (this: ^IDebug5, Enable: BOOL),
}
RLDO_FLAGS :: distinct bit_set[RLDO_FLAG; u32] RLDO_FLAGS :: distinct bit_set[RLDO_FLAG; u32]
RLDO_FLAG :: enum u32 { RLDO_FLAG :: enum u32 {
SUMMARY = 0, SUMMARY = 0,
@@ -4890,6 +5097,19 @@ IInfoQueue1_VTable :: struct {
UnregisterMessageCallback: proc "system" (this: ^IInfoQueue1, pCallbackCookie: u32) -> HRESULT, UnregisterMessageCallback: proc "system" (this: ^IInfoQueue1, pCallbackCookie: u32) -> HRESULT,
} }
ISDKConfiguration_UUID_STRING :: "E9EB5314-33AA-42B2-A718-D77F58B1F1C7"
ISDKConfiguration_UUID := &IID{0xE9EB5314, 0x33AA, 0x42B2, {0xA7, 0x18, 0xD7, 0x7F, 0x58, 0xB1, 0xF1, 0xC7}}
ISDKConfiguration :: struct #raw_union {
#subtype iunknown: IUnknown,
using id3d12sdkconfiguration_vtable: ^ISDKConfiguration_VTable,
}
ISDKConfiguration_VTable :: struct {
using iunknown_vtable: IUnknown_VTable,
SetSDKVersion: proc "system" (this: ^ISDKConfiguration, SDKVersion: u32, SDKPath: cstring) -> HRESULT,
}
PFN_CREATE_DEVICE :: #type proc "c" (a0: ^IUnknown, a1: FEATURE_LEVEL, a2: ^IID, a3: ^rawptr) -> HRESULT PFN_CREATE_DEVICE :: #type proc "c" (a0: ^IUnknown, a1: FEATURE_LEVEL, a2: ^IID, a3: ^rawptr) -> HRESULT
PFN_GET_DEBUG_INTERFACE :: #type proc "c" (a0: ^IID, a1: ^rawptr) -> HRESULT PFN_GET_DEBUG_INTERFACE :: #type proc "c" (a0: ^IID, a1: ^rawptr) -> HRESULT
+207 -11
View File
@@ -26,6 +26,8 @@ LONG :: win32.LONG
RECT :: win32.RECT RECT :: win32.RECT
POINT :: win32.POINT POINT :: win32.POINT
SIZE :: win32.SIZE SIZE :: win32.SIZE
WCHAR :: win32.WCHAR
DWORD :: win32.DWORD
IUnknown :: struct { IUnknown :: struct {
using _iunknown_vtable: ^IUnknown_VTable, using _iunknown_vtable: ^IUnknown_VTable,
@@ -38,10 +40,11 @@ IUnknown_VTable :: struct {
@(default_calling_convention="system") @(default_calling_convention="system")
foreign dxgi { foreign dxgi {
CreateDXGIFactory :: proc(riid: ^IID, ppFactory: ^rawptr) -> HRESULT --- CreateDXGIFactory :: proc(riid: ^IID, ppFactory: ^rawptr) -> HRESULT ---
CreateDXGIFactory1 :: proc(riid: ^IID, ppFactory: ^rawptr) -> HRESULT --- CreateDXGIFactory1 :: proc(riid: ^IID, ppFactory: ^rawptr) -> HRESULT ---
CreateDXGIFactory2 :: proc(Flags: CREATE_FACTORY, riid: ^IID, ppFactory: ^rawptr) -> HRESULT --- CreateDXGIFactory2 :: proc(Flags: CREATE_FACTORY, riid: ^IID, ppFactory: ^rawptr) -> HRESULT ---
DXGIGetDebugInterface1 :: proc(Flags: u32, riid: ^IID, pDebug: ^rawptr) -> HRESULT --- DXGIGetDebugInterface1 :: proc(Flags: u32, riid: ^IID, pDebug: ^rawptr) -> HRESULT ---
DeclareAdapterRemovalSupport :: proc() -> HRESULT ---
} }
STANDARD_MULTISAMPLE_QUALITY_PATTERN :: 0xffffffff STANDARD_MULTISAMPLE_QUALITY_PATTERN :: 0xffffffff
@@ -617,11 +620,11 @@ IDevice_VTable :: struct {
SetGPUThreadPriority: proc "system" (this: ^IDevice, Priority: i32) -> HRESULT, SetGPUThreadPriority: proc "system" (this: ^IDevice, Priority: i32) -> HRESULT,
GetGPUThreadPriority: proc "system" (this: ^IDevice, pPriority: ^i32) -> HRESULT, GetGPUThreadPriority: proc "system" (this: ^IDevice, pPriority: ^i32) -> HRESULT,
} }
ADAPTER_FLAG :: enum u32 { // TODO: convert to bit_set
NONE = 0x0, ADAPTER_FLAGS :: bit_set[ADAPTER_FLAG;u32]
REMOTE = 0x1, ADAPTER_FLAG :: enum u32 {
SOFTWARE = 0x2, REMOTE = 0,
FORCE_DWORD = 0xffffffff, SOFTWARE = 1,
} }
ADAPTER_DESC1 :: struct { ADAPTER_DESC1 :: struct {
@@ -634,7 +637,7 @@ ADAPTER_DESC1 :: struct {
DedicatedSystemMemory: SIZE_T, DedicatedSystemMemory: SIZE_T,
SharedSystemMemory: SIZE_T, SharedSystemMemory: SIZE_T,
AdapterLuid: LUID, AdapterLuid: LUID,
Flags: ADAPTER_FLAG, Flags: ADAPTER_FLAGS,
} }
DISPLAY_COLOR_SPACE :: struct { DISPLAY_COLOR_SPACE :: struct {
@@ -911,7 +914,7 @@ ADAPTER_DESC2 :: struct {
DedicatedSystemMemory: SIZE_T, DedicatedSystemMemory: SIZE_T,
SharedSystemMemory: SIZE_T, SharedSystemMemory: SIZE_T,
AdapterLuid: LUID, AdapterLuid: LUID,
Flags: ADAPTER_FLAG, Flags: ADAPTER_FLAGS,
GraphicsPreemptionGranularity: GRAPHICS_PREEMPTION_GRANULARITY, GraphicsPreemptionGranularity: GRAPHICS_PREEMPTION_GRANULARITY,
ComputePreemptionGranularity: COMPUTE_PREEMPTION_GRANULARITY, ComputePreemptionGranularity: COMPUTE_PREEMPTION_GRANULARITY,
} }
@@ -1165,6 +1168,199 @@ IAdapter3_VTable :: struct {
UnregisterVideoMemoryBudgetChangeNotification: proc "system" (this: ^IAdapter3, dwCookie: u32), UnregisterVideoMemoryBudgetChangeNotification: proc "system" (this: ^IAdapter3, dwCookie: u32),
} }
OUTDUPL_FLAG :: enum i32 {
COMPOSITED_UI_CAPTURE_ONLY = 1,
}
IOutput5_UUID_STRING :: "80A07424-AB52-42EB-833C-0C42FD282D98"
IOutput5_UUID := &IID{0x80A07424, 0xAB52, 0x42EB, {0x83, 0x3C, 0x0C, 0x42, 0xFD, 0x28, 0x2D, 0x98}}
IOutput5 :: struct #raw_union {
#subtype idxgioutput4: IOutput4,
using idxgioutput5_vtable: ^IOutput5_VTable,
}
IOutput5_VTable :: struct {
using idxgioutput4_vtable: IOutput4_VTable,
DuplicateOutput1: proc "system" (this: ^IOutput5, pDevice: ^IUnknown, Flags: u32, SupportedFormatsCount: u32, pSupportedFormats: ^FORMAT, ppOutputDuplication: ^^IOutputDuplication) -> HRESULT,
}
HDR_METADATA_TYPE :: enum i32 {
NONE = 0,
HDR10 = 1,
HDR10PLUS = 2,
}
HDR_METADATA_HDR10 :: struct {
RedPrimary: [2]u16,
GreenPrimary: [2]u16,
BluePrimary: [2]u16,
WhitePoint: [2]u16,
MaxMasteringLuminance: u32,
MinMasteringLuminance: u32,
MaxContentLightLevel: u16,
MaxFrameAverageLightLevel: u16,
}
HDR_METADATA_HDR10PLUS :: struct {
Data: [72]byte,
}
ISwapChain4_UUID_STRING :: "3D585D5A-BD4A-489E-B1F4-3DBCB6452FFB"
ISwapChain4_UUID := &IID{0x3D585D5A, 0xBD4A, 0x489E, {0xB1, 0xF4, 0x3D, 0xBC, 0xB6, 0x45, 0x2F, 0xFB}}
ISwapChain4 :: struct #raw_union {
#subtype idxgiswapchain3: ISwapChain3,
using idxgiswapchain4_vtable: ^ISwapChain4_VTable,
}
ISwapChain4_VTable :: struct {
using idxgiswapchain3_vtable: ISwapChain3_VTable,
SetHDRMetaData: proc "system" (this: ^ISwapChain4, Type: HDR_METADATA_TYPE, Size: u32, pMetaData: rawptr) -> HRESULT,
}
OFFER_RESOURCE_FLAGS :: bit_set[OFFER_RESOURCE_FLAG;u32]
OFFER_RESOURCE_FLAG :: enum u32 {
ALLOW_DECOMMIT = 0,
}
RECLAIM_RESOURCE_RESULTS :: enum i32 {
OK = 0,
DISCARDED = 1,
NOT_COMMITTED = 2,
}
IDevice4_UUID_STRING :: "95B4F95F-D8DA-4CA4-9EE6-3B76D5968A10"
IDevice4_UUID := &IID{0x95B4F95F, 0xD8DA, 0x4CA4, {0x9E, 0xE6, 0x3B, 0x76, 0xD5, 0x96, 0x8A, 0x10}}
IDevice4 :: struct #raw_union {
#subtype idxgidevice3: IDevice3,
using idxgidevice4_vtable: ^IDevice4_VTable,
}
IDevice4_VTable :: struct {
using idxgidevice3_vtable: IDevice3_VTable,
OfferResources1: proc "system" (this: ^IDevice4, NumResources: u32, ppResources: ^^IResource, Priority: OFFER_RESOURCE_PRIORITY, Flags: OFFER_RESOURCE_FLAGS) -> HRESULT,
ReclaimResources1: proc "system" (this: ^IDevice4, NumResources: u32, ppResources: ^^IResource, pResults: ^RECLAIM_RESOURCE_RESULTS) -> HRESULT,
}
FEATURE :: enum i32 {
PRESENT_ALLOW_TEARING = 0,
}
IFactory5_UUID_STRING :: "7632e1f5-ee65-4dca-87fd-84cd75f8838d"
IFactory5_UUID := &IID{0x7632e1f5, 0xee65, 0x4dca, {0x87, 0xfd, 0x84, 0xcd, 0x75, 0xf8, 0x83, 0x8d}}
IFactory5 :: struct #raw_union {
#subtype idxgifactory4: IFactory4,
using idxgifactory5_vtable: ^IFactory5_VTable,
}
IFactory5_VTable :: struct {
using idxgifactory4_vtable: IFactory4_VTable,
CheckFeatureSupport: proc "system" (this: ^IFactory5, Feature: FEATURE, pFeatureSupportData: rawptr, FeatureSupportDataSize: u32) -> HRESULT,
}
ADAPTER_FLAGS3 :: bit_set[ADAPTER_FLAG3;u32]
ADAPTER_FLAG3 :: enum u32 {
REMOTE = 0,
SOFTWARE = 1,
ACG_COMPATIBLE = 3,
SUPPORT_MONITORED_FENCES = 4,
SUPPORT_NON_MONITORED_FENCES = 5,
KEYED_MUTEX_CONFORMANCE = 6,
}
ADAPTER_DESC3 :: struct {
Description: [128]WCHAR,
VendorId: u32,
DeviceId: u32,
SubSysId: u32,
Revision: u32,
DedicatedVideoMemory: u64,
DedicatedSystemMemory: u64,
SharedSystemMemory: u64,
AdapterLuid: LUID,
Flags: ADAPTER_FLAGS3,
GraphicsPreemptionGranularity: GRAPHICS_PREEMPTION_GRANULARITY,
ComputePreemptionGranularity: COMPUTE_PREEMPTION_GRANULARITY,
}
IAdapter4_UUID_STRING :: "3c8d99d1-4fbf-4181-a82c-af66bf7bd24e"
IAdapter4_UUID := &IID{0x3c8d99d1, 0x4fbf, 0x4181, {0xa8, 0x2c, 0xaf, 0x66, 0xbf, 0x7b, 0xd2, 0x4e}}
IAdapter4 :: struct #raw_union {
#subtype idxgiadapter3: IAdapter3,
using idxgiadapter4_vtable: ^IAdapter4_VTable,
}
IAdapter4_VTable :: struct {
using idxgiadapter3_vtable: IAdapter3_VTable,
GetDesc3: proc "system" (this: ^IAdapter4, pDesc: ^ADAPTER_DESC3) -> HRESULT,
}
OUTPUT_DESC1 :: struct {
DeviceName: [32]WCHAR,
DesktopCoordinates: RECT,
AttachedToDesktop: BOOL,
Rotation: MODE_ROTATION,
Monitor: HMONITOR,
BitsPerColor: u32,
ColorSpace: COLOR_SPACE_TYPE,
RedPrimary: [2]f32,
GreenPrimary: [2]f32,
BluePrimary: [2]f32,
WhitePoint: [2]f32,
MinLuminance: f32,
MaxLuminance: f32,
MaxFullFrameLuminance: f32,
}
HARDWARE_COMPOSITION_SUPPORT_FLAGS :: bit_set[HARDWARE_COMPOSITION_SUPPORT_FLAG;u32]
HARDWARE_COMPOSITION_SUPPORT_FLAG :: enum u32 {
FULLSCREEN = 0,
WINDOWED = 1,
CURSOR_STRETCHED = 2,
}
IOutput6_UUID_STRING :: "068346e8-aaec-4b84-add7-137f513f77a1"
IOutput6_UUID := &IID{0x068346e8, 0xaaec, 0x4b84, {0xad, 0xd7, 0x13, 0x7f, 0x51, 0x3f, 0x77, 0xa1}}
IOutput6 :: struct #raw_union {
#subtype idxgioutput5: IOutput5,
using idxgioutput6_vtable: ^IOutput6_VTable,
}
IOutput6_VTable :: struct {
using idxgioutput5_vtable: IOutput5_VTable,
GetDesc1: proc "system" (this: ^IOutput6, pDesc: ^OUTPUT_DESC1) -> HRESULT,
CheckHardwareCompositionSupport: proc "system" (this: ^IOutput6, pFlags: ^HARDWARE_COMPOSITION_SUPPORT_FLAGS) -> HRESULT,
}
GPU_PREFERENCE :: enum i32 {
UNSPECIFIED = 0,
MINIMUM_POWER = 1,
HIGH_PERFORMANCE = 2,
}
IFactory6_UUID_STRING :: "c1b6694f-ff09-44a9-b03c-77900a0a1d17"
IFactory6_UUID := &IID{0xc1b6694f, 0xff09, 0x44a9, {0xb0, 0x3c, 0x77, 0x90, 0x0a, 0x0a, 0x1d, 0x17}}
IFactory6 :: struct #raw_union {
#subtype idxgifactory5: IFactory5,
using idxgifactory6_vtable: ^IFactory6_VTable,
}
IFactory6_VTable :: struct {
using idxgifactory5_vtable: IFactory5_VTable,
EnumAdapterByGpuPreference: proc "system" (this: ^IFactory6, Adapter: u32, GpuPreference: GPU_PREFERENCE, riid: ^IID, ppvAdapter: ^rawptr) -> HRESULT,
}
IFactory7_UUID_STRING :: "a4966eed-76db-44da-84c1-ee9a7afb20a8"
IFactory7_UUID := &IID{0xa4966eed, 0x76db, 0x44da, {0x84, 0xc1, 0xee, 0x9a, 0x7a, 0xfb, 0x20, 0xa8}}
IFactory7 :: struct #raw_union {
#subtype idxgifactory6: IFactory6,
using idxgifactory7_vtable: ^IFactory7_VTable,
}
IFactory7_VTable :: struct {
using idxgifactory6_vtable: IFactory6_VTable,
RegisterAdaptersChangedEvent: proc "system" (this: ^IFactory7, hEvent: HANDLE, pdwCookie: ^DWORD) -> HRESULT,
UnregisterAdaptersChangedEvent: proc "system" (this: ^IFactory7, dwCookie: DWORD) -> HRESULT,
}
ERROR_ACCESS_DENIED :: HRESULT(-2005270485) //0x887A002B ERROR_ACCESS_DENIED :: HRESULT(-2005270485) //0x887A002B
ERROR_ACCESS_LOST :: HRESULT(-2005270490) //0x887A0026 ERROR_ACCESS_LOST :: HRESULT(-2005270490) //0x887A0026
ERROR_ALREADY_EXISTS :: HRESULT(-2005270474) //0x887A0036 ERROR_ALREADY_EXISTS :: HRESULT(-2005270474) //0x887A0036