adding proper subpass management and image resolve
This commit is contained in:
@@ -68,10 +68,12 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v
|
||||
.endRenderPass = endRenderPass,
|
||||
.executeCommands = executeCommands,
|
||||
.fillBuffer = fillBuffer,
|
||||
.nextSubpass = nextSubpass,
|
||||
.pipelineBarrier = pipelineBarrier,
|
||||
.pushConstants = pushConstants,
|
||||
.reset = reset,
|
||||
.resetEvent = resetEvent,
|
||||
.resolveImage = resolveImage,
|
||||
.setEvent = setEvent,
|
||||
.setScissor = setScissor,
|
||||
.setViewport = setViewport,
|
||||
@@ -144,6 +146,7 @@ pub fn beginRenderPass(interface: *Interface, render_pass: *base.RenderPass, fra
|
||||
const impl: *Impl = @ptrCast(@alignCast(context));
|
||||
device.renderer.render_pass = impl.render_pass;
|
||||
device.renderer.framebuffer = impl.framebuffer;
|
||||
device.renderer.subpass_index = 0;
|
||||
|
||||
for (impl.render_pass.interface.attachments, impl.framebuffer.interface.attachments, 0..) |desc, attachment, index| {
|
||||
const image: *SoftImage = @alignCast(@fieldParentPtr("interface", attachment.image));
|
||||
@@ -378,20 +381,44 @@ pub fn clearAttachment(interface: *Interface, attachment: vk.ClearAttachment, re
|
||||
pub fn execute(context: *anyopaque, device: *ExecutionDevice) VkError!void {
|
||||
const impl: *Impl = @ptrCast(@alignCast(context));
|
||||
|
||||
if (device.renderer.framebuffer) |framebuffer| {
|
||||
const image_view = framebuffer.interface.attachments[impl.attachment.color_attachment];
|
||||
const image: *SoftImage = @alignCast(@fieldParentPtr("interface", image_view.image));
|
||||
const clear_format = try image.getClearFormat();
|
||||
const framebuffer = device.renderer.framebuffer orelse return;
|
||||
const render_pass = device.renderer.render_pass orelse return;
|
||||
const subpass = render_pass.interface.subpasses[device.renderer.subpass_index];
|
||||
|
||||
try blitter.clear(
|
||||
impl.attachment.clear_value,
|
||||
clear_format,
|
||||
image,
|
||||
image_view.format,
|
||||
image_view.subresource_range,
|
||||
null,
|
||||
);
|
||||
}
|
||||
const image_view = blk: {
|
||||
if (impl.attachment.aspect_mask.toInt() == (vk.ImageAspectFlags{ .color_bit = true }).toInt()) {
|
||||
const fb_attachment_index = (subpass.color_attachments orelse return)[impl.attachment.color_attachment].attachment;
|
||||
|
||||
if (fb_attachment_index != vk.ATTACHMENT_UNUSED)
|
||||
break :blk framebuffer.interface.attachments[impl.attachment.color_attachment];
|
||||
} else if (impl.attachment.aspect_mask.depth_bit or impl.attachment.aspect_mask.stencil_bit) {
|
||||
if (render_pass.interface.subpasses[device.renderer.subpass_index].depth_stencil_attachments) |desc| {
|
||||
if (desc.attachment != vk.ATTACHMENT_UNUSED)
|
||||
break :blk framebuffer.interface.attachments[desc.attachment];
|
||||
}
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
const image: *SoftImage = @alignCast(@fieldParentPtr("interface", image_view.image));
|
||||
const clear_format = try image.getClearFormat();
|
||||
|
||||
const range: vk.ImageSubresourceRange = .{
|
||||
.aspect_mask = impl.attachment.aspect_mask,
|
||||
.base_mip_level = image_view.subresource_range.base_mip_level,
|
||||
.level_count = image_view.subresource_range.level_count,
|
||||
.base_array_layer = impl.rect.base_array_layer + image_view.subresource_range.base_array_layer,
|
||||
.layer_count = impl.rect.layer_count,
|
||||
};
|
||||
|
||||
try blitter.clear(
|
||||
impl.attachment.clear_value,
|
||||
clear_format,
|
||||
image,
|
||||
image_view.format,
|
||||
range,
|
||||
impl.rect.rect,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -821,27 +848,26 @@ pub fn fillBuffer(interface: *Interface, buffer: *base.Buffer, offset: vk.Device
|
||||
self.commands.append(allocator, .{ .ptr = cmd, .vtable = &.{ .execute = CommandImpl.execute } }) catch return VkError.OutOfHostMemory;
|
||||
}
|
||||
|
||||
pub fn pipelineBarrier(interface: *Interface, src_stage: vk.PipelineStageFlags, dst_stage: vk.PipelineStageFlags, dependency: vk.DependencyFlags, memory_barriers: []const vk.MemoryBarrier, buffer_barriers: []const vk.BufferMemoryBarrier, image_barriers: []const vk.ImageMemoryBarrier) VkError!void {
|
||||
pub fn nextSubpass(interface: *Interface, _: vk.SubpassContents) VkError!void {
|
||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||
const allocator = self.command_allocator.allocator();
|
||||
|
||||
const CommandImpl = struct {
|
||||
const Impl = @This();
|
||||
|
||||
pub fn execute(_: *anyopaque, _: *ExecutionDevice) VkError!void {}
|
||||
pub fn execute(_: *anyopaque, device: *ExecutionDevice) VkError!void {
|
||||
device.renderer.subpass_index += 1;
|
||||
}
|
||||
};
|
||||
|
||||
const cmd = allocator.create(CommandImpl) catch return VkError.OutOfHostMemory;
|
||||
errdefer allocator.destroy(cmd);
|
||||
cmd.* = .{};
|
||||
self.commands.append(allocator, .{ .ptr = cmd, .vtable = &.{ .execute = CommandImpl.execute } }) catch return VkError.OutOfHostMemory;
|
||||
}
|
||||
|
||||
_ = src_stage;
|
||||
_ = dst_stage;
|
||||
_ = dependency;
|
||||
_ = memory_barriers;
|
||||
_ = buffer_barriers;
|
||||
_ = image_barriers;
|
||||
pub fn pipelineBarrier(_: *Interface, _: vk.PipelineStageFlags, _: vk.PipelineStageFlags, _: vk.DependencyFlags, _: []const vk.MemoryBarrier, _: []const vk.BufferMemoryBarrier, _: []const vk.ImageMemoryBarrier) VkError!void {
|
||||
// No-op
|
||||
}
|
||||
|
||||
pub fn pushConstants(interface: *Interface, stages: vk.ShaderStageFlags, offset: u32, blob: []const u8) VkError!void {
|
||||
@@ -880,12 +906,10 @@ pub fn pushConstants(interface: *Interface, stages: vk.ShaderStageFlags, offset:
|
||||
self.commands.append(allocator, .{ .ptr = cmd, .vtable = &.{ .execute = CommandImpl.execute } }) catch return VkError.OutOfHostMemory;
|
||||
}
|
||||
|
||||
pub fn resetEvent(interface: *Interface, event: *base.Event, stage: vk.PipelineStageFlags) VkError!void {
|
||||
pub fn resetEvent(interface: *Interface, event: *base.Event, _: vk.PipelineStageFlags) VkError!void {
|
||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||
const allocator = self.command_allocator.allocator();
|
||||
|
||||
_ = stage;
|
||||
|
||||
const CommandImpl = struct {
|
||||
const Impl = @This();
|
||||
|
||||
@@ -905,6 +929,33 @@ pub fn resetEvent(interface: *Interface, event: *base.Event, stage: vk.PipelineS
|
||||
self.commands.append(allocator, .{ .ptr = cmd, .vtable = &.{ .execute = CommandImpl.execute } }) catch return VkError.OutOfHostMemory;
|
||||
}
|
||||
|
||||
pub fn resolveImage(interface: *Interface, src: *base.Image, _: vk.ImageLayout, dst: *base.Image, _: vk.ImageLayout, region: vk.ImageResolve) 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,
|
||||
region: vk.ImageResolve,
|
||||
|
||||
pub fn execute(context: *anyopaque, _: *ExecutionDevice) VkError!void {
|
||||
const impl: *Impl = @ptrCast(@alignCast(context));
|
||||
try blitter.resolve(impl.src, impl.dst, impl.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)),
|
||||
.region = region,
|
||||
};
|
||||
self.commands.append(allocator, .{ .ptr = cmd, .vtable = &.{ .execute = CommandImpl.execute } }) catch return VkError.OutOfHostMemory;
|
||||
}
|
||||
|
||||
pub fn setEvent(interface: *Interface, event: *base.Event, stage: vk.PipelineStageFlags) VkError!void {
|
||||
const self: *Self = @alignCast(@fieldParentPtr("interface", interface));
|
||||
const allocator = self.command_allocator.allocator();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const vk = @import("vulkan");
|
||||
const base = @import("base");
|
||||
const lib = @import("lib.zig");
|
||||
const cpuinfo = lib.c;
|
||||
|
||||
const SoftDevice = @import("SoftDevice.zig");
|
||||
|
||||
@@ -189,9 +189,6 @@ pub fn create(allocator: std.mem.Allocator, instance: *base.Instance) VkError!*S
|
||||
.shader_float_64 = .true,
|
||||
.shader_int_64 = .true,
|
||||
.shader_int_16 = .true,
|
||||
.texture_compression_etc2 = .false,
|
||||
.texture_compression_bc = .false,
|
||||
.texture_compression_astc_ldr = .false,
|
||||
};
|
||||
|
||||
var queue_family_props = [_]vk.QueueFamilyProperties{
|
||||
@@ -201,30 +198,47 @@ pub fn create(allocator: std.mem.Allocator, instance: *base.Instance) VkError!*S
|
||||
.timestamp_valid_bits = 0,
|
||||
.min_image_transfer_granularity = .{ .width = 1, .height = 1, .depth = 1 },
|
||||
},
|
||||
.{
|
||||
.queue_flags = .{ .graphics_bit = true },
|
||||
.queue_count = 1,
|
||||
.timestamp_valid_bits = 0,
|
||||
.min_image_transfer_granularity = .{ .width = 1, .height = 1, .depth = 1 },
|
||||
},
|
||||
.{
|
||||
.queue_flags = .{ .transfer_bit = true },
|
||||
.queue_count = 1,
|
||||
.timestamp_valid_bits = 0,
|
||||
.min_image_transfer_granularity = .{ .width = 1, .height = 1, .depth = 1 },
|
||||
},
|
||||
// TODO: maybe add a compute specialized queue
|
||||
};
|
||||
interface.queue_family_props.appendSlice(allocator, queue_family_props[0..]) catch return VkError.OutOfHostMemory;
|
||||
|
||||
if (device_name[0] == 0) {
|
||||
const name = blk: {
|
||||
if (cpuinfo.cpuinfo_initialize()) {
|
||||
const package = cpuinfo.cpuinfo_get_package(0).*;
|
||||
const non_sentinel_name = package.name[0..(std.mem.len(@as([*:0]const u8, @ptrCast(&package.name))))];
|
||||
break :blk std.fmt.allocPrint(command_allocator, "{s} ({d} threads)", .{ non_sentinel_name, package.processor_count }) catch return VkError.OutOfHostMemory;
|
||||
|
||||
// If arch is x86 we try to get precise CPU name through CPUID
|
||||
// and fallback to vendor name if not available
|
||||
if (comptime builtin.cpu.arch.isX86()) {
|
||||
const max_extended_leaf = cpuid(0x80000000, 0).eax;
|
||||
|
||||
if (max_extended_leaf >= 0x80000004) {
|
||||
var brand: [49]u8 = @splat(0);
|
||||
|
||||
for (0..3) |i| {
|
||||
const regs = cpuid(0x80000002 + @as(u32, @intCast(i)), 0);
|
||||
const offset = i * 16;
|
||||
|
||||
writeU32Le(brand[0..], offset + 0, regs.eax);
|
||||
writeU32Le(brand[0..], offset + 4, regs.ebx);
|
||||
writeU32Le(brand[0..], offset + 8, regs.ecx);
|
||||
writeU32Le(brand[0..], offset + 12, regs.edx);
|
||||
}
|
||||
|
||||
const brand_str = std.mem.trim(u8, brand[0..48], " \x00");
|
||||
break :blk command_allocator.dupe(u8, brand_str) catch return VkError.OutOfHostMemory;
|
||||
} else {
|
||||
var vendor: [13]u8 = @splat(0);
|
||||
|
||||
const leaf0 = cpuid(0, 0);
|
||||
|
||||
writeU32Le(vendor[0..], 0, leaf0.ebx);
|
||||
writeU32Le(vendor[0..], 4, leaf0.edx);
|
||||
writeU32Le(vendor[0..], 8, leaf0.ecx);
|
||||
|
||||
const vendor_str = std.mem.trim(u8, vendor[0..12], " \x00");
|
||||
break :blk command_allocator.dupe(u8, vendor_str) catch return VkError.OutOfHostMemory;
|
||||
}
|
||||
}
|
||||
break :blk command_allocator.dupe(u8, "Unkown") catch return VkError.OutOfHostMemory;
|
||||
|
||||
break :blk command_allocator.dupe(u8, lib.PHYSICAL_DEVICE_DEFAULT_NAME) catch return VkError.OutOfHostMemory;
|
||||
};
|
||||
defer command_allocator.free(name);
|
||||
|
||||
@@ -857,3 +871,47 @@ fn checkFormatUsage(usage: vk.ImageUsageFlags, features: vk.FormatFeatureFlags)
|
||||
pub fn getSurfaceSupportKHR(_: *Interface, _: u32, _: *SurfaceKHR) VkError!bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
const CpuidRegs = packed struct {
|
||||
eax: u32,
|
||||
ebx: u32,
|
||||
ecx: u32,
|
||||
edx: u32,
|
||||
};
|
||||
|
||||
fn cpuid(leaf_id: u32, subleaf_id: u32) CpuidRegs {
|
||||
comptime {
|
||||
switch (builtin.cpu.arch) {
|
||||
.x86, .x86_64 => {},
|
||||
else => @compileError("cpuid is only available on x86/x86_64"),
|
||||
}
|
||||
}
|
||||
|
||||
var eax: u32 = undefined;
|
||||
var ebx: u32 = undefined;
|
||||
var ecx: u32 = undefined;
|
||||
var edx: u32 = undefined;
|
||||
|
||||
asm volatile ("cpuid"
|
||||
: [_] "={eax}" (eax),
|
||||
[_] "={ebx}" (ebx),
|
||||
[_] "={ecx}" (ecx),
|
||||
[_] "={edx}" (edx),
|
||||
: [_] "{eax}" (leaf_id),
|
||||
[_] "{ecx}" (subleaf_id),
|
||||
);
|
||||
|
||||
return .{
|
||||
.eax = eax,
|
||||
.ebx = ebx,
|
||||
.ecx = ecx,
|
||||
.edx = edx,
|
||||
};
|
||||
}
|
||||
|
||||
fn writeU32Le(dst: []u8, offset: usize, value: u32) void {
|
||||
dst[offset + 0] = @truncate(value);
|
||||
dst[offset + 1] = @truncate(value >> 8);
|
||||
dst[offset + 2] = @truncate(value >> 16);
|
||||
dst[offset + 3] = @truncate(value >> 24);
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
#include <cpuinfo.h>
|
||||
@@ -82,7 +82,7 @@ pub const DrawCall = struct {
|
||||
.viewport = undefined,
|
||||
.scissor = undefined,
|
||||
.color_attachments = framebuffer.interface.attachments[0..],
|
||||
.depth_attachment = if (render_pass.interface.subpasses[0].depth_stencil_attachments) |desc| framebuffer.interface.attachments[desc.attachment] else null,
|
||||
.depth_attachment = if (render_pass.interface.subpasses[renderer.subpass_index].depth_stencil_attachments) |desc| framebuffer.interface.attachments[desc.attachment] else null,
|
||||
.render_pass = render_pass,
|
||||
.framebuffer = framebuffer,
|
||||
.rasterizer_wait_group = .init,
|
||||
@@ -117,6 +117,8 @@ render_pass: ?*SoftRenderPass,
|
||||
framebuffer: ?*SoftFramebuffer,
|
||||
dynamic_state: DynamicState,
|
||||
|
||||
subpass_index: usize,
|
||||
|
||||
pub fn init(device: *SoftDevice, state: *PipelineState) Self {
|
||||
return .{
|
||||
.device = device,
|
||||
@@ -128,6 +130,7 @@ pub fn init(device: *SoftDevice, state: *PipelineState) Self {
|
||||
.scissor = null,
|
||||
.line_width = null,
|
||||
},
|
||||
.subpass_index = 0,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+62
-17
@@ -50,6 +50,18 @@ fn computeOffset3D(x: usize, y: usize, z: usize, slice_bytes: usize, pitch_bytes
|
||||
}
|
||||
|
||||
pub fn clear(pixel: vk.ClearValue, format: vk.Format, dst: *SoftImage, view_format: vk.Format, range: vk.ImageSubresourceRange, render_area: ?vk.Rect2D) VkError!void {
|
||||
if (range.aspect_mask.depth_bit and range.aspect_mask.stencil_bit) {
|
||||
var depth_range = range;
|
||||
depth_range.aspect_mask = .{ .depth_bit = true };
|
||||
try clear(pixel, format, dst, view_format, depth_range, render_area);
|
||||
|
||||
var stencil_range = range;
|
||||
stencil_range.aspect_mask = .{ .stencil_bit = true };
|
||||
try clear(pixel, format, dst, view_format, stencil_range, render_area);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const dst_format = base.format.fromAspect(view_format, range.aspect_mask);
|
||||
if (dst_format == .undefined) {
|
||||
return;
|
||||
@@ -64,23 +76,38 @@ pub fn clear(pixel: vk.ClearValue, format: vk.Format, dst: *SoftImage, view_form
|
||||
};
|
||||
|
||||
var clamped_pixel: vk.ClearValue = pixel;
|
||||
if (base.format.isSnorm(view_format) or base.format.isUnorm(view_format)) {
|
||||
if (range.aspect_mask.color_bit and (base.format.isSnorm(view_format) or base.format.isUnorm(view_format))) {
|
||||
const min_value: f32 = if (base.format.isSnorm(view_format)) -1.0 else 0.0;
|
||||
|
||||
if (range.aspect_mask.color_bit) {
|
||||
clamped_pixel.color.float_32[0] = std.math.clamp(pixel.color.float_32[0], min_value, 1.0);
|
||||
clamped_pixel.color.float_32[1] = std.math.clamp(pixel.color.float_32[1], min_value, 1.0);
|
||||
clamped_pixel.color.float_32[2] = std.math.clamp(pixel.color.float_32[2], min_value, 1.0);
|
||||
clamped_pixel.color.float_32[3] = std.math.clamp(pixel.color.float_32[3], min_value, 1.0);
|
||||
}
|
||||
|
||||
if (range.aspect_mask.depth_bit) {
|
||||
clamped_pixel.depth_stencil.depth = std.math.clamp(pixel.depth_stencil.depth, min_value, 1.0);
|
||||
}
|
||||
clamped_pixel.color.float_32[0] = std.math.clamp(pixel.color.float_32[0], min_value, 1.0);
|
||||
clamped_pixel.color.float_32[1] = std.math.clamp(pixel.color.float_32[1], min_value, 1.0);
|
||||
clamped_pixel.color.float_32[2] = std.math.clamp(pixel.color.float_32[2], min_value, 1.0);
|
||||
clamped_pixel.color.float_32[3] = std.math.clamp(pixel.color.float_32[3], min_value, 1.0);
|
||||
}
|
||||
|
||||
if (range.aspect_mask.depth_bit) {
|
||||
clamped_pixel.depth_stencil.depth = std.math.clamp(pixel.depth_stencil.depth, 0.0, 1.0);
|
||||
}
|
||||
|
||||
const depth_clear: F32x4 = @splat(clamped_pixel.depth_stencil.depth);
|
||||
const stencil_clear: U32x4 = @splat(clamped_pixel.depth_stencil.stencil);
|
||||
|
||||
const src_format: vk.Format = if (range.aspect_mask.stencil_bit)
|
||||
.r32g32b32a32_uint
|
||||
else if (range.aspect_mask.depth_bit)
|
||||
.r32g32b32a32_sfloat
|
||||
else
|
||||
format;
|
||||
|
||||
const src_map: []const u8 = if (range.aspect_mask.stencil_bit)
|
||||
std.mem.asBytes(&stencil_clear)
|
||||
else if (range.aspect_mask.depth_bit)
|
||||
std.mem.asBytes(&depth_clear)
|
||||
else
|
||||
std.mem.asBytes(&clamped_pixel);
|
||||
|
||||
const state: State = .{
|
||||
.src_format = format,
|
||||
.src_format = src_format,
|
||||
.dst_format = dst_format,
|
||||
.filter = .nearest,
|
||||
.allow_srgb_conversion = true,
|
||||
@@ -120,10 +147,10 @@ pub fn clear(pixel: vk.ClearValue, format: vk.Format, dst: *SoftImage, view_form
|
||||
const dst_map = try dst.mapAsSliceWithAddedOffset(u8, dst_texel_offset, vk.WHOLE_SIZE);
|
||||
|
||||
blit(state, .{
|
||||
.src_map = std.mem.asBytes(&clamped_pixel),
|
||||
.src_map = src_map,
|
||||
.dst_map = dst_map,
|
||||
|
||||
.src_slice_pitch_bytes = base.format.texelSize(format),
|
||||
.src_slice_pitch_bytes = base.format.texelSize(src_format),
|
||||
.src_row_pitch_bytes = 0,
|
||||
.dst_slice_pitch_bytes = dst.interface.getSliceMemSizeForMipLevel(subresource.aspect_mask, subresource.mip_level),
|
||||
.dst_row_pitch_bytes = dst.interface.getRowPitchMemSizeForMipLevel(subresource.aspect_mask, subresource.mip_level),
|
||||
@@ -456,6 +483,26 @@ fn blit(state: State, data: BlitData) void {
|
||||
}
|
||||
}
|
||||
|
||||
/// Using image blitting to resolve
|
||||
pub inline fn resolve(src: *const SoftImage, dst: *SoftImage, region: vk.ImageResolve) VkError!void {
|
||||
var blit_region: vk.ImageBlit = .{
|
||||
.src_offsets = .{ region.src_offset, region.src_offset },
|
||||
.src_subresource = region.src_subresource,
|
||||
.dst_offsets = .{ region.dst_offset, region.dst_offset },
|
||||
.dst_subresource = region.dst_subresource,
|
||||
};
|
||||
|
||||
blit_region.src_offsets[1].x += @intCast(region.extent.width);
|
||||
blit_region.src_offsets[1].y += @intCast(region.extent.height);
|
||||
blit_region.src_offsets[1].z += @intCast(region.extent.depth);
|
||||
|
||||
blit_region.dst_offsets[1].x += @intCast(region.extent.width);
|
||||
blit_region.dst_offsets[1].y += @intCast(region.extent.height);
|
||||
blit_region.dst_offsets[1].z += @intCast(region.extent.depth);
|
||||
|
||||
try blitRegion(src, dst, blit_region, .nearest);
|
||||
}
|
||||
|
||||
fn applyScaleAndClamp(base_color: F32x4, state: State, apply_srgb_convertion: bool) F32x4 {
|
||||
var color: F32x4 = base_color;
|
||||
|
||||
@@ -764,8 +811,7 @@ pub fn writeFloat4(color: F32x4, map: []u8, dst_format: vk.Format) void {
|
||||
.s8_uint,
|
||||
=> map[0] = @intFromFloat(@round(color[0] * std.math.maxInt(u8))),
|
||||
|
||||
.r8_snorm,
|
||||
=> map[0] = @intFromFloat(@round(color[0] * std.math.maxInt(i8))),
|
||||
.r8_snorm => map[0] = @intFromFloat(@round(color[0] * std.math.maxInt(i8))),
|
||||
|
||||
.r16_sint,
|
||||
.r16_uint,
|
||||
@@ -1150,7 +1196,6 @@ pub fn writeInt4(c: U32x4, map: []u8, dst_format: vk.Format) void {
|
||||
.r8g8b8_uscaled,
|
||||
.r8g8_uscaled,
|
||||
.r8_uscaled,
|
||||
.s8_uint,
|
||||
=> color = @min(color, U32x4{ 0xFF, 0xFF, 0xFF, 0xFF }),
|
||||
|
||||
.r16g16b16a16_uint,
|
||||
|
||||
@@ -20,7 +20,7 @@ pub fn processThenFragmentStage(renderer: *Renderer, allocator: std.mem.Allocato
|
||||
const pipeline_data = (renderer.state.pipeline orelse return VkError.InvalidHandleDrv).interface.mode.graphics;
|
||||
const topology = pipeline_data.input_assembly.topology;
|
||||
|
||||
const color_attachment = if (draw_call.render_pass.interface.subpasses[0].color_attachments) |attachments| attachments[0].attachment else return VkError.InvalidAttachmentDrv;
|
||||
const color_attachment = if (draw_call.render_pass.interface.subpasses[renderer.subpass_index].color_attachments) |attachments| attachments[0].attachment else return VkError.InvalidAttachmentDrv;
|
||||
const render_target_view: *base.ImageView = draw_call.color_attachments[color_attachment];
|
||||
const render_target: *SoftImage = @alignCast(@fieldParentPtr("interface", render_target_view.image));
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ fn runWrapper(data: RunData) void {
|
||||
}
|
||||
|
||||
inline fn run(data: RunData) !void {
|
||||
const color_attachment = if (data.draw_call.render_pass.interface.subpasses[0].color_attachments) |attachments| attachments[0].attachment else return VkError.InvalidAttachmentDrv;
|
||||
const color_attachment = if (data.draw_call.render_pass.interface.subpasses[data.draw_call.renderer.subpass_index].color_attachments) |attachments| attachments[0].attachment else return VkError.InvalidAttachmentDrv;
|
||||
const render_target_view: *base.ImageView = data.draw_call.color_attachments[color_attachment];
|
||||
const render_target: *SoftImage = @alignCast(@fieldParentPtr("interface", render_target_view.image));
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ pub const MAX_IMAGE_LEVELS_3D = 12;
|
||||
pub const MAX_IMAGE_LEVELS_CUBE = 15;
|
||||
pub const MAX_IMAGE_ARRAY_LAYERS = 2048;
|
||||
|
||||
pub const PHYSICAL_DEVICE_DEFAULT_NAME = "StrollSoft device";
|
||||
pub const PHYSICAL_DEVICE_FALLBACK_HEAP_SIZE = 0x10000000; // 256MB
|
||||
|
||||
pub const std_options = base.std_options;
|
||||
|
||||
@@ -62,10 +62,12 @@ pub const DispatchTable = struct {
|
||||
endRenderPass: *const fn (*Self) VkError!void,
|
||||
executeCommands: *const fn (*Self, *Self) VkError!void,
|
||||
fillBuffer: *const fn (*Self, *Buffer, vk.DeviceSize, vk.DeviceSize, u32) VkError!void,
|
||||
nextSubpass: *const fn (*Self, vk.SubpassContents) VkError!void,
|
||||
pipelineBarrier: *const fn (*Self, vk.PipelineStageFlags, vk.PipelineStageFlags, vk.DependencyFlags, []const vk.MemoryBarrier, []const vk.BufferMemoryBarrier, []const vk.ImageMemoryBarrier) VkError!void,
|
||||
pushConstants: *const fn (*Self, vk.ShaderStageFlags, u32, []const u8) VkError!void,
|
||||
reset: *const fn (*Self, vk.CommandBufferResetFlags) VkError!void,
|
||||
resetEvent: *const fn (*Self, *Event, vk.PipelineStageFlags) VkError!void,
|
||||
resolveImage: *const fn (*Self, *Image, vk.ImageLayout, *Image, vk.ImageLayout, vk.ImageResolve) VkError!void,
|
||||
setEvent: *const fn (*Self, *Event, vk.PipelineStageFlags) VkError!void,
|
||||
setScissor: *const fn (*Self, u32, []const vk.Rect2D) VkError!void,
|
||||
setViewport: *const fn (*Self, u32, []const vk.Viewport) VkError!void,
|
||||
@@ -250,6 +252,10 @@ pub inline fn fillBuffer(self: *Self, buffer: *Buffer, offset: vk.DeviceSize, si
|
||||
try self.dispatch_table.fillBuffer(self, buffer, offset, size, data);
|
||||
}
|
||||
|
||||
pub inline fn nextSubpass(self: *Self, contents: vk.SubpassContents) VkError!void {
|
||||
try self.dispatch_table.nextSubpass(self, contents);
|
||||
}
|
||||
|
||||
pub inline fn pipelineBarrier(
|
||||
self: *Self,
|
||||
src_stage: vk.PipelineStageFlags,
|
||||
@@ -270,6 +276,12 @@ pub inline fn resetEvent(self: *Self, event: *Event, stage: vk.PipelineStageFlag
|
||||
try self.dispatch_table.resetEvent(self, event, stage);
|
||||
}
|
||||
|
||||
pub inline fn resolveImage(self: *Self, src: *Image, src_layout: vk.ImageLayout, dst: *Image, dst_layout: vk.ImageLayout, regions: []const vk.ImageResolve) VkError!void {
|
||||
for (regions[0..]) |region| {
|
||||
try self.dispatch_table.resolveImage(self, src, src_layout, dst, dst_layout, region);
|
||||
}
|
||||
}
|
||||
|
||||
pub inline fn setEvent(self: *Self, event: *Event, stage: vk.PipelineStageFlags) VkError!void {
|
||||
try self.dispatch_table.setEvent(self, event, stage);
|
||||
}
|
||||
|
||||
@@ -1912,11 +1912,7 @@ pub export fn strollCmdNextSubpass(p_cmd: vk.CommandBuffer, contents: vk.Subpass
|
||||
defer entryPointEndLogTrace();
|
||||
|
||||
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
|
||||
|
||||
notImplementedWarning();
|
||||
|
||||
_ = cmd;
|
||||
_ = contents;
|
||||
cmd.nextSubpass(contents) catch |err| return errorLogger(err);
|
||||
}
|
||||
|
||||
pub export fn strollCmdPipelineBarrier(
|
||||
@@ -1991,18 +1987,9 @@ pub export fn strollCmdResolveImage(
|
||||
defer entryPointEndLogTrace();
|
||||
|
||||
const cmd = Dispatchable(CommandBuffer).fromHandleObject(p_cmd) catch |err| return errorLogger(err);
|
||||
const src = Dispatchable(Image).fromHandleObject(p_src) catch |err| return errorLogger(err);
|
||||
const dst = Dispatchable(Image).fromHandleObject(p_dst) catch |err| return errorLogger(err);
|
||||
|
||||
notImplementedWarning();
|
||||
|
||||
_ = cmd;
|
||||
_ = src;
|
||||
_ = src_layout;
|
||||
_ = dst;
|
||||
_ = dst_layout;
|
||||
_ = count;
|
||||
_ = regions;
|
||||
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.resolveImage(src, src_layout, dst, dst_layout, regions[0..count]) catch |err| return errorLogger(err);
|
||||
}
|
||||
|
||||
pub export fn strollCmdSetBlendConstants(p_cmd: vk.CommandBuffer, p_constants: [*]f32) callconv(vk.vulkan_call_conv) void {
|
||||
|
||||
Reference in New Issue
Block a user