WSI is finally working
This commit is contained in:
@@ -76,6 +76,7 @@ pub fn build(b: *std.Build) !void {
|
|||||||
|
|
||||||
if (builtin.target.os.tag == .linux) {
|
if (builtin.target.os.tag == .linux) {
|
||||||
base_c_includes.link_libc = true;
|
base_c_includes.link_libc = true;
|
||||||
|
base_c_includes.defineCMacroRaw("STROLL_ENABLE_WAYLAND");
|
||||||
}
|
}
|
||||||
|
|
||||||
base_mod.addImport("base_c", base_c_includes.createModule());
|
base_mod.addImport("base_c", base_c_includes.createModule());
|
||||||
|
|||||||
@@ -25,11 +25,9 @@ fn castExtension(comptime ext: vk.ApiInfo) vk.ExtensionProperties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub const EXTENSIONS = [_]vk.ExtensionProperties{
|
pub const EXTENSIONS = [_]vk.ExtensionProperties{
|
||||||
//castExtension(vk.extensions.lunarg_direct_driver_loading),
|
|
||||||
castExtension(vk.extensions.khr_get_physical_device_properties_2),
|
castExtension(vk.extensions.khr_get_physical_device_properties_2),
|
||||||
castExtension(vk.extensions.khr_surface),
|
castExtension(vk.extensions.khr_surface),
|
||||||
castExtension(vk.extensions.khr_wayland_surface),
|
castExtension(vk.extensions.khr_wayland_surface),
|
||||||
castExtension(vk.extensions.khr_swapchain),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn create(allocator: std.mem.Allocator, infos: *const vk.InstanceCreateInfo) VkError!*Interface {
|
pub fn create(allocator: std.mem.Allocator, infos: *const vk.InstanceCreateInfo) VkError!*Interface {
|
||||||
|
|||||||
@@ -13,6 +13,19 @@ const SurfaceKHR = base.SurfaceKHR;
|
|||||||
const Self = @This();
|
const Self = @This();
|
||||||
pub const Interface = base.PhysicalDevice;
|
pub const Interface = base.PhysicalDevice;
|
||||||
|
|
||||||
|
fn castExtension(comptime ext: vk.ApiInfo) vk.ExtensionProperties {
|
||||||
|
var props: vk.ExtensionProperties = .{
|
||||||
|
.extension_name = @splat(0),
|
||||||
|
.spec_version = @bitCast(ext.version),
|
||||||
|
};
|
||||||
|
@memcpy(props.extension_name[0..ext.name.len], ext.name);
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
const EXTENSIONS = [_]vk.ExtensionProperties{
|
||||||
|
castExtension(vk.extensions.khr_swapchain),
|
||||||
|
};
|
||||||
|
|
||||||
// Device name should always be the same so avoid reprocessing it multiple times
|
// Device name should always be the same so avoid reprocessing it multiple times
|
||||||
var device_name: [vk.MAX_PHYSICAL_DEVICE_NAME_SIZE]u8 = @splat(0);
|
var device_name: [vk.MAX_PHYSICAL_DEVICE_NAME_SIZE]u8 = @splat(0);
|
||||||
|
|
||||||
@@ -31,6 +44,7 @@ pub fn create(allocator: std.mem.Allocator, instance: *base.Instance) VkError!*S
|
|||||||
.getFormatProperties = getFormatProperties,
|
.getFormatProperties = getFormatProperties,
|
||||||
.getImageFormatProperties = getImageFormatProperties,
|
.getImageFormatProperties = getImageFormatProperties,
|
||||||
.getSparseImageFormatProperties = getSparseImageFormatProperties,
|
.getSparseImageFormatProperties = getSparseImageFormatProperties,
|
||||||
|
.enumerateExtensionProperties = enumerateExtensionProperties,
|
||||||
.release = destroy,
|
.release = destroy,
|
||||||
|
|
||||||
// VK_KHR_get_physical_device_properties_2
|
// VK_KHR_get_physical_device_properties_2
|
||||||
@@ -234,6 +248,19 @@ pub fn createDevice(interface: *Interface, allocator: std.mem.Allocator, infos:
|
|||||||
return &device.interface;
|
return &device.interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn enumerateExtensionProperties(_: *const Interface, layer_name: ?[]const u8, count: *u32, p_properties: ?[*]vk.ExtensionProperties) VkError!void {
|
||||||
|
if (layer_name) |_| {
|
||||||
|
return VkError.LayerNotPresent;
|
||||||
|
}
|
||||||
|
|
||||||
|
count.* = EXTENSIONS.len;
|
||||||
|
if (p_properties) |properties| {
|
||||||
|
for (EXTENSIONS, properties[0..]) |ext, *prop| {
|
||||||
|
prop.* = ext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn getFormatProperties(interface: *Interface, format: vk.Format) VkError!vk.FormatProperties {
|
pub fn getFormatProperties(interface: *Interface, format: vk.Format) VkError!vk.FormatProperties {
|
||||||
_ = interface;
|
_ = interface;
|
||||||
var properties: vk.FormatProperties = .{};
|
var properties: vk.FormatProperties = .{};
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ pub fn bindMemory(self: *Self, memory: *DeviceMemory, offset: vk.DeviceSize) VkE
|
|||||||
|
|
||||||
pub fn getMemoryRequirements(self: *Self, requirements: *vk.MemoryRequirements) VkError!void {
|
pub fn getMemoryRequirements(self: *Self, requirements: *vk.MemoryRequirements) VkError!void {
|
||||||
requirements.size = try self.getTotalSize();
|
requirements.size = try self.getTotalSize();
|
||||||
requirements.memory_type_bits = self.allowed_memory_types.mask;
|
requirements.memory_type_bits = 0;
|
||||||
try self.vtable.getMemoryRequirements(self, requirements);
|
try self.vtable.getMemoryRequirements(self, requirements);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ pub fn enumerateExtensionProperties(layer_name: ?[]const u8, count: *u32, p_prop
|
|||||||
return VkError.LayerNotPresent;
|
return VkError.LayerNotPresent;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (comptime @hasDecl(root, "Instance") and @hasDecl(root.Instance, "EXTENSIONS")) {
|
if (comptime !builtin.is_test and @hasDecl(root.Instance, "EXTENSIONS")) {
|
||||||
count.* = root.Instance.EXTENSIONS.len;
|
count.* = root.Instance.EXTENSIONS.len;
|
||||||
if (p_properties) |properties| {
|
if (p_properties) |properties| {
|
||||||
for (root.Instance.EXTENSIONS, properties[0..]) |ext, *prop| {
|
for (root.Instance.EXTENSIONS, properties[0..]) |ext, *prop| {
|
||||||
|
|||||||
@@ -39,10 +39,6 @@ pub fn NonDispatchable(comptime T: type) type {
|
|||||||
return @enumFromInt(@intFromPtr(self));
|
return @enumFromInt(@intFromPtr(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fromObject(object: *T) *Self {
|
|
||||||
return @alignCast(@constCast(@fieldParentPtr("object", &object)));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn fromHandle(vk_handle: anytype) VkError!*Self {
|
pub fn fromHandle(vk_handle: anytype) VkError!*Self {
|
||||||
const handle = @intFromEnum(vk_handle);
|
const handle = @intFromEnum(vk_handle);
|
||||||
if (handle == 0) {
|
if (handle == 0) {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ pub const DispatchTable = struct {
|
|||||||
getFormatProperties: *const fn (*Self, vk.Format) VkError!vk.FormatProperties,
|
getFormatProperties: *const fn (*Self, vk.Format) VkError!vk.FormatProperties,
|
||||||
getImageFormatProperties: *const fn (*Self, vk.Format, vk.ImageType, vk.ImageTiling, vk.ImageUsageFlags, vk.ImageCreateFlags) VkError!vk.ImageFormatProperties,
|
getImageFormatProperties: *const fn (*Self, vk.Format, vk.ImageType, vk.ImageTiling, vk.ImageUsageFlags, vk.ImageCreateFlags) VkError!vk.ImageFormatProperties,
|
||||||
getSparseImageFormatProperties: *const fn (*Self, vk.Format, vk.ImageType, vk.SampleCountFlags, vk.ImageTiling, vk.ImageUsageFlags, ?[*]vk.SparseImageFormatProperties) VkError!u32,
|
getSparseImageFormatProperties: *const fn (*Self, vk.Format, vk.ImageType, vk.SampleCountFlags, vk.ImageTiling, vk.ImageUsageFlags, ?[*]vk.SparseImageFormatProperties) VkError!u32,
|
||||||
|
enumerateExtensionProperties: *const fn (*const Self, ?[]const u8, *u32, ?[*]vk.ExtensionProperties) VkError!void,
|
||||||
release: *const fn (*Self, std.mem.Allocator) VkError!void,
|
release: *const fn (*Self, std.mem.Allocator) VkError!void,
|
||||||
|
|
||||||
// VK_KHR_get_physical_device_properties_2
|
// VK_KHR_get_physical_device_properties_2
|
||||||
@@ -66,6 +67,10 @@ pub inline fn getFormatProperties(self: *Self, format: vk.Format) VkError!vk.For
|
|||||||
return try self.dispatch_table.getFormatProperties(self, format);
|
return try self.dispatch_table.getFormatProperties(self, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub inline fn enumerateExtensionProperties(self: *const Self, layer_name: ?[]const u8, count: *u32, p_properties: ?[*]vk.ExtensionProperties) VkError!void {
|
||||||
|
return try self.dispatch_table.enumerateExtensionProperties(self, layer_name, count, p_properties);
|
||||||
|
}
|
||||||
|
|
||||||
pub inline fn getImageFormatProperties(
|
pub inline fn getImageFormatProperties(
|
||||||
self: *Self,
|
self: *Self,
|
||||||
format: vk.Format,
|
format: vk.Format,
|
||||||
|
|||||||
@@ -1,2 +1,6 @@
|
|||||||
#include <vulkan/vk_icd.h>
|
#include <vulkan/vk_icd.h>
|
||||||
#include <vulkan/utility/vk_format_utils.h>
|
#include <vulkan/utility/vk_format_utils.h>
|
||||||
|
|
||||||
|
#ifdef STROLL_ENABLE_WAYLAND
|
||||||
|
#include <wayland-client.h>
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -382,7 +382,7 @@ pub export fn strollCreateDevice(p_physical_device: vk.PhysicalDevice, info: *co
|
|||||||
return .success;
|
return .success;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub export fn strollEnumerateDeviceExtensionProperties(p_physical_device: vk.PhysicalDevice, p_layer_name: ?[*:0]const u8, property_count: *u32, properties: ?*vk.ExtensionProperties) callconv(vk.vulkan_call_conv) vk.Result {
|
pub export fn strollEnumerateDeviceExtensionProperties(p_physical_device: vk.PhysicalDevice, p_layer_name: ?[*:0]const u8, property_count: *u32, properties: ?[*]vk.ExtensionProperties) callconv(vk.vulkan_call_conv) vk.Result {
|
||||||
entryPointBeginLogTrace(.vkEnumerateDeviceExtensionProperties);
|
entryPointBeginLogTrace(.vkEnumerateDeviceExtensionProperties);
|
||||||
defer entryPointEndLogTrace();
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
@@ -390,9 +390,8 @@ pub export fn strollEnumerateDeviceExtensionProperties(p_physical_device: vk.Phy
|
|||||||
if (p_layer_name) |layer_name| {
|
if (p_layer_name) |layer_name| {
|
||||||
name = std.mem.span(layer_name);
|
name = std.mem.span(layer_name);
|
||||||
}
|
}
|
||||||
_ = p_physical_device;
|
const physical_device = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return toVkResult(err);
|
||||||
property_count.* = 0;
|
physical_device.enumerateExtensionProperties(name, property_count, properties) catch |err| return toVkResult(err);
|
||||||
_ = properties;
|
|
||||||
return .success;
|
return .success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2213,8 +2212,8 @@ pub export fn strollAcquireNextImageKHR(p_device: vk.Device, p_swapchain: vk.Swa
|
|||||||
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return toVkResult(err);
|
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return toVkResult(err);
|
||||||
|
|
||||||
const swapchain = NonDispatchable(SwapchainKHR).fromHandleObject(p_swapchain) catch |err| return toVkResult(err);
|
const swapchain = NonDispatchable(SwapchainKHR).fromHandleObject(p_swapchain) catch |err| return toVkResult(err);
|
||||||
const semaphore = NonDispatchable(BinarySemaphore).fromHandleObject(p_semaphore) catch |err| return toVkResult(err);
|
const semaphore = if (p_semaphore != .null_handle) NonDispatchable(BinarySemaphore).fromHandleObject(p_semaphore) catch |err| return toVkResult(err) else null;
|
||||||
const fence = NonDispatchable(Fence).fromHandleObject(p_fence) catch |err| return toVkResult(err);
|
const fence = if (p_fence != .null_handle) NonDispatchable(Fence).fromHandleObject(p_fence) catch |err| return toVkResult(err) else null;
|
||||||
swapchain.getNextImage(timeout, semaphore, fence, image_index) catch |err| return toVkResult(err);
|
swapchain.getNextImage(timeout, semaphore, fence, image_index) catch |err| return toVkResult(err);
|
||||||
return .success;
|
return .success;
|
||||||
}
|
}
|
||||||
@@ -2235,9 +2234,7 @@ pub export fn strollCreateSwapchainKHR(p_device: vk.Device, info: *const vk.Swap
|
|||||||
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
|
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
|
||||||
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err);
|
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err);
|
||||||
const surface = NonDispatchable(SurfaceKHR).fromHandleObject(info.surface) catch |err| return toVkResult(err);
|
const surface = NonDispatchable(SurfaceKHR).fromHandleObject(info.surface) catch |err| return toVkResult(err);
|
||||||
const swapchain = SwapchainKHR.create(device, allocator, info) catch |err| return toVkResult(err);
|
const swapchain = SwapchainKHR.create(device, allocator, surface, info) catch |err| return toVkResult(err);
|
||||||
swapchain.surface = surface;
|
|
||||||
surface.swapchain = swapchain;
|
|
||||||
p_swapchain.* = (NonDispatchable(SwapchainKHR).wrap(allocator, swapchain) catch |err| return toVkResult(err)).toVkHandle(vk.SwapchainKHR);
|
p_swapchain.* = (NonDispatchable(SwapchainKHR).wrap(allocator, swapchain) catch |err| return toVkResult(err)).toVkHandle(vk.SwapchainKHR);
|
||||||
return .success;
|
return .success;
|
||||||
}
|
}
|
||||||
@@ -2318,6 +2315,7 @@ pub export fn strollGetPhysicalDeviceSurfaceSupportKHR(p_physical_device: vk.Phy
|
|||||||
return .success;
|
return .success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// TODO: proper implementation when adding new drivers
|
||||||
pub export fn strollGetPhysicalDeviceWaylandPresentationSupportKHR(p_physical_device: vk.PhysicalDevice, _: u32, _: *anyopaque) callconv(vk.vulkan_call_conv) vk.Bool32 {
|
pub export fn strollGetPhysicalDeviceWaylandPresentationSupportKHR(p_physical_device: vk.PhysicalDevice, _: u32, _: *anyopaque) callconv(vk.vulkan_call_conv) vk.Bool32 {
|
||||||
entryPointBeginLogTrace(.vkGetPhysicalDeviceWaylandPresentationSupportKHR);
|
entryPointBeginLogTrace(.vkGetPhysicalDeviceWaylandPresentationSupportKHR);
|
||||||
defer entryPointEndLogTrace();
|
defer entryPointEndLogTrace();
|
||||||
@@ -2335,8 +2333,8 @@ pub export fn strollGetSwapchainImagesKHR(p_device: vk.Device, p_swapchain: vk.S
|
|||||||
const swapchain = NonDispatchable(SwapchainKHR).fromHandleObject(p_swapchain) catch |err| return toVkResult(err);
|
const swapchain = NonDispatchable(SwapchainKHR).fromHandleObject(p_swapchain) catch |err| return toVkResult(err);
|
||||||
count.* = @intCast(swapchain.images.len);
|
count.* = @intCast(swapchain.images.len);
|
||||||
if (p_images) |images| {
|
if (p_images) |images| {
|
||||||
for (images[0..], swapchain.images[0..]) |*image, swapchain_image| {
|
for (images[0..], swapchain.images[0..]) |*image, *swapchain_image| {
|
||||||
image.* = NonDispatchable(Image).fromObject(swapchain_image.image).toVkHandle(vk.Image);
|
image.* = swapchain_image.non_dispatchable_image.toVkHandle(vk.Image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ const VkError = @import("../error_set.zig").VkError;
|
|||||||
const Device = @import("../Device.zig");
|
const Device = @import("../Device.zig");
|
||||||
const DeviceMemory = @import("../DeviceMemory.zig");
|
const DeviceMemory = @import("../DeviceMemory.zig");
|
||||||
const Image = @import("../Image.zig");
|
const Image = @import("../Image.zig");
|
||||||
|
const NonDispatchable = @import("../NonDispatchable.zig").NonDispatchable;
|
||||||
|
|
||||||
pub const State = enum {
|
pub const State = enum {
|
||||||
Available,
|
Available,
|
||||||
@@ -16,6 +17,7 @@ pub const State = enum {
|
|||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
image: *Image,
|
image: *Image,
|
||||||
|
non_dispatchable_image: *NonDispatchable(Image),
|
||||||
memory: *DeviceMemory,
|
memory: *DeviceMemory,
|
||||||
state: State,
|
state: State,
|
||||||
|
|
||||||
@@ -36,12 +38,13 @@ pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.Image
|
|||||||
|
|
||||||
return .{
|
return .{
|
||||||
.image = image,
|
.image = image,
|
||||||
|
.non_dispatchable_image = try NonDispatchable(Image).wrap(allocator, image),
|
||||||
.memory = memory,
|
.memory = memory,
|
||||||
.state = .Available,
|
.state = .Available,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {
|
pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {
|
||||||
self.image.destroy(allocator);
|
self.non_dispatchable_image.intrusiveDestroy(allocator);
|
||||||
self.memory.destroy(allocator);
|
self.memory.destroy(allocator);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ owner: *Device,
|
|||||||
surface: ?*SurfaceKHR,
|
surface: ?*SurfaceKHR,
|
||||||
images: []PresentImage,
|
images: []PresentImage,
|
||||||
|
|
||||||
pub fn create(device: *Device, allocator: std.mem.Allocator, info: *const vk.SwapchainCreateInfoKHR) VkError!*Self {
|
pub fn create(device: *Device, allocator: std.mem.Allocator, surface: *SurfaceKHR, info: *const vk.SwapchainCreateInfoKHR) VkError!*Self {
|
||||||
const self = allocator.create(Self) catch return VkError.OutOfHostMemory;
|
const self = allocator.create(Self) catch return VkError.OutOfHostMemory;
|
||||||
errdefer allocator.destroy(self);
|
errdefer allocator.destroy(self);
|
||||||
|
|
||||||
@@ -46,17 +46,22 @@ pub fn create(device: *Device, allocator: std.mem.Allocator, info: *const vk.Swa
|
|||||||
.queue_family_index_count = info.queue_family_index_count,
|
.queue_family_index_count = info.queue_family_index_count,
|
||||||
.initial_layout = .general,
|
.initial_layout = .general,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
try surface.attachImage(allocator, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.owner = device,
|
.owner = device,
|
||||||
.surface = null,
|
.surface = surface,
|
||||||
.images = images,
|
.images = images,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
surface.swapchain = self;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getNextImage(self: *const Self, timeout: u64, semaphore: *BinarySemaphore, fence: *Fence, index: *u32) VkError!void {
|
pub fn getNextImage(self: *const Self, timeout: u64, semaphore: ?*BinarySemaphore, fence: ?*Fence, index: *u32) VkError!void {
|
||||||
// TODO: handle timeout correctly
|
// TODO: handle timeout correctly
|
||||||
|
|
||||||
for (self.images, 0..) |*image, i| {
|
for (self.images, 0..) |*image, i| {
|
||||||
@@ -65,7 +70,8 @@ pub fn getNextImage(self: *const Self, timeout: u64, semaphore: *BinarySemaphore
|
|||||||
index.* = @intCast(i);
|
index.* = @intCast(i);
|
||||||
// TODO: signal semaphore
|
// TODO: signal semaphore
|
||||||
_ = semaphore;
|
_ = semaphore;
|
||||||
try fence.signal();
|
if (fence) |f|
|
||||||
|
try f.signal();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,16 +19,16 @@ const WaylandImage = struct {
|
|||||||
stride: u32,
|
stride: u32,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn wlRegistryHandleGlobal(data: *anyopaque, registry: *wayland.wl_registry, name: c_uint, interface: [*:0]const u8, _: c_uint) callconv(.c) void {
|
fn wlRegistryHandleGlobal(data: ?*anyopaque, registry: ?*wayland.wl_registry, name: u32, interface: [*c]const u8, _: u32) callconv(.c) void {
|
||||||
const pshm: **wayland.wl_shm = @ptrCast(@alignCast(data));
|
const pshm: **wayland.wl_shm = @ptrCast(@alignCast(data orelse return));
|
||||||
if (std.mem.eql(u8, std.mem.span(interface), "wl_shm")) {
|
if (std.mem.eql(u8, std.mem.span(interface), "wl_shm")) {
|
||||||
if (wayland.wl_registry_bind(registry, name, wayland.wl_shm_interface, 1)) |shm| {
|
if (wayland.c.wl_registry_bind(registry orelse return, name, wayland.wl_shm_interface, 1)) |shm| {
|
||||||
pshm.* = @ptrCast(@alignCast(shm));
|
pshm.* = @ptrCast(@alignCast(shm));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wlRegistryHandleGlobalRemove(_: *anyopaque, _: *wayland.wl_registry, _: c_uint) callconv(.c) void {}
|
fn wlRegistryHandleGlobalRemove(_: ?*anyopaque, _: ?*wayland.wl_registry, _: u32) callconv(.c) void {}
|
||||||
|
|
||||||
const wl_registry_listener: wayland.wl_registry_listener = .{
|
const wl_registry_listener: wayland.wl_registry_listener = .{
|
||||||
.global = wlRegistryHandleGlobal,
|
.global = wlRegistryHandleGlobal,
|
||||||
@@ -65,9 +65,9 @@ pub fn create(instance: *Instance, allocator: std.mem.Allocator, info: *const vk
|
|||||||
.image_map = .empty,
|
.image_map = .empty,
|
||||||
};
|
};
|
||||||
|
|
||||||
const registry = wayland.wl_display_get_registry(self.display) orelse return VkError.Unknown;
|
const registry = wayland.c.wl_display_get_registry(@ptrCast(self.display)) orelse return VkError.Unknown;
|
||||||
_ = wayland.wl_registry_add_listener(registry, &wl_registry_listener, @ptrCast(&self.shm));
|
_ = wayland.c.wl_registry_add_listener(registry, &wl_registry_listener, @ptrCast(&self.shm));
|
||||||
_ = wayland.wl_display_dispatch(self.display);
|
_ = wayland.c.wl_display_dispatch(@ptrCast(self.display));
|
||||||
|
|
||||||
return &self.interface;
|
return &self.interface;
|
||||||
}
|
}
|
||||||
@@ -106,11 +106,11 @@ pub fn attachImage(interface: *Interface, allocator: std.mem.Allocator, image: *
|
|||||||
const data = std.posix.mmap(null, size, .{ .READ = true, .WRITE = true }, .{ .TYPE = .SHARED }, fd, 0) catch return VkError.OutOfHostMemory;
|
const data = std.posix.mmap(null, size, .{ .READ = true, .WRITE = true }, .{ .TYPE = .SHARED }, fd, 0) catch return VkError.OutOfHostMemory;
|
||||||
errdefer std.posix.munmap(data);
|
errdefer std.posix.munmap(data);
|
||||||
|
|
||||||
const pool = wayland.wl_shm_create_pool(self.shm, fd, @intCast(size)) orelse return VkError.Unknown;
|
const pool = wayland.c.wl_shm_create_pool(self.shm, fd, @intCast(size)) orelse return VkError.Unknown;
|
||||||
defer wayland.wl_shm_pool_destroy(pool);
|
defer wayland.c.wl_shm_pool_destroy(pool);
|
||||||
|
|
||||||
const buffer = wayland.wl_shm_pool_create_buffer(pool, 0, @intCast(width), @intCast(height), @intCast(stride), wayland.WL_SHM_FORMAT_ARGB8888) orelse return VkError.Unknown;
|
const buffer = wayland.c.wl_shm_pool_create_buffer(pool, 0, @intCast(width), @intCast(height), @intCast(stride), wayland.WL_SHM_FORMAT_ARGB8888) orelse return VkError.Unknown;
|
||||||
errdefer wayland.wl_buffer_destroy(buffer);
|
errdefer wayland.c.wl_buffer_destroy(buffer);
|
||||||
|
|
||||||
wl_image.* = .{
|
wl_image.* = .{
|
||||||
.buffer = buffer,
|
.buffer = buffer,
|
||||||
@@ -128,7 +128,7 @@ pub fn detachImage(interface: *Interface, allocator: std.mem.Allocator, image: *
|
|||||||
const entry = self.image_map.fetchRemove(image) orelse return;
|
const entry = self.image_map.fetchRemove(image) orelse return;
|
||||||
const wl_image = entry.value;
|
const wl_image = entry.value;
|
||||||
|
|
||||||
wayland.wl_buffer_destroy(wl_image.buffer);
|
wayland.c.wl_buffer_destroy(wl_image.buffer);
|
||||||
std.posix.munmap(wl_image.data);
|
std.posix.munmap(wl_image.data);
|
||||||
allocator.destroy(wl_image);
|
allocator.destroy(wl_image);
|
||||||
}
|
}
|
||||||
@@ -146,14 +146,11 @@ pub fn presentImage(interface: *Interface, allocator: std.mem.Allocator, image:
|
|||||||
.layer_count = 1,
|
.layer_count = 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
wayland.wl_surface_attach(self.surface, wl_image.buffer, 0, 0);
|
wayland.c.wl_surface_attach(@ptrCast(self.surface), wl_image.buffer, 0, 0);
|
||||||
wayland.wl_surface_damage(self.surface, 0, 0, @intCast(wl_image.width), @intCast(wl_image.height));
|
wayland.c.wl_surface_damage(@ptrCast(self.surface), 0, 0, @intCast(wl_image.width), @intCast(wl_image.height));
|
||||||
wayland.wl_surface_commit(self.surface);
|
wayland.c.wl_surface_commit(@ptrCast(self.surface));
|
||||||
|
|
||||||
// Better: bind wl_display_flush in wayland.zig and call it here.
|
_ = wayland.c.wl_display_flush(@ptrCast(self.display));
|
||||||
// With the currently available bindings, roundtrip forces the commit out,
|
|
||||||
// but it is heavier than necessary.
|
|
||||||
_ = wayland.wl_display_roundtrip(self.display);
|
|
||||||
|
|
||||||
image.state = .Available;
|
image.state = .Available;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,37 +2,29 @@ const std = @import("std");
|
|||||||
const vk = @import("vulkan");
|
const vk = @import("vulkan");
|
||||||
const lib = @import("../../lib.zig");
|
const lib = @import("../../lib.zig");
|
||||||
|
|
||||||
|
pub const c = lib.c;
|
||||||
|
|
||||||
const VkError = lib.VkError;
|
const VkError = lib.VkError;
|
||||||
|
|
||||||
pub const wl_registry_listener = extern struct {
|
pub const wl_registry_listener = c.wl_registry_listener;
|
||||||
global: *const fn (*anyopaque, *wl_registry, c_uint, [*:0]const u8, c_uint) callconv(.c) void,
|
|
||||||
global_remove: *const fn (*anyopaque, *wl_registry, c_uint) callconv(.c) void,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const WL_SHM_FORMAT_ARGB8888 = 0;
|
pub const WL_SHM_FORMAT_ARGB8888 = c.WL_SHM_FORMAT_ARGB8888;
|
||||||
|
|
||||||
pub const wl_buffer = opaque {};
|
pub const wl_buffer = c.wl_buffer;
|
||||||
pub const wl_callback = opaque {};
|
pub const wl_callback = c.wl_buffer;
|
||||||
|
pub const wl_interface = c.wl_interface;
|
||||||
|
pub const wl_registry = c.wl_registry;
|
||||||
|
pub const wl_shm = c.wl_shm;
|
||||||
|
pub const wl_shm_pool = c.wl_shm_pool;
|
||||||
|
pub const wl_proxy = c.wl_proxy;
|
||||||
|
|
||||||
|
// vk.wl_XXX instead of c.wl_XXX to avoid casts with Zig Vulkan bindings functions
|
||||||
pub const wl_display = vk.wl_display;
|
pub const wl_display = vk.wl_display;
|
||||||
pub const wl_interface = opaque {};
|
|
||||||
pub const wl_registry = opaque {};
|
|
||||||
pub const wl_shm = opaque {};
|
|
||||||
pub const wl_shm_pool = opaque {};
|
|
||||||
pub const wl_surface = vk.wl_surface;
|
pub const wl_surface = vk.wl_surface;
|
||||||
|
|
||||||
pub var wl_display_dispatch: *const fn (d: *wl_display) callconv(.c) c_int = undefined;
|
pub var wl_display_dispatch: *const fn (*wl_display) callconv(.c) c_int = undefined;
|
||||||
pub var wl_display_get_registry: *const fn (d: *wl_display) callconv(.c) ?*wl_registry = undefined;
|
pub var wl_proxy_marshal_flags: *const fn (*wl_proxy, u32, *const wl_interface, u32, u32, ...) callconv(.c) ?*wl_proxy = undefined;
|
||||||
pub var wl_display_roundtrip: *const fn (d: *wl_display) callconv(.c) c_int = undefined;
|
pub var wl_display_flush: *const fn (*wl_display) callconv(.c) c_int = undefined;
|
||||||
pub var wl_display_sync: *const fn (d: *wl_display) callconv(.c) ?*wl_callback = undefined;
|
|
||||||
pub var wl_registry_add_listener: *const fn (r: *wl_registry, l: *const wl_registry_listener, data: *anyopaque) callconv(.c) c_int = undefined;
|
|
||||||
pub var wl_registry_bind: *const fn (r: *wl_registry, name: u32, i: *const wl_interface, version: u32) callconv(.c) ?*anyopaque = undefined;
|
|
||||||
pub var wl_buffer_destroy: *const fn (b: *wl_buffer) callconv(.c) void = undefined;
|
|
||||||
pub var wl_shm_create_pool: *const fn (shm: *wl_shm, fd: i32, size: i32) callconv(.c) ?*wl_shm_pool = undefined;
|
|
||||||
pub var wl_shm_pool_create_buffer: *const fn (p: *wl_shm_pool, offset: i32, width: i32, height: i32, stride: i32, format: u32) callconv(.c) ?*wl_buffer = undefined;
|
|
||||||
pub var wl_shm_pool_destroy: *const fn (p: *wl_shm_pool) callconv(.c) void = undefined;
|
|
||||||
pub var wl_surface_attach: *const fn (s: *wl_surface, b: *wl_buffer, x: i32, y: i32) callconv(.c) void = undefined;
|
|
||||||
pub var wl_surface_damage: *const fn (s: *wl_surface, x: i32, y: i32, width: i32, height: i32) callconv(.c) void = undefined;
|
|
||||||
pub var wl_surface_commit: *const fn (s: *wl_surface) callconv(.c) void = undefined;
|
|
||||||
|
|
||||||
pub var wl_shm_interface: *wl_interface = undefined;
|
pub var wl_shm_interface: *wl_interface = undefined;
|
||||||
|
|
||||||
@@ -49,23 +41,11 @@ pub fn load() VkError!void {
|
|||||||
return VkError.Unknown;
|
return VkError.Unknown;
|
||||||
};
|
};
|
||||||
errdefer module.close();
|
errdefer module.close();
|
||||||
errdefer std.debug.print("test {s}\n", .{std.c.dlerror().?});
|
errdefer std.log.scoped(.WaylandClient).err("Could not open 'libwayland-client.so.0': {s}", .{std.c.dlerror() orelse "unknown error"});
|
||||||
|
|
||||||
// zig fmt: off
|
wl_display_dispatch = module.lookup(@TypeOf(wl_display_dispatch), "wl_display_dispatch") orelse return VkError.Unknown;
|
||||||
wl_display_dispatch = module.lookup(@TypeOf(wl_display_dispatch), "wl_display_dispatch" ) orelse return VkError.Unknown;
|
wl_proxy_marshal_flags = module.lookup(@TypeOf(wl_proxy_marshal_flags), "wl_proxy_marshal_flags") orelse return VkError.Unknown;
|
||||||
wl_display_get_registry = module.lookup(@TypeOf(wl_display_get_registry), "wl_display_get_registry" ) orelse return VkError.Unknown;
|
wl_display_flush = module.lookup(@TypeOf(wl_display_flush), "wl_display_flush") orelse return VkError.Unknown;
|
||||||
wl_display_roundtrip = module.lookup(@TypeOf(wl_display_roundtrip), "wl_display_roundtrip" ) orelse return VkError.Unknown;
|
|
||||||
wl_display_sync = module.lookup(@TypeOf(wl_display_sync), "wl_display_sync" ) orelse return VkError.Unknown;
|
|
||||||
wl_registry_add_listener = module.lookup(@TypeOf(wl_registry_add_listener), "wl_registry_add_listener" ) orelse return VkError.Unknown;
|
|
||||||
wl_registry_bind = module.lookup(@TypeOf(wl_registry_bind), "wl_registry_bind" ) orelse return VkError.Unknown;
|
|
||||||
wl_buffer_destroy = module.lookup(@TypeOf(wl_buffer_destroy), "wl_buffer_destroy" ) orelse return VkError.Unknown;
|
|
||||||
wl_shm_create_pool = module.lookup(@TypeOf(wl_shm_create_pool), "wl_shm_create_pool" ) orelse return VkError.Unknown;
|
|
||||||
wl_shm_pool_create_buffer = module.lookup(@TypeOf(wl_shm_pool_create_buffer), "wl_shm_pool_create_buffer") orelse return VkError.Unknown;
|
|
||||||
wl_shm_pool_destroy = module.lookup(@TypeOf(wl_shm_pool_destroy), "wl_shm_pool_destroy" ) orelse return VkError.Unknown;
|
|
||||||
wl_surface_attach = module.lookup(@TypeOf(wl_surface_attach), "wl_surface_attach" ) orelse return VkError.Unknown;
|
|
||||||
wl_surface_damage = module.lookup(@TypeOf(wl_surface_damage), "wl_surface_damage" ) orelse return VkError.Unknown;
|
|
||||||
wl_surface_commit = module.lookup(@TypeOf(wl_surface_commit), "wl_surface_commit" ) orelse return VkError.Unknown;
|
|
||||||
// zig fmt: on
|
|
||||||
|
|
||||||
wl_shm_interface = module.lookup(*wl_interface, "wl_shm_interface") orelse return VkError.Unknown;
|
wl_shm_interface = module.lookup(*wl_interface, "wl_shm_interface") orelse return VkError.Unknown;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user