adding image to png export to C test
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,3 +4,4 @@ zig-out/
|
|||||||
*.o
|
*.o
|
||||||
.gdb_history
|
.gdb_history
|
||||||
*.json
|
*.json
|
||||||
|
*.png
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ pub fn build(b: *std.Build) !void {
|
|||||||
|
|
||||||
const volk = b.lazyDependency("volk", .{}) orelse continue;
|
const volk = b.lazyDependency("volk", .{}) orelse continue;
|
||||||
const kvf = b.lazyDependency("kvf", .{}) orelse continue;
|
const kvf = b.lazyDependency("kvf", .{}) orelse continue;
|
||||||
|
const stb = b.lazyDependency("stb", .{}) orelse continue;
|
||||||
|
|
||||||
const c_test_exe = b.addExecutable(.{
|
const c_test_exe = b.addExecutable(.{
|
||||||
.name = b.fmt("c_test_vulkan_{s}", .{impl.name}),
|
.name = b.fmt("c_test_vulkan_{s}", .{impl.name}),
|
||||||
@@ -104,6 +105,7 @@ pub fn build(b: *std.Build) !void {
|
|||||||
|
|
||||||
c_test_exe.root_module.addSystemIncludePath(volk.path(""));
|
c_test_exe.root_module.addSystemIncludePath(volk.path(""));
|
||||||
c_test_exe.root_module.addSystemIncludePath(kvf.path(""));
|
c_test_exe.root_module.addSystemIncludePath(kvf.path(""));
|
||||||
|
c_test_exe.root_module.addSystemIncludePath(stb.path(""));
|
||||||
c_test_exe.root_module.addSystemIncludePath(vulkan_headers.path("include"));
|
c_test_exe.root_module.addSystemIncludePath(vulkan_headers.path("include"));
|
||||||
|
|
||||||
c_test_exe.root_module.addCSourceFile(.{
|
c_test_exe.root_module.addCSourceFile(.{
|
||||||
|
|||||||
@@ -40,6 +40,10 @@
|
|||||||
.hash = "N-V-__8AAEGKAgC2cGDnxmAIFKkaICxS_ogfVYWH83Re29zN",
|
.hash = "N-V-__8AAEGKAgC2cGDnxmAIFKkaICxS_ogfVYWH83Re29zN",
|
||||||
.lazy = true,
|
.lazy = true,
|
||||||
},
|
},
|
||||||
|
.stb = .{
|
||||||
|
.url = "git+https://github.com/nothings/stb#f1c79c02822848a9bed4315b12c8c8f3761e1296",
|
||||||
|
.hash = "N-V-__8AABQ7TgCnPlp8MP4YA8znrjd6E-ZjpF1rvrS8J_2I",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
.paths = .{
|
.paths = .{
|
||||||
|
|||||||
@@ -18,12 +18,31 @@ pub fn deinit(self: *Self) void {
|
|||||||
pub fn dispatch(self: *Self, command: *const cmd.Command) VkError!void {
|
pub fn dispatch(self: *Self, command: *const cmd.Command) VkError!void {
|
||||||
_ = self;
|
_ = self;
|
||||||
switch (command.*) {
|
switch (command.*) {
|
||||||
|
.ClearColorImage => |data| try clearColorImage(&data),
|
||||||
.CopyBuffer => |data| try copyBuffer(&data),
|
.CopyBuffer => |data| try copyBuffer(&data),
|
||||||
|
.CopyImage => |data| try copyImage(&data),
|
||||||
.FillBuffer => |data| try fillBuffer(&data),
|
.FillBuffer => |data| try fillBuffer(&data),
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clearColorImage(data: *const cmd.CommandClearColorImage) VkError!void {
|
||||||
|
// TODO: use a blitter
|
||||||
|
|
||||||
|
const image = data.image;
|
||||||
|
for (data.ranges) |range| {
|
||||||
|
const image_size = image.getTotalSize();
|
||||||
|
|
||||||
|
const memory = if (image.memory) |memory| memory else return VkError.ValidationFailed;
|
||||||
|
var memory_map: []u32 = @as([*]u32, @ptrCast(@alignCast(try memory.map(0, image_size))))[0..image_size];
|
||||||
|
|
||||||
|
_ = range;
|
||||||
|
_ = &memory_map;
|
||||||
|
|
||||||
|
memory.unmap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn copyBuffer(data: *const cmd.CommandCopyBuffer) VkError!void {
|
fn copyBuffer(data: *const cmd.CommandCopyBuffer) VkError!void {
|
||||||
for (data.regions) |region| {
|
for (data.regions) |region| {
|
||||||
const src_memory = if (data.src.memory) |memory| memory else return VkError.ValidationFailed;
|
const src_memory = if (data.src.memory) |memory| memory else return VkError.ValidationFailed;
|
||||||
@@ -39,10 +58,13 @@ fn copyBuffer(data: *const cmd.CommandCopyBuffer) VkError!void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn copyImage(data: *const cmd.CommandCopyImage) VkError!void {
|
||||||
|
_ = data;
|
||||||
|
}
|
||||||
|
|
||||||
fn fillBuffer(data: *const cmd.CommandFillBuffer) VkError!void {
|
fn fillBuffer(data: *const cmd.CommandFillBuffer) VkError!void {
|
||||||
const memory = if (data.buffer.memory) |memory| memory else return VkError.ValidationFailed;
|
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 = @as([*]u32, @ptrCast(@alignCast(try memory.map(data.offset, data.size))))[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| {
|
||||||
memory_map[i] = data.data;
|
memory_map[i] = data.data;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getMemoryRequirements(interface: *Interface, requirements: *vk.MemoryRequirements) void {
|
pub fn getMemoryRequirements(interface: *Interface, requirements: *vk.MemoryRequirements) void {
|
||||||
requirements.alignment = lib.MEMORY_REQUIREMENTS_ALIGNMENT;
|
requirements.alignment = lib.MEMORY_REQUIREMENTS_BUFFER_ALIGNMENT;
|
||||||
if (interface.usage.uniform_texel_buffer_bit or interface.usage.uniform_texel_buffer_bit) {
|
if (interface.usage.uniform_texel_buffer_bit or interface.usage.uniform_texel_buffer_bit) {
|
||||||
requirements.alignment = @max(requirements.alignment, lib.MIN_TEXEL_BUFFER_ALIGNMENT);
|
requirements.alignment = @max(requirements.alignment, lib.MIN_TEXEL_BUFFER_ALIGNMENT);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v
|
|||||||
|
|
||||||
interface.dispatch_table = &.{
|
interface.dispatch_table = &.{
|
||||||
.begin = begin,
|
.begin = begin,
|
||||||
|
.clearColorImage = clearColorImage,
|
||||||
.copyBuffer = copyBuffer,
|
.copyBuffer = copyBuffer,
|
||||||
|
.copyImage = copyImage,
|
||||||
.end = end,
|
.end = end,
|
||||||
.fillBuffer = fillBuffer,
|
.fillBuffer = fillBuffer,
|
||||||
.reset = reset,
|
.reset = reset,
|
||||||
@@ -58,6 +60,15 @@ pub fn reset(interface: *Interface, flags: vk.CommandBufferResetFlags) VkError!v
|
|||||||
|
|
||||||
// Commands ====================================================================================================
|
// Commands ====================================================================================================
|
||||||
|
|
||||||
|
pub fn clearColorImage(interface: *Interface, image: *base.Image, layout: vk.ImageLayout, color: *const vk.ClearColorValue, ranges: []const vk.ImageSubresourceRange) VkError!void {
|
||||||
|
// No-op
|
||||||
|
_ = interface;
|
||||||
|
_ = image;
|
||||||
|
_ = layout;
|
||||||
|
_ = color;
|
||||||
|
_ = ranges;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fillBuffer(interface: *Interface, buffer: *base.Buffer, offset: vk.DeviceSize, size: vk.DeviceSize, data: u32) VkError!void {
|
pub fn fillBuffer(interface: *Interface, buffer: *base.Buffer, offset: vk.DeviceSize, size: vk.DeviceSize, data: u32) VkError!void {
|
||||||
// No-op
|
// No-op
|
||||||
_ = interface;
|
_ = interface;
|
||||||
@@ -74,3 +85,11 @@ pub fn copyBuffer(interface: *Interface, src: *base.Buffer, dst: *base.Buffer, r
|
|||||||
_ = dst;
|
_ = dst;
|
||||||
_ = regions;
|
_ = regions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn copyImage(interface: *Interface, src: *base.Image, dst: *base.Image, regions: []const vk.ImageCopy) VkError!void {
|
||||||
|
// No-op
|
||||||
|
_ = interface;
|
||||||
|
_ = src;
|
||||||
|
_ = dst;
|
||||||
|
_ = regions;
|
||||||
|
}
|
||||||
|
|||||||
@@ -36,5 +36,5 @@ pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void {
|
|||||||
|
|
||||||
pub fn getMemoryRequirements(interface: *Interface, requirements: *vk.MemoryRequirements) void {
|
pub fn getMemoryRequirements(interface: *Interface, requirements: *vk.MemoryRequirements) void {
|
||||||
_ = interface;
|
_ = interface;
|
||||||
requirements.alignment = lib.MEMORY_REQUIREMENTS_ALIGNMENT;
|
requirements.alignment = lib.MEMORY_REQUIREMENTS_IMAGE_ALIGNMENT;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ pub const DEVICE_ID = 0x600DCAFE;
|
|||||||
pub const MEMORY_TYPE_GENERIC_BIT = 0;
|
pub const MEMORY_TYPE_GENERIC_BIT = 0;
|
||||||
|
|
||||||
/// 16 bytes for 128-bit vector types.
|
/// 16 bytes for 128-bit vector types.
|
||||||
pub const MEMORY_REQUIREMENTS_ALIGNMENT = 16;
|
pub const MEMORY_REQUIREMENTS_BUFFER_ALIGNMENT = 16;
|
||||||
|
|
||||||
|
pub const MEMORY_REQUIREMENTS_IMAGE_ALIGNMENT = 256;
|
||||||
|
|
||||||
/// Vulkan 1.2 requires buffer offset alignment to be at most 256.
|
/// Vulkan 1.2 requires buffer offset alignment to be at most 256.
|
||||||
pub const MIN_TEXEL_BUFFER_ALIGNMENT = 256;
|
pub const MIN_TEXEL_BUFFER_ALIGNMENT = 256;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ const Device = @import("Device.zig");
|
|||||||
|
|
||||||
const Buffer = @import("Buffer.zig");
|
const Buffer = @import("Buffer.zig");
|
||||||
const CommandPool = @import("CommandPool.zig");
|
const CommandPool = @import("CommandPool.zig");
|
||||||
|
const Image = @import("Image.zig");
|
||||||
|
|
||||||
const COMMAND_BUFFER_BASE_CAPACITY = 256;
|
const COMMAND_BUFFER_BASE_CAPACITY = 256;
|
||||||
|
|
||||||
@@ -38,7 +39,9 @@ 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,
|
||||||
|
clearColorImage: *const fn (*Self, *Image, vk.ImageLayout, *const vk.ClearColorValue, []const vk.ImageSubresourceRange) VkError!void,
|
||||||
copyBuffer: *const fn (*Self, *Buffer, *Buffer, []const vk.BufferCopy) VkError!void,
|
copyBuffer: *const fn (*Self, *Buffer, *Buffer, []const vk.BufferCopy) VkError!void,
|
||||||
|
copyImage: *const fn (*Self, *Image, *Image, []const vk.ImageCopy) 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,
|
||||||
@@ -54,7 +57,7 @@ pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.Comma
|
|||||||
.pool = try NonDispatchable(CommandPool).fromHandleObject(info.command_pool),
|
.pool = try NonDispatchable(CommandPool).fromHandleObject(info.command_pool),
|
||||||
.state = .Initial,
|
.state = .Initial,
|
||||||
.begin_info = null,
|
.begin_info = null,
|
||||||
.host_allocator = VulkanAllocator.from(allocator).clone(),
|
.host_allocator = VulkanAllocator.from(allocator).cloneWithScope(.object),
|
||||||
.commands = std.ArrayList(cmd.Command).initCapacity(allocator, COMMAND_BUFFER_BASE_CAPACITY) catch return VkError.OutOfHostMemory,
|
.commands = std.ArrayList(cmd.Command).initCapacity(allocator, COMMAND_BUFFER_BASE_CAPACITY) catch return VkError.OutOfHostMemory,
|
||||||
.state_mutex = .{},
|
.state_mutex = .{},
|
||||||
.vtable = undefined,
|
.vtable = undefined,
|
||||||
@@ -113,9 +116,11 @@ pub inline fn submit(self: *Self) VkError!void {
|
|||||||
|
|
||||||
fn cleanCommandList(self: *Self) void {
|
fn cleanCommandList(self: *Self) void {
|
||||||
const allocator = self.host_allocator.allocator();
|
const allocator = self.host_allocator.allocator();
|
||||||
_ = allocator;
|
|
||||||
for (self.commands.items) |command| {
|
for (self.commands.items) |command| {
|
||||||
switch (command) {
|
switch (command) {
|
||||||
|
.ClearColorImage => |data| allocator.free(data.ranges),
|
||||||
|
.CopyBuffer => |data| allocator.free(data.regions),
|
||||||
|
.CopyImage => |data| allocator.free(data.regions),
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,6 +128,37 @@ fn cleanCommandList(self: *Self) void {
|
|||||||
|
|
||||||
// Commands ====================================================================================================
|
// Commands ====================================================================================================
|
||||||
|
|
||||||
|
pub inline fn clearColorImage(self: *Self, image: *Image, layout: vk.ImageLayout, color: *const vk.ClearColorValue, ranges: []const vk.ImageSubresourceRange) VkError!void {
|
||||||
|
const allocator = self.host_allocator.allocator();
|
||||||
|
self.commands.append(allocator, .{ .ClearColorImage = .{
|
||||||
|
.image = image,
|
||||||
|
.layout = layout,
|
||||||
|
.clear_color = color.*,
|
||||||
|
.ranges = allocator.dupe(vk.ImageSubresourceRange, ranges) catch return VkError.OutOfHostMemory,
|
||||||
|
} }) catch return VkError.OutOfHostMemory;
|
||||||
|
try self.dispatch_table.clearColorImage(self, image, layout, color, ranges);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = allocator.dupe(vk.BufferCopy, regions) catch return VkError.OutOfHostMemory,
|
||||||
|
} }) catch return VkError.OutOfHostMemory;
|
||||||
|
try self.dispatch_table.copyBuffer(self, src, dst, regions);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn copyImage(self: *Self, src: *Image, dst: *Image, regions: []const vk.ImageCopy) VkError!void {
|
||||||
|
const allocator = self.host_allocator.allocator();
|
||||||
|
self.commands.append(allocator, .{ .CopyImage = .{
|
||||||
|
.src = src,
|
||||||
|
.dst = dst,
|
||||||
|
.regions = allocator.dupe(vk.ImageCopy, regions) catch return VkError.OutOfHostMemory,
|
||||||
|
} }) catch return VkError.OutOfHostMemory;
|
||||||
|
try self.dispatch_table.copyImage(self, src, dst, regions);
|
||||||
|
}
|
||||||
|
|
||||||
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 {
|
||||||
const allocator = self.host_allocator.allocator();
|
const allocator = self.host_allocator.allocator();
|
||||||
self.commands.append(allocator, .{ .FillBuffer = .{
|
self.commands.append(allocator, .{ .FillBuffer = .{
|
||||||
@@ -133,13 +169,3 @@ 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);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const vk = @import("vulkan");
|
const vk = @import("vulkan");
|
||||||
const vku = @cImport({
|
const lib = @import("lib.zig");
|
||||||
@cInclude("vulkan/utility/vk_format_utils.h");
|
|
||||||
});
|
|
||||||
|
|
||||||
const VkError = @import("error_set.zig").VkError;
|
const VkError = @import("error_set.zig").VkError;
|
||||||
const DeviceMemory = @import("DeviceMemory.zig");
|
const DeviceMemory = @import("DeviceMemory.zig");
|
||||||
@@ -55,17 +53,35 @@ pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn bindMemory(self: *Self, memory: *DeviceMemory, offset: vk.DeviceSize) VkError!void {
|
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)) {
|
const image_size = self.getTotalSize();
|
||||||
|
if (offset >= image_size or !self.allowed_memory_types.isSet(memory.memory_type_index)) {
|
||||||
return VkError.ValidationFailed;
|
return VkError.ValidationFailed;
|
||||||
}
|
}
|
||||||
self.memory = memory;
|
self.memory = memory;
|
||||||
self.offset = offset;
|
self.memory_offset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn getMemoryRequirements(self: *Self, requirements: *vk.MemoryRequirements) void {
|
pub inline fn getMemoryRequirements(self: *Self, requirements: *vk.MemoryRequirements) void {
|
||||||
const pixel_size = vku.vkuFormatTexelBlockSize(@intCast(@intFromEnum(self.format)));
|
const image_size = self.getTotalSize();
|
||||||
|
requirements.size = image_size;
|
||||||
requirements.size = self.extent.width * self.extent.height * self.extent.depth * pixel_size;
|
|
||||||
requirements.memory_type_bits = self.allowed_memory_types.mask;
|
requirements.memory_type_bits = self.allowed_memory_types.mask;
|
||||||
self.vtable.getMemoryRequirements(self, requirements);
|
self.vtable.getMemoryRequirements(self, requirements);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub inline fn getClearFormat(self: *Self) vk.Format {
|
||||||
|
return if (lib.vku.vkuFormatIsSINT(@intCast(@intFromEnum(self.format))))
|
||||||
|
.r32g32b32a32_sint
|
||||||
|
else if (lib.vku.vkuFormatIsUINT(@intCast(@intFromEnum(self.format))))
|
||||||
|
.r32g32b32a32_uint
|
||||||
|
else
|
||||||
|
.r32g32b32a32_sfloat;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn getPixelSize(self: *Self) usize {
|
||||||
|
return lib.vku.vkuFormatTexelBlockSize(@intCast(@intFromEnum(self.format)));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn getTotalSize(self: *Self) usize {
|
||||||
|
const pixel_size = self.getPixelSize();
|
||||||
|
return self.extent.width * self.extent.height * self.extent.depth * pixel_size;
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,11 +2,14 @@ const std = @import("std");
|
|||||||
const vk = @import("vulkan");
|
const vk = @import("vulkan");
|
||||||
|
|
||||||
const Buffer = @import("Buffer.zig");
|
const Buffer = @import("Buffer.zig");
|
||||||
|
const Image = @import("Image.zig");
|
||||||
|
|
||||||
pub const CommandType = enum {
|
pub const CommandType = enum {
|
||||||
BindPipeline,
|
BindPipeline,
|
||||||
BindVertexBuffer,
|
BindVertexBuffer,
|
||||||
|
ClearColorImage,
|
||||||
CopyBuffer,
|
CopyBuffer,
|
||||||
|
CopyImage,
|
||||||
Draw,
|
Draw,
|
||||||
DrawIndexed,
|
DrawIndexed,
|
||||||
DrawIndexedIndirect,
|
DrawIndexedIndirect,
|
||||||
@@ -14,32 +17,36 @@ pub const CommandType = enum {
|
|||||||
FillBuffer,
|
FillBuffer,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const CommandCopyBuffer = struct {
|
pub const CommandBindPipeline = struct {
|
||||||
src: *Buffer,
|
bind_point: vk.PipelineBindPoint,
|
||||||
dst: *Buffer,
|
|
||||||
regions: []const vk.BufferCopy,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const CommandFillBuffer = struct {
|
|
||||||
buffer: *Buffer,
|
|
||||||
offset: vk.DeviceSize,
|
|
||||||
size: vk.DeviceSize,
|
|
||||||
data: u32,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const CommandBindVertexBuffer = struct {
|
pub const CommandBindVertexBuffer = struct {
|
||||||
buffers: []*const Buffer,
|
buffers: []*const Buffer,
|
||||||
offsets: []vk.DeviceSize,
|
offsets: []vk.DeviceSize,
|
||||||
first_binding: u32,
|
first_binding: u32,
|
||||||
};
|
};
|
||||||
|
pub const CommandClearColorImage = struct {
|
||||||
|
image: *Image,
|
||||||
|
layout: vk.ImageLayout,
|
||||||
|
clear_color: vk.ClearColorValue,
|
||||||
|
ranges: []const vk.ImageSubresourceRange,
|
||||||
|
};
|
||||||
|
pub const CommandCopyBuffer = struct {
|
||||||
|
src: *Buffer,
|
||||||
|
dst: *Buffer,
|
||||||
|
regions: []const vk.BufferCopy,
|
||||||
|
};
|
||||||
|
pub const CommandCopyImage = struct {
|
||||||
|
src: *Image,
|
||||||
|
dst: *Image,
|
||||||
|
regions: []const vk.ImageCopy,
|
||||||
|
};
|
||||||
pub const CommandDraw = struct {
|
pub const CommandDraw = struct {
|
||||||
vertex_count: u32,
|
vertex_count: u32,
|
||||||
instance_count: u32,
|
instance_count: u32,
|
||||||
first_vertex: u32,
|
first_vertex: u32,
|
||||||
first_instance: u32,
|
first_instance: u32,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const CommandDrawIndexed = struct {
|
pub const CommandDrawIndexed = struct {
|
||||||
index_count: u32,
|
index_count: u32,
|
||||||
instance_count: u32,
|
instance_count: u32,
|
||||||
@@ -47,29 +54,31 @@ pub const CommandDrawIndexed = struct {
|
|||||||
vertex_offset: i32,
|
vertex_offset: i32,
|
||||||
first_instance: u32,
|
first_instance: u32,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const CommandDrawIndirect = struct {
|
|
||||||
buffer: *Buffer,
|
|
||||||
offset: vk.DeviceSize,
|
|
||||||
count: u32,
|
|
||||||
stride: u32,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const CommandDrawIndexedIndirect = struct {
|
pub const CommandDrawIndexedIndirect = struct {
|
||||||
buffer: *Buffer,
|
buffer: *Buffer,
|
||||||
offset: vk.DeviceSize,
|
offset: vk.DeviceSize,
|
||||||
count: u32,
|
count: u32,
|
||||||
stride: u32,
|
stride: u32,
|
||||||
};
|
};
|
||||||
|
pub const CommandDrawIndirect = struct {
|
||||||
pub const CommandBindPipeline = struct {
|
buffer: *Buffer,
|
||||||
bind_point: vk.PipelineBindPoint,
|
offset: vk.DeviceSize,
|
||||||
|
count: u32,
|
||||||
|
stride: u32,
|
||||||
|
};
|
||||||
|
pub const CommandFillBuffer = struct {
|
||||||
|
buffer: *Buffer,
|
||||||
|
offset: vk.DeviceSize,
|
||||||
|
size: vk.DeviceSize,
|
||||||
|
data: u32,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Command = union(CommandType) {
|
pub const Command = union(CommandType) {
|
||||||
BindPipeline: CommandBindPipeline,
|
BindPipeline: CommandBindPipeline,
|
||||||
BindVertexBuffer: CommandBindVertexBuffer,
|
BindVertexBuffer: CommandBindVertexBuffer,
|
||||||
|
ClearColorImage: CommandClearColorImage,
|
||||||
CopyBuffer: CommandCopyBuffer,
|
CopyBuffer: CommandCopyBuffer,
|
||||||
|
CopyImage: CommandCopyImage,
|
||||||
Draw: CommandDraw,
|
Draw: CommandDraw,
|
||||||
DrawIndexed: CommandDrawIndexed,
|
DrawIndexed: CommandDrawIndexed,
|
||||||
DrawIndexedIndirect: CommandDrawIndexedIndirect,
|
DrawIndexedIndirect: CommandDrawIndexedIndirect,
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const vk = @import("vulkan");
|
const vk = @import("vulkan");
|
||||||
|
pub const vku = @cImport({
|
||||||
|
@cInclude("vulkan/utility/vk_format_utils.h");
|
||||||
|
});
|
||||||
|
|
||||||
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");
|
||||||
|
|||||||
@@ -91,7 +91,10 @@ const device_pfn_map = std.StaticStringMap(vk.PfnVoidFunction).initComptime(.{
|
|||||||
functionMapEntryPoint("vkAllocateMemory"),
|
functionMapEntryPoint("vkAllocateMemory"),
|
||||||
functionMapEntryPoint("vkBeginCommandBuffer"),
|
functionMapEntryPoint("vkBeginCommandBuffer"),
|
||||||
functionMapEntryPoint("vkBindBufferMemory"),
|
functionMapEntryPoint("vkBindBufferMemory"),
|
||||||
|
functionMapEntryPoint("vkBindImageMemory"),
|
||||||
|
functionMapEntryPoint("vkCmdClearColorImage"),
|
||||||
functionMapEntryPoint("vkCmdCopyBuffer"),
|
functionMapEntryPoint("vkCmdCopyBuffer"),
|
||||||
|
functionMapEntryPoint("vkCmdCopyImage"),
|
||||||
functionMapEntryPoint("vkCmdFillBuffer"),
|
functionMapEntryPoint("vkCmdFillBuffer"),
|
||||||
functionMapEntryPoint("vkCreateCommandPool"),
|
functionMapEntryPoint("vkCreateCommandPool"),
|
||||||
functionMapEntryPoint("vkCreateBuffer"),
|
functionMapEntryPoint("vkCreateBuffer"),
|
||||||
@@ -458,6 +461,21 @@ pub export fn strollBindBufferMemory(p_device: vk.Device, p_buffer: vk.Buffer, p
|
|||||||
return .success;
|
return .success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub export fn strollBindImageMemory(p_device: vk.Device, p_image: vk.Image, p_memory: vk.DeviceMemory, offset: vk.DeviceSize) callconv(vk.vulkan_call_conv) vk.Result {
|
||||||
|
entryPointBeginLogTrace(.vkBindImageMemory);
|
||||||
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
|
std.log.scoped(.vkBindImageMemory).debug("Binding device memory 0x{X} to image 0x{X}", .{ @intFromEnum(p_memory), @intFromEnum(p_image) });
|
||||||
|
|
||||||
|
Dispatchable(Device).checkHandleValidity(p_device) catch |err| return toVkResult(err);
|
||||||
|
|
||||||
|
const image = NonDispatchable(Image).fromHandleObject(p_image) catch |err| return toVkResult(err);
|
||||||
|
const memory = NonDispatchable(DeviceMemory).fromHandleObject(p_memory) catch |err| return toVkResult(err);
|
||||||
|
|
||||||
|
image.bindMemory(memory, offset) catch |err| return toVkResult(err);
|
||||||
|
return .success;
|
||||||
|
}
|
||||||
|
|
||||||
pub export fn strollCreateBuffer(p_device: vk.Device, p_info: ?*const vk.BufferCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_buffer: *vk.Buffer) callconv(vk.vulkan_call_conv) vk.Result {
|
pub export fn strollCreateBuffer(p_device: vk.Device, p_info: ?*const vk.BufferCreateInfo, callbacks: ?*const vk.AllocationCallbacks, p_buffer: *vk.Buffer) callconv(vk.vulkan_call_conv) vk.Result {
|
||||||
entryPointBeginLogTrace(.vkCreateBuffer);
|
entryPointBeginLogTrace(.vkCreateBuffer);
|
||||||
defer entryPointEndLogTrace();
|
defer entryPointEndLogTrace();
|
||||||
@@ -728,6 +746,15 @@ pub export fn strollBeginCommandBuffer(p_cmd: vk.CommandBuffer, p_info: ?*const
|
|||||||
return .success;
|
return .success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub export fn strollCmdClearColorImage(p_cmd: vk.CommandBuffer, p_image: vk.Image, layout: vk.ImageLayout, color: *const vk.ClearColorValue, count: u32, ranges: [*]const vk.ImageSubresourceRange) callconv(vk.vulkan_call_conv) void {
|
||||||
|
entryPointBeginLogTrace(.vkCmdCopyImage);
|
||||||
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
|
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
|
||||||
|
const image = NonDispatchable(Image).fromHandleObject(p_image) catch |err| return errorLogger(err);
|
||||||
|
cmd.clearColorImage(image, layout, color, ranges[0..count]) catch |err| return errorLogger(err);
|
||||||
|
}
|
||||||
|
|
||||||
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 {
|
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);
|
entryPointBeginLogTrace(.vkCmdCopyBuffer);
|
||||||
defer entryPointEndLogTrace();
|
defer entryPointEndLogTrace();
|
||||||
@@ -738,6 +765,16 @@ pub export fn strollCmdCopyBuffer(p_cmd: vk.CommandBuffer, p_src: vk.Buffer, p_d
|
|||||||
cmd.copyBuffer(src, dst, regions[0..count]) catch |err| return errorLogger(err);
|
cmd.copyBuffer(src, dst, regions[0..count]) catch |err| return errorLogger(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub export fn strollCmdCopyImage(p_cmd: vk.CommandBuffer, p_src: vk.Image, p_dst: vk.Image, count: u32, regions: [*]const vk.ImageCopy) callconv(vk.vulkan_call_conv) void {
|
||||||
|
entryPointBeginLogTrace(.vkCmdCopyImage);
|
||||||
|
defer entryPointEndLogTrace();
|
||||||
|
|
||||||
|
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
|
||||||
|
const src = NonDispatchable(Image).fromHandleObject(p_src) catch |err| return errorLogger(err);
|
||||||
|
const dst = NonDispatchable(Image).fromHandleObject(p_dst) catch |err| return errorLogger(err);
|
||||||
|
cmd.copyImage(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();
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ comptime {
|
|||||||
const DebugStackElement = struct {
|
const DebugStackElement = struct {
|
||||||
log: [512]u8,
|
log: [512]u8,
|
||||||
indent_level: usize,
|
indent_level: usize,
|
||||||
|
log_level: std.log.Level,
|
||||||
};
|
};
|
||||||
|
|
||||||
var indent_level: usize = 0;
|
var indent_level: usize = 0;
|
||||||
@@ -73,9 +74,16 @@ pub fn log(comptime level: std.log.Level, comptime scope: @Type(.enum_literal),
|
|||||||
std.debug.lockStdErr();
|
std.debug.lockStdErr();
|
||||||
defer std.debug.unlockStdErr();
|
defer std.debug.unlockStdErr();
|
||||||
|
|
||||||
var buffer = std.mem.zeroes([512]u8);
|
|
||||||
var stderr_file = std.fs.File.stderr();
|
var stderr_file = std.fs.File.stderr();
|
||||||
var out_config = std.Io.tty.Config.detect(stderr_file);
|
var stdout_file = std.fs.File.stdout();
|
||||||
|
|
||||||
|
const file = switch (level) {
|
||||||
|
.info, .debug => stdout_file,
|
||||||
|
.warn, .err => stderr_file,
|
||||||
|
};
|
||||||
|
|
||||||
|
var buffer = std.mem.zeroes([512]u8);
|
||||||
|
var out_config = std.Io.tty.Config.detect(file);
|
||||||
var writer = std.Io.Writer.fixed(&buffer);
|
var writer = std.Io.Writer.fixed(&buffer);
|
||||||
|
|
||||||
var timezone = zdt.Timezone.tzLocal(std.heap.page_allocator) catch zdt.Timezone.UTC;
|
var timezone = zdt.Timezone.tzLocal(std.heap.page_allocator) catch zdt.Timezone.UTC;
|
||||||
@@ -111,12 +119,19 @@ pub fn log(comptime level: std.log.Level, comptime scope: @Type(.enum_literal),
|
|||||||
(debug_stack.addOne(std.heap.c_allocator) catch return).* = .{
|
(debug_stack.addOne(std.heap.c_allocator) catch return).* = .{
|
||||||
.log = buffer,
|
.log = buffer,
|
||||||
.indent_level = indent_level,
|
.indent_level = indent_level,
|
||||||
|
.log_level = level,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
while (debug_stack.items.len != 0) {
|
while (debug_stack.items.len != 0) {
|
||||||
const elem_buffer = debug_stack.orderedRemove(0).log;
|
const elem = debug_stack.orderedRemove(0);
|
||||||
_ = stderr_file.write(&elem_buffer) catch return;
|
switch (elem.log_level) {
|
||||||
}
|
.info, .debug => _ = stdout_file.write(&elem.log) catch {},
|
||||||
_ = stderr_file.write(&buffer) catch return;
|
.warn, .err => _ = stderr_file.write(&elem.log) catch {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (level) {
|
||||||
|
.info, .debug => _ = stdout_file.write(&buffer) catch {},
|
||||||
|
.warn, .err => _ = stderr_file.write(&buffer) catch {},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,19 +20,35 @@
|
|||||||
#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)
|
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||||
|
#include <stb_image_write.h>
|
||||||
|
|
||||||
|
void CreateAndBindMemoryToBuffer(VkPhysicalDevice physical_device, VkDevice device, VkBuffer buffer, VkDeviceMemory* memory, VkMemoryPropertyFlags props)
|
||||||
{
|
{
|
||||||
VkMemoryRequirements requirements;
|
VkMemoryRequirements requirements;
|
||||||
vkGetBufferMemoryRequirements(device, buffer, &requirements);
|
vkGetBufferMemoryRequirements(device, buffer, &requirements);
|
||||||
|
|
||||||
VkMemoryAllocateInfo alloc_info = {0};
|
VkMemoryAllocateInfo alloc_info = {0};
|
||||||
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
alloc_info.allocationSize = size;
|
alloc_info.allocationSize = requirements.size;
|
||||||
alloc_info.memoryTypeIndex = kvfFindMemoryType(physical_device, requirements.memoryTypeBits, props);
|
alloc_info.memoryTypeIndex = kvfFindMemoryType(physical_device, requirements.memoryTypeBits, props);
|
||||||
kvfCheckVk(vkAllocateMemory(device, &alloc_info, NULL, memory));
|
kvfCheckVk(vkAllocateMemory(device, &alloc_info, NULL, memory));
|
||||||
kvfCheckVk(vkBindBufferMemory(device, buffer, *memory, 0));
|
kvfCheckVk(vkBindBufferMemory(device, buffer, *memory, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CreateAndBindMemoryToImage(VkPhysicalDevice physical_device, VkDevice device, VkImage image, VkDeviceMemory* memory, VkMemoryPropertyFlags props)
|
||||||
|
{
|
||||||
|
VkMemoryRequirements requirements;
|
||||||
|
vkGetImageMemoryRequirements(device, image, &requirements);
|
||||||
|
|
||||||
|
VkMemoryAllocateInfo alloc_info = {0};
|
||||||
|
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
|
alloc_info.allocationSize = requirements.size;
|
||||||
|
alloc_info.memoryTypeIndex = kvfFindMemoryType(physical_device, requirements.memoryTypeBits, props);
|
||||||
|
kvfCheckVk(vkAllocateMemory(device, &alloc_info, NULL, memory));
|
||||||
|
kvfCheckVk(vkBindImageMemory(device, image, *memory, 0));
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
volkInitialize();
|
volkInitialize();
|
||||||
@@ -65,15 +81,9 @@ 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_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, 256);
|
VkImage image = kvfCreateImage(device, 256, 256, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_LINEAR, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, KVF_IMAGE_COLOR);
|
||||||
VkDeviceMemory memory;
|
VkDeviceMemory memory;
|
||||||
CreateAndBindMemoryToBuffer(physical_device, device, buffer, &memory, 256, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
CreateAndBindMemoryToImage(physical_device, device, image, &memory, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
|
||||||
|
|
||||||
VkBuffer buffer2 = kvfCreateBuffer(device, VK_BUFFER_USAGE_TRANSFER_DST_BIT, 256);
|
|
||||||
VkDeviceMemory memory2;
|
|
||||||
CreateAndBindMemoryToBuffer(physical_device, device, buffer2, &memory2, 256, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
|
|
||||||
|
|
||||||
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);
|
||||||
@@ -83,33 +93,32 @@ int main(void)
|
|||||||
|
|
||||||
kvfBeginCommandBuffer(cmd, 0);
|
kvfBeginCommandBuffer(cmd, 0);
|
||||||
{
|
{
|
||||||
vkCmdFillBuffer(cmd, buffer, 0, VK_WHOLE_SIZE, 0x600DCAFE);
|
VkClearColorValue color = {0};
|
||||||
|
color.uint32[0] = 0xFF;
|
||||||
VkBufferCopy region = {0};
|
color.uint32[1] = 0x00;
|
||||||
region.srcOffset = 0;
|
color.uint32[2] = 0x00;
|
||||||
region.dstOffset = 0;
|
color.uint32[3] = 0xFF;
|
||||||
region.size = 256;
|
VkImageSubresourceRange range = {0};
|
||||||
vkCmdCopyBuffer(cmd, buffer, buffer2, 1, ®ion);
|
range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
range.levelCount = 1;
|
||||||
|
range.layerCount = 1;
|
||||||
|
vkCmdClearColorImage(cmd, image, VK_IMAGE_LAYOUT_GENERAL, &color, 1, &range);
|
||||||
}
|
}
|
||||||
kvfEndCommandBuffer(cmd);
|
kvfEndCommandBuffer(cmd);
|
||||||
|
|
||||||
kvfSubmitCommandBuffer(device, cmd, KVF_GRAPHICS_QUEUE, VK_NULL_HANDLE, VK_NULL_HANDLE, fence, NULL);
|
kvfSubmitCommandBuffer(device, cmd, KVF_GRAPHICS_QUEUE, VK_NULL_HANDLE, VK_NULL_HANDLE, fence, NULL);
|
||||||
kvfWaitForFence(device, fence);
|
kvfWaitForFence(device, fence);
|
||||||
|
|
||||||
uint32_t* map = NULL;
|
void* map = NULL;
|
||||||
kvfCheckVk(vkMapMemory(device, memory2, 0, VK_WHOLE_SIZE, 0, (void**)&map));
|
kvfCheckVk(vkMapMemory(device, memory, 0, VK_WHOLE_SIZE, 0, &map));
|
||||||
for(size_t i = 0; i < 64; i++)
|
if(!stbi_write_png("res.png", 256, 256, 4, map, 256 * 4))
|
||||||
printf("0x%X ", map[i]);
|
fprintf(stderr, "Failed to write result image to file\n");
|
||||||
puts("");
|
vkUnmapMemory(device, memory);
|
||||||
vkUnmapMemory(device, memory2);
|
|
||||||
|
|
||||||
kvfDestroyFence(device, fence);
|
kvfDestroyFence(device, fence);
|
||||||
kvfDestroyBuffer(device, buffer);
|
|
||||||
vkFreeMemory(device, memory, NULL);
|
|
||||||
kvfDestroyBuffer(device, buffer2);
|
|
||||||
vkFreeMemory(device, memory2, NULL);
|
|
||||||
|
|
||||||
kvfDestroyImage(device, image);
|
kvfDestroyImage(device, image);
|
||||||
|
vkFreeMemory(device, memory, NULL);
|
||||||
|
|
||||||
kvfDestroyDevice(device);
|
kvfDestroyDevice(device);
|
||||||
kvfDestroyInstance(instance);
|
kvfDestroyInstance(instance);
|
||||||
|
|||||||
Reference in New Issue
Block a user