adding fragdepth propagation, adjusting attachment sizing
This commit is contained in:
@@ -529,7 +529,7 @@ pub fn clearAttachment(interface: *Interface, attachment: vk.ClearAttachment, re
|
|||||||
const fb_attachment_index = (subpass.color_attachments orelse return)[impl.attachment.color_attachment].attachment;
|
const fb_attachment_index = (subpass.color_attachments orelse return)[impl.attachment.color_attachment].attachment;
|
||||||
|
|
||||||
if (fb_attachment_index != vk.ATTACHMENT_UNUSED)
|
if (fb_attachment_index != vk.ATTACHMENT_UNUSED)
|
||||||
break :blk framebuffer.interface.attachments[impl.attachment.color_attachment];
|
break :blk framebuffer.interface.attachments[fb_attachment_index];
|
||||||
} else if (impl.attachment.aspect_mask.depth_bit or impl.attachment.aspect_mask.stencil_bit) {
|
} 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 (render_pass.interface.subpasses[device.renderer.subpass_index].depth_stencil_attachments) |desc| {
|
||||||
if (desc.attachment != vk.ATTACHMENT_UNUSED)
|
if (desc.attachment != vk.ATTACHMENT_UNUSED)
|
||||||
|
|||||||
@@ -56,14 +56,14 @@ pub fn resolveAttachments(self: *Self, render_pass: *SoftRenderPass, subpass_ind
|
|||||||
.src_subresource = .{
|
.src_subresource = .{
|
||||||
.aspect_mask = src_image_view.subresource_range.aspect_mask,
|
.aspect_mask = src_image_view.subresource_range.aspect_mask,
|
||||||
.base_array_layer = src_image_view.subresource_range.base_array_layer,
|
.base_array_layer = src_image_view.subresource_range.base_array_layer,
|
||||||
.layer_count = src_image_view.subresource_range.layer_count,
|
.layer_count = src_image_view.layerCount(),
|
||||||
.mip_level = src_image_view.subresource_range.base_mip_level,
|
.mip_level = src_image_view.subresource_range.base_mip_level,
|
||||||
},
|
},
|
||||||
.src_offset = .{ .x = 0, .y = 0, .z = 0 },
|
.src_offset = .{ .x = 0, .y = 0, .z = 0 },
|
||||||
.dst_subresource = .{
|
.dst_subresource = .{
|
||||||
.aspect_mask = dst_image_view.subresource_range.aspect_mask,
|
.aspect_mask = dst_image_view.subresource_range.aspect_mask,
|
||||||
.base_array_layer = dst_image_view.subresource_range.base_array_layer,
|
.base_array_layer = dst_image_view.subresource_range.base_array_layer,
|
||||||
.layer_count = dst_image_view.subresource_range.layer_count,
|
.layer_count = dst_image_view.layerCount(),
|
||||||
.mip_level = dst_image_view.subresource_range.base_mip_level,
|
.mip_level = dst_image_view.subresource_range.base_mip_level,
|
||||||
},
|
},
|
||||||
.dst_offset = .{ .x = 0, .y = 0, .z = 0 },
|
.dst_offset = .{ .x = 0, .y = 0, .z = 0 },
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ const Device = base.Device;
|
|||||||
const VkError = base.VkError;
|
const VkError = base.VkError;
|
||||||
const SpvRuntimeError = spv.Runtime.RuntimeError;
|
const SpvRuntimeError = spv.Runtime.RuntimeError;
|
||||||
|
|
||||||
|
pub threadlocal var current_fragment_coord: ?vk.Offset3D = null; // Ugly hack
|
||||||
|
|
||||||
const NonDispatchable = base.NonDispatchable;
|
const NonDispatchable = base.NonDispatchable;
|
||||||
const ShaderModule = base.ShaderModule;
|
const ShaderModule = base.ShaderModule;
|
||||||
|
|
||||||
@@ -294,16 +296,18 @@ fn imageApi() spv.Runtime.ImageAPI {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn imageMipLevel(image: *SoftImage, image_view: *SoftImageView, lod: ?i32) u32 {
|
fn imageMipLevel(image_view: *SoftImageView, lod: ?i32) u32 {
|
||||||
const range = image_view.interface.subresource_range;
|
|
||||||
const mip_lod: u32 = if (lod) |level| @intCast(@max(level, 0)) else 0;
|
const mip_lod: u32 = if (lod) |level| @intCast(@max(level, 0)) else 0;
|
||||||
const max_lod = if (range.level_count == vk.REMAINING_MIP_LEVELS)
|
const range = image_view.interface.subresource_range;
|
||||||
image.interface.mip_levels - range.base_mip_level - 1
|
const max_lod = image_view.interface.levelCount() - 1;
|
||||||
else
|
|
||||||
range.level_count - 1;
|
|
||||||
return range.base_mip_level + @min(mip_lod, max_lod);
|
return range.base_mip_level + @min(mip_lod, max_lod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn subpassDataCoord(x: i32, y: i32, z: i32) SpvRuntimeError!vk.Offset3D {
|
||||||
|
const coord = current_fragment_coord orelse return SpvRuntimeError.Unknown;
|
||||||
|
return .{ .x = coord.x + x, .y = coord.y + y, .z = coord.z + z };
|
||||||
|
}
|
||||||
|
|
||||||
fn readImageFloat4(context: *anyopaque, dim: spv.SpvDim, x: i32, y: i32, z: i32, lod: ?i32) SpvRuntimeError!spv.Runtime.Vec4(f32) {
|
fn readImageFloat4(context: *anyopaque, dim: spv.SpvDim, x: i32, y: i32, z: i32, lod: ?i32) SpvRuntimeError!spv.Runtime.Vec4(f32) {
|
||||||
var pixel = zm.f32x4s(0.0);
|
var pixel = zm.f32x4s(0.0);
|
||||||
if (dim == .Buffer) {
|
if (dim == .Buffer) {
|
||||||
@@ -315,8 +319,8 @@ fn readImageFloat4(context: *anyopaque, dim: spv.SpvDim, x: i32, y: i32, z: i32,
|
|||||||
const image_view: *SoftImageView = @ptrCast(@alignCast(context));
|
const image_view: *SoftImageView = @ptrCast(@alignCast(context));
|
||||||
const image: *SoftImage = @alignCast(@fieldParentPtr("interface", image_view.interface.image));
|
const image: *SoftImage = @alignCast(@fieldParentPtr("interface", image_view.interface.image));
|
||||||
const cube_face: u32 = if (dim == .Cube) @intCast(z) else 0;
|
const cube_face: u32 = if (dim == .Cube) @intCast(z) else 0;
|
||||||
const mip_level = imageMipLevel(image, image_view, lod);
|
const mip_level = imageMipLevel(image_view, lod);
|
||||||
const image_coord: vk.Offset3D = switch (image_view.interface.view_type) {
|
const image_coord: vk.Offset3D = if (dim == .SubpassData) try subpassDataCoord(x, y, z) else switch (image_view.interface.view_type) {
|
||||||
.@"1d", .@"1d_array" => .{ .x = x, .y = 0, .z = 0 },
|
.@"1d", .@"1d_array" => .{ .x = x, .y = 0, .z = 0 },
|
||||||
.@"2d", .@"2d_array", .cube, .cube_array => .{ .x = x, .y = y, .z = 0 },
|
.@"2d", .@"2d_array", .cube, .cube_array => .{ .x = x, .y = y, .z = 0 },
|
||||||
else => .{ .x = x, .y = y, .z = z },
|
else => .{ .x = x, .y = y, .z = z },
|
||||||
@@ -356,8 +360,8 @@ fn readImageInt4(context: *anyopaque, dim: spv.SpvDim, x: i32, y: i32, z: i32, l
|
|||||||
const image_view: *SoftImageView = @ptrCast(@alignCast(context));
|
const image_view: *SoftImageView = @ptrCast(@alignCast(context));
|
||||||
const image: *SoftImage = @alignCast(@fieldParentPtr("interface", image_view.interface.image));
|
const image: *SoftImage = @alignCast(@fieldParentPtr("interface", image_view.interface.image));
|
||||||
const cube_face: u32 = if (dim == .Cube) @intCast(z) else 0;
|
const cube_face: u32 = if (dim == .Cube) @intCast(z) else 0;
|
||||||
const mip_level = imageMipLevel(image, image_view, lod);
|
const mip_level = imageMipLevel(image_view, lod);
|
||||||
const image_coord: vk.Offset3D = switch (image_view.interface.view_type) {
|
const image_coord: vk.Offset3D = if (dim == .SubpassData) try subpassDataCoord(x, y, z) else switch (image_view.interface.view_type) {
|
||||||
.@"1d", .@"1d_array" => .{ .x = x, .y = 0, .z = 0 },
|
.@"1d", .@"1d_array" => .{ .x = x, .y = 0, .z = 0 },
|
||||||
.@"2d", .@"2d_array", .cube, .cube_array => .{ .x = x, .y = y, .z = 0 },
|
.@"2d", .@"2d_array", .cube, .cube_array => .{ .x = x, .y = y, .z = 0 },
|
||||||
else => .{ .x = x, .y = y, .z = z },
|
else => .{ .x = x, .y = y, .z = z },
|
||||||
@@ -516,19 +520,13 @@ fn queryImageSize(context: *anyopaque, dim: spv.SpvDim, arrayed: bool, lod: ?i32
|
|||||||
}
|
}
|
||||||
|
|
||||||
const image_view: *SoftImageView = @ptrCast(@alignCast(context));
|
const image_view: *SoftImageView = @ptrCast(@alignCast(context));
|
||||||
const image: *SoftImage = @alignCast(@fieldParentPtr("interface", image_view.interface.image));
|
|
||||||
const range = image_view.interface.subresource_range;
|
const range = image_view.interface.subresource_range;
|
||||||
const mip_lod: u32 = if (lod) |level| @intCast(@max(level, 0)) else 0;
|
const mip_lod: u32 = if (lod) |level| @intCast(@max(level, 0)) else 0;
|
||||||
const max_lod = if (range.level_count == vk.REMAINING_MIP_LEVELS)
|
const max_lod = image_view.interface.levelCount() - 1;
|
||||||
image.interface.mip_levels - range.base_mip_level - 1
|
|
||||||
else
|
|
||||||
range.level_count - 1;
|
|
||||||
const mip_level = range.base_mip_level + @min(mip_lod, max_lod);
|
const mip_level = range.base_mip_level + @min(mip_lod, max_lod);
|
||||||
|
const image: *SoftImage = @alignCast(@fieldParentPtr("interface", image_view.interface.image));
|
||||||
const extent = image.getMipLevelExtent(mip_level);
|
const extent = image.getMipLevelExtent(mip_level);
|
||||||
const layers = if (range.layer_count == vk.REMAINING_ARRAY_LAYERS)
|
const layers = image_view.interface.layerCount();
|
||||||
image.interface.array_layers - range.base_array_layer
|
|
||||||
else
|
|
||||||
range.layer_count;
|
|
||||||
return switch (dim) {
|
return switch (dim) {
|
||||||
.@"1D" => if (arrayed)
|
.@"1D" => if (arrayed)
|
||||||
.{ .x = extent.width, .y = layers, .z = 0, .w = 0 }
|
.{ .x = extent.width, .y = layers, .z = 0, .w = 0 }
|
||||||
@@ -551,12 +549,7 @@ fn queryImageSamples(context: *anyopaque) SpvRuntimeError!u32 {
|
|||||||
|
|
||||||
fn queryImageLevels(context: *anyopaque) SpvRuntimeError!u32 {
|
fn queryImageLevels(context: *anyopaque) SpvRuntimeError!u32 {
|
||||||
const image_view: *SoftImageView = @ptrCast(@alignCast(context));
|
const image_view: *SoftImageView = @ptrCast(@alignCast(context));
|
||||||
const image: *SoftImage = @alignCast(@fieldParentPtr("interface", image_view.interface.image));
|
return image_view.interface.levelCount();
|
||||||
const range = image_view.interface.subresource_range;
|
|
||||||
return if (range.level_count == vk.REMAINING_MIP_LEVELS)
|
|
||||||
image.interface.mip_levels - range.base_mip_level
|
|
||||||
else
|
|
||||||
range.level_count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn queryImageLod(context: *anyopaque, context2: *anyopaque, dim: spv.SpvDim, derivatives: spv.Runtime.ImageDerivatives) SpvRuntimeError!spv.Runtime.Vec4(f32) {
|
fn queryImageLod(context: *anyopaque, context2: *anyopaque, dim: spv.SpvDim, derivatives: spv.Runtime.ImageDerivatives) SpvRuntimeError!spv.Runtime.Vec4(f32) {
|
||||||
|
|||||||
@@ -191,23 +191,17 @@ fn samplerBorderColorInt(sampler: *Self, format: vk.Format) U32x4 {
|
|||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn viewLayerCount(image: *SoftImage, range: vk.ImageSubresourceRange) u32 {
|
fn viewLayerCount(image_view: *SoftImageView) u32 {
|
||||||
return if (range.layer_count == vk.REMAINING_ARRAY_LAYERS)
|
return image_view.interface.layerCount();
|
||||||
image.interface.array_layers - range.base_array_layer
|
|
||||||
else
|
|
||||||
range.layer_count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn viewMipCount(image: *SoftImage, range: vk.ImageSubresourceRange) u32 {
|
fn viewMipCount(image_view: *SoftImageView) u32 {
|
||||||
return if (range.level_count == vk.REMAINING_MIP_LEVELS)
|
return image_view.interface.levelCount();
|
||||||
image.interface.mip_levels - range.base_mip_level
|
|
||||||
else
|
|
||||||
range.level_count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sampleMipLevel(image: *SoftImage, image_view: *SoftImageView, sampler: *Self, lod: ?f32) u32 {
|
fn sampleMipLevel(image_view: *SoftImageView, sampler: *Self, lod: ?f32) u32 {
|
||||||
const range = image_view.interface.subresource_range;
|
const range = image_view.interface.subresource_range;
|
||||||
const mip_count = viewMipCount(image, range);
|
const mip_count = viewMipCount(image_view);
|
||||||
if (mip_count <= 1)
|
if (mip_count <= 1)
|
||||||
return range.base_mip_level;
|
return range.base_mip_level;
|
||||||
|
|
||||||
@@ -256,7 +250,7 @@ pub fn queryImageLod(image: *SoftImage, image_view: *SoftImageView, sampler: *Se
|
|||||||
const lod = if (rho > 0.0) @log2(rho) else -std.math.inf(f32);
|
const lod = if (rho > 0.0) @log2(rho) else -std.math.inf(f32);
|
||||||
const biased_lod = lod + sampler.interface.mip_lod_bias;
|
const biased_lod = lod + sampler.interface.mip_lod_bias;
|
||||||
const clamped_lod = std.math.clamp(biased_lod, sampler.interface.min_lod, sampler.interface.max_lod);
|
const clamped_lod = std.math.clamp(biased_lod, sampler.interface.min_lod, sampler.interface.max_lod);
|
||||||
const max_level: f32 = @floatFromInt(viewMipCount(image, range) - 1);
|
const max_level: f32 = @floatFromInt(viewMipCount(image_view) - 1);
|
||||||
const level = std.math.clamp(mipmapModeLevel(sampler, clamped_lod), 0.0, max_level);
|
const level = std.math.clamp(mipmapModeLevel(sampler, clamped_lod), 0.0, max_level);
|
||||||
|
|
||||||
return .{ level, lod, 0.0, 0.0 };
|
return .{ level, lod, 0.0, 0.0 };
|
||||||
@@ -357,9 +351,9 @@ fn readSampledFloat4(
|
|||||||
} else coord;
|
} else coord;
|
||||||
|
|
||||||
const z: i32, const layer: u32 = switch (image_view.interface.view_type) {
|
const z: i32, const layer: u32 = switch (image_view.interface.view_type) {
|
||||||
.@"1d_array" => .{ 0, range.base_array_layer + sampleArrayLayer(coord.v, viewLayerCount(image, range)) },
|
.@"1d_array" => .{ 0, range.base_array_layer + sampleArrayLayer(coord.v, viewLayerCount(image_view)) },
|
||||||
.@"2d_array" => .{ 0, range.base_array_layer + sampleArrayLayer(coord.w, viewLayerCount(image, range)) },
|
.@"2d_array" => .{ 0, range.base_array_layer + sampleArrayLayer(coord.w, viewLayerCount(image_view)) },
|
||||||
.cube_array => .{ 0, range.base_array_layer + sampleArrayLayer(coord.w, @divTrunc(viewLayerCount(image, range), 6)) * 6 + texel.face },
|
.cube_array => .{ 0, range.base_array_layer + sampleArrayLayer(coord.w, @divTrunc(viewLayerCount(image_view), 6)) * 6 + texel.face },
|
||||||
.@"3d" => .{ sampleAddressOrBorder(iz, extent.depth, sampler.interface.address_mode_w) orelse return samplerBorderColor(sampler, format), range.base_array_layer },
|
.@"3d" => .{ sampleAddressOrBorder(iz, extent.depth, sampler.interface.address_mode_w) orelse return samplerBorderColor(sampler, format), range.base_array_layer },
|
||||||
.cube => .{ 0, range.base_array_layer + texel.face },
|
.cube => .{ 0, range.base_array_layer + texel.face },
|
||||||
else => .{ 0, range.base_array_layer },
|
else => .{ 0, range.base_array_layer },
|
||||||
@@ -432,9 +426,9 @@ fn readSampledInt4(
|
|||||||
} else coord;
|
} else coord;
|
||||||
|
|
||||||
const z: i32, const layer: u32 = switch (image_view.interface.view_type) {
|
const z: i32, const layer: u32 = switch (image_view.interface.view_type) {
|
||||||
.@"1d_array" => .{ 0, range.base_array_layer + sampleArrayLayer(coord.v, viewLayerCount(image, range)) },
|
.@"1d_array" => .{ 0, range.base_array_layer + sampleArrayLayer(coord.v, viewLayerCount(image_view)) },
|
||||||
.@"2d_array" => .{ 0, range.base_array_layer + sampleArrayLayer(coord.w, viewLayerCount(image, range)) },
|
.@"2d_array" => .{ 0, range.base_array_layer + sampleArrayLayer(coord.w, viewLayerCount(image_view)) },
|
||||||
.cube_array => .{ 0, range.base_array_layer + sampleArrayLayer(coord.w, @divTrunc(viewLayerCount(image, range), 6)) * 6 + texel.face },
|
.cube_array => .{ 0, range.base_array_layer + sampleArrayLayer(coord.w, @divTrunc(viewLayerCount(image_view), 6)) * 6 + texel.face },
|
||||||
.@"3d" => .{ sampleAddressOrBorder(iz, extent.depth, sampler.interface.address_mode_w) orelse return samplerBorderColorInt(sampler, format), range.base_array_layer },
|
.@"3d" => .{ sampleAddressOrBorder(iz, extent.depth, sampler.interface.address_mode_w) orelse return samplerBorderColorInt(sampler, format), range.base_array_layer },
|
||||||
.cube => .{ 0, range.base_array_layer + texel.face },
|
.cube => .{ 0, range.base_array_layer + texel.face },
|
||||||
else => .{ 0, range.base_array_layer },
|
else => .{ 0, range.base_array_layer },
|
||||||
@@ -465,7 +459,7 @@ fn readSampledInt4(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn sampleImageFloat4(image: *SoftImage, image_view: *SoftImageView, sampler: *Self, dim: spv.SpvDim, x: f32, y: f32, z: f32, lod: ?f32, offset: ImageOffset) VkError!F32x4 {
|
pub fn sampleImageFloat4(image: *SoftImage, image_view: *SoftImageView, sampler: *Self, dim: spv.SpvDim, x: f32, y: f32, z: f32, lod: ?f32, offset: ImageOffset) VkError!F32x4 {
|
||||||
const mip_level = sampleMipLevel(image, image_view, sampler, lod);
|
const mip_level = sampleMipLevel(image_view, sampler, lod);
|
||||||
const extent = image.getMipLevelExtent(mip_level);
|
const extent = image.getMipLevelExtent(mip_level);
|
||||||
const coord: CubeCoordinate = switch (image_view.interface.view_type) {
|
const coord: CubeCoordinate = switch (image_view.interface.view_type) {
|
||||||
.@"1d_array" => .{
|
.@"1d_array" => .{
|
||||||
@@ -523,7 +517,7 @@ pub fn sampleImageFloat4(image: *SoftImage, image_view: *SoftImageView, sampler:
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn sampleImageInt4(image: *SoftImage, image_view: *SoftImageView, sampler: *Self, dim: spv.SpvDim, x: f32, y: f32, z: f32, lod: ?f32, offset: ImageOffset) VkError!U32x4 {
|
pub fn sampleImageInt4(image: *SoftImage, image_view: *SoftImageView, sampler: *Self, dim: spv.SpvDim, x: f32, y: f32, z: f32, lod: ?f32, offset: ImageOffset) VkError!U32x4 {
|
||||||
const mip_level = sampleMipLevel(image, image_view, sampler, lod);
|
const mip_level = sampleMipLevel(image_view, sampler, lod);
|
||||||
const extent = image.getMipLevelExtent(mip_level);
|
const extent = image.getMipLevelExtent(mip_level);
|
||||||
const coord: CubeCoordinate = switch (image_view.interface.view_type) {
|
const coord: CubeCoordinate = switch (image_view.interface.view_type) {
|
||||||
.@"1d_array" => .{
|
.@"1d_array" => .{
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ const VkError = base.VkError;
|
|||||||
const SpvRuntimeError = spv.Runtime.RuntimeError;
|
const SpvRuntimeError = spv.Runtime.RuntimeError;
|
||||||
const INTERFACE_BLOB_PADDING = @sizeOf(zm.F32x4);
|
const INTERFACE_BLOB_PADDING = @sizeOf(zm.F32x4);
|
||||||
|
|
||||||
|
pub const InvocationResult = struct {
|
||||||
|
outputs: [spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(zm.F32x4)]u8,
|
||||||
|
depth: ?f32,
|
||||||
|
};
|
||||||
|
|
||||||
pub const DerivativeInputs = struct {
|
pub const DerivativeInputs = struct {
|
||||||
dx: [spv.SPIRV_MAX_OUTPUT_LOCATIONS]VertexInterpolationLocation,
|
dx: [spv.SPIRV_MAX_OUTPUT_LOCATIONS]VertexInterpolationLocation,
|
||||||
dy: [spv.SPIRV_MAX_OUTPUT_LOCATIONS]VertexInterpolationLocation,
|
dy: [spv.SPIRV_MAX_OUTPUT_LOCATIONS]VertexInterpolationLocation,
|
||||||
@@ -27,7 +32,7 @@ pub fn shaderInvocation(
|
|||||||
front_face: bool,
|
front_face: bool,
|
||||||
inputs: [spv.SPIRV_MAX_OUTPUT_LOCATIONS]VertexInterpolationLocation,
|
inputs: [spv.SPIRV_MAX_OUTPUT_LOCATIONS]VertexInterpolationLocation,
|
||||||
derivative_inputs: ?DerivativeInputs,
|
derivative_inputs: ?DerivativeInputs,
|
||||||
) SpvRuntimeError![spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(zm.F32x4)]u8 {
|
) SpvRuntimeError!InvocationResult {
|
||||||
var fragment_inputs = inputs;
|
var fragment_inputs = inputs;
|
||||||
errdefer freeOwnedInputs(allocator, fragment_inputs);
|
errdefer freeOwnedInputs(allocator, fragment_inputs);
|
||||||
|
|
||||||
@@ -66,6 +71,15 @@ pub fn shaderInvocation(
|
|||||||
else => return err,
|
else => return err,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const SoftPipeline = @import("../SoftPipeline.zig");
|
||||||
|
const previous_fragment_coord = SoftPipeline.current_fragment_coord;
|
||||||
|
SoftPipeline.current_fragment_coord = .{
|
||||||
|
.x = @intFromFloat(position[0]),
|
||||||
|
.y = @intFromFloat(position[1]),
|
||||||
|
.z = @intFromFloat(position[2]),
|
||||||
|
};
|
||||||
|
defer SoftPipeline.current_fragment_coord = previous_fragment_coord;
|
||||||
|
|
||||||
const entry = try rt.getEntryPointByName(shader.entry);
|
const entry = try rt.getEntryPointByName(shader.entry);
|
||||||
|
|
||||||
for (0..spv.SPIRV_MAX_OUTPUT_LOCATIONS) |location| {
|
for (0..spv.SPIRV_MAX_OUTPUT_LOCATIONS) |location| {
|
||||||
@@ -142,6 +156,15 @@ pub fn shaderInvocation(
|
|||||||
try readFragmentOutput(allocator, rt, &outputs, location, 0, result_word);
|
try readFragmentOutput(allocator, rt, &outputs, location, 0, result_word);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var depth: ?f32 = null;
|
||||||
|
var frag_depth: f32 = undefined;
|
||||||
|
if (rt.readBuiltIn(std.mem.asBytes(&frag_depth), .FragDepth)) {
|
||||||
|
depth = frag_depth;
|
||||||
|
} else |err| switch (err) {
|
||||||
|
SpvRuntimeError.InvalidSpirV, SpvRuntimeError.NotFound => {},
|
||||||
|
else => return err,
|
||||||
|
}
|
||||||
|
|
||||||
try rt.flushDescriptorSets(allocator);
|
try rt.flushDescriptorSets(allocator);
|
||||||
freeOwnedInputs(allocator, fragment_inputs);
|
freeOwnedInputs(allocator, fragment_inputs);
|
||||||
if (derivatives) |owned_derivatives| {
|
if (derivatives) |owned_derivatives| {
|
||||||
@@ -149,7 +172,10 @@ pub fn shaderInvocation(
|
|||||||
freeOwnedInputs(allocator, owned_derivatives.dy);
|
freeOwnedInputs(allocator, owned_derivatives.dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
return outputs;
|
return .{
|
||||||
|
.outputs = outputs,
|
||||||
|
.depth = depth,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn readFragmentOutput(
|
fn readFragmentOutput(
|
||||||
|
|||||||
@@ -19,6 +19,18 @@ const SoftImage = @import("../SoftImage.zig");
|
|||||||
const VkError = base.VkError;
|
const VkError = base.VkError;
|
||||||
const SpvRuntimeError = spv.Runtime.RuntimeError;
|
const SpvRuntimeError = spv.Runtime.RuntimeError;
|
||||||
|
|
||||||
|
fn renderTargetSubresourceSize(image: *const SoftImage, image_view: *const base.ImageView, aspect_mask: vk.ImageAspectFlags, mip_level: u32) usize {
|
||||||
|
if (image.interface.image_type == .@"3d" and image.interface.flags.@"2d_array_compatible_bit" and
|
||||||
|
(image_view.view_type == .@"2d" or image_view.view_type == .@"2d_array"))
|
||||||
|
{
|
||||||
|
return image.interface.getSliceMemSizeForMipLevel(aspect_mask, mip_level) *
|
||||||
|
image.interface.samples.toInt() *
|
||||||
|
image_view.layerCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
return image.getMultiSampledLevelSize(aspect_mask, mip_level);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn processThenFragmentStage(renderer: *Renderer, allocator: std.mem.Allocator, draw_call: *DrawCall) VkError!void {
|
pub fn processThenFragmentStage(renderer: *Renderer, allocator: std.mem.Allocator, draw_call: *DrawCall) VkError!void {
|
||||||
const io = draw_call.renderer.device.interface.io();
|
const io = draw_call.renderer.device.interface.io();
|
||||||
|
|
||||||
@@ -45,7 +57,7 @@ pub fn processThenFragmentStage(renderer: *Renderer, allocator: std.mem.Allocato
|
|||||||
color_range.base_mip_level,
|
color_range.base_mip_level,
|
||||||
color_range.base_array_layer,
|
color_range.base_array_layer,
|
||||||
);
|
);
|
||||||
const color_attachment_subresource_size = render_target.getLayerSize(color_range.aspect_mask);
|
const color_attachment_subresource_size = renderTargetSubresourceSize(render_target, render_target_view, color_range.aspect_mask, color_range.base_mip_level);
|
||||||
access.* = .{
|
access.* = .{
|
||||||
.mutex = undefined,
|
.mutex = undefined,
|
||||||
.base = try render_target.mapAsSliceWithAddedOffset(u8, color_attachment_subresource_offset, color_attachment_subresource_size),
|
.base = try render_target.mapAsSliceWithAddedOffset(u8, color_attachment_subresource_offset, color_attachment_subresource_size),
|
||||||
@@ -78,7 +90,7 @@ pub fn processThenFragmentStage(renderer: *Renderer, allocator: std.mem.Allocato
|
|||||||
depth_range.base_mip_level,
|
depth_range.base_mip_level,
|
||||||
depth_range.base_array_layer,
|
depth_range.base_array_layer,
|
||||||
);
|
);
|
||||||
const attachment_subresource_size = depth_attachment.?.getLayerSize(depth_aspect);
|
const attachment_subresource_size = renderTargetSubresourceSize(depth_attachment.?, depth_attachment_view.?, depth_aspect, depth_range.base_mip_level);
|
||||||
break :blk .{
|
break :blk .{
|
||||||
.mutex = .init,
|
.mutex = .init,
|
||||||
.base = try depth_attachment.?.mapAsSliceWithAddedOffset(u8, attachment_subresource_offset, attachment_subresource_size),
|
.base = try depth_attachment.?.mapAsSliceWithAddedOffset(u8, attachment_subresource_offset, attachment_subresource_size),
|
||||||
@@ -108,7 +120,7 @@ pub fn processThenFragmentStage(renderer: *Renderer, allocator: std.mem.Allocato
|
|||||||
stencil_range.base_mip_level,
|
stencil_range.base_mip_level,
|
||||||
stencil_range.base_array_layer,
|
stencil_range.base_array_layer,
|
||||||
);
|
);
|
||||||
const attachment_subresource_size = depth_attachment.?.getLayerSize(stencil_aspect);
|
const attachment_subresource_size = renderTargetSubresourceSize(depth_attachment.?, depth_attachment_view.?, stencil_aspect, stencil_range.base_mip_level);
|
||||||
break :blk .{
|
break :blk .{
|
||||||
.mutex = .init,
|
.mutex = .init,
|
||||||
.base = try depth_attachment.?.mapAsSliceWithAddedOffset(u8, attachment_subresource_offset, attachment_subresource_size),
|
.base = try depth_attachment.?.mapAsSliceWithAddedOffset(u8, attachment_subresource_offset, attachment_subresource_size),
|
||||||
@@ -340,7 +352,10 @@ fn clipTransformAndRasterizePoint(
|
|||||||
if (!common.scissorContainsPixel(draw_call.scissor, px, py))
|
if (!common.scissorContainsPixel(draw_call.scissor, px, py))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var outputs = std.mem.zeroes([spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(zm.F32x4)]u8);
|
var fragment_result: fragment.InvocationResult = .{
|
||||||
|
.outputs = std.mem.zeroes([spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(zm.F32x4)]u8),
|
||||||
|
.depth = null,
|
||||||
|
};
|
||||||
if (has_fragment_shader) {
|
if (has_fragment_shader) {
|
||||||
const frag_x = @as(f32, @floatFromInt(px)) + 0.5;
|
const frag_x = @as(f32, @floatFromInt(px)) + 0.5;
|
||||||
const frag_y = @as(f32, @floatFromInt(py)) + 0.5;
|
const frag_y = @as(f32, @floatFromInt(py)) + 0.5;
|
||||||
@@ -349,7 +364,7 @@ fn clipTransformAndRasterizePoint(
|
|||||||
(frag_y - point_min_y) / point_size,
|
(frag_y - point_min_y) / point_size,
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = fragment.shaderInvocation(
|
fragment_result = fragment.shaderInvocation(
|
||||||
allocator,
|
allocator,
|
||||||
draw_call,
|
draw_call,
|
||||||
0,
|
0,
|
||||||
@@ -372,7 +387,7 @@ fn clipTransformAndRasterizePoint(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
try common.writeToTargets(outputs, draw_call, color_attachment_access, depth_attachment_access, stencil_attachment_access, true, @intCast(px), @intCast(py), transformed.position[2]);
|
try common.writeToTargets(fragment_result.outputs, draw_call, color_attachment_access, depth_attachment_access, stencil_attachment_access, true, @intCast(px), @intCast(py), fragment_result.depth orelse transformed.position[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,9 +153,12 @@ inline fn run(data: RunData) !void {
|
|||||||
const z = ((1.0 - t) * data.start_vertex.position[2]) + (t * data.end_vertex.position[2]);
|
const z = ((1.0 - t) * data.start_vertex.position[2]) + (t * data.end_vertex.position[2]);
|
||||||
const frag_w = ((1.0 - t) / data.start_vertex.position[3]) + (t / data.end_vertex.position[3]);
|
const frag_w = ((1.0 - t) / data.start_vertex.position[3]) + (t / data.end_vertex.position[3]);
|
||||||
|
|
||||||
var outputs = std.mem.zeroes([spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(F32x4)]u8);
|
var fragment_result: fragment.InvocationResult = .{
|
||||||
|
.outputs = std.mem.zeroes([spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(F32x4)]u8),
|
||||||
|
.depth = null,
|
||||||
|
};
|
||||||
if (data.has_fragment_shader) {
|
if (data.has_fragment_shader) {
|
||||||
outputs = fragment.shaderInvocation(
|
fragment_result = fragment.shaderInvocation(
|
||||||
data.allocator,
|
data.allocator,
|
||||||
data.draw_call,
|
data.draw_call,
|
||||||
data.batch_id,
|
data.batch_id,
|
||||||
@@ -180,7 +183,7 @@ inline fn run(data: RunData) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try common.writeToTargets(
|
try common.writeToTargets(
|
||||||
outputs,
|
fragment_result.outputs,
|
||||||
data.draw_call,
|
data.draw_call,
|
||||||
data.color_attachment_access,
|
data.color_attachment_access,
|
||||||
data.depth_attachment_access,
|
data.depth_attachment_access,
|
||||||
@@ -188,7 +191,7 @@ inline fn run(data: RunData) !void {
|
|||||||
true,
|
true,
|
||||||
@intCast(pixel_x),
|
@intCast(pixel_x),
|
||||||
@intCast(pixel_y),
|
@intCast(pixel_y),
|
||||||
z,
|
fragment_result.depth orelse z,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,7 +179,10 @@ inline fn run(data: RunData) !void {
|
|||||||
const z = (b0 * data.v0.position[2]) + (b1 * data.v1.position[2]) + (b2 * data.v2.position[2]);
|
const z = (b0 * data.v0.position[2]) + (b1 * data.v1.position[2]) + (b2 * data.v2.position[2]);
|
||||||
const frag_w = (b0 / data.v0.position[3]) + (b1 / data.v1.position[3]) + (b2 / data.v2.position[3]);
|
const frag_w = (b0 / data.v0.position[3]) + (b1 / data.v1.position[3]) + (b2 / data.v2.position[3]);
|
||||||
|
|
||||||
var outputs = std.mem.zeroes([spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(F32x4)]u8);
|
var fragment_result: fragment.InvocationResult = .{
|
||||||
|
.outputs = std.mem.zeroes([spv.SPIRV_MAX_OUTPUT_LOCATIONS][@sizeOf(F32x4)]u8),
|
||||||
|
.depth = null,
|
||||||
|
};
|
||||||
if (data.has_fragment_shader) {
|
if (data.has_fragment_shader) {
|
||||||
const inputs = try common.interpolateVertexOutputs(data.allocator, &data.v0, &data.v1, &data.v2, b0, b1, b2);
|
const inputs = try common.interpolateVertexOutputs(data.allocator, &data.v0, &data.v1, &data.v2, b0, b1, b2);
|
||||||
const derivative_inputs: ?fragment.DerivativeInputs = if (data.fragment_uses_derivatives) blk: {
|
const derivative_inputs: ?fragment.DerivativeInputs = if (data.fragment_uses_derivatives) blk: {
|
||||||
@@ -215,7 +218,7 @@ inline fn run(data: RunData) !void {
|
|||||||
break :blk derivatives;
|
break :blk derivatives;
|
||||||
} else null;
|
} else null;
|
||||||
|
|
||||||
outputs = fragment.shaderInvocation(
|
fragment_result = fragment.shaderInvocation(
|
||||||
data.allocator,
|
data.allocator,
|
||||||
data.draw_call,
|
data.draw_call,
|
||||||
data.batch_id,
|
data.batch_id,
|
||||||
@@ -239,7 +242,7 @@ inline fn run(data: RunData) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try common.writeToTargets(
|
try common.writeToTargets(
|
||||||
outputs,
|
fragment_result.outputs,
|
||||||
data.draw_call,
|
data.draw_call,
|
||||||
data.color_attachment_access,
|
data.color_attachment_access,
|
||||||
data.depth_attachment_access,
|
data.depth_attachment_access,
|
||||||
@@ -247,7 +250,7 @@ inline fn run(data: RunData) !void {
|
|||||||
data.front_face,
|
data.front_face,
|
||||||
@intCast(x),
|
@intCast(x),
|
||||||
@intCast(y),
|
@intCast(y),
|
||||||
z,
|
fragment_result.depth orelse z,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,3 +40,33 @@ pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.Image
|
|||||||
pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void {
|
pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void {
|
||||||
self.vtable.destroy(self, allocator);
|
self.vtable.destroy(self, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn levelCount(self: *const Self) u32 {
|
||||||
|
return if (self.subresource_range.level_count == vk.REMAINING_MIP_LEVELS)
|
||||||
|
self.image.mip_levels - self.subresource_range.base_mip_level
|
||||||
|
else
|
||||||
|
self.subresource_range.level_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn layerCount(self: *const Self) u32 {
|
||||||
|
return if (self.subresource_range.layer_count == vk.REMAINING_ARRAY_LAYERS)
|
||||||
|
self.remainingLayerCount()
|
||||||
|
else
|
||||||
|
self.subresource_range.layer_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resolvedSubresourceRange(self: *const Self) vk.ImageSubresourceRange {
|
||||||
|
var range = self.subresource_range;
|
||||||
|
range.level_count = self.levelCount();
|
||||||
|
range.layer_count = self.layerCount();
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remainingLayerCount(self: *const Self) u32 {
|
||||||
|
if (self.image.image_type == .@"3d" and self.image.flags.@"2d_array_compatible_bit") {
|
||||||
|
const depth = @max(@as(u32, 1), self.image.extent.depth >> @intCast(self.subresource_range.base_mip_level));
|
||||||
|
return depth - self.subresource_range.base_array_layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.image.array_layers - self.subresource_range.base_array_layer;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user