Merge remote-tracking branch 'offical/master'

This commit is contained in:
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)
// Typeid_Bit_Field :: bit_field #align(align_of(uintptr)) {
// index: 8*size_of(uintptr) - 8,
// kind: 5, // Typeid_Kind
// named: 1,
// special: 1, // signed, cstring, etc
// reserved: 1,
// }
// #assert(size_of(Typeid_Bit_Field) == size_of(uintptr));
Typeid_Bit_Field :: bit_field uintptr {
index: uintptr | 8*size_of(uintptr) - 8,
kind: Typeid_Kind | 5, // Typeid_Kind
named: bool | 1,
special: bool | 1, // signed, cstring, etc
reserved: bool | 1,
}
#assert(size_of(Typeid_Bit_Field) == size_of(uintptr))
// NOTE(bill): only the ones that are needed (not all types)
// 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.
Printing
@@ -33,6 +33,8 @@ Floating-point, complex numbers, and quaternions:
%E scientific notation, e.g. -1.23456E+78
%f decimal point but no exponent, e.g. 123.456
%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 (upper-case) representation with 0H prefix (0h01234ABCD)
%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, ...}
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.
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.
A period with no following number specifies a precision of 0.
@@ -75,7 +77,7 @@ Examples:
%8.f width 8, precision 0
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:
@@ -92,7 +94,7 @@ Other flags:
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
@@ -105,19 +107,20 @@ Explicit argument indices:
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
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.
Python-like syntax with argument indices differs for the selecting the argument index: {N:v}
The same notation before an '*' for a width or precision specifier selects the argument index
holding the value.
Python-like syntax with argument indices differs for selecting the argument index: {n:v}
Examples:
fmt.printf("%[1]d %[0]d\n", 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) // C-like syntax
fmt.printfln("{1:d} {0:d}", 13, 37) // Python-like syntax
prints "37 13", whilst:
fmt.printf("%[2]*.[1]*[0]f\n", 17.0, 2, 6); // C-like syntax
fmt.printf("%{0:[2]*.[1]*f}\n", 17.0, 2, 6); // Python-like syntax
equivalent to:
fmt.printf("%6.2f\n", 17.0, 2, 6); // C-like syntax
fmt.printf("{:6.2f}\n", 17.0, 2, 6); // Python-like syntax
prints "17.00"
fmt.printfln("%*[2].*[1][0]f", 17.0, 2, 6) // C-like syntax
fmt.printfln("{0:*[2].*[1]f}", 17.0, 2, 6) // Python-like syntax
is equivalent to:
fmt.printfln("%6.2f", 17.0) // C-like syntax
fmt.printfln("{:6.2f}", 17.0) // Python-like syntax
and prints "17.00".
Format errors:
+156 -191
View File
@@ -25,8 +25,6 @@ Info :: struct {
prec: int,
indent: int,
reordered: bool,
good_arg_index: bool,
ignore_user_formatters: 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
//
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
arg_index: int = 0
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; /**/ {
fi = Info{writer = w, good_arg_index = true, reordered = fi.reordered, n = fi.n}
fi = Info{writer = w, n = fi.n}
prev_i := 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 == '%' {
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
}
}
arg_index, i, was_prev_index = _arg_number(&fi, arg_index, fmt, i, len(args))
// Width
if i < end && fmt[i] == '*' {
if i < end && fmt[i] == '%' {
io.write_byte(fi.writer, '%', &fi.n)
i += 1
fi.width, arg_index, fi.width_set = int_from_arg(args, arg_index)
if !fi.width_set {
io.write_string(w, "%!(BAD WIDTH)", &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
}
continue loop
}
// 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)
}
}
i = parse_options(&fi, fmt, i, end, &unused_args, ..args)
if !was_prev_index {
arg_index, i, was_prev_index = _arg_number(&fi, arg_index, fmt, i, len(args))
arg_index, arg_parsed, index_ok := _arg_number(fmt, &i, len(args))
if !index_ok {
arg_index, index_ok = error_check_arg(&fi, arg_parsed, unused_args)
}
if i >= end {
io.write_string(fi.writer, "%!(NO VERB)", &fi.n)
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:])
i += w
switch {
case verb == '%':
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:
if index_ok {
unused_args -= {arg_index}
fmt_arg(&fi, args[arg_index], verb)
arg_index += 1
}
} else if char == '{' {
arg_index: int
arg_parsed, index_ok: bool
if i < end && fmt[i] != '}' && fmt[i] != ':' {
new_arg_index, new_i, ok := _parse_int(fmt, i)
if ok {
fi.reordered = true
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)
arg_index, i, arg_parsed = _parse_int(fmt, i)
if arg_parsed {
index_ok = 0 <= arg_index && arg_index < len(args)
}
}
if !index_ok {
arg_index, index_ok = error_check_arg(&fi, arg_parsed, unused_args)
}
verb: rune = 'v'
if i < end && fmt[i] == ':' {
i += 1
prefix_loop_percent: 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_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))
}
i = parse_options(&fi, fmt, i, end, &unused_args, ..args)
if i >= end {
io.write_string(fi.writer, "%!(NO VERB)", &fi.n)
break loop
} else if fmt[i] == '}' {
i += 1
io.write_string(fi.writer, "%!(NO VERB)", &fi.n)
continue
}
w: int = 1
@@ -770,31 +736,35 @@ wprintf :: proc(w: io.Writer, fmt: string, args: ..any, flush := true, newline :
switch {
case brace != '}':
io.write_string(fi.writer, "%!(MISSING CLOSE BRACE)", &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:
case index_ok:
fmt_arg(&fi, args[arg_index], verb)
arg_index += 1
unused_args -= {arg_index}
}
}
}
if !fi.reordered && arg_index < len(args) {
io.write_string(fi.writer, "%!(EXTRA ", &fi.n)
for arg, index in args[arg_index:] {
if index > 0 {
io.write_string(fi.writer, ", ", &fi.n)
if unused_args != {} {
// Use default options when formatting extra arguments.
extra_fi := Info { writer = fi.writer, n = 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 {
io.write_string(fi.writer, "<nil>", &fi.n)
io.write_string(extra_fi.writer, "<nil>", &extra_fi.n)
} 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 {
@@ -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
//
// Inputs:
// - fi: A pointer to an Info structure
// - arg_index: The current argument index
// - 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
//
// Returns:
// - index: The parsed argument index
// - new_offset: The new position in the format string
// - ok: A boolean indicating if the parsed argument number is valid
// - parsed: A boolean indicating if an argument number was parsed
// - 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) {
if len(format) < 3 {
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) {
if format[i] == ']' {
width, new_index, ok := _parse_int(format, 1)
value, new_index, ok := _parse_int(format, 1)
if !ok || new_index != i {
return 0, i+1, false
}
return width-1, i+1, true
return value, i+1, true
}
}
return 0, 1, false
}
i := offset^
if len(format) <= offset || format[offset] != '[' {
return arg_index, offset, false
if len(format) <= i || format[i] != '[' {
return 0, false, false
}
fi.reordered = true
width: int
index, width, ok = parse_arg_number(format[offset:])
if ok && 0 <= index && index < arg_count {
return index, offset+width, true
}
fi.good_arg_index = false
return arg_index, offset+width, false
index, width, parsed = parse_arg_number(format[i:])
offset^ = i + width
ok = parsed && 0 <= index && index < arg_count
return
}
// 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 {
formatter := _user_formatters[v.id]
if formatter != nil {
fi.ignore_user_formatters = false
if ok := formatter(fi, v, verb); !ok {
fi.ignore_user_formatters = true
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)
p.expr_level += 1
params, _ := parse_field_list(p, .Close_Paren, ast.Field_Flags_Signature_Params)
p.expr_level -= 1
expect_closing_parentheses_of_field_list(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 {
switch fmt {
case 'e', 'E':
prec += 1
decimal.round(d, prec)
decimal.round(d, prec + 1)
case 'f', 'F':
decimal.round(d, d.decimal_point+prec)
case 'g', 'G':
+2
View File
@@ -429,6 +429,8 @@ foreign kernel32 {
DisconnectNamedPipe :: proc(hNamedPipe: HANDLE) -> BOOL ---
WaitNamedPipeW :: proc(lpNamedPipeName: LPCWSTR, nTimeOut: DWORD) -> BOOL ---
AllocConsole :: proc() -> BOOL ---
AttachConsole :: proc(dwProcessId: DWORD) -> BOOL ---
SetConsoleCtrlHandler :: proc(HandlerRoutine: PHANDLER_ROUTINE, Add: BOOL) -> BOOL ---
GenerateConsoleCtrlEvent :: proc(dwCtrlEvent: DWORD, dwProcessGroupId: DWORD) -> 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) {
for_array(i, stmts) {
Ast *stmt = stmts[i];
for (Ast *stmt : stmts) {
if (check_has_break(stmt, label, implicit)) {
return true;
}
@@ -170,6 +169,14 @@ gb_internal bool check_has_break_list(Slice<Ast *> const &stmts, String const &l
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) {
switch (stmt->kind) {
@@ -227,6 +234,20 @@ gb_internal bool check_has_break(Ast *stmt, String const &label, bool implicit)
return true;
}
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;
@@ -250,6 +271,15 @@ gb_internal bool check_is_terminating(Ast *node, String const &label) {
return check_is_terminating(unparen_expr(es->expr), label);
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);
return bs->token.kind == Token_fallthrough;
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);
f->expr_level += 1;
params = parse_field_list(f, nullptr, FieldFlag_Signature, Token_CloseParen, true, true);
if (file_allow_newline(f)) {
skip_possible_newline(f);
}
f->expr_level -= 1;
expect_token_after(f, Token_CloseParen, "parameter list");
results = parse_results(f, &diverging);
+130 -6
View File
@@ -29,6 +29,8 @@ when ODIN_TEST {
main :: proc() {
t := testing.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)
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) {
got := fmt.tprintf(format, ..args)
expect(t, got == exp, fmt.tprintf("(%q, %v): %q != %q", format, args, got, exp), loc)
}
check :: proc(t: ^testing.T, exp: string, format: string, args: ..any, loc := #caller_location) {
got := fmt.tprintf(format, ..args)
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)
@@ -52,8 +55,129 @@ test_fmt_memory :: proc(t: ^testing.T) {
check(t, "3.50 gib", "%#m", u32(mem.Gigabyte * 3.5))
check(t, "01tib", "%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, "255 B", "%#M", u8(255))
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,
_12_0 = 49152,
_12_1 = 49408,
_12_2 = 49664,
}
PRIMITIVE_TOPOLOGY :: enum i32 {
@@ -833,6 +834,9 @@ FEATURE :: enum i32 {
OPTIONS7 = 32,
PROTECTED_RESOURCE_SESSION_TYPE_COUNT = 33,
PROTECTED_RESOURCE_SESSION_TYPES = 34,
OPTIONS8 = 36,
OPTIONS9 = 37,
WAVE_MMA = 38,
}
SHADER_MIN_PRECISION_SUPPORT :: enum i32 {
@@ -1017,6 +1021,7 @@ SHADER_MODEL :: enum i32 {
_6_4 = 100,
_6_5 = 101,
_6_6 = 102,
_6_7 = 103,
}
FEATURE_DATA_SHADER_MODEL :: struct {
@@ -1052,6 +1057,7 @@ SHADER_CACHE_SUPPORT_FLAG :: enum u32 {
LIBRARY = 1,
AUTOMATIC_INPROC_CACHE = 2,
AUTOMATIC_DISK_CACHE = 3,
DRIVER_MANAGED_CACHE = 4,
}
FEATURE_DATA_SHADER_CACHE :: struct {
@@ -1171,6 +1177,55 @@ FEATURE_DATA_QUERY_META_COMMAND :: struct {
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 {
SizeInBytes: u64,
Alignment: u64,
@@ -1261,6 +1316,7 @@ RESOURCE_FLAG :: enum u32 {
ALLOW_CROSS_ADAPTER = 4,
ALLOW_SIMULTANEOUS_ACCESS = 5,
VIDEO_DECODE_REFERENCE_ONLY = 6,
VIDEO_ENCODE_REFERENCE_ONLY = 7,
}
MIP_REGION :: struct {
@@ -2140,6 +2196,7 @@ QUERY_HEAP_TYPE :: enum i32 {
SO_STATISTICS = 3,
VIDEO_DECODE_STATISTICS = 4,
COPY_QUEUE_TIMESTAMP = 5,
PIPELINE_STATISTICS1 = 7,
}
QUERY_HEAP_DESC :: struct {
@@ -2158,6 +2215,7 @@ QUERY_TYPE :: enum i32 {
SO_STATISTICS_STREAM2 = 6,
SO_STATISTICS_STREAM3 = 7,
VIDEO_DECODE_STATISTICS = 8,
PIPELINE_STATISTICS1 = 10,
}
PREDICATION_OP :: enum i32 {
@@ -2179,6 +2237,23 @@ QUERY_DATA_PIPELINE_STATISTICS :: struct {
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 {
NumPrimitivesWritten: u64,
PrimitivesStorageNeeded: u64,
@@ -3244,6 +3319,8 @@ AUTO_BREADCRUMB_OP :: enum i32 {
INITIALIZEEXTENSIONCOMMAND = 40,
EXECUTEEXTENSIONCOMMAND = 41,
DISPATCHMESH = 42,
ENCODEFRAME = 43,
RESOLVEENCODEROUTPUTMETADATA = 44,
}
AUTO_BREADCRUMB_NODE :: struct {
@@ -3283,6 +3360,7 @@ DRED_VERSION :: enum i32 {
_1_0 = 1,
_1_1 = 2,
_1_2 = 3,
_1_3 = 4,
}
DRED_FLAGS :: distinct bit_set[DRED_FLAG; u32]
@@ -3329,6 +3407,8 @@ DRED_ALLOCATION_TYPE :: enum i32 {
VIDEO_MOTION_ESTIMATOR = 45,
VIDEO_MOTION_VECTOR_HEAP = 46,
VIDEO_EXTENSION_COMMAND = 47,
VIDEO_ENCODER = 48,
VIDEO_ENCODER_HEAP = 49,
INVALID = -1,
}
@@ -3367,6 +3447,24 @@ DRED_PAGE_FAULT_OUTPUT1 :: struct {
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 {
DeviceRemovedReason: HRESULT,
AutoBreadcrumbsOutput: DRED_AUTO_BREADCRUMBS_OUTPUT,
@@ -3379,12 +3477,20 @@ DEVICE_REMOVED_EXTENDED_DATA2 :: struct {
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 {
Version: DRED_VERSION,
using _: struct #raw_union {
Dred_1_0: DEVICE_REMOVED_EXTENDED_DATA,
Dred_1_1: DEVICE_REMOVED_EXTENDED_DATA1,
Dred_1_2: DEVICE_REMOVED_EXTENDED_DATA2,
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,
}
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 {
ALLOWED = 0,
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 := &IID{0x7071e1f0, 0xe84b, 0x4b33, {0x97, 0x4f, 0x12, 0xfa, 0x49, 0xde, 0x65, 0xc5}}
ITools :: struct #raw_union {
@@ -3766,6 +3949,30 @@ IDebug3_VTable :: struct {
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_FLAG :: enum u32 {
SUMMARY = 0,
@@ -4890,6 +5097,19 @@ IInfoQueue1_VTable :: struct {
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_GET_DEBUG_INTERFACE :: #type proc "c" (a0: ^IID, a1: ^rawptr) -> HRESULT
+208 -12
View File
@@ -26,6 +26,8 @@ LONG :: win32.LONG
RECT :: win32.RECT
POINT :: win32.POINT
SIZE :: win32.SIZE
WCHAR :: win32.WCHAR
DWORD :: win32.DWORD
IUnknown :: struct {
using _iunknown_vtable: ^IUnknown_VTable,
@@ -38,10 +40,11 @@ IUnknown_VTable :: struct {
@(default_calling_convention="system")
foreign dxgi {
CreateDXGIFactory :: proc(riid: ^IID, ppFactory: ^rawptr) -> HRESULT ---
CreateDXGIFactory1 :: proc(riid: ^IID, ppFactory: ^rawptr) -> HRESULT ---
CreateDXGIFactory2 :: proc(Flags: CREATE_FACTORY, riid: ^IID, ppFactory: ^rawptr) -> HRESULT ---
DXGIGetDebugInterface1 :: proc(Flags: u32, riid: ^IID, pDebug: ^rawptr) -> HRESULT ---
CreateDXGIFactory :: proc(riid: ^IID, ppFactory: ^rawptr) -> HRESULT ---
CreateDXGIFactory1 :: proc(riid: ^IID, ppFactory: ^rawptr) -> HRESULT ---
CreateDXGIFactory2 :: proc(Flags: CREATE_FACTORY, riid: ^IID, ppFactory: ^rawptr) -> HRESULT ---
DXGIGetDebugInterface1 :: proc(Flags: u32, riid: ^IID, pDebug: ^rawptr) -> HRESULT ---
DeclareAdapterRemovalSupport :: proc() -> HRESULT ---
}
STANDARD_MULTISAMPLE_QUALITY_PATTERN :: 0xffffffff
@@ -617,11 +620,11 @@ IDevice_VTable :: struct {
SetGPUThreadPriority: proc "system" (this: ^IDevice, Priority: i32) -> HRESULT,
GetGPUThreadPriority: proc "system" (this: ^IDevice, pPriority: ^i32) -> HRESULT,
}
ADAPTER_FLAG :: enum u32 { // TODO: convert to bit_set
NONE = 0x0,
REMOTE = 0x1,
SOFTWARE = 0x2,
FORCE_DWORD = 0xffffffff,
ADAPTER_FLAGS :: bit_set[ADAPTER_FLAG;u32]
ADAPTER_FLAG :: enum u32 {
REMOTE = 0,
SOFTWARE = 1,
}
ADAPTER_DESC1 :: struct {
@@ -634,7 +637,7 @@ ADAPTER_DESC1 :: struct {
DedicatedSystemMemory: SIZE_T,
SharedSystemMemory: SIZE_T,
AdapterLuid: LUID,
Flags: ADAPTER_FLAG,
Flags: ADAPTER_FLAGS,
}
DISPLAY_COLOR_SPACE :: struct {
@@ -911,7 +914,7 @@ ADAPTER_DESC2 :: struct {
DedicatedSystemMemory: SIZE_T,
SharedSystemMemory: SIZE_T,
AdapterLuid: LUID,
Flags: ADAPTER_FLAG,
Flags: ADAPTER_FLAGS,
GraphicsPreemptionGranularity: GRAPHICS_PREEMPTION_GRANULARITY,
ComputePreemptionGranularity: COMPUTE_PREEMPTION_GRANULARITY,
}
@@ -1165,6 +1168,199 @@ IAdapter3_VTable :: struct {
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_LOST :: HRESULT(-2005270490) //0x887A0026
ERROR_ALREADY_EXISTS :: HRESULT(-2005270474) //0x887A0036
@@ -1192,4 +1388,4 @@ ERROR_WAS_STILL_DRAWING :: HRESULT(-2005270518) //0x887A000A
STATUS_OCCLUDED :: HRESULT( 142213121) //0x087A0001
STATUS_MODE_CHANGED :: HRESULT( 142213127) //0x087A0007
STATUS_MODE_CHANGE_IN_PROGRESS :: HRESULT( 142213128) //0x087A0008
STATUS_MODE_CHANGE_IN_PROGRESS :: HRESULT( 142213128) //0x087A0008