From 8b33e61903698a8e5d051d8f778806753139a417 Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Tue, 9 Dec 2025 00:09:02 +0100 Subject: [PATCH] fixing some tests --- .github/workflows/Test.yml | 2 +- scripts/cts_report_to_html.py | 37 +-- src/soft/SoftDescriptorPool.zig | 18 +- src/soft/SoftDescriptorSet.zig | 32 +++ src/soft/SoftPhysicalDevice.zig | 422 +++++++++++++++++++++++++++++++- src/soft/lib.zig | 2 + src/vulkan/DescriptorPool.zig | 14 +- src/vulkan/DescriptorSet.zig | 14 +- src/vulkan/Image.zig | 38 +++ src/vulkan/lib_vulkan.zig | 25 +- 10 files changed, 542 insertions(+), 62 deletions(-) create mode 100644 src/soft/SoftDescriptorSet.zig diff --git a/.github/workflows/Test.yml b/.github/workflows/Test.yml index b9193e6..b394480 100644 --- a/.github/workflows/Test.yml +++ b/.github/workflows/Test.yml @@ -7,7 +7,7 @@ on: branches: [ "master" ] jobs: - build: + build_and_test: runs-on: ubuntu-latest if: "!contains(github.event.head_commit.message, 'ci skip')" diff --git a/scripts/cts_report_to_html.py b/scripts/cts_report_to_html.py index baf6480..db34501 100644 --- a/scripts/cts_report_to_html.py +++ b/scripts/cts_report_to_html.py @@ -10,6 +10,7 @@ import sys import re import os import math +import shutil import xml.etree.ElementTree as ET import pandas as pd from datetime import datetime @@ -859,47 +860,17 @@ body {{ - - """ - page_output_path = f"cts_report/{base_output}_page_{page_num}.html" if page_num != 1 else f"cts_report/index.html" + page_output_path = f"cts_report/{base_output}_page_{page_num}.html" os.makedirs(os.path.dirname(page_output_path), exist_ok=True) with open(page_output_path, "w", encoding="utf-8") as f: f.write(page_html) + shutil.copy(f"cts_report/{base_output}_page_1.html", "cts_report/index.html") + print(f"[OK] HTML report saved to: {output_path}") print(f"\n--- Test Statistics ---") print(f"Total tests: {stats['total']}") diff --git a/src/soft/SoftDescriptorPool.zig b/src/soft/SoftDescriptorPool.zig index 0b809b3..9cb8143 100644 --- a/src/soft/SoftDescriptorPool.zig +++ b/src/soft/SoftDescriptorPool.zig @@ -3,8 +3,12 @@ const vk = @import("vulkan"); const base = @import("base"); const VkError = base.VkError; +const VulkanAllocator = base.VulkanAllocator; + const Device = base.Device; +const SoftDescriptorSet = @import("SoftDescriptorSet.zig"); + const Self = @This(); pub const Interface = base.DescriptorPool; @@ -17,8 +21,9 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v var interface = try Interface.init(device, allocator, info); interface.vtable = &.{ + .allocateDescriptorSet = allocateDescriptorSet, .destroy = destroy, - .freeDescriptorSets = freeDescriptorSets, + .freeDescriptorSet = freeDescriptorSet, }; self.* = .{ @@ -27,12 +32,19 @@ pub fn create(device: *base.Device, allocator: std.mem.Allocator, info: *const v return self; } +pub fn allocateDescriptorSet(interface: *Interface, layout: *base.DescriptorSetLayout) VkError!*base.DescriptorSet { + const allocator = VulkanAllocator.init(null, .object).allocator(); + const set = try SoftDescriptorSet.create(interface.owner, allocator, layout); + return &set.interface; +} + pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void { const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); allocator.destroy(self); } -pub fn freeDescriptorSets(interface: *Interface, sets: []*base.Dispatchable(base.DescriptorSet)) VkError!void { +pub fn freeDescriptorSet(interface: *Interface, set: *base.DescriptorSet) VkError!void { _ = interface; - _ = sets; + const allocator = VulkanAllocator.init(null, .object).allocator(); + allocator.destroy(set); } diff --git a/src/soft/SoftDescriptorSet.zig b/src/soft/SoftDescriptorSet.zig new file mode 100644 index 0000000..0907251 --- /dev/null +++ b/src/soft/SoftDescriptorSet.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const vk = @import("vulkan"); +const base = @import("base"); + +const VkError = base.VkError; +const Device = base.Device; + +const Self = @This(); +pub const Interface = base.DescriptorSet; + +interface: Interface, + +pub fn create(device: *base.Device, allocator: std.mem.Allocator, layout: *base.DescriptorSetLayout) VkError!*Self { + const self = allocator.create(Self) catch return VkError.OutOfHostMemory; + errdefer allocator.destroy(self); + + var interface = try Interface.init(device, allocator, layout); + + interface.vtable = &.{ + .destroy = destroy, + }; + + self.* = .{ + .interface = interface, + }; + return self; +} + +pub fn destroy(interface: *Interface, allocator: std.mem.Allocator) void { + const self: *Self = @alignCast(@fieldParentPtr("interface", interface)); + allocator.destroy(self); +} diff --git a/src/soft/SoftPhysicalDevice.zig b/src/soft/SoftPhysicalDevice.zig index 6c18f89..b8c9f86 100644 --- a/src/soft/SoftPhysicalDevice.zig +++ b/src/soft/SoftPhysicalDevice.zig @@ -167,6 +167,8 @@ pub fn create(allocator: std.mem.Allocator, instance: *const base.Instance) VkEr .shader_float_64 = .true, .shader_int_64 = .true, .shader_int_16 = .true, + .texture_compression_etc2 = .true, + .texture_compression_bc = .true, }; var queue_family_props = [_]vk.QueueFamilyProperties{ @@ -197,7 +199,7 @@ pub fn create(allocator: std.mem.Allocator, instance: *const base.Instance) VkEr 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} cores", .{ non_sentinel_name, package.processor_count }) catch return VkError.OutOfHostMemory; + break :blk std.fmt.allocPrint(command_allocator, "{s} ({d} threads)", .{ non_sentinel_name, package.processor_count }) catch return VkError.OutOfHostMemory; } break :blk command_allocator.dupe(u8, "Unkown") catch return VkError.OutOfHostMemory; }; @@ -227,8 +229,422 @@ pub fn createDevice(interface: *Interface, allocator: std.mem.Allocator, infos: pub fn getFormatProperties(interface: *Interface, format: vk.Format) VkError!vk.FormatProperties { _ = interface; - _ = format; - return .{}; + var properties: vk.FormatProperties = .{}; + + switch (format) { + // Formats which can be sampled *and* filtered + .r4g4b4a4_unorm_pack16, + .b4g4r4a4_unorm_pack16, + .a4r4g4b4_unorm_pack16, + .a4b4g4r4_unorm_pack16, + .r5g6b5_unorm_pack16, + .b5g6r5_unorm_pack16, + .r5g5b5a1_unorm_pack16, + .b5g5r5a1_unorm_pack16, + .a1r5g5b5_unorm_pack16, + .r8_unorm, + .r8_srgb, + .r8_snorm, + .r8g8_unorm, + .r8g8_srgb, + .r8g8_snorm, + .r8g8b8a8_unorm, + .r8g8b8a8_snorm, + .r8g8b8a8_srgb, + .b8g8r8a8_unorm, + .b8g8r8a8_srgb, + .a8b8g8r8_unorm_pack32, + .a8b8g8r8_snorm_pack32, + .a8b8g8r8_srgb_pack32, + .a2b10g10r10_unorm_pack32, + .a2r10g10b10_unorm_pack32, + .r16_unorm, + .r16_snorm, + .r16_sfloat, + .r16g16_unorm, + .r16g16_snorm, + .r16g16_sfloat, + .r16g16b16a16_unorm, + .r16g16b16a16_snorm, + .r16g16b16a16_sfloat, + .r32_sfloat, + .r32g32_sfloat, + .r32g32b32a32_sfloat, + .b10g11r11_ufloat_pack32, + .e5b9g9r9_ufloat_pack32, + .bc1_rgb_unorm_block, + .bc1_rgb_srgb_block, + .bc1_rgba_unorm_block, + .bc1_rgba_srgb_block, + .bc2_unorm_block, + .bc2_srgb_block, + .bc3_unorm_block, + .bc3_srgb_block, + .bc4_unorm_block, + .bc4_snorm_block, + .bc5_unorm_block, + .bc5_snorm_block, + .bc6h_ufloat_block, + .bc6h_sfloat_block, + .bc7_unorm_block, + .bc7_srgb_block, + .etc2_r8g8b8_unorm_block, + .etc2_r8g8b8_srgb_block, + .etc2_r8g8b8a1_unorm_block, + .etc2_r8g8b8a1_srgb_block, + .etc2_r8g8b8a8_unorm_block, + .etc2_r8g8b8a8_srgb_block, + .eac_r11_unorm_block, + .eac_r11_snorm_block, + .eac_r11g11_unorm_block, + .eac_r11g11_snorm_block, + //.astc_4x_4_unorm_block, + //.astc_5x_4_unorm_block, + //.astc_5x_5_unorm_block, + //.astc_6x_5_unorm_block, + //.astc_6x_6_unorm_block, + //.astc_8x_5_unorm_block, + //.astc_8x_6_unorm_block, + //.astc_8x_8_unorm_block, + //.astc_1_0x_5_unorm_block, + //.astc_1_0x_6_unorm_block, + //.astc_1_0x_8_unorm_block, + //.astc_1_0x_10_unorm_block, + //.astc_1_2x_10_unorm_block, + //.astc_1_2x_12_unorm_block, + //.astc_4x_4_srgb_block, + //.astc_5x_4_srgb_block, + //.astc_5x_5_srgb_block, + //.astc_6x_5_srgb_block, + //.astc_6x_6_srgb_block, + //.astc_8x_5_srgb_block, + //.astc_8x_6_srgb_block, + //.astc_8x_8_srgb_block, + //.astc_1_0x_5_srgb_block, + //.astc_1_0x_6_srgb_block, + //.astc_1_0x_8_srgb_block, + //.astc_1_0x_10_srgb_block, + //.astc_1_2x_10_srgb_block, + //.astc_1_2x_12_srgb_block, + .d16_unorm, + .d32_sfloat, + .d32_sfloat_s8_uint, + => { + properties.optimal_tiling_features.blit_src_bit = true; + properties.optimal_tiling_features.sampled_image_bit = true; + properties.optimal_tiling_features.transfer_dst_bit = true; + properties.optimal_tiling_features.transfer_src_bit = true; + properties.optimal_tiling_features.sampled_image_filter_linear_bit = true; + }, + + // Formats which can be sampled, but don't support filtering + .r8_uint, + .r8_sint, + .r8g8_uint, + .r8g8_sint, + .r8g8b8a8_uint, + .r8g8b8a8_sint, + .a8b8g8r8_uint_pack32, + .a8b8g8r8_sint_pack32, + .a2b10g10r10_uint_pack32, + .a2r10g10b10_uint_pack32, + .r16_uint, + .r16_sint, + .r16g16_uint, + .r16g16_sint, + .r16g16b16a16_uint, + .r16g16b16a16_sint, + .r32_uint, + .r32_sint, + .r32g32_uint, + .r32g32_sint, + .r32g32b32a32_uint, + .r32g32b32a32_sint, + .s8_uint, + => { + properties.optimal_tiling_features.blit_src_bit = true; + properties.optimal_tiling_features.sampled_image_bit = true; + properties.optimal_tiling_features.transfer_dst_bit = true; + properties.optimal_tiling_features.transfer_src_bit = true; + }, + + // YCbCr formats + .g8_b8_r8_3plane_420_unorm, + .g8_b8r8_2plane_420_unorm, + .g10x6_b10x6r10x6_2plane_420_unorm_3pack16, + => { + properties.optimal_tiling_features.sampled_image_bit = true; + properties.optimal_tiling_features.sampled_image_filter_linear_bit = true; + properties.optimal_tiling_features.sampled_image_ycbcr_conversion_linear_filter_bit = true; + properties.optimal_tiling_features.transfer_src_bit = true; + properties.optimal_tiling_features.transfer_dst_bit = true; + properties.optimal_tiling_features.cosited_chroma_samples_bit = true; + }, + else => {}, + } + + switch (format) { + // Vulkan 1.0 mandatory storage image formats supporting atomic operations + .r32_uint, + .r32_sint, + => { + properties.buffer_features.storage_texel_buffer_bit = true; + properties.buffer_features.storage_texel_buffer_atomic_bit = true; + properties.optimal_tiling_features.storage_image_bit = true; + properties.optimal_tiling_features.storage_image_atomic_bit = true; + }, + // vulkan 1.0 mandatory storage image formats + .r8g8b8a8_unorm, + .r8g8b8a8_snorm, + .r8g8b8a8_uint, + .r8g8b8a8_sint, + .r16g16b16a16_uint, + .r16g16b16a16_sint, + .r16g16b16a16_sfloat, + .r32_sfloat, + .r32g32_uint, + .r32g32_sint, + .r32g32_sfloat, + .r32g32b32a32_uint, + .r32g32b32a32_sint, + .r32g32b32a32_sfloat, + .a2b10g10r10_unorm_pack32, + .a2b10g10r10_uint_pack32, + // vulkan 1.0 shaderstorageimageextendedformats + .r16g16_sfloat, + .b10g11r11_ufloat_pack32, + .r16_sfloat, + .r16g16b16a16_unorm, + .r16g16_unorm, + .r8g8_unorm, + .r16_unorm, + .r8_unorm, + .r16g16b16a16_snorm, + .r16g16_snorm, + .r8g8_snorm, + .r16_snorm, + .r8_snorm, + .r16g16_sint, + .r8g8_sint, + .r16_sint, + .r8_sint, + .r16g16_uint, + .r8g8_uint, + .r16_uint, + .r8_uint, + // additional formats not listed under "formats without shader storage format" + .a8b8g8r8_unorm_pack32, + .a8b8g8r8_snorm_pack32, + .a8b8g8r8_uint_pack32, + .a8b8g8r8_sint_pack32, + .b8g8r8a8_unorm, + .b8g8r8a8_srgb, + => { + properties.optimal_tiling_features.storage_image_bit = true; + properties.buffer_features.storage_texel_buffer_bit = true; + }, + + else => {}, + } + + switch (format) { + .r5g6b5_unorm_pack16, + .a1r5g5b5_unorm_pack16, + .r4g4b4a4_unorm_pack16, + .b4g4r4a4_unorm_pack16, + .a4r4g4b4_unorm_pack16, + .a4b4g4r4_unorm_pack16, + .b5g6r5_unorm_pack16, + .r5g5b5a1_unorm_pack16, + .b5g5r5a1_unorm_pack16, + .r8_unorm, + .r8g8_unorm, + .r8g8b8a8_unorm, + .r8g8b8a8_srgb, + .b8g8r8a8_unorm, + .b8g8r8a8_srgb, + .a8b8g8r8_unorm_pack32, + .a8b8g8r8_srgb_pack32, + .a2b10g10r10_unorm_pack32, + .a2r10g10b10_unorm_pack32, + .r16_sfloat, + .r16g16_sfloat, + .r16g16b16a16_sfloat, + .r32_sfloat, + .r32g32_sfloat, + .r32g32b32a32_sfloat, + .b10g11r11_ufloat_pack32, + .r8_uint, + .r8_sint, + .r8g8_uint, + .r8g8_sint, + .r8g8b8a8_uint, + .r8g8b8a8_sint, + .a8b8g8r8_uint_pack32, + .a8b8g8r8_sint_pack32, + .a2b10g10r10_uint_pack32, + .a2r10g10b10_uint_pack32, + .r16_unorm, + .r16_uint, + .r16_sint, + .r16g16_unorm, + .r16g16_uint, + .r16g16_sint, + .r16g16b16a16_unorm, + .r16g16b16a16_uint, + .r16g16b16a16_sint, + .r32_uint, + .r32_sint, + .r32g32_uint, + .r32g32_sint, + .r32g32b32a32_uint, + .r32g32b32a32_sint, + => { + properties.optimal_tiling_features.color_attachment_bit = true; + properties.optimal_tiling_features.blit_dst_bit = true; + }, + .s8_uint, + .d16_unorm, + .d32_sfloat, // note: either vk_format_d32_sfloat or vk_format_x8_d24_unorm_pack32 must be supported + .d32_sfloat_s8_uint, + => { // note: either vk_format_d24_unorm_s8_uint or vk_format_d32_sfloat_s8_uint must be supported + properties.optimal_tiling_features.depth_stencil_attachment_bit = true; + }, + + else => {}, + } + + if (base.Image.formatSupportsColorAttachemendBlend(format)) { + properties.optimal_tiling_features.color_attachment_blend_bit = true; + } + + switch (format) { + .r8_unorm, + .r8_snorm, + .r8_uscaled, + .r8_sscaled, + .r8_uint, + .r8_sint, + .r8g8_unorm, + .r8g8_snorm, + .r8g8_uscaled, + .r8g8_sscaled, + .r8g8_uint, + .r8g8_sint, + .r8g8b8a8_unorm, + .r8g8b8a8_snorm, + .r8g8b8a8_uscaled, + .r8g8b8a8_sscaled, + .r8g8b8a8_uint, + .r8g8b8a8_sint, + .b8g8r8a8_unorm, + .a8b8g8r8_unorm_pack32, + .a8b8g8r8_snorm_pack32, + .a8b8g8r8_uscaled_pack32, + .a8b8g8r8_sscaled_pack32, + .a8b8g8r8_uint_pack32, + .a8b8g8r8_sint_pack32, + .a2r10g10b10_unorm_pack32, + .a2r10g10b10_snorm_pack32, + .a2r10g10b10_uint_pack32, + .a2r10g10b10_sint_pack32, + .a2b10g10r10_unorm_pack32, + .a2b10g10r10_snorm_pack32, + .a2b10g10r10_uint_pack32, + .a2b10g10r10_sint_pack32, + .r16_unorm, + .r16_snorm, + .r16_uscaled, + .r16_sscaled, + .r16_uint, + .r16_sint, + .r16_sfloat, + .r16g16_unorm, + .r16g16_snorm, + .r16g16_uscaled, + .r16g16_sscaled, + .r16g16_uint, + .r16g16_sint, + .r16g16_sfloat, + .r16g16b16a16_unorm, + .r16g16b16a16_snorm, + .r16g16b16a16_uscaled, + .r16g16b16a16_sscaled, + .r16g16b16a16_uint, + .r16g16b16a16_sint, + .r16g16b16a16_sfloat, + .r32_uint, + .r32_sint, + .r32_sfloat, + .r32g32_uint, + .r32g32_sint, + .r32g32_sfloat, + .r32g32b32_uint, + .r32g32b32_sint, + .r32g32b32_sfloat, + .r32g32b32a32_uint, + .r32g32b32a32_sint, + .r32g32b32a32_sfloat, + => properties.buffer_features.vertex_buffer_bit = true, + else => {}, + } + + switch (format) { + // Vulkan 1.1 mandatory + .r8_unorm, + .r8_snorm, + .r8_uint, + .r8_sint, + .r8g8_unorm, + .r8g8_snorm, + .r8g8_uint, + .r8g8_sint, + .r8g8b8a8_unorm, + .r8g8b8a8_snorm, + .r8g8b8a8_uint, + .r8g8b8a8_sint, + .b8g8r8a8_unorm, + .a8b8g8r8_unorm_pack32, + .a8b8g8r8_snorm_pack32, + .a8b8g8r8_uint_pack32, + .a8b8g8r8_sint_pack32, + .a2b10g10r10_unorm_pack32, + .a2b10g10r10_uint_pack32, + .r16_uint, + .r16_sint, + .r16_sfloat, + .r16g16_uint, + .r16g16_sint, + .r16g16_sfloat, + .r16g16b16a16_uint, + .r16g16b16a16_sint, + .r16g16b16a16_sfloat, + .r32_uint, + .r32_sint, + .r32_sfloat, + .r32g32_uint, + .r32g32_sint, + .r32g32_sfloat, + .r32g32b32a32_uint, + .r32g32b32a32_sint, + .r32g32b32a32_sfloat, + .b10g11r11_ufloat_pack32, + // optional + .a2r10g10b10_unorm_pack32, + .a2r10g10b10_uint_pack32, + => properties.buffer_features.uniform_texel_buffer_bit = true, + else => {}, + } + + if (properties.optimal_tiling_features.toInt() != 0) { + // "Formats that are required to support VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT must also support + // VK_FORMAT_FEATURE_TRANSFER_SRC_BIT and VK_FORMAT_FEATURE_TRANSFER_DST_BIT." + + properties.linear_tiling_features.transfer_src_bit = true; + properties.linear_tiling_features.transfer_dst_bit = true; + } + + return properties; } pub fn getImageFormatProperties( diff --git a/src/soft/lib.zig b/src/soft/lib.zig index e5734fb..135a4c1 100644 --- a/src/soft/lib.zig +++ b/src/soft/lib.zig @@ -15,6 +15,7 @@ pub const SoftBufferView = @import("SoftBufferView.zig"); pub const SoftCommandBuffer = @import("SoftCommandBuffer.zig"); pub const SoftCommandPool = @import("SoftCommandPool.zig"); pub const SoftDescriptorPool = @import("SoftDescriptorPool.zig"); +pub const SoftDescriptorSet = @import("SoftDescriptorSet.zig"); pub const SoftDescriptorSetLayout = @import("SoftDescriptorSetLayout.zig"); pub const SoftDeviceMemory = @import("SoftDeviceMemory.zig"); pub const SoftEvent = @import("SoftEvent.zig"); @@ -68,6 +69,7 @@ test { std.testing.refAllDecls(SoftCommandBuffer); std.testing.refAllDecls(SoftCommandPool); std.testing.refAllDecls(SoftDescriptorPool); + std.testing.refAllDecls(SoftDescriptorSet); std.testing.refAllDecls(SoftDescriptorSetLayout); std.testing.refAllDecls(SoftDevice); std.testing.refAllDecls(SoftDeviceMemory); diff --git a/src/vulkan/DescriptorPool.zig b/src/vulkan/DescriptorPool.zig index 59d315a..dacd67b 100644 --- a/src/vulkan/DescriptorPool.zig +++ b/src/vulkan/DescriptorPool.zig @@ -2,11 +2,12 @@ const std = @import("std"); const vk = @import("vulkan"); const VkError = @import("error_set.zig").VkError; -const Dispatchable = @import("Dispatchable.zig").Dispatchable; +const NonDispatchable = @import("NonDispatchable.zig").NonDispatchable; const Device = @import("Device.zig"); const DescriptorSet = @import("DescriptorSet.zig"); +const DescriptorSetLayout = @import("DescriptorSetLayout.zig"); const Self = @This(); pub const ObjectType: vk.ObjectType = .descriptor_pool; @@ -17,8 +18,9 @@ flags: vk.DescriptorPoolCreateFlags, vtable: *const VTable, pub const VTable = struct { + allocateDescriptorSet: *const fn (*Self, *DescriptorSetLayout) VkError!*DescriptorSet, destroy: *const fn (*Self, std.mem.Allocator) void, - freeDescriptorSets: *const fn (*Self, []*Dispatchable(DescriptorSet)) VkError!void, + freeDescriptorSet: *const fn (*Self, *DescriptorSet) VkError!void, }; pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.DescriptorPoolCreateInfo) VkError!Self { @@ -30,10 +32,14 @@ pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.Descr }; } +pub inline fn allocateDescriptorSet(self: *Self, layout: *DescriptorSetLayout) VkError!*DescriptorSet { + return self.vtable.allocateDescriptorSet(self, layout); +} + pub inline fn destroy(self: *Self, allocator: std.mem.Allocator) void { self.vtable.destroy(self, allocator); } -pub inline fn freeDescriptorSets(self: *Self, sets: []*Dispatchable(DescriptorSet)) VkError!void { - try self.vtable.freeDescriptorSets(self, sets); +pub inline fn freeDescriptorSet(self: *Self, set: *DescriptorSet) VkError!void { + try self.vtable.freeDescriptorSet(self, set); } diff --git a/src/vulkan/DescriptorSet.zig b/src/vulkan/DescriptorSet.zig index dc1b6fb..7afc508 100644 --- a/src/vulkan/DescriptorSet.zig +++ b/src/vulkan/DescriptorSet.zig @@ -13,7 +13,7 @@ const Self = @This(); pub const ObjectType: vk.ObjectType = .descriptor_set; owner: *Device, -layouts: []*const DescriptorSetLayout, +layout: *DescriptorSetLayout, vtable: *const VTable, @@ -21,17 +21,11 @@ pub const VTable = struct { destroy: *const fn (*Self, std.mem.Allocator) void, }; -pub fn init(device: *Device, allocator: std.mem.Allocator, info: *const vk.DescriptorSetAllocateInfo) VkError!Self { - var layouts = allocator.alloc(*DescriptorSetLayout, info.descriptor_set_count) catch return VkError.OutOfHostMemory; - errdefer allocator.free(layouts); - - for (info.p_set_layouts, 0..info.descriptor_set_count) |p_set_layout, i| { - layouts[i] = try NonDispatchable(DescriptorSetLayout).fromHandleObject(p_set_layout); - } - +pub fn init(device: *Device, allocator: std.mem.Allocator, layout: *DescriptorSetLayout) VkError!Self { + _ = allocator; return .{ .owner = device, - .layouts = layouts, + .layout = layout, .vtable = undefined, }; } diff --git a/src/vulkan/Image.zig b/src/vulkan/Image.zig index 90a3a53..d913de0 100644 --- a/src/vulkan/Image.zig +++ b/src/vulkan/Image.zig @@ -87,3 +87,41 @@ pub inline fn getTotalSize(self: *Self) usize { const pixel_size = self.getPixelSize(); return self.extent.width * self.extent.height * self.extent.depth * pixel_size; } + +pub fn formatSupportsColorAttachemendBlend(format: vk.Format) bool { + return switch (format) { + // Vulkan 1.1 mandatory + .r5g6b5_unorm_pack16, + .a1r5g5b5_unorm_pack16, + .r8_unorm, + .r8g8_unorm, + .r8g8b8a8_unorm, + .r8g8b8a8_srgb, + .b8g8r8a8_unorm, + .b8g8r8a8_srgb, + .a8b8g8r8_unorm_pack32, + .a8b8g8r8_srgb_pack32, + .a2b10g10r10_unorm_pack32, + .r16_sfloat, + .r16g16_sfloat, + .r16g16b16a16_sfloat, + // optional + .r4g4b4a4_unorm_pack16, + .b4g4r4a4_unorm_pack16, + .b5g6r5_unorm_pack16, + .r5g5b5a1_unorm_pack16, + .b5g5r5a1_unorm_pack16, + .a2r10g10b10_unorm_pack32, + .r16_unorm, + .r16g16_unorm, + .r16g16b16a16_unorm, + .r32_sfloat, + .r32g32_sfloat, + .r32g32b32a32_sfloat, + .b10g11r11_ufloat_pack32, + .a4r4g4b4_unorm_pack16, + .a4b4g4r4_unorm_pack16, + => true, + else => false, + }; +} diff --git a/src/vulkan/lib_vulkan.zig b/src/vulkan/lib_vulkan.zig index eb41992..adb2449 100644 --- a/src/vulkan/lib_vulkan.zig +++ b/src/vulkan/lib_vulkan.zig @@ -526,20 +526,24 @@ pub export fn strollAllocateCommandBuffers(p_device: vk.Device, info: *const vk. return .success; } -pub export fn strollAllocateDescriptorSets(p_device: vk.Device, info: *const vk.DescriptorSetAllocateInfo, p_set: *vk.DescriptorSet) callconv(vk.vulkan_call_conv) vk.Result { +pub export fn strollAllocateDescriptorSets(p_device: vk.Device, info: *const vk.DescriptorSetAllocateInfo, p_sets: [*]vk.DescriptorSet) callconv(vk.vulkan_call_conv) vk.Result { entryPointBeginLogTrace(.vkAllocateCommandBuffers); defer entryPointEndLogTrace(); + Dispatchable(Device).checkHandleValidity(p_device) catch |err| return toVkResult(err); + if (info.s_type != .descriptor_set_allocate_info) { return .error_validation_failed; } - const device = Dispatchable(Device).fromHandleObject(p_device) catch |err| return toVkResult(err); + const allocator = VulkanAllocator.init(null, .command).allocator(); - notImplementedWarning(); - - _ = device; - _ = p_set; + const pool = NonDispatchable(DescriptorPool).fromHandleObject(info.descriptor_pool) catch |err| return toVkResult(err); + for (0..info.descriptor_set_count) |i| { + const layout = NonDispatchable(DescriptorSetLayout).fromHandleObject(info.p_set_layouts[i]) catch |err| return toVkResult(err); + const set = pool.allocateDescriptorSet(layout) catch |err| return toVkResult(err); + p_sets[i] = (NonDispatchable(DescriptorSet).wrap(allocator, set) catch |err| return toVkResult(err)).toVkHandle(vk.DescriptorSet); + } return .success; } @@ -1127,11 +1131,16 @@ pub export fn strollFreeDescriptorSets(p_device: vk.Device, p_pool: vk.CommandPo entryPointBeginLogTrace(.vkFreeDescriptorSets); defer entryPointEndLogTrace(); + const allocator = VulkanAllocator.init(null, .command).allocator(); + Dispatchable(Device).checkHandleValidity(p_device) catch |err| return errorLogger(err); const pool = NonDispatchable(DescriptorPool).fromHandleObject(p_pool) catch |err| return errorLogger(err); - const sets: [*]*Dispatchable(DescriptorSet) = @ptrCast(@constCast(p_sets)); - pool.freeDescriptorSets(sets[0..count]) catch |err| return errorLogger(err); + for (p_sets[0..], 0..count) |p_set, _| { + const non_dispatchable_set = NonDispatchable(DescriptorSet).fromHandle(p_set) catch |err| return errorLogger(err); + pool.freeDescriptorSet(non_dispatchable_set.object) catch |err| return errorLogger(err); + non_dispatchable_set.destroy(allocator); + } } pub export fn strollFreeMemory(p_device: vk.Device, p_memory: vk.DeviceMemory, callbacks: ?*const vk.AllocationCallbacks) callconv(vk.vulkan_call_conv) void {