working on wsi
This commit is contained in:
@@ -168,10 +168,10 @@ vkGetPhysicalDeviceMemoryProperties | ✅ Implemented
|
||||
vkGetPhysicalDeviceProperties | ✅ Implemented
|
||||
vkGetPhysicalDeviceQueueFamilyProperties | ✅ Implemented
|
||||
vkGetPhysicalDeviceSparseImageFormatProperties | ⚙️ WIP
|
||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR | ⚙️ WIP
|
||||
vkGetPhysicalDeviceSurfaceFormatsKHR | ⚙️ WIP
|
||||
vkGetPhysicalDeviceSurfacePresentModesKHR | ⚙️ WIP
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR | ⚙️ WIP
|
||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR | ✅ Implemented
|
||||
vkGetPhysicalDeviceSurfaceFormatsKHR | ✅ Implemented
|
||||
vkGetPhysicalDeviceSurfacePresentModesKHR | ✅ Implemented
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR | ✅ Implemented
|
||||
vkGetPhysicalDeviceWaylandPresentationSupportKHR | ⚙️ WIP
|
||||
vkGetPhysicalDeviceWin32PresentationSupportKHR | ⚙️ WIP
|
||||
vkGetPhysicalDeviceXcbPresentationSupportKHR | ⚙️ WIP
|
||||
@@ -184,7 +184,7 @@ vkInvalidateMappedMemoryRanges | ✅ Implemented
|
||||
vkMapMemory | ✅ Implemented
|
||||
vkMergePipelineCaches | ⚙️ WIP
|
||||
vkQueueBindSparse | ⚙️ WIP
|
||||
vkQueuePresentKHR | ⚙️ WIP
|
||||
vkQueuePresentKHR | ✅ Implemented
|
||||
vkQueueSubmit | ✅ Implemented
|
||||
vkQueueWaitIdle | ✅ Implemented
|
||||
vkResetCommandBuffer | ✅ Implemented
|
||||
|
||||
+28
-16
@@ -29,6 +29,9 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v
|
||||
.getMemoryRequirements = getMemoryRequirements,
|
||||
.getSubresourceLayout = getSubresourceLayout,
|
||||
.getTotalSizeForAspect = getTotalSizeForAspect,
|
||||
.getSliceMemSizeForMipLevel = getSliceMemSizeForMipLevel,
|
||||
.getRowPitchMemSizeForMipLevel = getRowPitchMemSizeForMipLevel,
|
||||
.copyToMemory = copyToMemory,
|
||||
};
|
||||
|
||||
self.* = .{
|
||||
@@ -106,10 +109,10 @@ pub fn copyToImageSingleAspect(self: *const Self, dst: *Self, region: vk.ImageCo
|
||||
const one_is_3D = (self.interface.image_type == .@"3d") != (dst.interface.image_type == .@"3d");
|
||||
const both_are_3D = (self.interface.image_type == .@"3d") and (dst.interface.image_type == .@"3d");
|
||||
|
||||
const src_row_pitch_bytes = self.getRowPitchMemSizeForMipLevel(region.src_subresource.aspect_mask, region.src_subresource.mip_level);
|
||||
const src_depth_pitch_bytes = self.getSliceMemSizeForMipLevel(region.src_subresource.aspect_mask, region.src_subresource.mip_level);
|
||||
const dst_row_pitch_bytes = dst.getRowPitchMemSizeForMipLevel(region.dst_subresource.aspect_mask, region.dst_subresource.mip_level);
|
||||
const dst_depth_pitch_bytes = dst.getSliceMemSizeForMipLevel(region.dst_subresource.aspect_mask, region.dst_subresource.mip_level);
|
||||
const src_row_pitch_bytes = self.interface.getRowPitchMemSizeForMipLevel(region.src_subresource.aspect_mask, region.src_subresource.mip_level);
|
||||
const src_depth_pitch_bytes = self.interface.getSliceMemSizeForMipLevel(region.src_subresource.aspect_mask, region.src_subresource.mip_level);
|
||||
const dst_row_pitch_bytes = dst.interface.getRowPitchMemSizeForMipLevel(region.dst_subresource.aspect_mask, region.dst_subresource.mip_level);
|
||||
const dst_depth_pitch_bytes = dst.interface.getSliceMemSizeForMipLevel(region.dst_subresource.aspect_mask, region.dst_subresource.mip_level);
|
||||
|
||||
const src_array_pitch = self.getLayerSize(region.src_subresource.aspect_mask);
|
||||
const dst_array_pitch = dst.getLayerSize(region.dst_subresource.aspect_mask);
|
||||
@@ -238,6 +241,11 @@ pub fn copyFromBuffer(self: *const Self, src: *const SoftBuffer, region: vk.Buff
|
||||
);
|
||||
}
|
||||
|
||||
pub fn copyToMemory(interface: *const Interface, memory: []u8, subresource: vk.ImageSubresourceLayers) VkError!void {
|
||||
const self: *const Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||
try self.copy(null, memory, subresource, .{ .x = 0, .y = 0, .z = 0 }, interface.extent);
|
||||
}
|
||||
|
||||
/// Based on SwiftShader vk::Image::copy
|
||||
pub fn copy(
|
||||
self: *const Self,
|
||||
@@ -284,10 +292,10 @@ pub fn copy(
|
||||
var src_memory = if (is_source) base_src_memory orelse return VkError.InvalidDeviceMemoryDrv else image_map;
|
||||
var dst_memory = if (is_source) image_map else base_dst_memory orelse return VkError.InvalidDeviceMemoryDrv;
|
||||
|
||||
const src_slice_pitch_bytes = if (is_source) memory_slice_pitch_bytes else self.getSliceMemSizeForMipLevel(image_subresource.aspect_mask, image_subresource.mip_level);
|
||||
const dst_slice_pitch_bytes = if (is_source) self.getSliceMemSizeForMipLevel(image_subresource.aspect_mask, image_subresource.mip_level) else memory_slice_pitch_bytes;
|
||||
const src_row_pitch_bytes = if (is_source) memory_row_pitch_bytes else self.getRowPitchMemSizeForMipLevel(image_subresource.aspect_mask, image_subresource.mip_level);
|
||||
const dst_row_pitch_bytes = if (is_source) self.getRowPitchMemSizeForMipLevel(image_subresource.aspect_mask, image_subresource.mip_level) else memory_row_pitch_bytes;
|
||||
const src_slice_pitch_bytes = if (is_source) memory_slice_pitch_bytes else self.interface.getSliceMemSizeForMipLevel(image_subresource.aspect_mask, image_subresource.mip_level);
|
||||
const dst_slice_pitch_bytes = if (is_source) self.interface.getSliceMemSizeForMipLevel(image_subresource.aspect_mask, image_subresource.mip_level) else memory_slice_pitch_bytes;
|
||||
const src_row_pitch_bytes = if (is_source) memory_row_pitch_bytes else self.interface.getRowPitchMemSizeForMipLevel(image_subresource.aspect_mask, image_subresource.mip_level);
|
||||
const dst_row_pitch_bytes = if (is_source) self.interface.getRowPitchMemSizeForMipLevel(image_subresource.aspect_mask, image_subresource.mip_level) else memory_row_pitch_bytes;
|
||||
|
||||
const src_layer_size = if (is_source) memory_slice_pitch_bytes else self.getLayerSize(image_subresource.aspect_mask);
|
||||
const dst_layer_size = if (is_source) self.getLayerSize(image_subresource.aspect_mask) else memory_slice_pitch_bytes;
|
||||
@@ -352,8 +360,8 @@ pub fn writeInt4(self: *Self, offset: vk.Offset3D, subresource: vk.ImageSubresou
|
||||
}
|
||||
|
||||
pub fn getTexelMemoryOffsetInSubresource(self: *const Self, offset: vk.Offset3D, subresource: vk.ImageSubresource) usize {
|
||||
return @as(usize, @intCast(offset.z)) * self.getSliceMemSizeForMipLevel(subresource.aspect_mask, subresource.mip_level) +
|
||||
@as(usize, @intCast(offset.y)) * self.getRowPitchMemSizeForMipLevel(subresource.aspect_mask, subresource.mip_level) +
|
||||
return @as(usize, @intCast(offset.z)) * self.interface.getSliceMemSizeForMipLevel(subresource.aspect_mask, subresource.mip_level) +
|
||||
@as(usize, @intCast(offset.y)) * self.interface.getRowPitchMemSizeForMipLevel(subresource.aspect_mask, subresource.mip_level) +
|
||||
@as(usize, @intCast(offset.x)) * base.format.texelSize(base.format.fromAspect(self.interface.format, subresource.aspect_mask));
|
||||
}
|
||||
|
||||
@@ -369,7 +377,7 @@ fn getSubresourceOffset(self: *const Self, aspect_mask: vk.ImageAspectFlags, mip
|
||||
|
||||
const is_3D = (self.interface.image_type == .@"3d") and self.interface.flags.@"2d_array_compatible_bit";
|
||||
const layer_offset = if (is_3D)
|
||||
self.getSliceMemSizeForMipLevel(aspect_mask, mip_level)
|
||||
self.interface.getSliceMemSizeForMipLevel(aspect_mask, mip_level)
|
||||
else
|
||||
self.getLayerSize(aspect_mask);
|
||||
return offset + layer * layer_offset;
|
||||
@@ -427,8 +435,8 @@ fn getSubresourceLayout(interface: *const Interface, subresource: vk.ImageSubres
|
||||
return .{
|
||||
.offset = try self.getSubresourceOffset(subresource.aspect_mask, subresource.mip_level, subresource.array_layer),
|
||||
.size = self.getMultiSampledLevelSize(subresource.aspect_mask, subresource.mip_level),
|
||||
.row_pitch = self.getRowPitchMemSizeForMipLevel(subresource.aspect_mask, subresource.mip_level),
|
||||
.array_pitch = self.getSliceMemSizeForMipLevel(subresource.aspect_mask, subresource.mip_level),
|
||||
.row_pitch = self.interface.getRowPitchMemSizeForMipLevel(subresource.aspect_mask, subresource.mip_level),
|
||||
.array_pitch = self.interface.getSliceMemSizeForMipLevel(subresource.aspect_mask, subresource.mip_level),
|
||||
.depth_pitch = self.getLayerSize(subresource.aspect_mask),
|
||||
};
|
||||
}
|
||||
@@ -446,7 +454,7 @@ pub inline fn getMultiSampledLevelSize(self: *const Self, aspect_mask: vk.ImageA
|
||||
}
|
||||
|
||||
pub inline fn getMipLevelSize(self: *const Self, aspect_mask: vk.ImageAspectFlags, mip_level: u32) usize {
|
||||
return self.getSliceMemSizeForMipLevel(aspect_mask, mip_level) * self.getMipLevelExtent(mip_level).depth;
|
||||
return self.interface.getSliceMemSizeForMipLevel(aspect_mask, mip_level) * self.getMipLevelExtent(mip_level).depth;
|
||||
}
|
||||
|
||||
pub fn getMipLevelExtent(self: *const Self, mip_level: u32) vk.Extent3D {
|
||||
@@ -463,13 +471,17 @@ pub fn getMipLevelExtent(self: *const Self, mip_level: u32) vk.Extent3D {
|
||||
return extent;
|
||||
}
|
||||
|
||||
pub fn getSliceMemSizeForMipLevel(self: *const Self, aspect_mask: vk.ImageAspectFlags, mip_level: u32) usize {
|
||||
pub fn getSliceMemSizeForMipLevel(interface: *const Interface, aspect_mask: vk.ImageAspectFlags, mip_level: u32) usize {
|
||||
const self: *const Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||
|
||||
const mip_extent = self.getMipLevelExtent(mip_level);
|
||||
const format = self.interface.formatFromAspect(aspect_mask);
|
||||
return base.format.sliceMemSize(format, mip_extent.width, mip_extent.height);
|
||||
}
|
||||
|
||||
pub fn getRowPitchMemSizeForMipLevel(self: *const Self, aspect_mask: vk.ImageAspectFlags, mip_level: u32) usize {
|
||||
pub fn getRowPitchMemSizeForMipLevel(interface: *const Interface, aspect_mask: vk.ImageAspectFlags, mip_level: u32) usize {
|
||||
const self: *const Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||
|
||||
const mip_extent = self.getMipLevelExtent(mip_level);
|
||||
const format = self.interface.formatFromAspect(aspect_mask);
|
||||
return base.format.pitchMemSize(format, mip_extent.width);
|
||||
|
||||
@@ -17,7 +17,7 @@ allocator: std.mem.Allocator,
|
||||
|
||||
fn castExtension(comptime ext: vk.ApiInfo) vk.ExtensionProperties {
|
||||
var props: vk.ExtensionProperties = .{
|
||||
.extension_name = undefined,
|
||||
.extension_name = @splat(0),
|
||||
.spec_version = @bitCast(ext.version),
|
||||
};
|
||||
@memcpy(props.extension_name[0..ext.name.len], ext.name);
|
||||
@@ -25,7 +25,11 @@ fn castExtension(comptime ext: vk.ApiInfo) 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_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 {
|
||||
|
||||
@@ -8,6 +8,7 @@ const SoftDevice = @import("SoftDevice.zig");
|
||||
|
||||
const VkError = base.VkError;
|
||||
const VulkanAllocator = base.VulkanAllocator;
|
||||
const SurfaceKHR = base.SurfaceKHR;
|
||||
|
||||
const Self = @This();
|
||||
pub const Interface = base.PhysicalDevice;
|
||||
@@ -30,8 +31,13 @@ pub fn create(allocator: std.mem.Allocator, instance: *base.Instance) VkError!*S
|
||||
.getFormatProperties = getFormatProperties,
|
||||
.getImageFormatProperties = getImageFormatProperties,
|
||||
.getSparseImageFormatProperties = getSparseImageFormatProperties,
|
||||
.getSparseImageFormatProperties2 = getSparseImageFormatProperties2,
|
||||
.release = destroy,
|
||||
|
||||
// VK_KHR_get_physical_device_properties_2
|
||||
.getSparseImageFormatProperties2 = getSparseImageFormatProperties2,
|
||||
|
||||
// VK_KHR_surface
|
||||
.getSurfaceSupportKHR = getSurfaceSupportKHR,
|
||||
};
|
||||
|
||||
interface.props.api_version = @bitCast(lib.VULKAN_VERSION);
|
||||
@@ -813,3 +819,7 @@ fn checkFormatUsage(usage: vk.ImageUsageFlags, features: vk.FormatFeatureFlags)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn getSurfaceSupportKHR(_: *Interface, _: u32, _: *SurfaceKHR) VkError!bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -98,8 +98,8 @@ pub fn clear(pixel: vk.ClearValue, format: vk.Format, dst: *SoftImage, view_form
|
||||
.array_layer = range.base_array_layer,
|
||||
};
|
||||
|
||||
const dst_slice_pitch_bytes = dst.getSliceMemSizeForMipLevel(subresource.aspect_mask, subresource.mip_level);
|
||||
const dst_row_pitch_bytes = dst.getRowPitchMemSizeForMipLevel(subresource.aspect_mask, subresource.mip_level);
|
||||
const dst_slice_pitch_bytes = dst.interface.getSliceMemSizeForMipLevel(subresource.aspect_mask, subresource.mip_level);
|
||||
const dst_row_pitch_bytes = dst.interface.getRowPitchMemSizeForMipLevel(subresource.aspect_mask, subresource.mip_level);
|
||||
|
||||
const last_mip_level = dst.interface.getLastMipLevel(range);
|
||||
const last_layer = dst.interface.getLastLayerIndex(range);
|
||||
@@ -207,8 +207,8 @@ fn fastClear(clear_value: vk.ClearValue, clear_format: vk.Format, dst: *SoftImag
|
||||
const dst_memory = if (dst.interface.memory) |memory| memory else return VkError.InvalidDeviceMemoryDrv;
|
||||
|
||||
while (subresource.mip_level <= last_mip_level) : (subresource.mip_level += 1) {
|
||||
const dst_slice_pitch_bytes = dst.getSliceMemSizeForMipLevel(subresource.aspect_mask, subresource.mip_level);
|
||||
const dst_row_pitch_bytes = dst.getRowPitchMemSizeForMipLevel(subresource.aspect_mask, subresource.mip_level);
|
||||
const dst_slice_pitch_bytes = dst.interface.getSliceMemSizeForMipLevel(subresource.aspect_mask, subresource.mip_level);
|
||||
const dst_row_pitch_bytes = dst.interface.getRowPitchMemSizeForMipLevel(subresource.aspect_mask, subresource.mip_level);
|
||||
const extent = dst.getMipLevelExtent(subresource.mip_level);
|
||||
|
||||
if (render_area == null) {
|
||||
@@ -375,10 +375,10 @@ pub fn blitRegion(src: *const SoftImage, dst: *SoftImage, region: vk.ImageBlit,
|
||||
const y0 = @as(f32, @floatFromInt(src_offset_0.y)) + (0.5 - @as(f32, @floatFromInt(dst_offset_0.y))) * height_ratio;
|
||||
const z0 = @as(f32, @floatFromInt(src_offset_0.z)) + (0.5 - @as(f32, @floatFromInt(dst_offset_0.z))) * depth_ratio;
|
||||
|
||||
const src_slice_pitch_bytes = src.getSliceMemSizeForMipLevel(region.src_subresource.aspect_mask, region.src_subresource.mip_level);
|
||||
const src_row_pitch_bytes = src.getRowPitchMemSizeForMipLevel(region.src_subresource.aspect_mask, region.src_subresource.mip_level);
|
||||
const dst_slice_pitch_bytes = dst.getSliceMemSizeForMipLevel(region.dst_subresource.aspect_mask, region.dst_subresource.mip_level);
|
||||
const dst_row_pitch_bytes = dst.getRowPitchMemSizeForMipLevel(region.dst_subresource.aspect_mask, region.dst_subresource.mip_level);
|
||||
const src_slice_pitch_bytes = src.interface.getSliceMemSizeForMipLevel(region.src_subresource.aspect_mask, region.src_subresource.mip_level);
|
||||
const src_row_pitch_bytes = src.interface.getRowPitchMemSizeForMipLevel(region.src_subresource.aspect_mask, region.src_subresource.mip_level);
|
||||
const dst_slice_pitch_bytes = dst.interface.getSliceMemSizeForMipLevel(region.dst_subresource.aspect_mask, region.dst_subresource.mip_level);
|
||||
const dst_row_pitch_bytes = dst.interface.getRowPitchMemSizeForMipLevel(region.dst_subresource.aspect_mask, region.dst_subresource.mip_level);
|
||||
|
||||
const src_format = base.format.fromAspect(src.interface.format, region.src_subresource.aspect_mask);
|
||||
const dst_format = base.format.fromAspect(dst.interface.format, region.dst_subresource.aspect_mask);
|
||||
|
||||
@@ -80,7 +80,7 @@ pub fn init(allocator: std.mem.Allocator, instance: *Instance, physical_device:
|
||||
.instance = instance,
|
||||
.physical_device = physical_device,
|
||||
.queues = .empty,
|
||||
.host_allocator = VulkanAllocator.from(allocator).clone(),
|
||||
.host_allocator = VulkanAllocator.from(allocator).cloneWithScope(.object),
|
||||
.dispatch_table = undefined,
|
||||
.vtable = undefined,
|
||||
};
|
||||
|
||||
@@ -23,13 +23,13 @@ pub fn Dispatchable(comptime T: type) type {
|
||||
return self;
|
||||
}
|
||||
|
||||
pub inline fn intrusiveDestroy(self: *Self, allocator: std.mem.Allocator) void {
|
||||
pub fn intrusiveDestroy(self: *Self, allocator: std.mem.Allocator) void {
|
||||
self.object.destroy(allocator);
|
||||
allocator.destroy(self);
|
||||
std.log.debug("Destroyed dispatchable handle of type '{s}' at 0x{X}", .{ @typeName(T), @intFromPtr(self) });
|
||||
}
|
||||
|
||||
pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void {
|
||||
pub fn destroy(self: *Self, allocator: std.mem.Allocator) void {
|
||||
allocator.destroy(self);
|
||||
std.log.debug("Destroyed dispatchable handle of type '{s}' at 0x{X}", .{ @typeName(T), @intFromPtr(self) });
|
||||
}
|
||||
@@ -42,7 +42,7 @@ pub fn Dispatchable(comptime T: type) type {
|
||||
return @enumFromInt(@intFromPtr(self));
|
||||
}
|
||||
|
||||
pub inline fn fromHandle(vk_handle: anytype) VkError!*Self {
|
||||
pub fn fromHandle(vk_handle: anytype) VkError!*Self {
|
||||
const handle = @intFromEnum(vk_handle);
|
||||
if (handle == 0) {
|
||||
return VkError.InvalidHandleDrv;
|
||||
|
||||
+17
-2
@@ -32,6 +32,9 @@ pub const VTable = struct {
|
||||
getMemoryRequirements: *const fn (*Self, *vk.MemoryRequirements) VkError!void,
|
||||
getSubresourceLayout: *const fn (*const Self, vk.ImageSubresource) VkError!vk.SubresourceLayout,
|
||||
getTotalSizeForAspect: *const fn (*const Self, vk.ImageAspectFlags) VkError!usize,
|
||||
getSliceMemSizeForMipLevel: *const fn (*const Self, vk.ImageAspectFlags, u32) usize,
|
||||
getRowPitchMemSizeForMipLevel: *const fn (*const Self, vk.ImageAspectFlags, u32) usize,
|
||||
copyToMemory: *const fn (*const Self, []u8, vk.ImageSubresourceLayers) VkError!void,
|
||||
};
|
||||
|
||||
pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.ImageCreateInfo) VkError!Self {
|
||||
@@ -58,7 +61,7 @@ pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void {
|
||||
self.vtable.destroy(self, allocator);
|
||||
}
|
||||
|
||||
pub inline fn bindMemory(self: *Self, memory: *DeviceMemory, offset: vk.DeviceSize) VkError!void {
|
||||
pub fn bindMemory(self: *Self, memory: *DeviceMemory, offset: vk.DeviceSize) VkError!void {
|
||||
const image_size = try self.getTotalSize();
|
||||
if (offset >= image_size or !self.allowed_memory_types.isSet(memory.memory_type_index)) {
|
||||
return VkError.ValidationFailed;
|
||||
@@ -67,12 +70,24 @@ pub inline fn bindMemory(self: *Self, memory: *DeviceMemory, offset: vk.DeviceSi
|
||||
self.memory_offset = offset;
|
||||
}
|
||||
|
||||
pub inline 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.memory_type_bits = self.allowed_memory_types.mask;
|
||||
try self.vtable.getMemoryRequirements(self, requirements);
|
||||
}
|
||||
|
||||
pub fn getSliceMemSizeForMipLevel(self: *const Self, aspect_mask: vk.ImageAspectFlags, mip_level: u32) usize {
|
||||
return self.vtable.getSliceMemSizeForMipLevel(self, aspect_mask, mip_level);
|
||||
}
|
||||
|
||||
pub fn getRowPitchMemSizeForMipLevel(self: *const Self, aspect_mask: vk.ImageAspectFlags, mip_level: u32) usize {
|
||||
return self.vtable.getRowPitchMemSizeForMipLevel(self, aspect_mask, mip_level);
|
||||
}
|
||||
|
||||
pub inline fn copyToMemory(self: *const Self, memory: []u8, subresource: vk.ImageSubresourceLayers) VkError!void {
|
||||
try self.vtable.copyToMemory(self, memory, subresource);
|
||||
}
|
||||
|
||||
pub inline fn getTexelSize(self: *const Self) usize {
|
||||
return lib.format.texelSize(self.format);
|
||||
}
|
||||
|
||||
@@ -66,11 +66,12 @@ pub fn enumerateExtensionProperties(layer_name: ?[]const u8, count: *u32, p_prop
|
||||
if (layer_name) |_| {
|
||||
return VkError.LayerNotPresent;
|
||||
}
|
||||
if (@hasDecl(root, "EXTENSIONS")) {
|
||||
|
||||
if (comptime @hasDecl(root.Instance, "EXTENSIONS")) {
|
||||
count.* = root.Instance.EXTENSIONS.len;
|
||||
if (p_properties) |properties| {
|
||||
for (root.Instance.EXTENSIONS, 0..) |ext, i| {
|
||||
properties[i] = ext;
|
||||
for (root.Instance.EXTENSIONS, properties[0..]) |ext, *prop| {
|
||||
prop.* = ext;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -20,13 +20,13 @@ pub fn NonDispatchable(comptime T: type) type {
|
||||
return self;
|
||||
}
|
||||
|
||||
pub inline fn intrusiveDestroy(self: *Self, allocator: std.mem.Allocator) void {
|
||||
pub fn intrusiveDestroy(self: *Self, allocator: std.mem.Allocator) void {
|
||||
self.object.destroy(allocator);
|
||||
allocator.destroy(self);
|
||||
std.log.debug("Destroyed non dispatchable handle of type '{s}' at 0x{X}", .{ @typeName(T), @intFromPtr(self) });
|
||||
}
|
||||
|
||||
pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void {
|
||||
pub fn destroy(self: *Self, allocator: std.mem.Allocator) void {
|
||||
allocator.destroy(self);
|
||||
std.log.debug("Destroyed non dispatchable handle of type '{s}' at 0x{X}", .{ @typeName(T), @intFromPtr(self) });
|
||||
}
|
||||
@@ -39,7 +39,11 @@ pub fn NonDispatchable(comptime T: type) type {
|
||||
return @enumFromInt(@intFromPtr(self));
|
||||
}
|
||||
|
||||
pub inline fn fromHandle(vk_handle: anytype) VkError!*Self {
|
||||
pub fn fromObject(object: *T) *Self {
|
||||
return @alignCast(@constCast(@fieldParentPtr("object", &object)));
|
||||
}
|
||||
|
||||
pub fn fromHandle(vk_handle: anytype) VkError!*Self {
|
||||
const handle = @intFromEnum(vk_handle);
|
||||
if (handle == 0) {
|
||||
return VkError.InvalidHandleDrv;
|
||||
|
||||
@@ -5,6 +5,7 @@ const root = @import("lib.zig");
|
||||
const Instance = @import("Instance.zig");
|
||||
const VkError = @import("error_set.zig").VkError;
|
||||
const Device = @import("Device.zig");
|
||||
const SurfaceKHR = @import("wsi/SurfaceKHR.zig");
|
||||
|
||||
const Self = @This();
|
||||
pub const ObjectType: vk.ObjectType = .physical_device;
|
||||
@@ -21,8 +22,13 @@ pub const DispatchTable = struct {
|
||||
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,
|
||||
getSparseImageFormatProperties: *const fn (*Self, vk.Format, vk.ImageType, vk.SampleCountFlags, vk.ImageTiling, vk.ImageUsageFlags, ?[*]vk.SparseImageFormatProperties) VkError!u32,
|
||||
getSparseImageFormatProperties2: ?*const fn (*Self, vk.Format, vk.ImageType, vk.SampleCountFlags, vk.ImageTiling, vk.ImageUsageFlags, ?[*]vk.SparseImageFormatProperties2) VkError!u32,
|
||||
release: *const fn (*Self, std.mem.Allocator) VkError!void,
|
||||
|
||||
// VK_KHR_get_physical_device_properties_2
|
||||
getSparseImageFormatProperties2: ?*const fn (*Self, vk.Format, vk.ImageType, vk.SampleCountFlags, vk.ImageTiling, vk.ImageUsageFlags, ?[*]vk.SparseImageFormatProperties2) VkError!u32,
|
||||
|
||||
// VK_KHR_surface
|
||||
getSurfaceSupportKHR: ?*const fn (*Self, u32, *SurfaceKHR) VkError!bool,
|
||||
};
|
||||
|
||||
pub fn init(allocator: std.mem.Allocator, instance: *Instance) VkError!Self {
|
||||
@@ -52,15 +58,15 @@ pub fn init(allocator: std.mem.Allocator, instance: *Instance) VkError!Self {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn createDevice(self: *Self, allocator: std.mem.Allocator, infos: *const vk.DeviceCreateInfo) VkError!*Device {
|
||||
pub inline fn createDevice(self: *Self, allocator: std.mem.Allocator, infos: *const vk.DeviceCreateInfo) VkError!*Device {
|
||||
return try self.dispatch_table.createDevice(self, allocator, infos);
|
||||
}
|
||||
|
||||
pub fn getFormatProperties(self: *Self, format: vk.Format) VkError!vk.FormatProperties {
|
||||
pub inline fn getFormatProperties(self: *Self, format: vk.Format) VkError!vk.FormatProperties {
|
||||
return try self.dispatch_table.getFormatProperties(self, format);
|
||||
}
|
||||
|
||||
pub fn getImageFormatProperties(
|
||||
pub inline fn getImageFormatProperties(
|
||||
self: *Self,
|
||||
format: vk.Format,
|
||||
image_type: vk.ImageType,
|
||||
@@ -71,7 +77,7 @@ pub fn getImageFormatProperties(
|
||||
return self.dispatch_table.getImageFormatProperties(self, format, image_type, tiling, usage, flags);
|
||||
}
|
||||
|
||||
pub fn getSparseImageFormatProperties(
|
||||
pub inline fn getSparseImageFormatProperties(
|
||||
self: *Self,
|
||||
format: vk.Format,
|
||||
image_type: vk.ImageType,
|
||||
@@ -83,6 +89,12 @@ pub fn getSparseImageFormatProperties(
|
||||
return self.dispatch_table.getSparseImageFormatProperties(self, format, image_type, samples, tiling, usage, properties);
|
||||
}
|
||||
|
||||
pub fn releasePhysicalDevice(self: *Self, allocator: std.mem.Allocator) VkError!void {
|
||||
self.queue_family_props.deinit(allocator);
|
||||
self.queue_family_props = .empty;
|
||||
try self.dispatch_table.release(self, allocator);
|
||||
}
|
||||
|
||||
pub fn getSparseImageFormatProperties2(
|
||||
self: *Self,
|
||||
format: vk.Format,
|
||||
@@ -98,8 +110,33 @@ pub fn getSparseImageFormatProperties2(
|
||||
0;
|
||||
}
|
||||
|
||||
pub fn releasePhysicalDevice(self: *Self, allocator: std.mem.Allocator) VkError!void {
|
||||
self.queue_family_props.deinit(allocator);
|
||||
self.queue_family_props = .empty;
|
||||
try self.dispatch_table.release(self, allocator);
|
||||
pub fn getSurfaceCapabilitiesKHR(_: *Self, surface: *SurfaceKHR, capabilities: *vk.SurfaceCapabilitiesKHR) VkError!void {
|
||||
capabilities.* = try surface.getCapabilities();
|
||||
}
|
||||
|
||||
pub fn getSurfaceFormatsKHR(_: *Self, _: *SurfaceKHR, count: *u32, p_formats: ?[*]vk.SurfaceFormatKHR) VkError!void {
|
||||
const surface_formats = SurfaceKHR.getFormats();
|
||||
count.* = surface_formats.len;
|
||||
if (p_formats) |formats| {
|
||||
for (formats[0..], surface_formats[0..]) |*format, surface_format| {
|
||||
format.* = surface_format;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getSurfacePresentModesKHR(_: *Self, _: *SurfaceKHR, count: *u32, p_modes: ?[*]vk.PresentModeKHR) VkError!void {
|
||||
const surface_modes = SurfaceKHR.getPresentModes();
|
||||
count.* = surface_modes.len;
|
||||
if (p_modes) |modes| {
|
||||
for (modes[0..], surface_modes[0..]) |*mode, surface_mode| {
|
||||
mode.* = surface_mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getSurfaceSupportKHR(self: *Self, queue_family_index: u32, surface: *SurfaceKHR) VkError!bool {
|
||||
return if (self.dispatch_table.getSurfaceSupportKHR) |pfn|
|
||||
pfn(self, queue_family_index, surface)
|
||||
else
|
||||
false;
|
||||
}
|
||||
|
||||
+40
-4
@@ -1,12 +1,18 @@
|
||||
const std = @import("std");
|
||||
const vk = @import("vulkan");
|
||||
|
||||
const Dispatchable = @import("Dispatchable.zig").Dispatchable;
|
||||
const VkError = @import("error_set.zig").VkError;
|
||||
const VulkanAllocator = @import("VulkanAllocator.zig");
|
||||
const errors = @import("error_set.zig");
|
||||
|
||||
const Dispatchable = @import("Dispatchable.zig").Dispatchable;
|
||||
const NonDispatchable = @import("NonDispatchable.zig").NonDispatchable;
|
||||
const VkError = errors.VkError;
|
||||
const VulkanAllocator = @import("VulkanAllocator.zig");
|
||||
const toVkResult = errors.toVkResult;
|
||||
|
||||
const BinarySemaphore = @import("BinarySemaphore.zig");
|
||||
const CommandBuffer = @import("CommandBuffer.zig");
|
||||
const Device = @import("Device.zig");
|
||||
const SwapchainKHR = @import("wsi/SwapchainKHR.zig");
|
||||
|
||||
const Fence = @import("Fence.zig");
|
||||
|
||||
@@ -76,7 +82,7 @@ pub inline fn bindSparse(self: *Self, info: []const vk.BindSparseInfo, fence: ?*
|
||||
try self.dispatch_table.bindSparse(self, info, fence);
|
||||
}
|
||||
|
||||
pub inline fn submit(self: *Self, infos: []const vk.SubmitInfo, p_fence: ?*Fence) VkError!void {
|
||||
pub fn submit(self: *Self, infos: []const vk.SubmitInfo, p_fence: ?*Fence) VkError!void {
|
||||
if (infos.len == 0) {
|
||||
if (p_fence) |fence| {
|
||||
try fence.signal();
|
||||
@@ -92,6 +98,36 @@ pub inline fn submit(self: *Self, infos: []const vk.SubmitInfo, p_fence: ?*Fence
|
||||
try self.dispatch_table.submit(self, submit_infos.items, p_fence);
|
||||
}
|
||||
|
||||
pub fn presentKHR(_: *Self, info: *const vk.PresentInfoKHR) VkError!void {
|
||||
if (info.p_wait_semaphores) |p_wait_semaphores| {
|
||||
for (p_wait_semaphores[0..], 0..info.wait_semaphore_count) |p_semaphore, _| {
|
||||
const semaphore = try NonDispatchable(BinarySemaphore).fromHandleObject(p_semaphore);
|
||||
// TODO: handle semaphores
|
||||
_ = semaphore;
|
||||
}
|
||||
}
|
||||
|
||||
var cmd_err: ?VkError = null;
|
||||
for (info.p_swapchains[0..], info.p_image_indices[0..], 0..info.swapchain_count) |p_swapchain, image_index, i| {
|
||||
const swapchain = try NonDispatchable(SwapchainKHR).fromHandleObject(p_swapchain);
|
||||
swapchain.present(image_index) catch |err| {
|
||||
if (info.p_results) |results| {
|
||||
results[i] = toVkResult(err);
|
||||
}
|
||||
if (cmd_err) |cmd_err_type|
|
||||
switch (cmd_err_type) {
|
||||
VkError.SuboptimalKhr => cmd_err = err,
|
||||
else => {},
|
||||
}
|
||||
else
|
||||
cmd_err = err;
|
||||
};
|
||||
}
|
||||
|
||||
if (cmd_err) |err|
|
||||
return err;
|
||||
}
|
||||
|
||||
pub inline fn waitIdle(self: *Self) VkError!void {
|
||||
try self.dispatch_table.waitIdle(self);
|
||||
}
|
||||
|
||||
+127
-16
@@ -84,7 +84,9 @@ const global_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
|
||||
});
|
||||
|
||||
const instance_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
|
||||
functionMapEntryPoint("vkCreateWaylandSurfaceKHR"),
|
||||
functionMapEntryPoint("vkDestroyInstance"),
|
||||
functionMapEntryPoint("vkDestroySurfaceKHR"),
|
||||
functionMapEntryPoint("vkEnumeratePhysicalDevices"),
|
||||
functionMapEntryPoint("vkGetDeviceProcAddr"),
|
||||
});
|
||||
@@ -106,11 +108,17 @@ const physical_device_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComp
|
||||
functionMapEntryPoint("vkGetPhysicalDeviceQueueFamilyProperties2KHR"),
|
||||
functionMapEntryPoint("vkGetPhysicalDeviceSparseImageFormatProperties"),
|
||||
functionMapEntryPoint("vkGetPhysicalDeviceSparseImageFormatProperties2KHR"),
|
||||
functionMapEntryPoint("vkGetPhysicalDeviceSurfaceCapabilitiesKHR"),
|
||||
functionMapEntryPoint("vkGetPhysicalDeviceSurfaceFormatsKHR"),
|
||||
functionMapEntryPoint("vkGetPhysicalDeviceSurfacePresentModesKHR"),
|
||||
functionMapEntryPoint("vkGetPhysicalDeviceSurfaceSupportKHR"),
|
||||
functionMapEntryPoint("vkGetPhysicalDeviceWaylandPresentationSupportKHR"),
|
||||
});
|
||||
|
||||
const device_pfn_map = block: {
|
||||
@setEvalBranchQuota(65535);
|
||||
break :block std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
|
||||
functionMapEntryPoint("vkAcquireNextImageKHR"),
|
||||
functionMapEntryPoint("vkAllocateCommandBuffers"),
|
||||
functionMapEntryPoint("vkAllocateDescriptorSets"),
|
||||
functionMapEntryPoint("vkAllocateDescriptorSets"),
|
||||
@@ -181,6 +189,7 @@ const device_pfn_map = block: {
|
||||
functionMapEntryPoint("vkCreateSampler"),
|
||||
functionMapEntryPoint("vkCreateSemaphore"),
|
||||
functionMapEntryPoint("vkCreateShaderModule"),
|
||||
functionMapEntryPoint("vkCreateSwapchainKHR"),
|
||||
functionMapEntryPoint("vkDestroyBuffer"),
|
||||
functionMapEntryPoint("vkDestroyBufferView"),
|
||||
functionMapEntryPoint("vkDestroyCommandPool"),
|
||||
@@ -200,6 +209,7 @@ const device_pfn_map = block: {
|
||||
functionMapEntryPoint("vkDestroySampler"),
|
||||
functionMapEntryPoint("vkDestroySemaphore"),
|
||||
functionMapEntryPoint("vkDestroyShaderModule"),
|
||||
functionMapEntryPoint("vkDestroySwapchainKHR"),
|
||||
functionMapEntryPoint("vkDeviceWaitIdle"),
|
||||
functionMapEntryPoint("vkEndCommandBuffer"),
|
||||
functionMapEntryPoint("vkFlushMappedMemoryRanges"),
|
||||
@@ -218,10 +228,12 @@ const device_pfn_map = block: {
|
||||
functionMapEntryPoint("vkGetPipelineCacheData"),
|
||||
functionMapEntryPoint("vkGetQueryPoolResults"),
|
||||
functionMapEntryPoint("vkGetRenderAreaGranularity"),
|
||||
functionMapEntryPoint("vkGetSwapchainImagesKHR"),
|
||||
functionMapEntryPoint("vkInvalidateMappedMemoryRanges"),
|
||||
functionMapEntryPoint("vkMapMemory"),
|
||||
functionMapEntryPoint("vkMergePipelineCaches"),
|
||||
functionMapEntryPoint("vkQueueBindSparse"),
|
||||
functionMapEntryPoint("vkQueuePresentKHR"),
|
||||
functionMapEntryPoint("vkQueueSubmit"),
|
||||
functionMapEntryPoint("vkQueueWaitIdle"),
|
||||
functionMapEntryPoint("vkResetCommandBuffer"),
|
||||
@@ -2194,6 +2206,19 @@ pub export fn strollResetCommandBuffer(p_cmd: vk.CommandBuffer, flags: vk.Comman
|
||||
|
||||
// WSI functions ===================================================================================================================================
|
||||
|
||||
pub export fn strollAcquireNextImageKHR(p_device: vk.Device, p_swapchain: vk.SwapchainKHR, timeout: u64, p_semaphore: vk.Semaphore, p_fence: vk.Fence, image_index: *u32) callconv(vk.vulkan_call_conv) vk.Result {
|
||||
entryPointBeginLogTrace(.vkAcquireNextImageKHR);
|
||||
defer entryPointEndLogTrace();
|
||||
|
||||
Dispatchable(Device).checkHandleValidity(p_device) 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 fence = NonDispatchable(Fence).fromHandleObject(p_fence) catch |err| return toVkResult(err);
|
||||
swapchain.getNextImage(timeout, semaphore, fence, image_index) catch |err| return toVkResult(err);
|
||||
return .success;
|
||||
}
|
||||
|
||||
pub export fn strollCreateSwapchainKHR(p_device: vk.Device, info: *const vk.SwapchainCreateInfoKHR, callbacks: ?*const vk.AllocationCallbacks, p_swapchain: *vk.SwapchainKHR) callconv(vk.vulkan_call_conv) vk.Result {
|
||||
entryPointBeginLogTrace(.vkCreateSwapchainKHR);
|
||||
defer entryPointEndLogTrace();
|
||||
@@ -2201,13 +2226,47 @@ pub export fn strollCreateSwapchainKHR(p_device: vk.Device, info: *const vk.Swap
|
||||
if (info.s_type != .swapchain_create_info_khr) {
|
||||
return .error_validation_failed;
|
||||
}
|
||||
|
||||
if (info.old_swapchain != .null_handle) {
|
||||
const old_swapchain = NonDispatchable(SwapchainKHR).fromHandleObject(info.old_swapchain) catch |err| return toVkResult(err);
|
||||
old_swapchain.detachSurface() catch |err| return toVkResult(err);
|
||||
}
|
||||
|
||||
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
|
||||
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 swapchain = SwapchainKHR.create(device, allocator, 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);
|
||||
return .success;
|
||||
}
|
||||
|
||||
pub export fn strollCreateWaylandSurfaceKHR(p_instance: vk.Instance, info: *const vk.WaylandSurfaceCreateInfoKHR, callbacks: ?*const vk.AllocationCallbacks, p_surface: *vk.SurfaceKHR) callconv(vk.vulkan_call_conv) vk.Result {
|
||||
entryPointBeginLogTrace(.vkCreateWaylandSurfaceKHR);
|
||||
defer entryPointEndLogTrace();
|
||||
|
||||
if (info.s_type != .wayland_surface_create_info_khr) {
|
||||
return .error_validation_failed;
|
||||
}
|
||||
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
|
||||
const instance = Dispatchable(Instance).fromHandleObject(p_instance) catch |err| return toVkResult(err);
|
||||
const surface = WaylandSurfaceKHR.create(instance, allocator, info) catch |err| return toVkResult(err);
|
||||
p_surface.* = (NonDispatchable(SurfaceKHR).wrap(allocator, surface) catch |err| return toVkResult(err)).toVkHandle(vk.SurfaceKHR);
|
||||
return .success;
|
||||
}
|
||||
|
||||
pub export fn strollDestroySurfaceKHR(p_instance: vk.Instance, p_surface: vk.SurfaceKHR, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void {
|
||||
entryPointBeginLogTrace(.vkDestroySurfaceKHR);
|
||||
defer entryPointEndLogTrace();
|
||||
|
||||
NonDispatchable(Instance).checkHandleValidity(p_instance) catch |err| return errorLogger(err);
|
||||
|
||||
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
|
||||
const non_dispatchable = NonDispatchable(SurfaceKHR).fromHandle(p_surface) catch |err| return errorLogger(err);
|
||||
non_dispatchable.intrusiveDestroy(allocator);
|
||||
}
|
||||
|
||||
pub export fn strollDestroySwapchainKHR(p_device: vk.Device, p_swapchain: vk.SwapchainKHR, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void {
|
||||
entryPointBeginLogTrace(.vkDestroySwapchainKHR);
|
||||
defer entryPointEndLogTrace();
|
||||
@@ -2219,27 +2278,79 @@ pub export fn strollDestroySwapchainKHR(p_device: vk.Device, p_swapchain: vk.Swa
|
||||
non_dispatchable.intrusiveDestroy(allocator);
|
||||
}
|
||||
|
||||
pub export fn strollCreateWaylandSurfaceKHR(p_device: vk.Device, info: *const vk.WaylandSurfaceCreateInfoKHR, callbacks: ?*const vk.AllocationCallbacks, p_surface: *vk.SurfaceKHR) callconv(vk.vulkan_call_conv) vk.Result {
|
||||
entryPointBeginLogTrace(.vkCreateWaylandSurfaceKHR);
|
||||
pub export fn strollGetPhysicalDeviceSurfaceCapabilitiesKHR(p_physical_device: vk.PhysicalDevice, p_surface: vk.SurfaceKHR, capabilities: *vk.SurfaceCapabilitiesKHR) callconv(vk.vulkan_call_conv) vk.Result {
|
||||
entryPointBeginLogTrace(.vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
|
||||
defer entryPointEndLogTrace();
|
||||
|
||||
if (info.s_type != .wayland_surface_create_info_khr) {
|
||||
return .error_validation_failed;
|
||||
}
|
||||
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
|
||||
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err);
|
||||
const surface = WaylandSurfaceKHR.create(device, allocator, info) catch |err| return toVkResult(err);
|
||||
p_surface.* = (NonDispatchable(SurfaceKHR).wrap(allocator, surface) catch |err| return toVkResult(err)).toVkHandle(vk.SurfaceKHR);
|
||||
const physical_device = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return toVkResult(err);
|
||||
const surface = NonDispatchable(SurfaceKHR).fromHandleObject(p_surface) catch |err| return toVkResult(err);
|
||||
physical_device.getSurfaceCapabilitiesKHR(surface, capabilities) catch |err| return toVkResult(err);
|
||||
return .success;
|
||||
}
|
||||
|
||||
pub export fn strollDestroySurfaceKHR(p_device: vk.Device, p_surface: vk.SurfaceKHR, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void {
|
||||
entryPointBeginLogTrace(.vkDestroySurfaceKHR);
|
||||
pub export fn strollGetPhysicalDeviceSurfaceFormatsKHR(p_physical_device: vk.PhysicalDevice, p_surface: vk.SurfaceKHR, count: *u32, p_formats: ?[*]vk.SurfaceFormatKHR) callconv(vk.vulkan_call_conv) vk.Result {
|
||||
entryPointBeginLogTrace(.vkGetPhysicalDeviceSurfaceFormatsKHR);
|
||||
defer entryPointEndLogTrace();
|
||||
|
||||
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err);
|
||||
|
||||
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
|
||||
const non_dispatchable = NonDispatchable(SurfaceKHR).fromHandle(p_surface) catch |err| return errorLogger(err);
|
||||
non_dispatchable.intrusiveDestroy(allocator);
|
||||
const physical_device = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return toVkResult(err);
|
||||
const surface = NonDispatchable(SurfaceKHR).fromHandleObject(p_surface) catch |err| return toVkResult(err);
|
||||
physical_device.getSurfaceFormatsKHR(surface, count, p_formats) catch |err| return toVkResult(err);
|
||||
return .success;
|
||||
}
|
||||
|
||||
pub export fn strollGetPhysicalDeviceSurfacePresentModesKHR(p_physical_device: vk.PhysicalDevice, p_surface: vk.SurfaceKHR, count: *u32, p_modes: ?[*]vk.PresentModeKHR) callconv(vk.vulkan_call_conv) vk.Result {
|
||||
entryPointBeginLogTrace(.vkGetPhysicalDeviceSurfacePresentModesKHR);
|
||||
defer entryPointEndLogTrace();
|
||||
|
||||
const physical_device = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return toVkResult(err);
|
||||
const surface = NonDispatchable(SurfaceKHR).fromHandleObject(p_surface) catch |err| return toVkResult(err);
|
||||
physical_device.getSurfacePresentModesKHR(surface, count, p_modes) catch |err| return toVkResult(err);
|
||||
return .success;
|
||||
}
|
||||
|
||||
pub export fn strollGetPhysicalDeviceSurfaceSupportKHR(p_physical_device: vk.PhysicalDevice, queue_family_index: u32, p_surface: vk.SurfaceKHR, p_supported: *vk.Bool32) callconv(vk.vulkan_call_conv) vk.Result {
|
||||
entryPointBeginLogTrace(.vkGetPhysicalDeviceSurfaceSupportKHR);
|
||||
defer entryPointEndLogTrace();
|
||||
|
||||
const physical_device = Dispatchable(PhysicalDevice).fromHandleObject(p_physical_device) catch |err| return toVkResult(err);
|
||||
const surface = NonDispatchable(SurfaceKHR).fromHandleObject(p_surface) catch |err| return toVkResult(err);
|
||||
p_supported.* = if (physical_device.getSurfaceSupportKHR(queue_family_index, surface) catch |err| return toVkResult(err)) .true else .false;
|
||||
return .success;
|
||||
}
|
||||
|
||||
pub export fn strollGetPhysicalDeviceWaylandPresentationSupportKHR(p_physical_device: vk.PhysicalDevice, _: u32, _: *anyopaque) callconv(vk.vulkan_call_conv) vk.Bool32 {
|
||||
entryPointBeginLogTrace(.vkGetPhysicalDeviceWaylandPresentationSupportKHR);
|
||||
defer entryPointEndLogTrace();
|
||||
|
||||
Dispatchable(PhysicalDevice).checkHandleValidity(p_physical_device) catch |err| errorLogger(err);
|
||||
return .true;
|
||||
}
|
||||
|
||||
pub export fn strollGetSwapchainImagesKHR(p_device: vk.Device, p_swapchain: vk.SwapchainKHR, count: *u32, p_images: ?[*]vk.Image) callconv(vk.vulkan_call_conv) vk.Result {
|
||||
entryPointBeginLogTrace(.vkGetSwapchainImagesKHR);
|
||||
defer entryPointEndLogTrace();
|
||||
|
||||
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return toVkResult(err);
|
||||
|
||||
const swapchain = NonDispatchable(SwapchainKHR).fromHandleObject(p_swapchain) catch |err| return toVkResult(err);
|
||||
count.* = @intCast(swapchain.images.len);
|
||||
if (p_images) |images| {
|
||||
for (images[0..], swapchain.images[0..]) |*image, swapchain_image| {
|
||||
image.* = NonDispatchable(Image).fromObject(swapchain_image.image).toVkHandle(vk.Image);
|
||||
}
|
||||
}
|
||||
|
||||
return .success;
|
||||
}
|
||||
|
||||
pub export fn strollQueuePresentKHR(p_queue: vk.Queue, info: *const vk.PresentInfoKHR) callconv(vk.vulkan_call_conv) vk.Result {
|
||||
entryPointBeginLogTrace(.vkQueuePresentKHR);
|
||||
defer entryPointEndLogTrace();
|
||||
|
||||
if (info.s_type != .present_info_khr) {
|
||||
return .error_validation_failed;
|
||||
}
|
||||
const queue = Dispatchable(Queue).fromHandleObject(p_queue) catch |err| return toVkResult(err);
|
||||
queue.presentKHR(info) catch |err| return toVkResult(err);
|
||||
return .success;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ const lib = @import("../lib.zig");
|
||||
|
||||
const VkError = @import("../error_set.zig").VkError;
|
||||
|
||||
const Device = @import("../Device.zig");
|
||||
const Instance = lib.Instance;
|
||||
const PresentImage = @import("PresentImage.zig");
|
||||
const SwapchainKHR = @import("SwapchainKHR.zig");
|
||||
|
||||
@@ -20,7 +20,7 @@ const present_modes = [_]vk.PresentModeKHR{
|
||||
.immediate_khr,
|
||||
};
|
||||
|
||||
owner: *Device,
|
||||
owner: *Instance,
|
||||
swapchain: ?*SwapchainKHR,
|
||||
|
||||
vtable: *const VTable,
|
||||
@@ -33,10 +33,10 @@ pub const VTable = struct {
|
||||
presentImage: *const fn (*Self, std.mem.Allocator, *PresentImage) VkError!void,
|
||||
};
|
||||
|
||||
pub fn init(device: *Device, allocator: std.mem.Allocator) VkError!Self {
|
||||
pub fn init(instance: *Instance, allocator: std.mem.Allocator) VkError!Self {
|
||||
_ = allocator;
|
||||
return .{
|
||||
.owner = device,
|
||||
.owner = instance,
|
||||
.swapchain = null,
|
||||
.vtable = undefined,
|
||||
};
|
||||
@@ -83,10 +83,10 @@ pub inline fn presentImage(self: *Self, allocator: std.mem.Allocator, image: *Pr
|
||||
try self.vtable.presentImage(self, allocator, image);
|
||||
}
|
||||
|
||||
pub inline fn getFormats() []vk.SurfaceFormatKHR {
|
||||
return formats;
|
||||
pub inline fn getFormats() []const vk.SurfaceFormatKHR {
|
||||
return &formats;
|
||||
}
|
||||
|
||||
pub inline fn getPresentModes() []vk.PresentModeKHR {
|
||||
return present_modes;
|
||||
pub inline fn getPresentModes() []const vk.PresentModeKHR {
|
||||
return &present_modes;
|
||||
}
|
||||
|
||||
@@ -4,16 +4,18 @@ const lib = @import("../lib.zig");
|
||||
|
||||
const VkError = @import("../error_set.zig").VkError;
|
||||
|
||||
const BinarySemaphore = lib.BinarySemaphore;
|
||||
const Device = @import("../Device.zig");
|
||||
const SurfaceKHR = @import("SurfaceKHR.zig");
|
||||
const Fence = lib.Fence;
|
||||
const Image = lib.Image;
|
||||
const PresentImage = @import("PresentImage.zig");
|
||||
const Image = @import("../Image.zig");
|
||||
const SurfaceKHR = lib.SurfaceKHR;
|
||||
|
||||
const Self = @This();
|
||||
pub const ObjectType: vk.ObjectType = .swapchain_khr;
|
||||
|
||||
owner: *Device,
|
||||
surface: *SurfaceKHR,
|
||||
surface: ?*SurfaceKHR,
|
||||
images: []PresentImage,
|
||||
|
||||
pub fn create(device: *Device, allocator: std.mem.Allocator, info: *const vk.SwapchainCreateInfoKHR) VkError!*Self {
|
||||
@@ -48,19 +50,58 @@ pub fn create(device: *Device, allocator: std.mem.Allocator, info: *const vk.Swa
|
||||
|
||||
self.* = .{
|
||||
.owner = device,
|
||||
.surface = undefined,
|
||||
.surface = null,
|
||||
.images = images,
|
||||
};
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn getImage(self: *const Self, index: usize) VkError!*Image {
|
||||
return if (index < self.images.len) self.images[index].image else VkError.Incomplete;
|
||||
pub fn getNextImage(self: *const Self, timeout: u64, semaphore: *BinarySemaphore, fence: *Fence, index: *u32) VkError!void {
|
||||
// TODO: handle timeout correctly
|
||||
|
||||
for (self.images, 0..) |*image, i| {
|
||||
if (image.state == .Available) {
|
||||
image.state = .Drawing;
|
||||
index.* = @intCast(i);
|
||||
// TODO: signal semaphore
|
||||
_ = semaphore;
|
||||
try fence.signal();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return if (timeout > 0) VkError.Timeout else VkError.NotReady;
|
||||
}
|
||||
|
||||
pub fn present(self: *Self, index: usize) VkError!void {
|
||||
const allocator = self.owner.host_allocator.allocator();
|
||||
|
||||
const image = &self.images[index];
|
||||
if (self.surface) |surface| {
|
||||
image.state = .Presenting;
|
||||
try surface.presentImage(allocator, image);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn detachSurface(self: *Self) VkError!void {
|
||||
const allocator = self.owner.host_allocator.allocator();
|
||||
|
||||
if (self.surface) |surface| {
|
||||
surface.swapchain = null;
|
||||
for (self.images) |*image| {
|
||||
if (image.state == .Available)
|
||||
try surface.detachImage(allocator, image);
|
||||
}
|
||||
}
|
||||
self.surface = null;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *Self, allocator: std.mem.Allocator) void {
|
||||
if (self.surface) |surface| {
|
||||
for (self.images) |*image| {
|
||||
surface.detachImage(allocator, image) catch {};
|
||||
image.deinit(allocator);
|
||||
}
|
||||
}
|
||||
allocator.destroy(self);
|
||||
}
|
||||
|
||||
@@ -6,14 +6,17 @@ const wayland = @import("clients/wayland.zig");
|
||||
const PresentImage = @import("PresentImage.zig");
|
||||
|
||||
const VkError = @import("../error_set.zig").VkError;
|
||||
const Device = @import("../Device.zig");
|
||||
const Instance = lib.Instance;
|
||||
|
||||
const Self = @This();
|
||||
pub const Interface = @import("SurfaceKHR.zig");
|
||||
|
||||
const WaylandImage = struct {
|
||||
buffer: *wayland.wl_buffer,
|
||||
data: []u8,
|
||||
data: []align(std.heap.page_size_min) u8,
|
||||
width: u32,
|
||||
height: u32,
|
||||
stride: u32,
|
||||
};
|
||||
|
||||
fn wlRegistryHandleGlobal(data: *anyopaque, registry: *wayland.wl_registry, name: c_uint, interface: [*:0]const u8, _: c_uint) callconv(.c) void {
|
||||
@@ -38,13 +41,13 @@ surface: *wayland.wl_surface,
|
||||
shm: *wayland.wl_shm,
|
||||
image_map: std.AutoHashMapUnmanaged(*PresentImage, *WaylandImage),
|
||||
|
||||
pub fn create(device: *Device, allocator: std.mem.Allocator, info: *const vk.WaylandSurfaceCreateInfoKHR) VkError!*Interface {
|
||||
pub fn create(instance: *Instance, allocator: std.mem.Allocator, info: *const vk.WaylandSurfaceCreateInfoKHR) VkError!*Interface {
|
||||
const self = allocator.create(Self) catch return VkError.OutOfHostMemory;
|
||||
errdefer allocator.destroy(self);
|
||||
|
||||
try wayland.load();
|
||||
|
||||
var interface = try Interface.init(device, allocator);
|
||||
var interface = try Interface.init(instance, allocator);
|
||||
|
||||
interface.vtable = &.{
|
||||
.destroy = destroy,
|
||||
@@ -84,21 +87,84 @@ pub fn getCapabilities(interface: *const Interface, capabilities: *vk.SurfaceCap
|
||||
|
||||
pub fn attachImage(interface: *Interface, allocator: std.mem.Allocator, image: *PresentImage) VkError!void {
|
||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||
_ = self;
|
||||
_ = image;
|
||||
_ = allocator;
|
||||
|
||||
if (self.image_map.contains(image))
|
||||
return;
|
||||
|
||||
const width: u32 = image.image.extent.width;
|
||||
const height: u32 = image.image.extent.height;
|
||||
|
||||
const stride: u32 = @intCast(image.image.getRowPitchMemSizeForMipLevel(.{ .color_bit = true }, 0));
|
||||
const size: usize = @as(usize, stride) * @as(usize, height);
|
||||
|
||||
const wl_image = allocator.create(WaylandImage) catch return VkError.OutOfHostMemory;
|
||||
errdefer allocator.destroy(wl_image);
|
||||
|
||||
const fd = try createShmFile(size);
|
||||
defer _ = std.c.close(fd);
|
||||
|
||||
const data = std.posix.mmap(null, size, .{ .READ = true, .WRITE = true }, .{ .TYPE = .SHARED }, fd, 0) catch return VkError.OutOfHostMemory;
|
||||
errdefer std.posix.munmap(data);
|
||||
|
||||
const pool = wayland.wl_shm_create_pool(self.shm, fd, @intCast(size)) orelse return VkError.Unknown;
|
||||
defer wayland.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;
|
||||
errdefer wayland.wl_buffer_destroy(buffer);
|
||||
|
||||
wl_image.* = .{
|
||||
.buffer = buffer,
|
||||
.data = data,
|
||||
.width = width,
|
||||
.height = height,
|
||||
.stride = stride,
|
||||
};
|
||||
|
||||
self.image_map.put(allocator, image, wl_image) catch return VkError.OutOfHostMemory;
|
||||
}
|
||||
|
||||
pub fn detachImage(interface: *Interface, allocator: std.mem.Allocator, image: *PresentImage) VkError!void {
|
||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||
_ = self;
|
||||
_ = image;
|
||||
_ = allocator;
|
||||
const entry = self.image_map.fetchRemove(image) orelse return;
|
||||
const wl_image = entry.value;
|
||||
|
||||
wayland.wl_buffer_destroy(wl_image.buffer);
|
||||
std.posix.munmap(wl_image.data);
|
||||
allocator.destroy(wl_image);
|
||||
}
|
||||
|
||||
pub fn presentImage(interface: *Interface, allocator: std.mem.Allocator, image: *PresentImage) VkError!void {
|
||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||
_ = self;
|
||||
_ = image;
|
||||
_ = allocator;
|
||||
|
||||
const wl_image = self.image_map.get(image) orelse return VkError.Unknown;
|
||||
|
||||
try image.image.copyToMemory(wl_image.data, .{
|
||||
.aspect_mask = .{ .color_bit = true },
|
||||
.mip_level = 0,
|
||||
.base_array_layer = 0,
|
||||
.layer_count = 1,
|
||||
});
|
||||
|
||||
wayland.wl_surface_attach(self.surface, wl_image.buffer, 0, 0);
|
||||
wayland.wl_surface_damage(self.surface, 0, 0, @intCast(wl_image.width), @intCast(wl_image.height));
|
||||
wayland.wl_surface_commit(self.surface);
|
||||
|
||||
// Better: bind wl_display_flush in wayland.zig and call it here.
|
||||
// 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;
|
||||
}
|
||||
|
||||
fn createShmFile(size: usize) VkError!std.posix.fd_t {
|
||||
const name = "stroll_vk_wayland_surface";
|
||||
|
||||
const fd = std.posix.memfd_create(name, std.posix.FD_CLOEXEC) catch return VkError.Unknown;
|
||||
errdefer std.c.close(fd);
|
||||
|
||||
_ = std.c.ftruncate(fd, @intCast(size));
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ pub const wl_registry_listener = extern struct {
|
||||
global_remove: *const fn (*anyopaque, *wl_registry, c_uint) callconv(.c) void,
|
||||
};
|
||||
|
||||
pub const WL_SHM_FORMAT_ARGB8888 = 0;
|
||||
|
||||
pub const wl_buffer = opaque {};
|
||||
pub const wl_callback = opaque {};
|
||||
pub const wl_display = vk.wl_display;
|
||||
@@ -42,8 +44,12 @@ pub fn load() VkError!void {
|
||||
if (ref_count.load(.monotonic) != 0)
|
||||
return;
|
||||
|
||||
module = std.DynLib.open("libwayland-client.so.0") catch return VkError.Unknown;
|
||||
module = std.DynLib.open("libwayland-client.so.0") catch {
|
||||
_ = ref_count.fetchSub(1, .monotonic);
|
||||
return VkError.Unknown;
|
||||
};
|
||||
errdefer module.close();
|
||||
errdefer std.debug.print("test {s}\n", .{std.c.dlerror().?});
|
||||
|
||||
// zig fmt: off
|
||||
wl_display_dispatch = module.lookup(@TypeOf(wl_display_dispatch), "wl_display_dispatch" ) orelse return VkError.Unknown;
|
||||
@@ -54,7 +60,7 @@ pub fn load() VkError!void {
|
||||
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_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;
|
||||
|
||||
Reference in New Issue
Block a user