diff --git a/examples/hardware-check/App.zig b/examples/hardware-check/App.zig index c9c0d5a7f4..b2e405321c 100644 --- a/examples/hardware-check/App.zig +++ b/examples/hardware-check/App.zig @@ -346,7 +346,6 @@ fn loadTexture(core: *mach.Core.Mod, allocator: std.mem.Allocator) !*gpu.Texture .usage = .{ .texture_binding = true, .copy_dst = true, - .render_attachment = true, }, }); const data_layout = gpu.Texture.DataLayout{ diff --git a/examples/sprite/App.zig b/examples/sprite/App.zig index 6f668d45f6..ea1b38d859 100644 --- a/examples/sprite/App.zig +++ b/examples/sprite/App.zig @@ -45,11 +45,9 @@ pub const systems = .{ }; fn deinit( - core: *mach.Core.Mod, sprite_pipeline: *gfx.SpritePipeline.Mod, ) !void { sprite_pipeline.schedule(.deinit); - core.schedule(.deinit); } fn init( @@ -268,7 +266,6 @@ fn loadTexture(core: *mach.Core.Mod, allocator: std.mem.Allocator) !*gpu.Texture .usage = .{ .texture_binding = true, .copy_dst = true, - .render_attachment = true, }, }); const data_layout = gpu.Texture.DataLayout{ diff --git a/src/core/win32.zig b/src/core/win32.zig index d94ba69d34..cb93654244 100644 --- a/src/core/win32.zig +++ b/src/core/win32.zig @@ -111,32 +111,46 @@ pub fn init( }); if (w.RegisterClassW(&class) == 0) return error.Unexpected; + // TODO set title , copy to self.title const title = try std.unicode.utf8ToUtf16LeAllocZ(self.allocator, options.title); defer self.allocator.free(title); - // TODO set title , copy to self.title + + var request_window_width:i32 = @bitCast(self.size.width); + var request_window_height:i32 = @bitCast(self.size.height); + + const window_ex_style: w.WINDOW_EX_STYLE = .{.APPWINDOW = 1, .WINDOWEDGE = 1, .CLIENTEDGE = 1}; + const window_style: w.WINDOW_STYLE = if (options.border) w.WS_OVERLAPPEDWINDOW else w.WS_POPUPWINDOW; + + var rect: w.RECT = .{ .left = 0, .top = 0, .right = request_window_width, .bottom = request_window_height}; + + if (w.TRUE == w.AdjustWindowRectEx(&rect, + window_style, + w.FALSE, + window_ex_style)) + { + request_window_width = rect.right - rect.left; + request_window_height = rect.bottom - rect.top; + } const window = w.CreateWindowExW( - .{.APPWINDOW = 1, .WINDOWEDGE = 1, .CLIENTEDGE = 1}, + window_ex_style, class_name, title, - if (options.border) w.WS_OVERLAPPEDWINDOW else w.WS_POPUPWINDOW, + window_style, w.CW_USEDEFAULT, w.CW_USEDEFAULT, - @bitCast(self.size.width), - @bitCast(self.size.height), + request_window_width, + request_window_height, null, null, hInstance, null, ) orelse return error.Unexpected; + self.window = window; var dinput: ?*w.IDirectInput8W = undefined; - //@ptrCast(*anyopaque - const ptr: ?*?*anyopaque = @ptrCast(&dinput); - - // if (w.DirectInput8Create(instance, w.DIRECTINPUT_VERSION, &w.IID_IDirectInput8W, &dinput, null) != w.DI_OK) return error.Unexpected; if (w.DirectInput8Create(hInstance, w.DIRECTINPUT_VERSION, w.IID_IDirectInput8W, ptr, null) != w.DI_OK) { return error.Unexpected; } @@ -157,6 +171,18 @@ pub fn init( if (!options.headless) { setDisplayMode(self, options.display_mode); } + + self.size = getClientRect(self); +} + +pub fn getClientRect(self: *Win32) Size { + var rect: w.RECT = undefined; + _ = w.GetClientRect(self.window, &rect); + + const width:u32 = @intCast(rect.right - rect.left); + const height:u32 = @intCast(rect.bottom - rect.top); + + return .{ .width = width, .height = height }; } pub fn deinit(self: *Win32) void { @@ -206,7 +232,9 @@ pub fn setDisplayMode(self: *Win32, mode: DisplayMode) void { } pub fn setBorder(self: *Win32, value: bool) void { - _ = w.SetWindowLongW(self.window, w.GWL_STYLE, if (value) w.WS_OVERLAPPEDWINDOW else w.WS_POPUPWINDOW); + const overlappedwindow: i32 = @bitCast(w.WS_OVERLAPPEDWINDOW); + const popupwindow: i32 = @bitCast(w.WS_POPUPWINDOW); + _ = w.SetWindowLongW(self.window, w.GWL_STYLE, if (value) overlappedwindow else popupwindow); self.border = value; } @@ -220,7 +248,15 @@ pub fn setVSync(self: *Win32, mode: VSyncMode) void { } pub fn setSize(self: *Win32, value: Size) void { - _ = w.SetWindowPos(self.window, 0, 0, 0, value.width, value.height, w.SWP_NOMOVE | w.SWP_NOZORDER | w.SWP_NOACTIVATE); + // TODO - use AdjustClientRect to get correct client rect. + _ = w.SetWindowPos(self.window, + null, + 0, + 0, + @as(i32, @intCast(value.width)), + @as(i32, @intCast(value.height)), + w.SET_WINDOW_POS_FLAGS{.NOMOVE = 1, .NOZORDER = 1, .NOACTIVATE = 1} + ); self.size = value; } // pub fn size(self: *Core) core.Size { @@ -249,15 +285,15 @@ pub fn setSize(self: *Win32, value: Size) void { pub fn setCursorMode(self: *Win32, mode: CursorMode) void { switch (mode) { - .normal => while (w.ShowCursor(true) < 0) {}, - .hidden => while (w.ShowCursor(false) >= 0) {}, + .normal => while (w.ShowCursor(w.TRUE) < 0) {}, + .hidden => while (w.ShowCursor(w.FALSE) >= 0) {}, .disabled => {}, } self.cursor_mode = mode; } pub fn setCursorShape(self: *Win32, shape: CursorShape) void { - const name = switch (shape) { + const name: i32 = switch (shape) { .arrow => w.IDC_ARROW, .ibeam => w.IDC_IBEAM, .crosshair => w.IDC_CROSS, @@ -269,47 +305,42 @@ pub fn setCursorShape(self: *Win32, shape: CursorShape) void { .resize_all => w.IDC_SIZEALL, .not_allowed => w.IDC_NO, }; - _ = w.SetCursor(w.LoadCursorW(null, @ptrFromInt(name))); + _ = w.SetCursor(w.LoadCursorW(null, @ptrFromInt(@as(usize, @intCast(name))))); self.cursor_shape = shape; } pub fn keyPressed(self: *Win32, key: Key) bool { _ = self; _ = key; - // self.input_mutex.lockShared(); - // defer self.input_mutex.unlockShared(); - // return self.input_state.isKeyPressed(key); + // TODO: Not implemented + return false; } pub fn keyReleased(self: *Win32, key: Key) bool { _ = self; _ = key; - // self.input_mutex.lockShared(); - // defer self.input_mutex.unlockShared(); - // return self.input_state.isKeyReleased(key); + // TODO: Not implemented + return false; } pub fn mousePressed(self: *Win32, button: MouseButton) bool { _ = self; _ = button; - // self.input_mutex.lockShared(); - // defer self.input_mutex.unlockShared(); - // return self.input_state.isMouseButtonPressed(button); + // TODO: Not implemented + return false; } pub fn mouseReleased(self: *Win32, button: MouseButton) bool { _ = self; _ = button; - // self.input_mutex.lockShared(); - // defer self.input_mutex.unlockShared(); - // return self.input_state.isMouseButtonReleased(button); + // TODO: Not implemented + return false; } pub fn mousePosition(self: *Win32) Position { _ = self; - // self.input_mutex.lockShared(); - // defer self.input_mutex.unlockShared(); - // return self.input_state.mouse_position; + // TODO: Not implemented + return Position{.x = 0.0, .y = 0.0}; } pub fn outOfMemory(self: *Win32) bool { @@ -321,8 +352,6 @@ pub fn outOfMemory(self: *Win32) bool { } fn pushEvent(self: *Win32, event: Event) void { - //self.event_mutex.lock(); - //defer self.event_mutex.unlock(); self.events.writeItem(event) catch self.oom.set(); } @@ -353,7 +382,7 @@ fn wndProc(wnd: w.HWND, msg: u32, wParam: w.WPARAM, lParam: w.LPARAM) callconv(w // if (self.limits.max.height) |height| info.ptMaxTrackSize.y = @bitCast(height); return 0; }, - w.WM_KEYDOWN, w.WM_KEYUP => { + w.WM_KEYDOWN, w.WM_KEYUP, w.WM_SYSKEYDOWN, w.WM_SYSKEYUP => { const vkey: w.VIRTUAL_KEY = @enumFromInt(wParam); if (vkey == w.VK_PROCESSKEY) return 0; @@ -379,7 +408,7 @@ fn wndProc(wnd: w.HWND, msg: u32, wParam: w.WPARAM, lParam: w.LPARAM) callconv(w } const key = keyFromScancode(scancode); - if (msg == w.WM_KEYDOWN) { + if (msg == w.WM_KEYDOWN or msg == w.WM_SYSKEYDOWN) { if (flags & w.KF_REPEAT == 0) { self.pushEvent(.{ .key_press = .{ .key = key, .mods = undefined } }); } else { @@ -442,11 +471,14 @@ fn wndProc(wnd: w.HWND, msg: u32, wParam: w.WPARAM, lParam: w.LPARAM) callconv(w return if (msg == w.WM_XBUTTONDOWN or msg == w.WM_XBUTTONUP) w.TRUE else 0; }, w.WM_MOUSEMOVE => { + const x:f64 = @floatFromInt(@as(i16, @truncate(lParam & 0xFFFF))); + const y:f64 = @floatFromInt(@as(i16, @truncate((lParam >> 16) & 0xFFFF))); + self.pushEvent(.{ .mouse_motion = .{ .pos = .{ - .x = 0, - .y = 0, + .x = x, + .y = y, }, }, }); diff --git a/src/core/win32/win32.zig b/src/core/win32/win32.zig index a2c1b8b60a..75621caaec 100644 --- a/src/core/win32/win32.zig +++ b/src/core/win32/win32.zig @@ -91,6 +91,26 @@ pub extern "user32" fn GetClientRect( hWnd: ?HWND, lpRect: ?*RECT, ) callconv(@import("std").os.windows.WINAPI) BOOL; +// TODO: this type is limited to platform 'windows5.0' +pub extern "user32" fn GetWindowRect( + hWnd: ?HWND, + lpRect: ?*RECT, +) callconv(@import("std").os.windows.WINAPI) BOOL; + +// TODO: this type is limited to platform 'windows5.0' +pub extern "user32" fn AdjustWindowRect( + lpRect: ?*RECT, + dwStyle: WINDOW_STYLE, + bMenu: BOOL, +) callconv(@import("std").os.windows.WINAPI) BOOL; + +// TODO: this type is limited to platform 'windows5.0' +pub extern "user32" fn AdjustWindowRectEx( + lpRect: ?*RECT, + dwStyle: WINDOW_STYLE, + bMenu: BOOL, + dwExStyle: WINDOW_EX_STYLE, +) callconv(@import("std").os.windows.WINAPI) BOOL; // TODO: this type is limited to platform 'windows5.0' pub extern "user32" fn GetMessageTime() callconv(@import("std").os.windows.WINAPI) i32; @@ -180,19 +200,19 @@ pub const WINDOW_LONG_PTR_INDEX = enum(i32) { // _HWNDPARENT = -8, this enum value conflicts with P_HWNDPARENT _, }; +pub const GWL_EXSTYLE = WINDOW_LONG_PTR_INDEX._EXSTYLE; +pub const GWLP_HINSTANCE = WINDOW_LONG_PTR_INDEX.P_HINSTANCE; +pub const GWLP_HWNDPARENT = WINDOW_LONG_PTR_INDEX.P_HWNDPARENT; +pub const GWLP_ID = WINDOW_LONG_PTR_INDEX.P_ID; +pub const GWL_STYLE = WINDOW_LONG_PTR_INDEX._STYLE; pub const GWLP_USERDATA = WINDOW_LONG_PTR_INDEX.P_USERDATA; +pub const GWLP_WNDPROC = WINDOW_LONG_PTR_INDEX.P_WNDPROC; +pub const GWL_HINSTANCE = WINDOW_LONG_PTR_INDEX.P_HINSTANCE; +pub const GWL_ID = WINDOW_LONG_PTR_INDEX.P_ID; +pub const GWL_USERDATA = WINDOW_LONG_PTR_INDEX.P_USERDATA; +pub const GWL_WNDPROC = WINDOW_LONG_PTR_INDEX.P_WNDPROC; +pub const GWL_HWNDPARENT = WINDOW_LONG_PTR_INDEX.P_HWNDPARENT; -// pub usingnamespace if (@sizeOf(usize) == 8) struct { -// pub const SetWindowLongPtrA = win32.ui.windows_and_messaging.SetWindowLongPtrA; -// pub const SetWindowLongPtrW = win32.ui.windows_and_messaging.SetWindowLongPtrW; -// pub const GetWindowLongPtrA = win32.ui.windows_and_messaging.GetWindowLongPtrA; -// pub const GetWindowLongPtrW = win32.ui.windows_and_messaging.GetWindowLongPtrW; -// } else struct { -// pub const SetWindowLongPtrA = win32.ui.windows_and_messaging.SetWindowLongA; -// pub const SetWindowLongPtrW = win32.ui.windows_and_messaging.SetWindowLongW; -// pub const GetWindowLongPtrA = win32.ui.windows_and_messaging.GetWindowLongA; -// pub const GetWindowLongPtrW = win32.ui.windows_and_messaging.GetWindowLongW; -// }; pub const Arch = enum { X86, X64, Arm64 }; pub const arch: Arch = switch (builtin.target.cpu.arch) { .x86 => .X86, @@ -214,6 +234,21 @@ pub usingnamespace switch (arch) { else => struct {}, }; +// TODO: this type is limited to platform 'windows5.0' +pub extern "user32" fn SetCursor( + hCursor: ?HCURSOR, +) callconv(@import("std").os.windows.WINAPI) ?HCURSOR; + +// TODO: this type is limited to platform 'windows5.0' +pub extern "user32" fn GetCursorPos( + lpPoint: ?*POINT, +) callconv(@import("std").os.windows.WINAPI) BOOL; + +pub extern "user32" fn SetCursorPos( + X: i32, + Y: i32, +) callconv(@import("std").os.windows.WINAPI) BOOL; + //pub usingnamespace switch (@import("../zig.zig").arch) { pub usingnamespace switch (arch) { .X64, .Arm64 => struct { @@ -228,6 +263,75 @@ pub usingnamespace switch (arch) { else => struct {}, }; +pub extern "user32" fn SetWindowLongW( + hWnd: ?HWND, + nIndex: WINDOW_LONG_PTR_INDEX, + dwNewLong: i32, +) callconv(@import("std").os.windows.WINAPI) i32; + +//pub extern "user32" fn SetWindowPos(hWnd: HWND, hWndInsertAfter: HWND, X: i32, Y: i32, cx: i32, cy: i32, uFlags: u32) callconv(WINAPI) BOOL; +pub extern "user32" fn SetWindowPos( + hWnd: ?HWND, + hWndInsertAfter: ?HWND, + X: i32, + Y: i32, + cx: i32, + cy: i32, + uFlags: SET_WINDOW_POS_FLAGS, +) callconv(@import("std").os.windows.WINAPI) BOOL; + +pub const SET_WINDOW_POS_FLAGS = packed struct(u32) { + NOSIZE: u1 = 0, + NOMOVE: u1 = 0, + NOZORDER: u1 = 0, + NOREDRAW: u1 = 0, + NOACTIVATE: u1 = 0, + DRAWFRAME: u1 = 0, + SHOWWINDOW: u1 = 0, + HIDEWINDOW: u1 = 0, + NOCOPYBITS: u1 = 0, + NOOWNERZORDER: u1 = 0, + NOSENDCHANGING: u1 = 0, + _11: u1 = 0, + _12: u1 = 0, + DEFERERASE: u1 = 0, + ASYNCWINDOWPOS: u1 = 0, + _15: u1 = 0, + _16: u1 = 0, + _17: u1 = 0, + _18: u1 = 0, + _19: u1 = 0, + _20: u1 = 0, + _21: u1 = 0, + _22: u1 = 0, + _23: u1 = 0, + _24: u1 = 0, + _25: u1 = 0, + _26: u1 = 0, + _27: u1 = 0, + _28: u1 = 0, + _29: u1 = 0, + _30: u1 = 0, + _31: u1 = 0, + // FRAMECHANGED (bit index 5) conflicts with DRAWFRAME + // NOREPOSITION (bit index 9) conflicts with NOOWNERZORDER +}; +pub const SWP_ASYNCWINDOWPOS = SET_WINDOW_POS_FLAGS{ .ASYNCWINDOWPOS = 1 }; +pub const SWP_DEFERERASE = SET_WINDOW_POS_FLAGS{ .DEFERERASE = 1 }; +pub const SWP_DRAWFRAME = SET_WINDOW_POS_FLAGS{ .DRAWFRAME = 1 }; +pub const SWP_FRAMECHANGED = SET_WINDOW_POS_FLAGS{ .DRAWFRAME = 1 }; +pub const SWP_HIDEWINDOW = SET_WINDOW_POS_FLAGS{ .HIDEWINDOW = 1 }; +pub const SWP_NOACTIVATE = SET_WINDOW_POS_FLAGS{ .NOACTIVATE = 1 }; +pub const SWP_NOCOPYBITS = SET_WINDOW_POS_FLAGS{ .NOCOPYBITS = 1 }; +pub const SWP_NOMOVE = SET_WINDOW_POS_FLAGS{ .NOMOVE = 1 }; +pub const SWP_NOOWNERZORDER = SET_WINDOW_POS_FLAGS{ .NOOWNERZORDER = 1 }; +pub const SWP_NOREDRAW = SET_WINDOW_POS_FLAGS{ .NOREDRAW = 1 }; +pub const SWP_NOREPOSITION = SET_WINDOW_POS_FLAGS{ .NOOWNERZORDER = 1 }; +pub const SWP_NOSENDCHANGING = SET_WINDOW_POS_FLAGS{ .NOSENDCHANGING = 1 }; +pub const SWP_NOSIZE = SET_WINDOW_POS_FLAGS{ .NOSIZE = 1 }; +pub const SWP_NOZORDER = SET_WINDOW_POS_FLAGS{ .NOZORDER = 1 }; +pub const SWP_SHOWWINDOW = SET_WINDOW_POS_FLAGS{ .SHOWWINDOW = 1 }; + // TODO: this type is limited to platform 'windows5.0' pub extern "user32" fn SetWindowTextW( hWnd: ?HWND, @@ -678,491 +782,6 @@ pub const IDirectInputDevice8W = extern struct { } }; -// const IID_IDirectInputDevice8W_Value = Guid.initString("54d41081-dc15-4833-a41b-748f73a38179"); -// pub const IID_IDirectInputDevice8W = &IID_IDirectInputDevice8W_Value; -// pub const IDirectInputDevice8W = extern struct { -// pub const VTable = extern struct { -// base: IUnknown.VTable, -// GetCapabilities: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*DIDEVCAPS, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*DIDEVCAPS, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// EnumObjects: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?LPDIENUMDEVICEOBJECTSCALLBACKW, -// param1: ?*anyopaque, -// param2: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?LPDIENUMDEVICEOBJECTSCALLBACKW, -// param1: ?*anyopaque, -// param2: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// GetProperty: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*const Guid, -// param1: ?*DIPROPHEADER, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*const Guid, -// param1: ?*DIPROPHEADER, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// SetProperty: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*const Guid, -// param1: ?*DIPROPHEADER, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*const Guid, -// param1: ?*DIPROPHEADER, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// Acquire: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// Unacquire: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// GetDeviceState: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: u32, -// param1: ?*anyopaque, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: u32, -// param1: ?*anyopaque, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// GetDeviceData: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: u32, -// param1: ?*DIDEVICEOBJECTDATA, -// param2: ?*u32, -// param3: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: u32, -// param1: ?*DIDEVICEOBJECTDATA, -// param2: ?*u32, -// param3: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// SetDataFormat: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*DIDATAFORMAT, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*DIDATAFORMAT, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// SetEventNotification: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?HANDLE, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?HANDLE, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// SetCooperativeLevel: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?HWND, -// param1: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?HWND, -// param1: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// GetObjectInfo: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*DIDEVICEOBJECTINSTANCEW, -// param1: u32, -// param2: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*DIDEVICEOBJECTINSTANCEW, -// param1: u32, -// param2: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// GetDeviceInfo: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*DIDEVICEINSTANCEW, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*DIDEVICEINSTANCEW, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// RunControlPanel: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?HWND, -// param1: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?HWND, -// param1: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// Initialize: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?HINSTANCE, -// param1: u32, -// param2: ?*const Guid, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?HINSTANCE, -// param1: u32, -// param2: ?*const Guid, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// CreateEffect: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*const Guid, -// param1: ?*DIEFFECT, -// param2: ?*?*IDirectInputEffect, -// param3: ?*IUnknown, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*const Guid, -// param1: ?*DIEFFECT, -// param2: ?*?*IDirectInputEffect, -// param3: ?*IUnknown, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// EnumEffects: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?LPDIENUMEFFECTSCALLBACKW, -// param1: ?*anyopaque, -// param2: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?LPDIENUMEFFECTSCALLBACKW, -// param1: ?*anyopaque, -// param2: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// GetEffectInfo: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*DIEFFECTINFOW, -// param1: ?*const Guid, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*DIEFFECTINFOW, -// param1: ?*const Guid, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// GetForceFeedbackState: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// SendForceFeedbackCommand: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// EnumCreatedEffectObjects: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?LPDIENUMCREATEDEFFECTOBJECTSCALLBACK, -// param1: ?*anyopaque, -// param2: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?LPDIENUMCREATEDEFFECTOBJECTSCALLBACK, -// param1: ?*anyopaque, -// param2: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// Escape: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*DIEFFESCAPE, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*DIEFFESCAPE, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// Poll: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// SendDeviceData: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: u32, -// param1: ?*DIDEVICEOBJECTDATA, -// param2: ?*u32, -// param3: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: u32, -// param1: ?*DIDEVICEOBJECTDATA, -// param2: ?*u32, -// param3: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// EnumEffectsInFile: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?[*:0]const u16, -// param1: ?LPDIENUMEFFECTSINFILECALLBACK, -// param2: ?*anyopaque, -// param3: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?[*:0]const u16, -// param1: ?LPDIENUMEFFECTSINFILECALLBACK, -// param2: ?*anyopaque, -// param3: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// WriteEffectToFile: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?[*:0]const u16, -// param1: u32, -// param2: ?*DIFILEEFFECT, -// param3: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?[*:0]const u16, -// param1: u32, -// param2: ?*DIFILEEFFECT, -// param3: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// BuildActionMap: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*DIACTIONFORMATW, -// param1: ?[*:0]const u16, -// param2: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*DIACTIONFORMATW, -// param1: ?[*:0]const u16, -// param2: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// SetActionMap: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*DIACTIONFORMATW, -// param1: ?[*:0]const u16, -// param2: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*DIACTIONFORMATW, -// param1: ?[*:0]const u16, -// param2: u32, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// GetImageInfo: switch (@import("builtin").zig_backend) { -// .stage1 => fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*DIDEVICEIMAGEINFOHEADERW, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// else => *const fn ( -// self: *const IDirectInputDevice8W, -// param0: ?*DIDEVICEIMAGEINFOHEADERW, -// ) callconv(@import("std").os.windows.WINAPI) HRESULT, -// }, -// }; -// vtable: *const VTable, -// pub fn MethodMixin(comptime T: type) type { -// return struct { -// pub usingnamespace IUnknown.MethodMixin(T); -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_GetCapabilities(self: *const T, param0: ?*DIDEVCAPS) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).GetCapabilities(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_EnumObjects(self: *const T, param0: ?LPDIENUMDEVICEOBJECTSCALLBACKW, param1: ?*anyopaque, param2: u32) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).EnumObjects(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0, param1, param2); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_GetProperty(self: *const T, param0: ?*const Guid, param1: ?*DIPROPHEADER) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).GetProperty(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0, param1); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_SetProperty(self: *const T, param0: ?*const Guid, param1: ?*DIPROPHEADER) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).SetProperty(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0, param1); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_Acquire(self: *const T) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).Acquire(@as(*const IDirectInputDevice8W, @ptrCast(self))); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_Unacquire(self: *const T) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).Unacquire(@as(*const IDirectInputDevice8W, @ptrCast(self))); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_GetDeviceState(self: *const T, param0: u32, param1: ?*anyopaque) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).GetDeviceState(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0, param1); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_GetDeviceData(self: *const T, param0: u32, param1: ?*DIDEVICEOBJECTDATA, param2: ?*u32, param3: u32) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).GetDeviceData(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0, param1, param2, param3); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_SetDataFormat(self: *const T, param0: ?*DIDATAFORMAT) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).SetDataFormat(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_SetEventNotification(self: *const T, param0: ?HANDLE) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).SetEventNotification(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_SetCooperativeLevel(self: *const T, param0: ?HWND, param1: u32) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).SetCooperativeLevel(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0, param1); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_GetObjectInfo(self: *const T, param0: ?*DIDEVICEOBJECTINSTANCEW, param1: u32, param2: u32) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).GetObjectInfo(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0, param1, param2); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_GetDeviceInfo(self: *const T, param0: ?*DIDEVICEINSTANCEW) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).GetDeviceInfo(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_RunControlPanel(self: *const T, param0: ?HWND, param1: u32) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).RunControlPanel(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0, param1); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_Initialize(self: *const T, param0: ?HINSTANCE, param1: u32, param2: ?*const Guid) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).Initialize(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0, param1, param2); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_CreateEffect(self: *const T, param0: ?*const Guid, param1: ?*DIEFFECT, param2: ?*?*IDirectInputEffect, param3: ?*IUnknown) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).CreateEffect(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0, param1, param2, param3); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_EnumEffects(self: *const T, param0: ?LPDIENUMEFFECTSCALLBACKW, param1: ?*anyopaque, param2: u32) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).EnumEffects(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0, param1, param2); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_GetEffectInfo(self: *const T, param0: ?*DIEFFECTINFOW, param1: ?*const Guid) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).GetEffectInfo(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0, param1); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_GetForceFeedbackState(self: *const T, param0: ?*u32) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).GetForceFeedbackState(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_SendForceFeedbackCommand(self: *const T, param0: u32) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).SendForceFeedbackCommand(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_EnumCreatedEffectObjects(self: *const T, param0: ?LPDIENUMCREATEDEFFECTOBJECTSCALLBACK, param1: ?*anyopaque, param2: u32) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).EnumCreatedEffectObjects(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0, param1, param2); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_Escape(self: *const T, param0: ?*DIEFFESCAPE) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).Escape(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_Poll(self: *const T) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).Poll(@as(*const IDirectInputDevice8W, @ptrCast(self))); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_SendDeviceData(self: *const T, param0: u32, param1: ?*DIDEVICEOBJECTDATA, param2: ?*u32, param3: u32) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).SendDeviceData(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0, param1, param2, param3); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_EnumEffectsInFile(self: *const T, param0: ?[*:0]const u16, param1: ?LPDIENUMEFFECTSINFILECALLBACK, param2: ?*anyopaque, param3: u32) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).EnumEffectsInFile(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0, param1, param2, param3); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_WriteEffectToFile(self: *const T, param0: ?[*:0]const u16, param1: u32, param2: ?*DIFILEEFFECT, param3: u32) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).WriteEffectToFile(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0, param1, param2, param3); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_BuildActionMap(self: *const T, param0: ?*DIACTIONFORMATW, param1: ?[*:0]const u16, param2: u32) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).BuildActionMap(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0, param1, param2); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_SetActionMap(self: *const T, param0: ?*DIACTIONFORMATW, param1: ?[*:0]const u16, param2: u32) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).SetActionMap(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0, param1, param2); -// } -// // NOTE: method is namespaced with interface name to avoid conflicts for now -// pub inline fn IDirectInputDevice8W_GetImageInfo(self: *const T, param0: ?*DIDEVICEIMAGEINFOHEADERW) HRESULT { -// return @as(*const IDirectInputDevice8W.VTable, @ptrCast(self.vtable)).GetImageInfo(@as(*const IDirectInputDevice8W, @ptrCast(self)), param0); -// } -// }; -// } -// pub usingnamespace MethodMixin(@This()); -// }; - pub const DIACTIONFORMATW = extern struct { dwSize: u32, dwActionSize: u32, @@ -1580,6 +1199,19 @@ pub extern "user32" fn LoadIconW( ) callconv(@import("std").os.windows.WINAPI) ?HICON; pub const IDC_ARROW = 32512; +pub const IDC_HAND = 32649; +pub const IDC_HELP = 32651; +pub const IDC_IBEAM = 32513; +pub const IDC_ICON = 32641; +pub const IDC_CROSS = 32515; +pub const IDC_SIZE = 32640; +pub const IDC_SIZEALL = 32646; +pub const IDC_SIZENESW = 32643; +pub const IDC_SIZENS = 32645; +pub const IDC_SIZENWSE = 32642; +pub const IDC_SIZEWE = 32644; +pub const IDC_NO = 32648; + pub extern "user32" fn LoadCursorW( hInstance: ?HINSTANCE, lpCursorName: ?[*:0]align(1) const u16, @@ -1754,6 +1386,10 @@ pub extern "user32" fn CreateWindowExW( lpParam: ?*anyopaque, ) callconv(@import("std").os.windows.WINAPI) ?HWND; +pub extern "user32" fn ShowCursor( + bShow: BOOL, +) callconv(@import("std").os.windows.WINAPI) i32; + // TODO: this type is limited to platform 'windows5.0' pub extern "user32" fn ShowWindow( hWnd: ?HWND, @@ -2661,4 +2297,4 @@ pub const VK_PLAY = VIRTUAL_KEY.PLAY; pub const VK_ZOOM = VIRTUAL_KEY.ZOOM; pub const VK_NONAME = VIRTUAL_KEY.NONAME; pub const VK_PA1 = VIRTUAL_KEY.PA1; -pub const VK_OEM_CLEAR = VIRTUAL_KEY.OEM_CLEAR; +pub const VK_OEM_CLEAR = VIRTUAL_KEY.OEM_CLEAR; \ No newline at end of file diff --git a/src/gfx/TextPipeline.zig b/src/gfx/TextPipeline.zig index fecd4e97c2..9c7875df32 100644 --- a/src/gfx/TextPipeline.zig +++ b/src/gfx/TextPipeline.zig @@ -237,7 +237,6 @@ fn buildPipeline( .usage = .{ .texture_binding = true, .copy_dst = true, - .render_attachment = true, }, }); const texture_atlas = try gfx.Atlas.init( diff --git a/src/sysgpu/d3d12.zig b/src/sysgpu/d3d12.zig index e9d4ec25b8..fde2b0a22f 100644 --- a/src/sysgpu/d3d12.zig +++ b/src/sysgpu/d3d12.zig @@ -169,54 +169,108 @@ pub const Adapter = struct { dxgi_adapter: *c.IDXGIAdapter1, d3d_device: *c.ID3D12Device, dxgi_desc: c.DXGI_ADAPTER_DESC1, + description: [256:0]u8 = undefined, + adapter_type: sysgpu.Adapter.Type = .unknown, pub fn init(instance: *Instance, options: *const sysgpu.RequestAdapterOptions) !*Adapter { - // TODO - choose appropriate device from options - _ = options; + var last_adapter_type: sysgpu.Adapter.Type = .unknown; const dxgi_factory = instance.dxgi_factory; var hr: c.HRESULT = undefined; var i: u32 = 0; var dxgi_adapter: *c.IDXGIAdapter1 = undefined; + var dxgi_desc: c.DXGI_ADAPTER_DESC1 = undefined; + var last_dxgi_adapter: ?*c.IDXGIAdapter1 = null; + var last_dxgi_desc: c.DXGI_ADAPTER_DESC1 = undefined; + while (dxgi_factory.lpVtbl.*.EnumAdapters1.?( dxgi_factory, i, @ptrCast(&dxgi_adapter), ) != c.DXGI_ERROR_NOT_FOUND) : (i += 1) { - defer _ = dxgi_adapter.lpVtbl.*.Release.?(dxgi_adapter); - - var dxgi_desc: c.DXGI_ADAPTER_DESC1 = undefined; hr = dxgi_adapter.lpVtbl.*.GetDesc1.?( dxgi_adapter, &dxgi_desc, ); - std.debug.assert(hr == c.S_OK); + var description: [256:0]u8 = undefined; + const l = try std.unicode.utf16LeToUtf8(&description, &dxgi_desc.Description); + description[l] = 0; + + if ((dxgi_desc.Flags & c.DXGI_ADAPTER_FLAG_SOFTWARE) != 0) { + _ = dxgi_adapter.lpVtbl.*.Release.?(dxgi_adapter); + continue; + } - if ((dxgi_desc.Flags & c.DXGI_ADAPTER_FLAG_SOFTWARE) != 0) + const adapter_type: sysgpu.Adapter.Type = blk: { + var d3d_device: *c.ID3D12Device = undefined; + hr = c.D3D12CreateDevice( + @ptrCast(dxgi_adapter), + c.D3D_FEATURE_LEVEL_11_0, + &c.IID_ID3D12Device, + @ptrCast(&d3d_device), + ); + if (hr == c.S_OK) { + defer _ = d3d_device.lpVtbl.*.Release.?(d3d_device); + + var arch = c.D3D12_FEATURE_DATA_ARCHITECTURE{}; + _ = d3d_device.lpVtbl.*.CheckFeatureSupport.?(d3d_device, c.D3D12_FEATURE_ARCHITECTURE, &arch, @sizeOf(@TypeOf(arch))); + if (arch.UMA == 0) { + break :blk .discrete_gpu; + } else { + break :blk .integrated_gpu; + } + } + break :blk .unknown; + }; + + if (last_dxgi_adapter == null) { + last_dxgi_adapter = dxgi_adapter; + last_dxgi_desc = dxgi_desc; + last_adapter_type = adapter_type; continue; + } + + // Select the last discrete_gpu if power preference is high performance. + // Select the last integrated_gpu if power preference is not high performance. + // TOOD: Other selection criterias? + if ((options.power_preference == .high_performance and adapter_type == .discrete_gpu) + or (options.power_preference == .low_power and adapter_type != .discrete_gpu)) { + if (last_dxgi_adapter) |adapter| { + _ = adapter.lpVtbl.*.Release.?(adapter); + } + last_dxgi_adapter = dxgi_adapter; + last_dxgi_desc = dxgi_desc; + last_adapter_type = adapter_type; + } + } + if (last_dxgi_adapter) |selected_adapter| { var d3d_device: *c.ID3D12Device = undefined; hr = c.D3D12CreateDevice( - @ptrCast(dxgi_adapter), + @ptrCast(selected_adapter), c.D3D_FEATURE_LEVEL_11_0, &c.IID_ID3D12Device, @ptrCast(&d3d_device), ); if (hr == c.S_OK) { - _ = dxgi_adapter.lpVtbl.*.AddRef.?(dxgi_adapter); + _ = selected_adapter.lpVtbl.*.AddRef.?(selected_adapter); - const adapter = try allocator.create(Adapter); + var adapter = try allocator.create(Adapter); adapter.* = .{ .instance = instance, - .dxgi_adapter = dxgi_adapter, + .dxgi_adapter = selected_adapter, .d3d_device = d3d_device, - .dxgi_desc = dxgi_desc, + .dxgi_desc = last_dxgi_desc, + .adapter_type = last_adapter_type, }; + const l = try std.unicode.utf16LeToUtf8(&adapter.description, &last_dxgi_desc.Description); + adapter.description[l] = 0; return adapter; } } + return error.NoAdapterFound; } @@ -233,16 +287,15 @@ pub const Adapter = struct { } pub fn getProperties(adapter: *Adapter) sysgpu.Adapter.Properties { - const dxgi_desc = adapter.dxgi_desc; - + const dxgi_desc = adapter.dxgi_desc; return .{ .vendor_id = dxgi_desc.VendorId, .vendor_name = "", // TODO .architecture = "", // TODO .device_id = dxgi_desc.DeviceId, - .name = "", // TODO - wide to ascii - dxgi_desc.Description + .name = &adapter.description, .driver_description = "", // TODO - .adapter_type = .unknown, + .adapter_type = adapter.adapter_type, .backend_type = .d3d12, .compatibility_mode = .false, }; @@ -287,6 +340,9 @@ pub const Device = struct { streaming_manager: StreamingManager = undefined, reference_trackers: std.ArrayListUnmanaged(*ReferenceTracker) = .{}, mem_allocator: MemoryAllocator = undefined, + + mem_allocator_textures: MemoryAllocator = undefined, + map_callbacks: std.ArrayListUnmanaged(MapCallback) = .{}, lost_cb: ?sysgpu.Device.LostCallback = null, @@ -409,6 +465,9 @@ pub const Device = struct { try device.mem_allocator.init(device); + try device.mem_allocator_textures.init(device); + + return device; } @@ -698,8 +757,7 @@ pub const MemoryAllocator = struct { .rtv_dsv_texture => c.D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES, .other_texture => c.D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES, }, - }; - + }; var heap: ?*c.ID3D12Heap = null; const d3d_device = group.owning_pool.device.d3d_device; const hr = d3d_device.lpVtbl.*.CreateHeap.?( @@ -1013,6 +1071,8 @@ pub const MemoryAllocator = struct { 1, @ptrCast(desc.resource_desc), ); + // TODO: If size in bytes == UINT64_MAX then an error occured + break :blk AllocationCreateDescriptor{ .location = desc.location, .size = allocation_info.*.SizeInBytes, @@ -1676,7 +1736,8 @@ pub const Texture = struct { &clear_value else null, - .resource_category = .buffer, + // TODO: #1225: check if different textures need different resource categories. + .resource_category = .other_texture, .initial_state = initial_state, }; const resource = device.mem_allocator.createResource(&create_desc) catch