adding base Image and ICD file generation
This commit is contained in:
18
build.zig
18
build.zig
@@ -5,6 +5,7 @@ const zcc = @import("compile_commands");
|
|||||||
const ImplementationDesc = struct {
|
const ImplementationDesc = struct {
|
||||||
name: []const u8,
|
name: []const u8,
|
||||||
root_source_file: []const u8,
|
root_source_file: []const u8,
|
||||||
|
vulkan_version: std.SemanticVersion,
|
||||||
custom: ?*const fn (*std.Build, *std.Build.Module) anyerror!void = null,
|
custom: ?*const fn (*std.Build, *std.Build.Module) anyerror!void = null,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -12,6 +13,7 @@ const implementations = [_]ImplementationDesc{
|
|||||||
.{
|
.{
|
||||||
.name = "soft",
|
.name = "soft",
|
||||||
.root_source_file = "src/soft/lib.zig",
|
.root_source_file = "src/soft/lib.zig",
|
||||||
|
.vulkan_version = .{ .major = 1, .minor = 0, .patch = 0 },
|
||||||
.custom = customSoft,
|
.custom = customSoft,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -29,6 +31,7 @@ pub fn build(b: *std.Build) !void {
|
|||||||
|
|
||||||
const zdt = b.dependency("zdt", .{}).module("zdt");
|
const zdt = b.dependency("zdt", .{}).module("zdt");
|
||||||
const vulkan_headers = b.dependency("vulkan_headers", .{});
|
const vulkan_headers = b.dependency("vulkan_headers", .{});
|
||||||
|
const vulkan_utility_libraries = b.dependency("vulkan_utility_libraries", .{});
|
||||||
|
|
||||||
const vulkan = b.dependency("vulkan_zig", .{
|
const vulkan = b.dependency("vulkan_zig", .{
|
||||||
.registry = vulkan_headers.path("registry/vk.xml"),
|
.registry = vulkan_headers.path("registry/vk.xml"),
|
||||||
@@ -37,6 +40,7 @@ pub fn build(b: *std.Build) !void {
|
|||||||
base_mod.addImport("zdt", zdt);
|
base_mod.addImport("zdt", zdt);
|
||||||
base_mod.addImport("vulkan", vulkan);
|
base_mod.addImport("vulkan", vulkan);
|
||||||
base_mod.addSystemIncludePath(vulkan_headers.path("include"));
|
base_mod.addSystemIncludePath(vulkan_headers.path("include"));
|
||||||
|
base_mod.addSystemIncludePath(vulkan_utility_libraries.path("include"));
|
||||||
|
|
||||||
for (implementations) |impl| {
|
for (implementations) |impl| {
|
||||||
var targets = std.ArrayList(*std.Build.Step.Compile){};
|
var targets = std.ArrayList(*std.Build.Step.Compile){};
|
||||||
@@ -64,6 +68,20 @@ pub fn build(b: *std.Build) !void {
|
|||||||
.linkage = .dynamic,
|
.linkage = .dynamic,
|
||||||
.use_llvm = true, // Fixes some random bugs happenning with custom backend. Investigations needed
|
.use_llvm = true, // Fixes some random bugs happenning with custom backend. Investigations needed
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const icd_file = b.addWriteFile(b.getInstallPath(.lib, b.fmt("vk_stroll_{s}.json", .{impl.name})), b.fmt(
|
||||||
|
\\{{
|
||||||
|
\\ "file_format_version": "1.0.1",
|
||||||
|
\\ "ICD": {{
|
||||||
|
\\ "library_path": "{s}",
|
||||||
|
\\ "api_version": "{}.{}.{}",
|
||||||
|
\\ "library_arch": "64",
|
||||||
|
\\ "is_portability_driver": false
|
||||||
|
\\ }}
|
||||||
|
\\}}
|
||||||
|
, .{ lib.out_lib_filename, impl.vulkan_version.major, impl.vulkan_version.minor, impl.vulkan_version.patch }));
|
||||||
|
|
||||||
|
lib.step.dependOn(&icd_file.step);
|
||||||
const lib_install = b.addInstallArtifact(lib, .{});
|
const lib_install = b.addInstallArtifact(lib, .{});
|
||||||
|
|
||||||
const lib_tests = b.addTest(.{ .root_module = lib_mod });
|
const lib_tests = b.addTest(.{ .root_module = lib_mod });
|
||||||
|
|||||||
@@ -17,6 +17,10 @@
|
|||||||
.url = "git+https://github.com/catmeow72/vulkan-zig/#8961518db28f88d2cf09ea68e146923de2cfa7f0",
|
.url = "git+https://github.com/catmeow72/vulkan-zig/#8961518db28f88d2cf09ea68e146923de2cfa7f0",
|
||||||
.hash = "vulkan-0.0.0-r7Ytx6hBAwD8X_TN32qlkzul4riK6vFvjtK9fZfRvALg",
|
.hash = "vulkan-0.0.0-r7Ytx6hBAwD8X_TN32qlkzul4riK6vFvjtK9fZfRvALg",
|
||||||
},
|
},
|
||||||
|
.vulkan_utility_libraries = .{
|
||||||
|
.url = "git+https://github.com/KhronosGroup/Vulkan-Utility-Libraries.git#ba452bad58bb4d4c64d7fbd872bf69f70141510e",
|
||||||
|
.hash = "N-V-__8AAE42fwC1FFw26LNZ8AaSuGMdgG4vfYkfV_227sET",
|
||||||
|
},
|
||||||
.zdt = .{
|
.zdt = .{
|
||||||
.url = "git+https://github.com/FObersteiner/zdt/?ref=v0.8.1#8b551a0a3e5ae64a32b5bad0e6a93119787b43af",
|
.url = "git+https://github.com/FObersteiner/zdt/?ref=v0.8.1#8b551a0a3e5ae64a32b5bad0e6a93119787b43af",
|
||||||
.hash = "zdt-0.8.1-xr0_vAxUDwCJRDh9pcAS_mdZBIsvcGTtN-K8JJSWY4I6",
|
.hash = "zdt-0.8.1-xr0_vAxUDwCJRDh9pcAS_mdZBIsvcGTtN-K8JJSWY4I6",
|
||||||
@@ -32,8 +36,8 @@
|
|||||||
.lazy = true,
|
.lazy = true,
|
||||||
},
|
},
|
||||||
.kvf = .{
|
.kvf = .{
|
||||||
.url = "git+https://github.com/Kbz-8/KVF#f633db3070033db1a9358fd4b5cae7b35245ed9d",
|
.url = "git+https://github.com/Kbz-8/KVF#98b845f876bea94f7bf1b9d30588cf617bf93452",
|
||||||
.hash = "N-V-__8AAPaHAgCFo6mTsjpxuOdPZSpYtFZlDOlRXeu499mJ",
|
.hash = "N-V-__8AAEGKAgC2cGDnxmAIFKkaICxS_ogfVYWH83Re29zN",
|
||||||
.lazy = true,
|
.lazy = true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const vk = @import("vulkan");
|
const vk = @import("vulkan");
|
||||||
|
const base = @import("base");
|
||||||
|
|
||||||
const cmd = @import("base").commands;
|
const cmd = base.commands;
|
||||||
|
const VkError = base.VkError;
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
@@ -13,17 +15,33 @@ pub fn deinit(self: *Self) void {
|
|||||||
_ = self;
|
_ = self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dispatch(self: *Self, command: *const cmd.Command) void {
|
pub fn dispatch(self: *Self, command: *const cmd.Command) VkError!void {
|
||||||
_ = self;
|
_ = self;
|
||||||
switch (command.*) {
|
switch (command.*) {
|
||||||
.FillBuffer => |data| fillBuffer(&data),
|
.CopyBuffer => |data| try copyBuffer(&data),
|
||||||
|
.FillBuffer => |data| try fillBuffer(&data),
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fillBuffer(data: *const cmd.CommandFillBuffer) void {
|
fn copyBuffer(data: *const cmd.CommandCopyBuffer) VkError!void {
|
||||||
const memory = if (data.buffer.memory) |memory| memory else unreachable;
|
for (data.regions) |region| {
|
||||||
const raw_memory_map: [*]u32 = @ptrCast(@alignCast(memory.map(data.offset, data.size) catch unreachable));
|
const src_memory = if (data.src.memory) |memory| memory else return VkError.ValidationFailed;
|
||||||
|
const dst_memory = if (data.dst.memory) |memory| memory else return VkError.ValidationFailed;
|
||||||
|
|
||||||
|
const src_map: []u8 = @as([*]u8, @ptrCast(try src_memory.map(region.src_offset, region.size)))[0..region.size];
|
||||||
|
const dst_map: []u8 = @as([*]u8, @ptrCast(try dst_memory.map(region.dst_offset, region.size)))[0..region.size];
|
||||||
|
|
||||||
|
@memcpy(dst_map, src_map);
|
||||||
|
|
||||||
|
src_memory.unmap();
|
||||||
|
dst_memory.unmap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fillBuffer(data: *const cmd.CommandFillBuffer) VkError!void {
|
||||||
|
const memory = if (data.buffer.memory) |memory| memory else return VkError.ValidationFailed;
|
||||||
|
const raw_memory_map: [*]u32 = @ptrCast(@alignCast(try memory.map(data.offset, data.size)));
|
||||||
var memory_map: []u32 = raw_memory_map[0..data.size];
|
var memory_map: []u32 = raw_memory_map[0..data.size];
|
||||||
|
|
||||||
for (0..@divExact(data.size, @sizeOf(u32))) |i| {
|
for (0..@divExact(data.size, @sizeOf(u32))) |i| {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v
|
|||||||
|
|
||||||
interface.dispatch_table = &.{
|
interface.dispatch_table = &.{
|
||||||
.begin = begin,
|
.begin = begin,
|
||||||
|
.copyBuffer = copyBuffer,
|
||||||
.end = end,
|
.end = end,
|
||||||
.fillBuffer = fillBuffer,
|
.fillBuffer = fillBuffer,
|
||||||
.reset = reset,
|
.reset = reset,
|
||||||
@@ -65,3 +66,11 @@ pub fn fillBuffer(interface: *Interface, buffer: *base.Buffer, offset: vk.Device
|
|||||||
_ = size;
|
_ = size;
|
||||||
_ = data;
|
_ = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn copyBuffer(interface: *Interface, src: *base.Buffer, dst: *base.Buffer, regions: []const vk.BufferCopy) VkError!void {
|
||||||
|
// No-op
|
||||||
|
_ = interface;
|
||||||
|
_ = src;
|
||||||
|
_ = dst;
|
||||||
|
_ = regions;
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,10 +11,9 @@ const SoftQueue = @import("SoftQueue.zig");
|
|||||||
const SoftBuffer = @import("SoftBuffer.zig");
|
const SoftBuffer = @import("SoftBuffer.zig");
|
||||||
const SoftDeviceMemory = @import("SoftDeviceMemory.zig");
|
const SoftDeviceMemory = @import("SoftDeviceMemory.zig");
|
||||||
const SoftFence = @import("SoftFence.zig");
|
const SoftFence = @import("SoftFence.zig");
|
||||||
|
const SoftImage = @import("SoftImage.zig");
|
||||||
|
|
||||||
const VkError = base.VkError;
|
const VkError = base.VkError;
|
||||||
const Dispatchable = base.Dispatchable;
|
|
||||||
const NonDispatchable = base.NonDispatchable;
|
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
pub const Interface = base.Device;
|
pub const Interface = base.Device;
|
||||||
@@ -41,6 +40,7 @@ pub fn create(physical_device: *base.PhysicalDevice, allocator: std.mem.Allocato
|
|||||||
.createBuffer = createBuffer,
|
.createBuffer = createBuffer,
|
||||||
.createCommandPool = createCommandPool,
|
.createCommandPool = createCommandPool,
|
||||||
.createFence = createFence,
|
.createFence = createFence,
|
||||||
|
.createImage = createImage,
|
||||||
.destroy = destroy,
|
.destroy = destroy,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -73,6 +73,12 @@ pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) VkError!void
|
|||||||
allocator.destroy(self);
|
allocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn allocateMemory(interface: *Interface, allocator: std.mem.Allocator, info: *const vk.MemoryAllocateInfo) VkError!*base.DeviceMemory {
|
||||||
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
|
const device_memory = try SoftDeviceMemory.create(self, allocator, info.allocation_size, info.memory_type_index);
|
||||||
|
return &device_memory.interface;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn createBuffer(interface: *Interface, allocator: std.mem.Allocator, info: *const vk.BufferCreateInfo) VkError!*base.Buffer {
|
pub fn createBuffer(interface: *Interface, allocator: std.mem.Allocator, info: *const vk.BufferCreateInfo) VkError!*base.Buffer {
|
||||||
const buffer = try SoftBuffer.create(interface, allocator, info);
|
const buffer = try SoftBuffer.create(interface, allocator, info);
|
||||||
return &buffer.interface;
|
return &buffer.interface;
|
||||||
@@ -88,8 +94,7 @@ pub fn createCommandPool(interface: *Interface, allocator: std.mem.Allocator, in
|
|||||||
return &pool.interface;
|
return &pool.interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn allocateMemory(interface: *Interface, allocator: std.mem.Allocator, info: *const vk.MemoryAllocateInfo) VkError!*base.DeviceMemory {
|
pub fn createImage(interface: *Interface, allocator: std.mem.Allocator, info: *const vk.ImageCreateInfo) VkError!*base.Image {
|
||||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
const image = try SoftImage.create(interface, allocator, info);
|
||||||
const device_memory = try SoftDeviceMemory.create(self, allocator, info.allocation_size, info.memory_type_index);
|
return &image.interface;
|
||||||
return &device_memory.interface;
|
|
||||||
}
|
}
|
||||||
|
|||||||
40
src/soft/SoftImage.zig
git.filemode.normal_file
40
src/soft/SoftImage.zig
git.filemode.normal_file
@@ -0,0 +1,40 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const vk = @import("vulkan");
|
||||||
|
const base = @import("base");
|
||||||
|
|
||||||
|
const lib = @import("lib.zig");
|
||||||
|
|
||||||
|
const VkError = base.VkError;
|
||||||
|
const Device = base.Device;
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
pub const Interface = base.Image;
|
||||||
|
|
||||||
|
interface: Interface,
|
||||||
|
|
||||||
|
pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const vk.ImageCreateInfo) VkError!*Self {
|
||||||
|
const self = allocator.create(Self) catch return VkError.OutOfHostMemory;
|
||||||
|
errdefer allocator.destroy(self);
|
||||||
|
|
||||||
|
var interface = try Interface.init(device, allocator, info);
|
||||||
|
|
||||||
|
interface.vtable = &.{
|
||||||
|
.destroy = destroy,
|
||||||
|
.getMemoryRequirements = getMemoryRequirements,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.* = .{
|
||||||
|
.interface = interface,
|
||||||
|
};
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void {
|
||||||
|
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||||
|
allocator.destroy(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getMemoryRequirements(interface: *Interface, requirements: *vk.MemoryRequirements) void {
|
||||||
|
_ = interface;
|
||||||
|
requirements.alignment = lib.MEMORY_REQUIREMENTS_ALIGNMENT;
|
||||||
|
}
|
||||||
@@ -35,8 +35,114 @@ pub fn create(allocator: std.mem.Allocator, instance: *const base.Instance) VkEr
|
|||||||
interface.props.device_id = root.DEVICE_ID;
|
interface.props.device_id = root.DEVICE_ID;
|
||||||
interface.props.device_type = .cpu;
|
interface.props.device_type = .cpu;
|
||||||
|
|
||||||
interface.props.limits.max_bound_descriptor_sets = 1024; // tmp
|
interface.props.limits = .{
|
||||||
interface.props.limits.max_memory_allocation_count = 1024;
|
.max_image_dimension_1d = 4096,
|
||||||
|
.max_image_dimension_2d = 4096,
|
||||||
|
.max_image_dimension_3d = 256,
|
||||||
|
.max_image_dimension_cube = 4096,
|
||||||
|
.max_image_array_layers = 256,
|
||||||
|
.max_texel_buffer_elements = 65536,
|
||||||
|
.max_uniform_buffer_range = 16384,
|
||||||
|
.max_storage_buffer_range = 134217728,
|
||||||
|
.max_push_constants_size = 128,
|
||||||
|
.max_memory_allocation_count = std.math.maxInt(u32),
|
||||||
|
.max_sampler_allocation_count = 4096,
|
||||||
|
.buffer_image_granularity = 131072,
|
||||||
|
.sparse_address_space_size = 0,
|
||||||
|
.max_bound_descriptor_sets = 4,
|
||||||
|
.max_per_stage_descriptor_samplers = 16,
|
||||||
|
.max_per_stage_descriptor_uniform_buffers = 12,
|
||||||
|
.max_per_stage_descriptor_storage_buffers = 4,
|
||||||
|
.max_per_stage_descriptor_sampled_images = 16,
|
||||||
|
.max_per_stage_descriptor_storage_images = 4,
|
||||||
|
.max_per_stage_descriptor_input_attachments = 4,
|
||||||
|
.max_per_stage_resources = 128,
|
||||||
|
.max_descriptor_set_samplers = 96,
|
||||||
|
.max_descriptor_set_uniform_buffers = 72,
|
||||||
|
.max_descriptor_set_uniform_buffers_dynamic = 8,
|
||||||
|
.max_descriptor_set_storage_buffers = 24,
|
||||||
|
.max_descriptor_set_storage_buffers_dynamic = 4,
|
||||||
|
.max_descriptor_set_sampled_images = 96,
|
||||||
|
.max_descriptor_set_storage_images = 24,
|
||||||
|
.max_descriptor_set_input_attachments = 4,
|
||||||
|
.max_vertex_input_attributes = 16,
|
||||||
|
.max_vertex_input_bindings = 16,
|
||||||
|
.max_vertex_input_attribute_offset = 2047,
|
||||||
|
.max_vertex_input_binding_stride = 2048,
|
||||||
|
.max_vertex_output_components = 64,
|
||||||
|
.max_tessellation_generation_level = 0,
|
||||||
|
.max_tessellation_patch_size = 0,
|
||||||
|
.max_tessellation_control_per_vertex_input_components = 0,
|
||||||
|
.max_tessellation_control_per_vertex_output_components = 0,
|
||||||
|
.max_tessellation_control_per_patch_output_components = 0,
|
||||||
|
.max_tessellation_control_total_output_components = 0,
|
||||||
|
.max_tessellation_evaluation_input_components = 0,
|
||||||
|
.max_tessellation_evaluation_output_components = 0,
|
||||||
|
.max_geometry_shader_invocations = 0,
|
||||||
|
.max_geometry_input_components = 0,
|
||||||
|
.max_geometry_output_components = 0,
|
||||||
|
.max_geometry_output_vertices = 0,
|
||||||
|
.max_geometry_total_output_components = 0,
|
||||||
|
.max_fragment_input_components = 64,
|
||||||
|
.max_fragment_output_attachments = 4,
|
||||||
|
.max_fragment_dual_src_attachments = 0,
|
||||||
|
.max_fragment_combined_output_resources = 4,
|
||||||
|
.max_compute_shared_memory_size = 16384,
|
||||||
|
.max_compute_work_group_count = .{ 65535, 65535, 65535 },
|
||||||
|
.max_compute_work_group_invocations = 128,
|
||||||
|
.max_compute_work_group_size = .{ 128, 128, 64 },
|
||||||
|
.sub_pixel_precision_bits = 4,
|
||||||
|
.sub_texel_precision_bits = 4,
|
||||||
|
.mipmap_precision_bits = 4,
|
||||||
|
.max_draw_indexed_index_value = 4294967295,
|
||||||
|
.max_draw_indirect_count = 65535,
|
||||||
|
.max_sampler_lod_bias = 2.0,
|
||||||
|
.max_sampler_anisotropy = 1.0,
|
||||||
|
.max_viewports = 1,
|
||||||
|
.max_viewport_dimensions = .{ 4096, 4096 },
|
||||||
|
.viewport_bounds_range = .{ -8192.0, 8191.0 },
|
||||||
|
.viewport_sub_pixel_bits = 0,
|
||||||
|
.min_memory_map_alignment = 64,
|
||||||
|
.min_texel_buffer_offset_alignment = 256,
|
||||||
|
.min_uniform_buffer_offset_alignment = 256,
|
||||||
|
.min_storage_buffer_offset_alignment = 256,
|
||||||
|
.min_texel_offset = -8,
|
||||||
|
.max_texel_offset = 7,
|
||||||
|
.min_texel_gather_offset = 0,
|
||||||
|
.max_texel_gather_offset = 0,
|
||||||
|
.min_interpolation_offset = 0.0,
|
||||||
|
.max_interpolation_offset = 0.0,
|
||||||
|
.sub_pixel_interpolation_offset_bits = 0,
|
||||||
|
.max_framebuffer_width = 4096,
|
||||||
|
.max_framebuffer_height = 4096,
|
||||||
|
.max_framebuffer_layers = 256,
|
||||||
|
.framebuffer_color_sample_counts = .{ .@"1_bit" = true, .@"4_bit" = true },
|
||||||
|
.framebuffer_depth_sample_counts = .{ .@"1_bit" = true, .@"4_bit" = true },
|
||||||
|
.framebuffer_stencil_sample_counts = .{ .@"1_bit" = true, .@"4_bit" = true },
|
||||||
|
.framebuffer_no_attachments_sample_counts = .{ .@"1_bit" = true, .@"4_bit" = true },
|
||||||
|
.max_color_attachments = 4,
|
||||||
|
.sampled_image_color_sample_counts = .{ .@"1_bit" = true, .@"4_bit" = true },
|
||||||
|
.sampled_image_integer_sample_counts = .{ .@"1_bit" = true, .@"4_bit" = true },
|
||||||
|
.sampled_image_depth_sample_counts = .{ .@"1_bit" = true, .@"4_bit" = true },
|
||||||
|
.sampled_image_stencil_sample_counts = .{ .@"1_bit" = true, .@"4_bit" = true },
|
||||||
|
.storage_image_sample_counts = .{ .@"1_bit" = true, .@"4_bit" = true },
|
||||||
|
.max_sample_mask_words = 1,
|
||||||
|
.timestamp_compute_and_graphics = .false,
|
||||||
|
.timestamp_period = 1.0,
|
||||||
|
.max_clip_distances = 0,
|
||||||
|
.max_cull_distances = 0,
|
||||||
|
.max_combined_clip_and_cull_distances = 0,
|
||||||
|
.discrete_queue_priorities = 2,
|
||||||
|
.point_size_range = .{ 1.0, 1.0 },
|
||||||
|
.line_width_range = .{ 1.0, 1.0 },
|
||||||
|
.point_size_granularity = 0.0,
|
||||||
|
.line_width_granularity = 0.0,
|
||||||
|
.strict_lines = .false,
|
||||||
|
.standard_sample_locations = .true,
|
||||||
|
.optimal_buffer_copy_offset_alignment = 1,
|
||||||
|
.optimal_buffer_copy_row_pitch_alignment = 1,
|
||||||
|
.non_coherent_atom_size = 256,
|
||||||
|
};
|
||||||
|
|
||||||
interface.mem_props.memory_type_count = 1;
|
interface.mem_props.memory_type_count = 1;
|
||||||
interface.mem_props.memory_types[0] = .{
|
interface.mem_props.memory_types[0] = .{
|
||||||
@@ -122,7 +228,13 @@ pub fn getImageFormatProperties(
|
|||||||
_ = tiling;
|
_ = tiling;
|
||||||
_ = usage;
|
_ = usage;
|
||||||
_ = flags;
|
_ = flags;
|
||||||
return VkError.FormatNotSupported;
|
return .{
|
||||||
|
.max_extent = undefined,
|
||||||
|
.max_mip_levels = 1,
|
||||||
|
.max_array_layers = 6,
|
||||||
|
.sample_counts = .{ .@"1_bit" = true, .@"4_bit" = true },
|
||||||
|
.max_resource_size = 0,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getSparseImageFormatProperties(
|
pub fn getSparseImageFormatProperties(
|
||||||
@@ -141,7 +253,7 @@ pub fn getSparseImageFormatProperties(
|
|||||||
_ = tiling;
|
_ = tiling;
|
||||||
_ = usage;
|
_ = usage;
|
||||||
_ = flags;
|
_ = flags;
|
||||||
return VkError.FormatNotSupported;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) VkError!void {
|
pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) VkError!void {
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ fn taskRunner(self: *Self, info: Interface.SubmitInfo, p_fence: ?*base.Fence) vo
|
|||||||
loop: for (info.command_buffers.items) |command_buffer| {
|
loop: for (info.command_buffers.items) |command_buffer| {
|
||||||
command_buffer.submit() catch continue :loop;
|
command_buffer.submit() catch continue :loop;
|
||||||
for (command_buffer.commands.items) |command| {
|
for (command_buffer.commands.items) |command| {
|
||||||
executor.dispatch(&command);
|
executor.dispatch(&command) catch |err| base.errors.errorLoggerContext(err, "the software command dispatcher");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ pub const SoftCommandBuffer = @import("SoftCommandBuffer.zig");
|
|||||||
pub const SoftCommandPool = @import("SoftCommandPool.zig");
|
pub const SoftCommandPool = @import("SoftCommandPool.zig");
|
||||||
pub const SoftDeviceMemory = @import("SoftDeviceMemory.zig");
|
pub const SoftDeviceMemory = @import("SoftDeviceMemory.zig");
|
||||||
pub const SoftFence = @import("SoftFence.zig");
|
pub const SoftFence = @import("SoftFence.zig");
|
||||||
|
pub const SoftImage = @import("SoftImage.zig");
|
||||||
|
|
||||||
pub const Instance = SoftInstance;
|
pub const Instance = SoftInstance;
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ dispatch_table: *const DispatchTable,
|
|||||||
|
|
||||||
pub const DispatchTable = struct {
|
pub const DispatchTable = struct {
|
||||||
begin: *const fn (*Self, *const vk.CommandBufferBeginInfo) VkError!void,
|
begin: *const fn (*Self, *const vk.CommandBufferBeginInfo) VkError!void,
|
||||||
|
copyBuffer: *const fn (*Self, *Buffer, *Buffer, []const vk.BufferCopy) VkError!void,
|
||||||
end: *const fn (*Self) VkError!void,
|
end: *const fn (*Self) VkError!void,
|
||||||
fillBuffer: *const fn (*Self, *Buffer, vk.DeviceSize, vk.DeviceSize, u32) VkError!void,
|
fillBuffer: *const fn (*Self, *Buffer, vk.DeviceSize, vk.DeviceSize, u32) VkError!void,
|
||||||
reset: *const fn (*Self, vk.CommandBufferResetFlags) VkError!void,
|
reset: *const fn (*Self, vk.CommandBufferResetFlags) VkError!void,
|
||||||
@@ -71,6 +72,7 @@ inline fn transitionState(self: *Self, target: State, from_allowed: []const Stat
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void {
|
pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void {
|
||||||
|
self.cleanCommandList();
|
||||||
self.commands.deinit(allocator);
|
self.commands.deinit(allocator);
|
||||||
self.vtable.destroy(self, allocator);
|
self.vtable.destroy(self, allocator);
|
||||||
}
|
}
|
||||||
@@ -94,6 +96,8 @@ pub inline fn reset(self: *Self, flags: vk.CommandBufferResetFlags) VkError!void
|
|||||||
if (!self.pool.flags.reset_command_buffer_bit) {
|
if (!self.pool.flags.reset_command_buffer_bit) {
|
||||||
return VkError.ValidationFailed;
|
return VkError.ValidationFailed;
|
||||||
}
|
}
|
||||||
|
defer self.cleanCommandList();
|
||||||
|
|
||||||
self.transitionState(.Initial, &.{ .Initial, .Recording, .Executable, .Invalid }) catch return VkError.ValidationFailed;
|
self.transitionState(.Initial, &.{ .Initial, .Recording, .Executable, .Invalid }) catch return VkError.ValidationFailed;
|
||||||
try self.dispatch_table.reset(self, flags);
|
try self.dispatch_table.reset(self, flags);
|
||||||
}
|
}
|
||||||
@@ -107,15 +111,19 @@ pub inline fn submit(self: *Self) VkError!void {
|
|||||||
self.transitionState(.Pending, &.{ .Pending, .Executable }) catch return VkError.ValidationFailed;
|
self.transitionState(.Pending, &.{ .Pending, .Executable }) catch return VkError.ValidationFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cleanCommandList(self: *Self) void {
|
||||||
|
const allocator = self.host_allocator.allocator();
|
||||||
|
_ = allocator;
|
||||||
|
for (self.commands.items) |command| {
|
||||||
|
switch (command) {
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Commands ====================================================================================================
|
// Commands ====================================================================================================
|
||||||
|
|
||||||
pub inline fn fillBuffer(self: *Self, buffer: *Buffer, offset: vk.DeviceSize, size: vk.DeviceSize, data: u32) VkError!void {
|
pub inline fn fillBuffer(self: *Self, buffer: *Buffer, offset: vk.DeviceSize, size: vk.DeviceSize, data: u32) VkError!void {
|
||||||
if (offset >= buffer.size) return VkError.ValidationFailed;
|
|
||||||
if (size != vk.WHOLE_SIZE and (size == 0 or size > offset + buffer.size)) return VkError.ValidationFailed;
|
|
||||||
if ((size != vk.WHOLE_SIZE and @mod(size, 4) != 0) or @mod(offset, 4) != 0) return VkError.ValidationFailed;
|
|
||||||
if (!buffer.usage.transfer_dst_bit) return VkError.ValidationFailed;
|
|
||||||
if (buffer.memory == null) return VkError.ValidationFailed;
|
|
||||||
|
|
||||||
const allocator = self.host_allocator.allocator();
|
const allocator = self.host_allocator.allocator();
|
||||||
self.commands.append(allocator, .{ .FillBuffer = .{
|
self.commands.append(allocator, .{ .FillBuffer = .{
|
||||||
.buffer = buffer,
|
.buffer = buffer,
|
||||||
@@ -125,3 +133,13 @@ pub inline fn fillBuffer(self: *Self, buffer: *Buffer, offset: vk.DeviceSize, si
|
|||||||
} }) catch return VkError.OutOfHostMemory;
|
} }) catch return VkError.OutOfHostMemory;
|
||||||
try self.dispatch_table.fillBuffer(self, buffer, offset, size, data);
|
try self.dispatch_table.fillBuffer(self, buffer, offset, size, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub inline fn copyBuffer(self: *Self, src: *Buffer, dst: *Buffer, regions: []const vk.BufferCopy) VkError!void {
|
||||||
|
const allocator = self.host_allocator.allocator();
|
||||||
|
self.commands.append(allocator, .{ .CopyBuffer = .{
|
||||||
|
.src = src,
|
||||||
|
.dst = dst,
|
||||||
|
.regions = regions,
|
||||||
|
} }) catch return VkError.OutOfHostMemory;
|
||||||
|
try self.dispatch_table.copyBuffer(self, src, dst, regions);
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ const CommandBuffer = @import("CommandBuffer.zig");
|
|||||||
const CommandPool = @import("CommandPool.zig");
|
const CommandPool = @import("CommandPool.zig");
|
||||||
const DeviceMemory = @import("DeviceMemory.zig");
|
const DeviceMemory = @import("DeviceMemory.zig");
|
||||||
const Fence = @import("Fence.zig");
|
const Fence = @import("Fence.zig");
|
||||||
|
const Image = @import("Image.zig");
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
pub const ObjectType: vk.ObjectType = .device;
|
pub const ObjectType: vk.ObjectType = .device;
|
||||||
@@ -35,6 +36,7 @@ pub const DispatchTable = struct {
|
|||||||
createBuffer: *const fn (*Self, std.mem.Allocator, *const vk.BufferCreateInfo) VkError!*Buffer,
|
createBuffer: *const fn (*Self, std.mem.Allocator, *const vk.BufferCreateInfo) VkError!*Buffer,
|
||||||
createCommandPool: *const fn (*Self, std.mem.Allocator, *const vk.CommandPoolCreateInfo) VkError!*CommandPool,
|
createCommandPool: *const fn (*Self, std.mem.Allocator, *const vk.CommandPoolCreateInfo) VkError!*CommandPool,
|
||||||
createFence: *const fn (*Self, std.mem.Allocator, *const vk.FenceCreateInfo) VkError!*Fence,
|
createFence: *const fn (*Self, std.mem.Allocator, *const vk.FenceCreateInfo) VkError!*Fence,
|
||||||
|
createImage: *const fn (*Self, std.mem.Allocator, *const vk.ImageCreateInfo) VkError!*Image,
|
||||||
destroy: *const fn (*Self, std.mem.Allocator) VkError!void,
|
destroy: *const fn (*Self, std.mem.Allocator) VkError!void,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -84,6 +86,10 @@ pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) VkError!void {
|
|||||||
try self.dispatch_table.destroy(self, allocator);
|
try self.dispatch_table.destroy(self, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub inline fn allocateMemory(self: *Self, allocator: std.mem.Allocator, info: *const vk.MemoryAllocateInfo) VkError!*DeviceMemory {
|
||||||
|
return self.dispatch_table.allocateMemory(self, allocator, info);
|
||||||
|
}
|
||||||
|
|
||||||
pub inline fn createBuffer(self: *Self, allocator: std.mem.Allocator, info: *const vk.BufferCreateInfo) VkError!*Buffer {
|
pub inline fn createBuffer(self: *Self, allocator: std.mem.Allocator, info: *const vk.BufferCreateInfo) VkError!*Buffer {
|
||||||
return self.dispatch_table.createBuffer(self, allocator, info);
|
return self.dispatch_table.createBuffer(self, allocator, info);
|
||||||
}
|
}
|
||||||
@@ -96,6 +102,6 @@ pub inline fn createCommandPool(self: *Self, allocator: std.mem.Allocator, info:
|
|||||||
return self.dispatch_table.createCommandPool(self, allocator, info);
|
return self.dispatch_table.createCommandPool(self, allocator, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn allocateMemory(self: *Self, allocator: std.mem.Allocator, info: *const vk.MemoryAllocateInfo) VkError!*DeviceMemory {
|
pub inline fn createImage(self: *Self, allocator: std.mem.Allocator, info: *const vk.ImageCreateInfo) VkError!*Image {
|
||||||
return self.dispatch_table.allocateMemory(self, allocator, info);
|
return self.dispatch_table.createImage(self, allocator, info);
|
||||||
}
|
}
|
||||||
|
|||||||
71
src/vulkan/Image.zig
git.filemode.normal_file
71
src/vulkan/Image.zig
git.filemode.normal_file
@@ -0,0 +1,71 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const vk = @import("vulkan");
|
||||||
|
const vku = @cImport({
|
||||||
|
@cInclude("vulkan/utility/vk_format_utils.h");
|
||||||
|
});
|
||||||
|
|
||||||
|
const VkError = @import("error_set.zig").VkError;
|
||||||
|
const DeviceMemory = @import("DeviceMemory.zig");
|
||||||
|
const Device = @import("Device.zig");
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
pub const ObjectType: vk.ObjectType = .image;
|
||||||
|
|
||||||
|
owner: *Device,
|
||||||
|
image_type: vk.ImageType,
|
||||||
|
format: vk.Format,
|
||||||
|
extent: vk.Extent3D,
|
||||||
|
mip_levels: u32,
|
||||||
|
array_layers: u32,
|
||||||
|
samples: vk.SampleCountFlags,
|
||||||
|
tiling: vk.ImageTiling,
|
||||||
|
usage: vk.ImageUsageFlags,
|
||||||
|
memory: ?*DeviceMemory,
|
||||||
|
memory_offset: vk.DeviceSize,
|
||||||
|
allowed_memory_types: std.bit_set.IntegerBitSet(32),
|
||||||
|
|
||||||
|
vtable: *const VTable,
|
||||||
|
|
||||||
|
pub const VTable = struct {
|
||||||
|
destroy: *const fn (*Self, std.mem.Allocator) void,
|
||||||
|
getMemoryRequirements: *const fn (*Self, *vk.MemoryRequirements) void,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.ImageCreateInfo) VkError!Self {
|
||||||
|
_ = allocator;
|
||||||
|
return .{
|
||||||
|
.owner = device,
|
||||||
|
.image_type = info.image_type,
|
||||||
|
.format = info.format,
|
||||||
|
.extent = info.extent,
|
||||||
|
.mip_levels = info.mip_levels,
|
||||||
|
.array_layers = info.array_layers,
|
||||||
|
.samples = info.samples,
|
||||||
|
.tiling = info.tiling,
|
||||||
|
.usage = info.usage,
|
||||||
|
.memory = null,
|
||||||
|
.memory_offset = 0,
|
||||||
|
.allowed_memory_types = std.bit_set.IntegerBitSet(32).initFull(),
|
||||||
|
.vtable = undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
if (offset >= self.size or !self.allowed_memory_types.isSet(memory.memory_type_index)) {
|
||||||
|
return VkError.ValidationFailed;
|
||||||
|
}
|
||||||
|
self.memory = memory;
|
||||||
|
self.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn getMemoryRequirements(self: *Self, requirements: *vk.MemoryRequirements) void {
|
||||||
|
const pixel_size = vku.vkuFormatTexelBlockSize(@intCast(@intFromEnum(self.format)));
|
||||||
|
|
||||||
|
requirements.size = self.extent.width * self.extent.height * self.extent.depth * pixel_size;
|
||||||
|
requirements.memory_type_bits = self.allowed_memory_types.mask;
|
||||||
|
self.vtable.getMemoryRequirements(self, requirements);
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ pub const CommandType = enum {
|
|||||||
pub const CommandCopyBuffer = struct {
|
pub const CommandCopyBuffer = struct {
|
||||||
src: *Buffer,
|
src: *Buffer,
|
||||||
dst: *Buffer,
|
dst: *Buffer,
|
||||||
regions: []*const vk.BufferCopy,
|
regions: []const vk.BufferCopy,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const CommandFillBuffer = struct {
|
pub const CommandFillBuffer = struct {
|
||||||
|
|||||||
@@ -56,6 +56,10 @@ pub inline fn errorLogger(err: VkError) void {
|
|||||||
std.log.scoped(.errorLogger).err("Error logger catched a '{s}'", .{@errorName(err)});
|
std.log.scoped(.errorLogger).err("Error logger catched a '{s}'", .{@errorName(err)});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub inline fn errorLoggerContext(err: VkError, context: []const u8) void {
|
||||||
|
std.log.scoped(.errorLogger).err("Error logger catched a '{s}' in {s}", .{ @errorName(err), context });
|
||||||
|
}
|
||||||
|
|
||||||
pub inline fn toVkResult(err: VkError) vk.Result {
|
pub inline fn toVkResult(err: VkError) vk.Result {
|
||||||
errorLogger(err);
|
errorLogger(err);
|
||||||
return switch (err) {
|
return switch (err) {
|
||||||
|
|||||||
@@ -4,10 +4,11 @@ const vk = @import("vulkan");
|
|||||||
pub const commands = @import("commands.zig");
|
pub const commands = @import("commands.zig");
|
||||||
pub const lib_vulkan = @import("lib_vulkan.zig");
|
pub const lib_vulkan = @import("lib_vulkan.zig");
|
||||||
pub const logger = @import("logger.zig");
|
pub const logger = @import("logger.zig");
|
||||||
|
pub const errors = @import("error_set.zig");
|
||||||
|
|
||||||
pub const Dispatchable = @import("Dispatchable.zig").Dispatchable;
|
pub const Dispatchable = @import("Dispatchable.zig").Dispatchable;
|
||||||
pub const NonDispatchable = @import("NonDispatchable.zig").NonDispatchable;
|
pub const NonDispatchable = @import("NonDispatchable.zig").NonDispatchable;
|
||||||
pub const VkError = @import("error_set.zig").VkError;
|
pub const VkError = errors.VkError;
|
||||||
pub const VulkanAllocator = @import("VulkanAllocator.zig");
|
pub const VulkanAllocator = @import("VulkanAllocator.zig");
|
||||||
|
|
||||||
pub const Instance = @import("Instance.zig");
|
pub const Instance = @import("Instance.zig");
|
||||||
@@ -20,6 +21,7 @@ pub const CommandBuffer = @import("CommandBuffer.zig");
|
|||||||
pub const CommandPool = @import("CommandPool.zig");
|
pub const CommandPool = @import("CommandPool.zig");
|
||||||
pub const DeviceMemory = @import("DeviceMemory.zig");
|
pub const DeviceMemory = @import("DeviceMemory.zig");
|
||||||
pub const Fence = @import("Fence.zig");
|
pub const Fence = @import("Fence.zig");
|
||||||
|
pub const Image = @import("Image.zig");
|
||||||
|
|
||||||
pub const VULKAN_VENDOR_ID = @typeInfo(vk.VendorId).@"enum".fields[@typeInfo(vk.VendorId).@"enum".fields.len - 1].value + 1;
|
pub const VULKAN_VENDOR_ID = @typeInfo(vk.VendorId).@"enum".fields[@typeInfo(vk.VendorId).@"enum".fields.len - 1].value + 1;
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ const CommandBuffer = @import("CommandBuffer.zig");
|
|||||||
const CommandPool = @import("CommandPool.zig");
|
const CommandPool = @import("CommandPool.zig");
|
||||||
const DeviceMemory = @import("DeviceMemory.zig");
|
const DeviceMemory = @import("DeviceMemory.zig");
|
||||||
const Fence = @import("Fence.zig");
|
const Fence = @import("Fence.zig");
|
||||||
|
const Image = @import("Image.zig");
|
||||||
|
|
||||||
fn entryPointBeginLogTrace(comptime scope: @Type(.enum_literal)) void {
|
fn entryPointBeginLogTrace(comptime scope: @Type(.enum_literal)) void {
|
||||||
std.log.scoped(scope).debug("Calling {s}...", .{@tagName(scope)});
|
std.log.scoped(scope).debug("Calling {s}...", .{@tagName(scope)});
|
||||||
@@ -43,6 +44,7 @@ fn entryPointNotFoundErrorLog(comptime scope: @Type(.enum_literal), name: []cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn functionMapEntryPoint(comptime name: []const u8) struct { []const u8, vk.PfnVoidFunction } {
|
fn functionMapEntryPoint(comptime name: []const u8) struct { []const u8, vk.PfnVoidFunction } {
|
||||||
|
// Mapping 'vkFnName' to 'strollFnName'
|
||||||
const stroll_name = std.fmt.comptimePrint("stroll{s}", .{name[2..]});
|
const stroll_name = std.fmt.comptimePrint("stroll{s}", .{name[2..]});
|
||||||
|
|
||||||
return if (std.meta.hasFn(@This(), name))
|
return if (std.meta.hasFn(@This(), name))
|
||||||
@@ -89,20 +91,24 @@ const device_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
|
|||||||
functionMapEntryPoint("vkAllocateMemory"),
|
functionMapEntryPoint("vkAllocateMemory"),
|
||||||
functionMapEntryPoint("vkBeginCommandBuffer"),
|
functionMapEntryPoint("vkBeginCommandBuffer"),
|
||||||
functionMapEntryPoint("vkBindBufferMemory"),
|
functionMapEntryPoint("vkBindBufferMemory"),
|
||||||
|
functionMapEntryPoint("vkCmdCopyBuffer"),
|
||||||
functionMapEntryPoint("vkCmdFillBuffer"),
|
functionMapEntryPoint("vkCmdFillBuffer"),
|
||||||
functionMapEntryPoint("vkCreateCommandPool"),
|
functionMapEntryPoint("vkCreateCommandPool"),
|
||||||
functionMapEntryPoint("vkCreateBuffer"),
|
functionMapEntryPoint("vkCreateBuffer"),
|
||||||
functionMapEntryPoint("vkCreateFence"),
|
functionMapEntryPoint("vkCreateFence"),
|
||||||
|
functionMapEntryPoint("vkCreateImage"),
|
||||||
functionMapEntryPoint("vkDestroyBuffer"),
|
functionMapEntryPoint("vkDestroyBuffer"),
|
||||||
functionMapEntryPoint("vkDestroyCommandPool"),
|
functionMapEntryPoint("vkDestroyCommandPool"),
|
||||||
functionMapEntryPoint("vkDestroyFence"),
|
|
||||||
functionMapEntryPoint("vkDestroyDevice"),
|
functionMapEntryPoint("vkDestroyDevice"),
|
||||||
|
functionMapEntryPoint("vkDestroyFence"),
|
||||||
|
functionMapEntryPoint("vkDestroyImage"),
|
||||||
functionMapEntryPoint("vkEndCommandBuffer"),
|
functionMapEntryPoint("vkEndCommandBuffer"),
|
||||||
functionMapEntryPoint("vkFreeCommandBuffers"),
|
functionMapEntryPoint("vkFreeCommandBuffers"),
|
||||||
functionMapEntryPoint("vkFreeMemory"),
|
functionMapEntryPoint("vkFreeMemory"),
|
||||||
|
functionMapEntryPoint("vkGetBufferMemoryRequirements"),
|
||||||
functionMapEntryPoint("vkGetDeviceQueue"),
|
functionMapEntryPoint("vkGetDeviceQueue"),
|
||||||
functionMapEntryPoint("vkGetFenceStatus"),
|
functionMapEntryPoint("vkGetFenceStatus"),
|
||||||
functionMapEntryPoint("vkGetBufferMemoryRequirements"),
|
functionMapEntryPoint("vkGetImageMemoryRequirements"),
|
||||||
functionMapEntryPoint("vkMapMemory"),
|
functionMapEntryPoint("vkMapMemory"),
|
||||||
functionMapEntryPoint("vkUnmapMemory"),
|
functionMapEntryPoint("vkUnmapMemory"),
|
||||||
functionMapEntryPoint("vkResetCommandBuffer"),
|
functionMapEntryPoint("vkResetCommandBuffer"),
|
||||||
@@ -302,7 +308,15 @@ pub export fn strollGetPhysicalDeviceFeatures(p_physical_device: vk.PhysicalDevi
|
|||||||
features.* = physical_device.features;
|
features.* = physical_device.features;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub export fn strollGetPhysicalDeviceImageFormatProperties(p_physical_device: vk.PhysicalDevice, format: vk.Format, image_type: vk.ImageType, tiling: vk.ImageTiling, usage: vk.ImageUsageFlags, flags: vk.ImageCreateFlags, properties: *vk.ImageFormatProperties) callconv(vk.vulkan_call_conv) vk.Result {
|
pub export fn strollGetPhysicalDeviceImageFormatProperties(
|
||||||
|
p_physical_device: vk.PhysicalDevice,
|
||||||
|
format: vk.Format,
|
||||||
|
image_type: vk.ImageType,
|
||||||
|
tiling: vk.ImageTiling,
|
||||||
|
usage: vk.ImageUsageFlags,
|
||||||
|
flags: vk.ImageCreateFlags,
|
||||||
|
properties: *vk.ImageFormatProperties,
|
||||||
|
) callconv(vk.vulkan_call_conv) vk.Result {
|
||||||
entryPointBeginLogTrace(.vkGetPhysicalDeviceImageFormatProperties);
|
entryPointBeginLogTrace(.vkGetPhysicalDeviceImageFormatProperties);
|
||||||
defer entryPointEndLogTrace();
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
@@ -491,6 +505,21 @@ pub export fn strollCreateFence(p_device: vk.Device, p_info: ?*const vk.FenceCre
|
|||||||
return .success;
|
return .success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub export fn strollCreateImage(p_device: vk.Device, p_info: ?*const vk.ImageCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_image: *vk.Image) callconv(vk.vulkan_call_conv) vk.Result {
|
||||||
|
entryPointBeginLogTrace(.vkCreateImage);
|
||||||
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
|
const info = p_info orelse return .error_validation_failed;
|
||||||
|
if (info.s_type != .image_create_info) {
|
||||||
|
return .error_validation_failed;
|
||||||
|
}
|
||||||
|
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
|
||||||
|
const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err);
|
||||||
|
const image = device.createImage(allocator, info) catch |err| return toVkResult(err);
|
||||||
|
p_image.* = (NonDispatchable(Image).wrap(allocator, image) catch |err| return toVkResult(err)).toVkHandle(vk.Image);
|
||||||
|
return .success;
|
||||||
|
}
|
||||||
|
|
||||||
pub export fn strollDestroyBuffer(p_device: vk.Device, p_buffer: vk.Buffer, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void {
|
pub export fn strollDestroyBuffer(p_device: vk.Device, p_buffer: vk.Buffer, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void {
|
||||||
entryPointBeginLogTrace(.vkDestroyBuffer);
|
entryPointBeginLogTrace(.vkDestroyBuffer);
|
||||||
defer entryPointEndLogTrace();
|
defer entryPointEndLogTrace();
|
||||||
@@ -537,6 +566,17 @@ pub export fn strollDestroyFence(p_device: vk.Device, p_fence: vk.Fence, callbac
|
|||||||
non_dispatchable.intrusiveDestroy(allocator);
|
non_dispatchable.intrusiveDestroy(allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub export fn strollDestroyImage(p_device: vk.Device, p_image: vk.Image, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void {
|
||||||
|
entryPointBeginLogTrace(.vkDestroyImage);
|
||||||
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
|
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err);
|
||||||
|
|
||||||
|
const allocator = VulkanAllocator.init(callbacks, .object).allocator();
|
||||||
|
const non_dispatchable = NonDispatchable(Image).fromHandle(p_image) catch |err| return errorLogger(err);
|
||||||
|
non_dispatchable.intrusiveDestroy(allocator);
|
||||||
|
}
|
||||||
|
|
||||||
pub export fn strollFreeCommandBuffers(p_device: vk.Device, p_pool: vk.CommandPool, count: u32, p_cmds: [*]const vk.CommandBuffer) callconv(vk.vulkan_call_conv) void {
|
pub export fn strollFreeCommandBuffers(p_device: vk.Device, p_pool: vk.CommandPool, count: u32, p_cmds: [*]const vk.CommandBuffer) callconv(vk.vulkan_call_conv) void {
|
||||||
entryPointBeginLogTrace(.vkFreeCommandBuffers);
|
entryPointBeginLogTrace(.vkFreeCommandBuffers);
|
||||||
defer entryPointEndLogTrace();
|
defer entryPointEndLogTrace();
|
||||||
@@ -559,6 +599,16 @@ pub export fn strollFreeMemory(p_device: vk.Device, p_memory: vk.DeviceMemory, c
|
|||||||
non_dispatchable.intrusiveDestroy(allocator);
|
non_dispatchable.intrusiveDestroy(allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub export fn strollGetBufferMemoryRequirements(p_device: vk.Device, p_buffer: vk.Buffer, requirements: *vk.MemoryRequirements) callconv(vk.vulkan_call_conv) void {
|
||||||
|
entryPointBeginLogTrace(.vkGetBufferMemoryRequirements);
|
||||||
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
|
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err);
|
||||||
|
|
||||||
|
const buffer = NonDispatchable(Buffer).fromHandleObject(p_buffer) catch |err| return errorLogger(err);
|
||||||
|
buffer.getMemoryRequirements(requirements);
|
||||||
|
}
|
||||||
|
|
||||||
pub export fn strollGetDeviceProcAddr(p_device: vk.Device, p_name: ?[*:0]const u8) callconv(vk.vulkan_call_conv) vk.PfnVoidFunction {
|
pub export fn strollGetDeviceProcAddr(p_device: vk.Device, p_name: ?[*:0]const u8) callconv(vk.vulkan_call_conv) vk.PfnVoidFunction {
|
||||||
if (lib.getLogVerboseLevel() == .TooMuch) {
|
if (lib.getLogVerboseLevel() == .TooMuch) {
|
||||||
entryPointBeginLogTrace(.vkGetDeviceProcAddr);
|
entryPointBeginLogTrace(.vkGetDeviceProcAddr);
|
||||||
@@ -605,14 +655,14 @@ pub export fn strollGetFenceStatus(p_device: vk.Device, p_fence: vk.Fence) callc
|
|||||||
return .success;
|
return .success;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub export fn strollGetBufferMemoryRequirements(p_device: vk.Device, p_buffer: vk.Buffer, requirements: *vk.MemoryRequirements) callconv(vk.vulkan_call_conv) void {
|
pub export fn strollGetImageMemoryRequirements(p_device: vk.Device, p_image: vk.Image, requirements: *vk.MemoryRequirements) callconv(vk.vulkan_call_conv) void {
|
||||||
entryPointBeginLogTrace(.vkGetBufferMemoryRequirements);
|
entryPointBeginLogTrace(.vkGetImageMemoryRequirements);
|
||||||
defer entryPointEndLogTrace();
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err);
|
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err);
|
||||||
|
|
||||||
const buffer = NonDispatchable(Buffer).fromHandleObject(p_buffer) catch |err| return errorLogger(err);
|
const image = NonDispatchable(Image).fromHandleObject(p_image) catch |err| return errorLogger(err);
|
||||||
buffer.getMemoryRequirements(requirements);
|
image.getMemoryRequirements(requirements);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub export fn strollMapMemory(p_device: vk.Device, p_memory: vk.DeviceMemory, offset: vk.DeviceSize, size: vk.DeviceSize, _: vk.MemoryMapFlags, pp_data: *?*anyopaque) callconv(vk.vulkan_call_conv) vk.Result {
|
pub export fn strollMapMemory(p_device: vk.Device, p_memory: vk.DeviceMemory, offset: vk.DeviceSize, size: vk.DeviceSize, _: vk.MemoryMapFlags, pp_data: *?*anyopaque) callconv(vk.vulkan_call_conv) vk.Result {
|
||||||
@@ -678,6 +728,16 @@ pub export fn strollBeginCommandBuffer(p_cmd: vk.CommandBuffer, p_info: ?*const
|
|||||||
return .success;
|
return .success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub export fn strollCmdCopyBuffer(p_cmd: vk.CommandBuffer, p_src: vk.Buffer, p_dst: vk.Buffer, count: u32, regions: [*]const vk.BufferCopy) callconv(vk.vulkan_call_conv) void {
|
||||||
|
entryPointBeginLogTrace(.vkCmdCopyBuffer);
|
||||||
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
|
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
|
||||||
|
const src = NonDispatchable(Buffer).fromHandleObject(p_src) catch |err| return errorLogger(err);
|
||||||
|
const dst = NonDispatchable(Buffer).fromHandleObject(p_dst) catch |err| return errorLogger(err);
|
||||||
|
cmd.copyBuffer(src, dst, regions[0..count]) catch |err| return errorLogger(err);
|
||||||
|
}
|
||||||
|
|
||||||
pub export fn strollCmdFillBuffer(p_cmd: vk.CommandBuffer, p_buffer: vk.Buffer, offset: vk.DeviceSize, size: vk.DeviceSize, data: u32) callconv(vk.vulkan_call_conv) void {
|
pub export fn strollCmdFillBuffer(p_cmd: vk.CommandBuffer, p_buffer: vk.Buffer, offset: vk.DeviceSize, size: vk.DeviceSize, data: u32) callconv(vk.vulkan_call_conv) void {
|
||||||
entryPointBeginLogTrace(.vkCmdFillBuffer);
|
entryPointBeginLogTrace(.vkCmdFillBuffer);
|
||||||
defer entryPointEndLogTrace();
|
defer entryPointEndLogTrace();
|
||||||
|
|||||||
@@ -20,6 +20,19 @@
|
|||||||
#define KVF_NO_KHR
|
#define KVF_NO_KHR
|
||||||
#include <kvf.h>
|
#include <kvf.h>
|
||||||
|
|
||||||
|
void CreateAndBindMemoryToBuffer(VkPhysicalDevice physical_device, VkDevice device, VkBuffer buffer, VkDeviceMemory* memory , VkDeviceSize size, VkMemoryPropertyFlags props)
|
||||||
|
{
|
||||||
|
VkMemoryRequirements requirements;
|
||||||
|
vkGetBufferMemoryRequirements(device, buffer, &requirements);
|
||||||
|
|
||||||
|
VkMemoryAllocateInfo alloc_info = {0};
|
||||||
|
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
|
alloc_info.allocationSize = size;
|
||||||
|
alloc_info.memoryTypeIndex = kvfFindMemoryType(physical_device, requirements.memoryTypeBits, props);
|
||||||
|
kvfCheckVk(vkAllocateMemory(device, &alloc_info, NULL, memory));
|
||||||
|
kvfCheckVk(vkBindBufferMemory(device, buffer, *memory, 0));
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
volkInitialize();
|
volkInitialize();
|
||||||
@@ -52,16 +65,15 @@ int main(void)
|
|||||||
VkDevice device = kvfCreateDevice(physical_device, NULL, 0, NULL);
|
VkDevice device = kvfCreateDevice(physical_device, NULL, 0, NULL);
|
||||||
volkLoadDevice(device);
|
volkLoadDevice(device);
|
||||||
|
|
||||||
VkBuffer buffer = kvfCreateBuffer(device, VK_BUFFER_USAGE_TRANSFER_DST_BIT, 256);
|
VkBuffer buffer = kvfCreateBuffer(device, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, 256);
|
||||||
|
VkDeviceMemory memory;
|
||||||
|
CreateAndBindMemoryToBuffer(physical_device, device, buffer, &memory, 256, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||||
|
|
||||||
VkDeviceMemory memory = VK_NULL_HANDLE;
|
VkBuffer buffer2 = kvfCreateBuffer(device, VK_BUFFER_USAGE_TRANSFER_DST_BIT, 256);
|
||||||
VkMemoryAllocateInfo alloc_info = {0};
|
VkDeviceMemory memory2;
|
||||||
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
CreateAndBindMemoryToBuffer(physical_device, device, buffer2, &memory2, 256, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
|
||||||
alloc_info.allocationSize = 256;
|
|
||||||
alloc_info.memoryTypeIndex = 0;
|
|
||||||
kvfCheckVk(vkAllocateMemory(device, &alloc_info, NULL, &memory));
|
|
||||||
|
|
||||||
kvfCheckVk(vkBindBufferMemory(device, buffer, memory, 0));
|
VkImage image = kvfCreateImage(device, 256, 256, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_LINEAR, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, KVF_IMAGE_COLOR);
|
||||||
|
|
||||||
VkQueue queue = kvfGetDeviceQueue(device, KVF_GRAPHICS_QUEUE);
|
VkQueue queue = kvfGetDeviceQueue(device, KVF_GRAPHICS_QUEUE);
|
||||||
VkFence fence = kvfCreateFence(device);
|
VkFence fence = kvfCreateFence(device);
|
||||||
@@ -71,7 +83,13 @@ int main(void)
|
|||||||
|
|
||||||
kvfBeginCommandBuffer(cmd, 0);
|
kvfBeginCommandBuffer(cmd, 0);
|
||||||
{
|
{
|
||||||
vkCmdFillBuffer(cmd, buffer, 0, VK_WHOLE_SIZE, 0x12ABCDEF);
|
vkCmdFillBuffer(cmd, buffer, 0, VK_WHOLE_SIZE, 0x600DCAFE);
|
||||||
|
|
||||||
|
VkBufferCopy region = {0};
|
||||||
|
region.srcOffset = 0;
|
||||||
|
region.dstOffset = 0;
|
||||||
|
region.size = 256;
|
||||||
|
vkCmdCopyBuffer(cmd, buffer, buffer2, 1, ®ion);
|
||||||
}
|
}
|
||||||
kvfEndCommandBuffer(cmd);
|
kvfEndCommandBuffer(cmd);
|
||||||
|
|
||||||
@@ -79,15 +97,19 @@ int main(void)
|
|||||||
kvfWaitForFence(device, fence);
|
kvfWaitForFence(device, fence);
|
||||||
|
|
||||||
uint32_t* map = NULL;
|
uint32_t* map = NULL;
|
||||||
kvfCheckVk(vkMapMemory(device, memory, 0, VK_WHOLE_SIZE, 0, (void**)&map));
|
kvfCheckVk(vkMapMemory(device, memory2, 0, VK_WHOLE_SIZE, 0, (void**)&map));
|
||||||
for(size_t i = 0; i < 64; i++)
|
for(size_t i = 0; i < 64; i++)
|
||||||
printf("0x%X%s", map[i], (i + 1 == 64 ? "" : " - "));
|
printf("0x%X ", map[i]);
|
||||||
puts("");
|
puts("");
|
||||||
vkUnmapMemory(device, memory);
|
vkUnmapMemory(device, memory2);
|
||||||
|
|
||||||
kvfDestroyFence(device, fence);
|
kvfDestroyFence(device, fence);
|
||||||
kvfDestroyBuffer(device, buffer);
|
kvfDestroyBuffer(device, buffer);
|
||||||
vkFreeMemory(device, memory, NULL);
|
vkFreeMemory(device, memory, NULL);
|
||||||
|
kvfDestroyBuffer(device, buffer2);
|
||||||
|
vkFreeMemory(device, memory2, NULL);
|
||||||
|
|
||||||
|
kvfDestroyImage(device, image);
|
||||||
|
|
||||||
kvfDestroyDevice(device);
|
kvfDestroyDevice(device);
|
||||||
kvfDestroyInstance(instance);
|
kvfDestroyInstance(instance);
|
||||||
|
|||||||
Reference in New Issue
Block a user