adding base blit
This commit is contained in:
@@ -41,6 +41,7 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v
|
||||
.begin = begin,
|
||||
.bindDescriptorSets = bindDescriptorSets,
|
||||
.bindPipeline = bindPipeline,
|
||||
.blitImage = blitImage,
|
||||
.clearColorImage = clearColorImage,
|
||||
.copyBuffer = copyBuffer,
|
||||
.copyBufferToImage = copyBufferToImage,
|
||||
@@ -162,7 +163,37 @@ pub fn bindPipeline(interface: *Interface, bind_point: vk.PipelineBindPoint, pip
|
||||
self.commands.append(allocator, Command.from(cmd)) catch return VkError.OutOfHostMemory;
|
||||
}
|
||||
|
||||
pub fn clearColorImage(interface: *Interface, image: *base.Image, layout: vk.ImageLayout, color: *const vk.ClearColorValue, range: vk.ImageSubresourceRange) VkError!void {
|
||||
pub fn blitImage(interface: *Interface, src: *base.Image, _: vk.ImageLayout, dst: *base.Image, _: vk.ImageLayout, regions: []const vk.ImageBlit, filter: vk.Filter) VkError!void {
|
||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||
const allocator = self.command_allocator.allocator();
|
||||
|
||||
const CommandImpl = struct {
|
||||
const Impl = @This();
|
||||
|
||||
src: *const SoftImage,
|
||||
dst: *SoftImage,
|
||||
regions: []const vk.ImageBlit,
|
||||
filter: vk.Filter,
|
||||
|
||||
pub fn execute(impl: *const Impl, device: *ExecutionDevice) VkError!void {
|
||||
for (impl.regions[0..]) |region| {
|
||||
try device.blitter.blitRegion(impl.src, impl.dst, region);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const cmd = allocator.create(CommandImpl) catch return VkError.OutOfHostMemory;
|
||||
errdefer allocator.destroy(cmd);
|
||||
cmd.* = .{
|
||||
.src = @alignCast(@fieldParentPtr("interface", src)),
|
||||
.dst = @alignCast(@fieldParentPtr("interface", dst)),
|
||||
.regions = allocator.dupe(vk.ImageBlit, regions) catch return VkError.OutOfHostMemory, // Will be freed on cmdbuf reset or destroy
|
||||
.filter = filter,
|
||||
};
|
||||
self.commands.append(allocator, Command.from(cmd)) catch return VkError.OutOfHostMemory;
|
||||
}
|
||||
|
||||
pub fn clearColorImage(interface: *Interface, image: *base.Image, _: vk.ImageLayout, color: *const vk.ClearColorValue, range: vk.ImageSubresourceRange) VkError!void {
|
||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||
const allocator = self.command_allocator.allocator();
|
||||
|
||||
@@ -170,12 +201,12 @@ pub fn clearColorImage(interface: *Interface, image: *base.Image, layout: vk.Ima
|
||||
const Impl = @This();
|
||||
|
||||
image: *SoftImage,
|
||||
layout: vk.ImageLayout,
|
||||
clear_color: vk.ClearColorValue,
|
||||
range: vk.ImageSubresourceRange,
|
||||
|
||||
pub fn execute(impl: *const Impl, _: *ExecutionDevice) VkError!void {
|
||||
try impl.image.clearRange(impl.clear_color, impl.range);
|
||||
pub fn execute(impl: *const Impl, device: *ExecutionDevice) VkError!void {
|
||||
const clear_format = try impl.image.getClearFormat();
|
||||
try device.blitter.clear(.{ .color = impl.clear_color }, clear_format, impl.image, impl.image.interface.format, impl.range, null);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -183,7 +214,6 @@ pub fn clearColorImage(interface: *Interface, image: *base.Image, layout: vk.Ima
|
||||
errdefer allocator.destroy(cmd);
|
||||
cmd.* = .{
|
||||
.image = @alignCast(@fieldParentPtr("interface", image)),
|
||||
.layout = layout,
|
||||
.clear_color = color.*,
|
||||
.range = range,
|
||||
};
|
||||
|
||||
@@ -5,7 +5,6 @@ const builtin = @import("builtin");
|
||||
const config = @import("config");
|
||||
|
||||
const SoftQueue = @import("SoftQueue.zig");
|
||||
const Blitter = @import("device/Blitter.zig");
|
||||
|
||||
pub const SoftBinarySemaphore = @import("SoftBinarySemaphore.zig");
|
||||
pub const SoftBuffer = @import("SoftBuffer.zig");
|
||||
@@ -44,7 +43,6 @@ const DeviceAllocator = struct {
|
||||
interface: Interface,
|
||||
device_allocator: if (config.debug_allocator) std.heap.DebugAllocator(.{}) else DeviceAllocator,
|
||||
workers: std.Thread.Pool,
|
||||
blitter: Blitter,
|
||||
|
||||
pub fn create(physical_device: *base.PhysicalDevice, allocator: std.mem.Allocator, info: *const vk.DeviceCreateInfo) VkError!*Self {
|
||||
const self = allocator.create(Self) catch return VkError.OutOfHostMemory;
|
||||
@@ -85,7 +83,6 @@ pub fn create(physical_device: *base.PhysicalDevice, allocator: std.mem.Allocato
|
||||
.interface = interface,
|
||||
.device_allocator = if (config.debug_allocator) .init else .{},
|
||||
.workers = undefined,
|
||||
.blitter = .init,
|
||||
};
|
||||
|
||||
self.workers.init(.{ .allocator = self.device_allocator.allocator() }) catch |err| return switch (err) {
|
||||
|
||||
@@ -42,21 +42,13 @@ pub fn getMemoryRequirements(_: *Interface, requirements: *vk.MemoryRequirements
|
||||
requirements.alignment = lib.MEMORY_REQUIREMENTS_IMAGE_ALIGNMENT;
|
||||
}
|
||||
|
||||
inline fn clear(self: *Self, pixel: vk.ClearValue, format: vk.Format, view_format: vk.Format, range: vk.ImageSubresourceRange, area: ?vk.Rect2D) VkError!void {
|
||||
const soft_device: *SoftDevice = @alignCast(@fieldParentPtr("interface", self.interface.owner));
|
||||
try soft_device.blitter.clear(pixel, format, self, view_format, range, area);
|
||||
}
|
||||
|
||||
pub fn clearRange(self: *Self, color: vk.ClearColorValue, range: vk.ImageSubresourceRange) VkError!void {
|
||||
std.debug.assert(range.aspect_mask == vk.ImageAspectFlags{ .color_bit = true });
|
||||
|
||||
const clear_format: vk.Format = if (base.vku.vkuFormatIsSINT(@intCast(@intFromEnum(self.interface.format))))
|
||||
pub fn getClearFormat(self: *Self) VkError!vk.Format {
|
||||
return if (base.vku.vkuFormatIsSINT(@intCast(@intFromEnum(self.interface.format))))
|
||||
.r32g32b32a32_sint
|
||||
else if (base.vku.vkuFormatIsUINT(@intCast(@intFromEnum(self.interface.format))))
|
||||
.r32g32b32a32_uint
|
||||
else
|
||||
.r32g32b32a32_sfloat;
|
||||
try self.clear(.{ .color = color }, clear_format, self.interface.format, range, null);
|
||||
}
|
||||
|
||||
/// Based on SwiftShader vk::Image::copyTo
|
||||
@@ -311,13 +303,13 @@ pub fn copy(
|
||||
}
|
||||
}
|
||||
|
||||
fn getTexelMemoryOffsetInSubresource(self: *const Self, offset: vk.Offset3D, subresource: vk.ImageSubresource) usize {
|
||||
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) +
|
||||
@as(usize, @intCast(offset.x)) * base.format.texelSize(base.format.fromAspect(self.interface.format, subresource.aspect_mask));
|
||||
}
|
||||
|
||||
fn getTexelMemoryOffset(self: *const Self, offset: vk.Offset3D, subresource: vk.ImageSubresource) VkError!usize {
|
||||
pub fn getTexelMemoryOffset(self: *const Self, offset: vk.Offset3D, subresource: vk.ImageSubresource) VkError!usize {
|
||||
return self.getTexelMemoryOffsetInSubresource(offset, subresource) + try self.getSubresourceOffset(subresource.aspect_mask, subresource.mip_level, subresource.array_layer);
|
||||
}
|
||||
|
||||
@@ -372,7 +364,7 @@ fn getTotalSizeForAspect(interface: *const Interface, aspect_mask: vk.ImageAspec
|
||||
return size * self.interface.array_layers;
|
||||
}
|
||||
|
||||
fn getLayerSize(self: *const Self, aspect_mask: vk.ImageAspectFlags) usize {
|
||||
pub fn getLayerSize(self: *const Self, aspect_mask: vk.ImageAspectFlags) usize {
|
||||
var size: usize = 0;
|
||||
for (0..self.interface.mip_levels) |mip_level| {
|
||||
size += self.getMultiSampledLevelSize(aspect_mask, @intCast(mip_level));
|
||||
@@ -380,15 +372,15 @@ fn getLayerSize(self: *const Self, aspect_mask: vk.ImageAspectFlags) usize {
|
||||
return size;
|
||||
}
|
||||
|
||||
inline fn getMultiSampledLevelSize(self: *const Self, aspect_mask: vk.ImageAspectFlags, mip_level: u32) usize {
|
||||
pub inline fn getMultiSampledLevelSize(self: *const Self, aspect_mask: vk.ImageAspectFlags, mip_level: u32) usize {
|
||||
return self.getMipLevelSize(aspect_mask, mip_level) * self.interface.samples.toInt();
|
||||
}
|
||||
|
||||
inline fn getMipLevelSize(self: *const Self, aspect_mask: vk.ImageAspectFlags, mip_level: u32) usize {
|
||||
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;
|
||||
}
|
||||
|
||||
fn getMipLevelExtent(self: *const Self, mip_level: u32) vk.Extent3D {
|
||||
pub fn getMipLevelExtent(self: *const Self, mip_level: u32) vk.Extent3D {
|
||||
var extent: vk.Extent3D = .{
|
||||
.width = self.interface.extent.width >> @intCast(mip_level),
|
||||
.height = self.interface.extent.height >> @intCast(mip_level),
|
||||
@@ -402,13 +394,13 @@ fn getMipLevelExtent(self: *const Self, mip_level: u32) vk.Extent3D {
|
||||
return extent;
|
||||
}
|
||||
|
||||
fn getSliceMemSizeForMipLevel(self: *const Self, aspect_mask: vk.ImageAspectFlags, mip_level: u32) usize {
|
||||
pub fn getSliceMemSizeForMipLevel(self: *const Self, aspect_mask: vk.ImageAspectFlags, mip_level: u32) usize {
|
||||
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);
|
||||
}
|
||||
|
||||
fn getRowPitchMemSizeForMipLevel(self: *const Self, aspect_mask: vk.ImageAspectFlags, mip_level: u32) usize {
|
||||
pub fn getRowPitchMemSizeForMipLevel(self: *const Self, aspect_mask: vk.ImageAspectFlags, mip_level: u32) usize {
|
||||
const mip_extent = self.getMipLevelExtent(mip_level);
|
||||
const format = self.interface.formatFromAspect(aspect_mask);
|
||||
return base.format.pitchMemSize(format, mip_extent.width);
|
||||
|
||||
@@ -11,11 +11,7 @@ pub const SoftImageView = @import("../SoftImageView.zig");
|
||||
|
||||
const Self = @This();
|
||||
|
||||
blit_mutex: std.Thread.Mutex,
|
||||
|
||||
pub const init: Self = .{
|
||||
.blit_mutex = .{},
|
||||
};
|
||||
pub const init: Self = .{};
|
||||
|
||||
pub fn clear(self: *Self, pixel: vk.ClearValue, format: vk.Format, dest: *SoftImage, view_format: vk.Format, range: vk.ImageSubresourceRange, area: ?vk.Rect2D) VkError!void {
|
||||
const dst_format = base.format.fromAspect(view_format, range.aspect_mask);
|
||||
@@ -104,3 +100,9 @@ fn fastClear(self: *Self, clear_value: vk.ClearValue, clear_format: vk.Format, d
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn blitRegion(_: *Self, src: *const SoftImage, dst: *SoftImage, region: vk.ImageBlit) VkError!void {
|
||||
_ = src;
|
||||
_ = dst;
|
||||
_ = region;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ const SoftDescriptorSet = @import("../SoftDescriptorSet.zig");
|
||||
const SoftDevice = @import("../SoftDevice.zig");
|
||||
const SoftPipeline = @import("../SoftPipeline.zig");
|
||||
|
||||
const Blitter = @import("Blitter.zig");
|
||||
const ComputeRoutines = @import("ComputeRoutines.zig");
|
||||
const PipelineState = @import("PipelineState.zig");
|
||||
|
||||
@@ -13,6 +14,8 @@ const VkError = base.VkError;
|
||||
|
||||
const Self = @This();
|
||||
|
||||
blitter: Blitter,
|
||||
|
||||
compute_routines: ComputeRoutines,
|
||||
|
||||
/// .graphics = 0
|
||||
@@ -20,6 +23,7 @@ compute_routines: ComputeRoutines,
|
||||
pipeline_states: [2]PipelineState,
|
||||
|
||||
pub const init: Self = .{
|
||||
.blitter = .init,
|
||||
.compute_routines = undefined,
|
||||
.pipeline_states = undefined,
|
||||
};
|
||||
|
||||
@@ -40,6 +40,7 @@ pub const DispatchTable = struct {
|
||||
begin: *const fn (*Self, *const vk.CommandBufferBeginInfo) VkError!void,
|
||||
bindDescriptorSets: *const fn (*Self, vk.PipelineBindPoint, u32, [lib.VULKAN_MAX_DESCRIPTOR_SETS]?*DescriptorSet, []const u32) VkError!void,
|
||||
bindPipeline: *const fn (*Self, vk.PipelineBindPoint, *Pipeline) VkError!void,
|
||||
blitImage: *const fn (*Self, *Image, vk.ImageLayout, *Image, vk.ImageLayout, []const vk.ImageBlit, vk.Filter) VkError!void,
|
||||
clearColorImage: *const fn (*Self, *Image, vk.ImageLayout, *const vk.ClearColorValue, vk.ImageSubresourceRange) VkError!void,
|
||||
copyBuffer: *const fn (*Self, *Buffer, *Buffer, []const vk.BufferCopy) VkError!void,
|
||||
copyBufferToImage: *const fn (*Self, *Buffer, *Image, vk.ImageLayout, []const vk.BufferImageCopy) VkError!void,
|
||||
@@ -148,6 +149,10 @@ pub inline fn bindPipeline(self: *Self, bind_point: vk.PipelineBindPoint, pipeli
|
||||
try self.dispatch_table.bindPipeline(self, bind_point, pipeline);
|
||||
}
|
||||
|
||||
pub inline fn blitImage(self: *Self, src: *Image, src_layout: vk.ImageLayout, dst: *Image, dst_layout: vk.ImageLayout, regions: []const vk.ImageBlit, filter: vk.Filter) VkError!void {
|
||||
try self.dispatch_table.blitImage(self, src, src_layout, dst, dst_layout, regions, filter);
|
||||
}
|
||||
|
||||
pub inline fn clearColorImage(self: *Self, image: *Image, layout: vk.ImageLayout, color: *const vk.ClearColorValue, ranges: []const vk.ImageSubresourceRange) VkError!void {
|
||||
for (ranges) |range| {
|
||||
try self.dispatch_table.clearColorImage(self, image, layout, color, range);
|
||||
|
||||
@@ -1735,16 +1735,7 @@ pub export fn strollCmdBlitImage(
|
||||
const src = NonDispatchable(Image).fromHandleObject(p_src_image) catch |err| return errorLogger(err);
|
||||
const dst = NonDispatchable(Image).fromHandleObject(p_dst_image) catch |err| return errorLogger(err);
|
||||
|
||||
notImplementedWarning();
|
||||
|
||||
_ = cmd;
|
||||
_ = src;
|
||||
_ = src_layout;
|
||||
_ = dst;
|
||||
_ = dst_layout;
|
||||
_ = count;
|
||||
_ = regions;
|
||||
_ = filter;
|
||||
cmd.blitImage(src, src_layout, dst, dst_layout, regions[0..count], filter) catch |err| return errorLogger(err);
|
||||
}
|
||||
|
||||
pub export fn strollCmdClearAttachments(p_cmd: vk.CommandBuffer, attachment_count: u32, attachments: [*]const vk.ClearAttachment, rect_count: u32, rects: [*]const vk.ClearRect) callconv(vk.vulkan_call_conv) void {
|
||||
|
||||
Reference in New Issue
Block a user