adding more image queries
Test / build_and_test (push) Successful in 30s
Build / build (push) Successful in 39s

This commit is contained in:
2026-06-14 22:54:20 +02:00
parent 57b5533195
commit df2ba1f7af
3 changed files with 127 additions and 23 deletions
+2 -2
View File
@@ -26,8 +26,8 @@
.hash = "N-V-__8AAF9uOh0I4P_99za7N822J3JwsDaqONrFVrcEQo59",
},
.SPIRV_Interpreter = .{
.url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#5c1eb25b4835f4161dd49cd000b19ae1cca6e80a",
.hash = "SPIRV_Interpreter-0.0.1-ajmpn8mDBwChlKPOGs3EkJl6RiTJYDcvpLbsIJaHBAOe",
.url = "git+https://git.kbz8.me/kbz_8/SPIRV-Interpreter#52ded6b490a47d843ad401cbd2c41b4dbdc7dca1",
.hash = "SPIRV_Interpreter-0.0.1-ajmpn0GXBwD01BnmV_Kf8EeNqTDoyuq7UvHVaq-WoBP0",
.lazy = true,
},
//.SPIRV_Interpreter = .{
+86 -21
View File
@@ -288,10 +288,23 @@ fn imageApi() spv.Runtime.ImageAPI {
.sampleImageInt4 = sampleImageInt4,
.sampleImageDref = sampleImageDref,
.queryImageSize = queryImageSize,
.queryImageLevels = queryImageLevels,
.queryImageSamples = queryImageSamples,
.queryImageLod = queryImageLod,
};
}
fn readImageFloat4(context: *anyopaque, dim: spv.SpvDim, x: i32, y: i32, z: i32) SpvRuntimeError!spv.Runtime.Vec4(f32) {
fn imageMipLevel(image: *SoftImage, 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 max_lod = if (range.level_count == vk.REMAINING_MIP_LEVELS)
image.interface.mip_levels - range.base_mip_level - 1
else
range.level_count - 1;
return range.base_mip_level + @min(mip_lod, max_lod);
}
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);
if (dim == .Buffer) {
const buffer_view: *SoftBufferView = @ptrCast(@alignCast(context));
@@ -302,16 +315,24 @@ fn readImageFloat4(context: *anyopaque, dim: spv.SpvDim, x: i32, y: i32, z: i32)
const image_view: *SoftImageView = @ptrCast(@alignCast(context));
const image: *SoftImage = @alignCast(@fieldParentPtr("interface", image_view.interface.image));
const cube_face: u32 = if (dim == .Cube) @intCast(z) else 0;
const mip_level = imageMipLevel(image, image_view, lod);
const image_coord: vk.Offset3D = switch (image_view.interface.view_type) {
.@"1d", .@"1d_array" => .{ .x = x, .y = 0, .z = 0 },
.@"2d", .@"2d_array", .cube, .cube_array => .{ .x = x, .y = y, .z = 0 },
else => .{ .x = x, .y = y, .z = z },
};
const array_layer = image_view.interface.subresource_range.base_array_layer + switch (image_view.interface.view_type) {
.@"1d_array" => @as(u32, @intCast(y)),
.@"2d_array" => @as(u32, @intCast(z)),
.cube => cube_face,
else => 0,
};
pixel = image.readFloat4(
.{
.x = x,
.y = y,
.z = if (dim == .Cube) 0 else z,
},
image_coord,
.{
.aspect_mask = image_view.interface.subresource_range.aspect_mask,
.mip_level = image_view.interface.subresource_range.base_mip_level,
.array_layer = image_view.interface.subresource_range.base_array_layer + cube_face,
.mip_level = mip_level,
.array_layer = array_layer,
},
image_view.interface.format,
) catch return SpvRuntimeError.Unknown;
@@ -324,7 +345,7 @@ fn readImageFloat4(context: *anyopaque, dim: spv.SpvDim, x: i32, y: i32, z: i32)
};
}
fn readImageInt4(context: *anyopaque, dim: spv.SpvDim, x: i32, y: i32, z: i32) SpvRuntimeError!spv.Runtime.Vec4(u32) {
fn readImageInt4(context: *anyopaque, dim: spv.SpvDim, x: i32, y: i32, z: i32, lod: ?i32) SpvRuntimeError!spv.Runtime.Vec4(u32) {
var pixel = @Vector(4, u32){ 0, 0, 0, 0 };
if (dim == .Buffer) {
const buffer_view: *SoftBufferView = @ptrCast(@alignCast(context));
@@ -335,16 +356,24 @@ fn readImageInt4(context: *anyopaque, dim: spv.SpvDim, x: i32, y: i32, z: i32) S
const image_view: *SoftImageView = @ptrCast(@alignCast(context));
const image: *SoftImage = @alignCast(@fieldParentPtr("interface", image_view.interface.image));
const cube_face: u32 = if (dim == .Cube) @intCast(z) else 0;
const mip_level = imageMipLevel(image, image_view, lod);
const image_coord: vk.Offset3D = switch (image_view.interface.view_type) {
.@"1d", .@"1d_array" => .{ .x = x, .y = 0, .z = 0 },
.@"2d", .@"2d_array", .cube, .cube_array => .{ .x = x, .y = y, .z = 0 },
else => .{ .x = x, .y = y, .z = z },
};
const array_layer = image_view.interface.subresource_range.base_array_layer + switch (image_view.interface.view_type) {
.@"1d_array" => @as(u32, @intCast(y)),
.@"2d_array" => @as(u32, @intCast(z)),
.cube => cube_face,
else => 0,
};
pixel = image.readInt4(
.{
.x = x,
.y = y,
.z = if (dim == .Cube) 0 else z,
},
image_coord,
.{
.aspect_mask = image_view.interface.subresource_range.aspect_mask,
.mip_level = image_view.interface.subresource_range.base_mip_level,
.array_layer = image_view.interface.subresource_range.base_array_layer + cube_face,
.mip_level = mip_level,
.array_layer = array_layer,
},
image_view.interface.format,
) catch return SpvRuntimeError.Unknown;
@@ -471,7 +500,7 @@ fn sampleImageDref(context: *anyopaque, context2: *anyopaque, dim: spv.SpvDim, x
return SoftSampler.sampleImageDref(image, image_view, sampler, dim, x, y, z, dref, lod, offset) catch return SpvRuntimeError.Unknown;
}
fn queryImageSize(context: *anyopaque, dim: spv.SpvDim, arrayed: bool) SpvRuntimeError!spv.Runtime.Vec4(u32) {
fn queryImageSize(context: *anyopaque, dim: spv.SpvDim, arrayed: bool, lod: ?i32) SpvRuntimeError!spv.Runtime.Vec4(u32) {
if (dim == .Buffer) {
const buffer_view: *SoftBufferView = @ptrCast(@alignCast(context));
const range = if (buffer_view.interface.range == vk.WHOLE_SIZE)
@@ -488,11 +517,18 @@ fn queryImageSize(context: *anyopaque, dim: spv.SpvDim, arrayed: bool) SpvRuntim
const image_view: *SoftImageView = @ptrCast(@alignCast(context));
const image: *SoftImage = @alignCast(@fieldParentPtr("interface", image_view.interface.image));
const extent = image.getMipLevelExtent(image_view.interface.subresource_range.base_mip_level);
const layers = if (image_view.interface.subresource_range.layer_count == vk.REMAINING_ARRAY_LAYERS)
image.interface.array_layers - image_view.interface.subresource_range.base_array_layer
const range = image_view.interface.subresource_range;
const mip_lod: u32 = if (lod) |level| @intCast(@max(level, 0)) else 0;
const max_lod = if (range.level_count == vk.REMAINING_MIP_LEVELS)
image.interface.mip_levels - range.base_mip_level - 1
else
image_view.interface.subresource_range.layer_count;
range.level_count - 1;
const mip_level = range.base_mip_level + @min(mip_lod, max_lod);
const extent = image.getMipLevelExtent(mip_level);
const layers = if (range.layer_count == vk.REMAINING_ARRAY_LAYERS)
image.interface.array_layers - range.base_array_layer
else
range.layer_count;
return switch (dim) {
.@"1D" => if (arrayed)
.{ .x = extent.width, .y = layers, .z = 0, .w = 0 }
@@ -506,3 +542,32 @@ fn queryImageSize(context: *anyopaque, dim: spv.SpvDim, arrayed: bool) SpvRuntim
else => .{ .x = extent.width, .y = extent.height, .z = layers, .w = 0 },
};
}
fn queryImageSamples(context: *anyopaque) SpvRuntimeError!u32 {
const image_view: *SoftImageView = @ptrCast(@alignCast(context));
const image: *SoftImage = @alignCast(@fieldParentPtr("interface", image_view.interface.image));
return @intCast(image.interface.samples.toInt());
}
fn queryImageLevels(context: *anyopaque) SpvRuntimeError!u32 {
const image_view: *SoftImageView = @ptrCast(@alignCast(context));
const image: *SoftImage = @alignCast(@fieldParentPtr("interface", image_view.interface.image));
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) {
const image_view: *SoftImageView = @ptrCast(@alignCast(context));
const image: *SoftImage = @alignCast(@fieldParentPtr("interface", image_view.interface.image));
const sampler: *SoftSampler = @ptrCast(@alignCast(context2));
const lod = SoftSampler.queryImageLod(image, image_view, sampler, dim, derivatives);
return .{
.x = lod[0],
.y = lod[1],
.z = 0.0,
.w = 0.0,
};
}
+39
View File
@@ -137,6 +137,7 @@ fn sampleAddressOrBorder(coord: i32, extent: u32, mode: vk.SamplerAddressMode) ?
const mirrored = @mod(coord, period);
break :blk if (mirrored < extent_i) mirrored else period - mirrored - 1;
},
.mirror_clamp_to_edge => std.math.clamp(if (coord < 0) -coord - 1 else coord, 0, extent_i - 1),
.clamp_to_border => if (coord < 0 or coord >= extent_i) null else coord,
else => std.math.clamp(coord, 0, extent_i - 1),
};
@@ -223,6 +224,44 @@ fn sampleMipLevel(image: *SoftImage, image_view: *SoftImageView, sampler: *Self,
return range.base_mip_level + level;
}
fn mipmapModeLevel(sampler: *Self, clamped_lod: f32) f32 {
return switch (sampler.interface.mipmap_mode) {
.nearest => @round(clamped_lod),
.linear => clamped_lod,
else => @floor(clamped_lod),
};
}
pub fn queryImageLod(image: *SoftImage, image_view: *SoftImageView, sampler: *Self, dim: spv.SpvDim, derivatives: spv.Runtime.ImageDerivatives) F32x4 {
const range = image_view.interface.subresource_range;
const extent = image.getMipLevelExtent(range.base_mip_level);
const width: f32 = @floatFromInt(extent.width);
const height: f32 = @floatFromInt(extent.height);
const depth: f32 = @floatFromInt(extent.depth);
const dx = switch (dim) {
.@"1D" => @abs(derivatives.dx.x) * width,
.@"2D", .Cube, .Rect => @sqrt(std.math.pow(f32, derivatives.dx.x * width, 2.0) + std.math.pow(f32, derivatives.dx.y * height, 2.0)),
.@"3D" => @sqrt(std.math.pow(f32, derivatives.dx.x * width, 2.0) + std.math.pow(f32, derivatives.dx.y * height, 2.0) + std.math.pow(f32, derivatives.dx.z * depth, 2.0)),
else => @abs(derivatives.dx.x) * width,
};
const dy = switch (dim) {
.@"1D" => @abs(derivatives.dy.x) * width,
.@"2D", .Cube, .Rect => @sqrt(std.math.pow(f32, derivatives.dy.x * width, 2.0) + std.math.pow(f32, derivatives.dy.y * height, 2.0)),
.@"3D" => @sqrt(std.math.pow(f32, derivatives.dy.x * width, 2.0) + std.math.pow(f32, derivatives.dy.y * height, 2.0) + std.math.pow(f32, derivatives.dy.z * depth, 2.0)),
else => @abs(derivatives.dy.x) * width,
};
const rho = @max(dx, dy);
const lod = if (rho > 0.0) @log2(rho) else -std.math.inf(f32);
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 max_level: f32 = @floatFromInt(viewMipCount(image, range) - 1);
const level = std.math.clamp(mipmapModeLevel(sampler, clamped_lod), 0.0, max_level);
return .{ level, lod, 0.0, 0.0 };
}
fn sampleArrayLayer(coord: f32, layer_count: u32) u32 {
const layer_coord: i32 = @intFromFloat(@floor(coord + 0.5));
return @intCast(sampleAddress(layer_coord, layer_count, .clamp_to_edge));