From ad98efe1fdc206d285b3fd4e4e8e0be1aac3d1b7 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 9 Sep 2022 10:47:02 +0100 Subject: [PATCH 1/5] Revert "Remove the workaround for NSWindow initWithContentFrame" --- vendor/darwin/Foundation/NSWindow.odin | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/vendor/darwin/Foundation/NSWindow.odin b/vendor/darwin/Foundation/NSWindow.odin index 2efbe8ba3..330af6012 100644 --- a/vendor/darwin/Foundation/NSWindow.odin +++ b/vendor/darwin/Foundation/NSWindow.odin @@ -103,7 +103,18 @@ Window_alloc :: proc() -> ^Window { @(objc_type=Window, objc_name="initWithContentRect") Window_initWithContentRect :: proc (self: ^Window, contentRect: Rect, styleMask: WindowStyleMask, backing: BackingStoreType, doDefer: bool) -> ^Window { - return msgSend(^Window, self, "initWithContentRect:styleMask:backing:defer:", contentRect, styleMask, backing, doDefer) + self := self + // HACK: due to a compiler bug, the generated calling code does not + // currently work for this message. Has to do with passing a struct along + // with other parameters, so we don't send the rect here. + // Omiting the rect argument here actually works, because of how the C + // calling conventions are defined. + self = msgSend(^Window, self, "initWithContentRect:styleMask:backing:defer:", styleMask, backing, doDefer) + + // apply the contentRect now, since we did not pass it to the init call + msgSend(nil, self, "setContentSize:", contentRect.size) + msgSend(nil, self, "setFrameOrigin:", contentRect.origin) + return self } @(objc_type=Window, objc_name="contentView") Window_contentView :: proc(self: ^Window) -> ^View { From 623d687192dac04efe144f1387c8220021de00b0 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 9 Sep 2022 23:07:09 +0100 Subject: [PATCH 2/5] Split debug info generation for direct and indirect parameters --- src/llvm_backend_debug.cpp | 67 +++++++++++++++++++++++++++++++++++++- src/llvm_backend_proc.cpp | 4 +-- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index ea7322297..a793aaa6d 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -981,7 +981,72 @@ void lb_add_debug_local_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, T } -void lb_add_debug_param_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token, unsigned arg_number, lbBlock *block) { +void lb_add_debug_param_variable_direct(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token, unsigned arg_number, lbBlock *block) { + if (p->debug_info == nullptr) { + return; + } + if (type == nullptr) { + return; + } + if (type == t_invalid) { + return; + } + if (p->body == nullptr) { + return; + } + + lbModule *m = p->module; + String const &name = token.string; + if (name == "" || name == "_") { + return; + } + + if (lb_get_llvm_metadata(m, ptr) != nullptr) { + // Already been set + return; + } + + + AstFile *file = p->body->file(); + + LLVMMetadataRef llvm_scope = lb_get_current_debug_scope(p); + LLVMMetadataRef llvm_file = lb_get_llvm_metadata(m, file); + GB_ASSERT(llvm_scope != nullptr); + if (llvm_file == nullptr) { + llvm_file = LLVMDIScopeGetFile(llvm_scope); + } + + if (llvm_file == nullptr) { + return; + } + + LLVMDIFlags flags = LLVMDIFlagZero; + LLVMBool always_preserve = build_context.optimization_level == 0; + + LLVMMetadataRef debug_type = lb_debug_type(m, type); + + LLVMMetadataRef var_info = LLVMDIBuilderCreateParameterVariable( + m->debug_builder, llvm_scope, + cast(char const *)name.text, cast(size_t)name.len, + arg_number, + llvm_file, token.pos.line, + debug_type, + always_preserve, flags + ); + + LLVMValueRef storage = ptr; + LLVMMetadataRef llvm_debug_loc = lb_debug_location_from_token_pos(p, token.pos); + LLVMMetadataRef llvm_expr = LLVMDIBuilderCreateExpression(m->debug_builder, nullptr, 0); + lb_set_llvm_metadata(m, ptr, llvm_expr); + + // NOTE(bill, 2022-02-01): For parameter values, you must insert them at the end of the decl block + // The reason is that if the parameter is at index 0 and a pointer, there is not such things as an + // instruction "before" it. + LLVMDIBuilderInsertDbgValueAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block->block); +} + + +void lb_add_debug_param_variable_indirect(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token, unsigned arg_number, lbBlock *block) { if (p->debug_info == nullptr) { return; } diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 530c08944..0e771fcc0 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -552,7 +552,7 @@ void lb_begin_procedure_body(lbProcedure *p) { if (original_value != value && LLVMIsALoadInst(value)) { debug_storage_value = LLVMGetOperand(value, 0); } - lb_add_debug_param_variable(p, debug_storage_value, e->type, e->token, param_index+1, block); + lb_add_debug_param_variable_direct(p, debug_storage_value, e->type, e->token, param_index+1, block); } } else if (arg_type->kind == lbArg_Indirect) { if (e->token.string.len != 0 && !is_blank_ident(e->token.string)) { @@ -560,7 +560,7 @@ void lb_begin_procedure_body(lbProcedure *p) { ptr.value = LLVMGetParam(p->value, param_offset+param_index); ptr.type = alloc_type_pointer(e->type); lb_add_entity(p->module, e, ptr); - lb_add_debug_param_variable(p, ptr.value, e->type, e->token, param_index+1, p->decl_block); + lb_add_debug_param_variable_indirect(p, ptr.value, e->type, e->token, param_index+1, p->decl_block); } } } From 913e8b2e02ea278235cade2c02c2ddae40e8470d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 10 Sep 2022 10:03:51 +0100 Subject: [PATCH 3/5] Unify debug parameter code --- src/llvm_backend_debug.cpp | 75 ++++---------------------------------- src/llvm_backend_proc.cpp | 4 +- 2 files changed, 10 insertions(+), 69 deletions(-) diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index a793aaa6d..ee2e03739 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -980,8 +980,7 @@ void lb_add_debug_local_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, T LLVMDIBuilderInsertDeclareAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block); } - -void lb_add_debug_param_variable_direct(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token, unsigned arg_number, lbBlock *block) { +void lb_add_debug_param_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token, unsigned arg_number, lbBlock *block, lbArgKind arg_kind) { if (p->debug_info == nullptr) { return; } @@ -1042,73 +1041,15 @@ void lb_add_debug_param_variable_direct(lbProcedure *p, LLVMValueRef ptr, Type * // NOTE(bill, 2022-02-01): For parameter values, you must insert them at the end of the decl block // The reason is that if the parameter is at index 0 and a pointer, there is not such things as an // instruction "before" it. - LLVMDIBuilderInsertDbgValueAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block->block); -} - - -void lb_add_debug_param_variable_indirect(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token, unsigned arg_number, lbBlock *block) { - if (p->debug_info == nullptr) { - return; - } - if (type == nullptr) { - return; - } - if (type == t_invalid) { - return; - } - if (p->body == nullptr) { - return; + switch (arg_kind) { + case lbArg_Direct: + LLVMDIBuilderInsertDbgValueAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block->block); + break; + case lbArg_Indirect: + LLVMDIBuilderInsertDeclareAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block->block); + break; } - lbModule *m = p->module; - String const &name = token.string; - if (name == "" || name == "_") { - return; - } - - if (lb_get_llvm_metadata(m, ptr) != nullptr) { - // Already been set - return; - } - - - AstFile *file = p->body->file(); - - LLVMMetadataRef llvm_scope = lb_get_current_debug_scope(p); - LLVMMetadataRef llvm_file = lb_get_llvm_metadata(m, file); - GB_ASSERT(llvm_scope != nullptr); - if (llvm_file == nullptr) { - llvm_file = LLVMDIScopeGetFile(llvm_scope); - } - - if (llvm_file == nullptr) { - return; - } - - LLVMDIFlags flags = LLVMDIFlagZero; - LLVMBool always_preserve = build_context.optimization_level == 0; - - LLVMMetadataRef debug_type = lb_debug_type(m, type); - - LLVMMetadataRef var_info = LLVMDIBuilderCreateParameterVariable( - m->debug_builder, llvm_scope, - cast(char const *)name.text, cast(size_t)name.len, - arg_number, - llvm_file, token.pos.line, - debug_type, - always_preserve, flags - ); - - LLVMValueRef storage = ptr; - LLVMMetadataRef llvm_debug_loc = lb_debug_location_from_token_pos(p, token.pos); - LLVMMetadataRef llvm_expr = LLVMDIBuilderCreateExpression(m->debug_builder, nullptr, 0); - lb_set_llvm_metadata(m, ptr, llvm_expr); - - // NOTE(bill, 2022-02-01): For parameter values, you must insert them at the end of the decl block - // The reason is that if the parameter is at index 0 and a pointer, there is not such things as an - // instruction "before" it. - LLVMDIBuilderInsertDeclareAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block->block); - // LLVMDIBuilderInsertDbgValueAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block->block); } diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 0e771fcc0..17501d657 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -552,7 +552,7 @@ void lb_begin_procedure_body(lbProcedure *p) { if (original_value != value && LLVMIsALoadInst(value)) { debug_storage_value = LLVMGetOperand(value, 0); } - lb_add_debug_param_variable_direct(p, debug_storage_value, e->type, e->token, param_index+1, block); + lb_add_debug_param_variable(p, debug_storage_value, e->type, e->token, param_index+1, block, arg_type->kind); } } else if (arg_type->kind == lbArg_Indirect) { if (e->token.string.len != 0 && !is_blank_ident(e->token.string)) { @@ -560,7 +560,7 @@ void lb_begin_procedure_body(lbProcedure *p) { ptr.value = LLVMGetParam(p->value, param_offset+param_index); ptr.type = alloc_type_pointer(e->type); lb_add_entity(p->module, e, ptr); - lb_add_debug_param_variable_indirect(p, ptr.value, e->type, e->token, param_index+1, p->decl_block); + lb_add_debug_param_variable(p, ptr.value, e->type, e->token, param_index+1, p->decl_block, arg_type->kind); } } } From 183a02c5844a316fae6517fb295bff60dcfb2bc4 Mon Sep 17 00:00:00 2001 From: Ryan Chan <33111856+ryancsh@users.noreply.github.com> Date: Sat, 10 Sep 2022 16:54:34 +0400 Subject: [PATCH 4/5] Add windows.timeGetTime() Here is the windows documentation for it: https://docs.microsoft.com/en-us/windows/win32/api/timeapi/nf-timeapi-timegettime --- core/sys/windows/winmm.odin | 1 + 1 file changed, 1 insertion(+) diff --git a/core/sys/windows/winmm.odin b/core/sys/windows/winmm.odin index 17f4d8e86..64ace19fc 100644 --- a/core/sys/windows/winmm.odin +++ b/core/sys/windows/winmm.odin @@ -7,4 +7,5 @@ foreign import winmm "system:Winmm.lib" foreign winmm { timeBeginPeriod :: proc(uPeriod: UINT) -> MMRESULT --- timeEndPeriod :: proc(uPeriod: UINT) -> MMRESULT --- + timeGetTime :: proc() -> DWORD --- } From 99f4cc30063c76588e666f564ed9a17e35730e45 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Sat, 10 Sep 2022 20:22:10 +0200 Subject: [PATCH 5/5] [core:image/tga] Add tests. --- tests/core/image/test_core_image.odin | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/core/image/test_core_image.odin b/tests/core/image/test_core_image.odin index 171e4674d..bce5c910b 100644 --- a/tests/core/image/test_core_image.odin +++ b/tests/core/image/test_core_image.odin @@ -16,6 +16,7 @@ import "core:image" import pbm "core:image/netpbm" import "core:image/png" import "core:image/qoi" +import "core:image/tga" import "core:bytes" import "core:hash" @@ -1530,6 +1531,28 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) { } } + // Roundtrip through TGA to test the TGA encoder and decoder. + if img.depth == 8 && (img.channels == 3 || img.channels == 4) { + tga_buffer: bytes.Buffer + defer bytes.buffer_destroy(&tga_buffer) + tga_save_err := tga.save(&tga_buffer, img) + + error = fmt.tprintf("%v test %v TGA save failed with %v.", file.file, count, tga_save_err) + expect(t, tga_save_err == nil, error) + + if tga_save_err == nil { + tga_img, tga_load_err := tga.load(tga_buffer.buf[:]) + defer tga.destroy(tga_img) + + error = fmt.tprintf("%v test %v TGA load failed with %v.", file.file, count, tga_load_err) + expect(t, tga_load_err == nil, error) + + tga_hash := hash.crc32(tga_img.pixels.buf[:]) + error = fmt.tprintf("%v test %v TGA load hash is %08x, expected it match PNG's %08x with %v.", file.file, count, tga_hash, png_hash, test.options) + expect(t, tga_hash == png_hash, error) + } + } + { // Roundtrip through PBM to test the PBM encoders and decoders - prefer binary pbm_buf, pbm_save_err := pbm.save_to_buffer(img)