diff options
| author | Lucas Fryzek <lucas.fryzek@fryzekconcepts.com> | 2025-11-24 19:39:30 -0500 |
|---|---|---|
| committer | Lucas Fryzek <lucas.fryzek@fryzekconcepts.com> | 2025-11-24 19:39:30 -0500 |
| commit | b5f3587df4048d2ba807721ff2faea8c8a43a93f (patch) | |
| tree | 6913f730a41822b98fecd5e82b7cae46164fd9c0 /src | |
| parent | 41c700fdbf1d79dfb571105ee93bfa46da6c8428 (diff) | |
WIPfrygon
Diffstat (limited to 'src')
45 files changed, 2291 insertions, 2 deletions
diff --git a/src/compiler/meson.build b/src/compiler/meson.build index 92e72a44f9a..3404bc0c445 100644 --- a/src/compiler/meson.build +++ b/src/compiler/meson.build @@ -72,6 +72,6 @@ if with_gallium endif subdir('isaspec') -if with_nouveau_vk +if with_nouveau_vk or with_frygon_vk subdir('rust') endif diff --git a/src/frygon/.rustfmt.toml b/src/frygon/.rustfmt.toml new file mode 100644 index 00000000000..df99c69198f --- /dev/null +++ b/src/frygon/.rustfmt.toml @@ -0,0 +1 @@ +max_width = 80 diff --git a/src/frygon/compiler/fgcc.h b/src/frygon/compiler/fgcc.h new file mode 100644 index 00000000000..a611818d19e --- /dev/null +++ b/src/frygon/compiler/fgcc.h @@ -0,0 +1,33 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#ifndef FGCC_H +#define FGCC_H 1 + +#include "compiler/shader_enums.h" +#include "nir_defines.h" + +#include <assert.h> +#include <stdbool.h> +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct fgcc_compiler; +struct fg_device_info; + +struct fgcc_compiler *fgcc_compiler_create(const struct fg_device_info *dev); + +const struct nir_shader_compiler_options * +fgcc_nir_options(const struct fgcc_compiler *fgcc); + +void fgcc_preprocess_nir(nir_shader *nir, const struct fgcc_compiler *fgcc); + +#ifdef __cplusplus +} +#endif + +#endif /* FGCC_H */ diff --git a/src/frygon/compiler/fgcc/api.rs b/src/frygon/compiler/fgcc/api.rs new file mode 100644 index 00000000000..ff09c213305 --- /dev/null +++ b/src/frygon/compiler/fgcc/api.rs @@ -0,0 +1,108 @@ +// Copyright © 2025 Lucas Francisco Fryzek +// SPDX-License-Identifier: MIT + +use compiler::bindings::*; +use fgcc_bindings::*; + +fn nir_options(dev: &fg_device_info) -> nir_shader_compiler_options { + let mut op: nir_shader_compiler_options = Default::default(); + + op.lower_fdiv = true; + op.fuse_ffma16 = true; + op.fuse_ffma32 = true; + op.fuse_ffma64 = true; + op.lower_flrp16 = true; + op.lower_flrp32 = true; + op.lower_flrp64 = true; + op.lower_fsqrt = true; // TODO + op.lower_bitfield_extract = false; + op.lower_bitfield_extract8 = true; + op.lower_bitfield_extract16 = true; + op.lower_bitfield_insert = true; + op.lower_pack_half_2x16 = true; + op.lower_pack_unorm_2x16 = true; + op.lower_pack_snorm_2x16 = true; + op.lower_pack_unorm_4x8 = true; + op.lower_pack_snorm_4x8 = true; + op.lower_unpack_half_2x16 = true; + op.lower_unpack_unorm_2x16 = true; + op.lower_unpack_snorm_2x16 = true; + op.lower_unpack_unorm_4x8 = true; + op.lower_unpack_snorm_4x8 = true; + op.lower_insert_byte = true; + op.lower_insert_word = true; + op.lower_cs_local_index_to_id = true; + op.lower_device_index_to_zero = true; + op.lower_isign = true; + op.lower_uadd_sat = true; // TODO + op.lower_usub_sat = true; // TODO + op.lower_iadd_sat = true; // TODO + op.lower_doubles_options = nir_lower_drcp + | nir_lower_dsqrt + | nir_lower_drsq + | nir_lower_dtrunc + | nir_lower_dfloor + | nir_lower_dceil + | nir_lower_dfract + | nir_lower_dround_even + | nir_lower_dsat + | nir_lower_dminmax; + op.lower_int64_options = !(nir_lower_icmp64 + | nir_lower_iadd64 + | nir_lower_ineg64 + | nir_lower_shift64 + | nir_lower_imul_2x32_64 + | nir_lower_vote_ieq64 + | nir_lower_conv64) + | nir_lower_vote_ieq64 + | nir_lower_shift64; + op.lower_ldexp = true; + op.lower_fmod = true; + op.lower_ffract = true; + op.lower_fpow = true; + op.lower_scmp = true; + op.lower_uadd_carry = true; + op.lower_usub_borrow = true; + /* + op.has_iadd3 = dev.sm >= 70; + op.has_imad32 = dev.sm >= 70; + op.has_sdot_4x8 = dev.sm >= 70; + op.has_udot_4x8 = dev.sm >= 70; + op.has_sudot_4x8 = dev.sm >= 70; + */ + // We set .ftz on f32 by default so we can support fmulz whenever the client + // doesn't explicitly request denorms. + op.has_fmulz_no_denorms = true; + op.has_find_msb_rev = true; + op.has_pack_half_2x16_rtz = true; + //op.has_bfm = dev.sm >= 70; + op.discard_is_demote = true; + + op.max_unroll_iterations = 32; + op.scalarize_ddx = true; + + op +} + +#[no_mangle] +pub extern "C" fn fgcc_nir_options( + fgcc: *const fgcc_compiler, +) -> *const nir_shader_compiler_options { + assert!(!fgcc.is_null()); + let fgcc = unsafe { &*fgcc }; + &fgcc.nir_options +} + +#[no_mangle] +pub extern "C" fn fgcc_compiler_create( + dev: *const fg_device_info, +) -> *mut fgcc_compiler { + assert!(!dev.is_null()); + let dev = unsafe { &*dev }; + + let nak = Box::new(fgcc_compiler { + nir_options: nir_options(dev), + }); + + Box::into_raw(nak) +} diff --git a/src/frygon/compiler/fgcc/lib.rs b/src/frygon/compiler/fgcc/lib.rs new file mode 100644 index 00000000000..413edd9af39 --- /dev/null +++ b/src/frygon/compiler/fgcc/lib.rs @@ -0,0 +1,4 @@ +// Copyright © 2025 Lucas Francisco Fryzek +// SPDX-License-Identifier: MIT + +mod api; diff --git a/src/frygon/compiler/fgcc_bindings.h b/src/frygon/compiler/fgcc_bindings.h new file mode 100644 index 00000000000..07b65794584 --- /dev/null +++ b/src/frygon/compiler/fgcc_bindings.h @@ -0,0 +1,6 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ + +#include "fgcc_private.h" diff --git a/src/frygon/compiler/fgcc_nir.c b/src/frygon/compiler/fgcc_nir.c new file mode 100644 index 00000000000..11a56bfa54a --- /dev/null +++ b/src/frygon/compiler/fgcc_nir.c @@ -0,0 +1,12 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ + +#include "fgcc_private.h" +#include "nir_builder.h" + +void +fgcc_preprocess_nir(nir_shader *nir, const struct fgcc_compiler *fgcc) +{ +} diff --git a/src/frygon/compiler/fgcc_private.h b/src/frygon/compiler/fgcc_private.h new file mode 100644 index 00000000000..82bdaa12343 --- /dev/null +++ b/src/frygon/compiler/fgcc_private.h @@ -0,0 +1,24 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#ifndef FGCC_PRIAVTE_H +#define FGCC_PRIVATE_H 1 + +#include "fgcc.h" +#include "nir.h" +#include "fg_device_info.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct fgcc_compiler { + struct nir_shader_compiler_options nir_options; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/frygon/compiler/meson.build b/src/frygon/compiler/meson.build new file mode 100644 index 00000000000..378d7c41e8f --- /dev/null +++ b/src/frygon/compiler/meson.build @@ -0,0 +1,107 @@ +# Copyright © 2025 Lucas Francisco Fryzek +# SPDX-License-Identifier: MIT + +fgcc_rust_args = [ + rust_2024_lint_args, + '-Aclippy::identity_op', + '-Aclippy::len_zero', + '-Aclippy::manual_range_contains', + # normally this is a good one, but we use it where the "better" code is worse + '-Aclippy::needless_range_loop', + '-Aclippy::redundant_field_names', + '-Aclippy::upper_case_acronyms', + '-Aclippy::vec_box', + '-Aclippy::write_with_newline', + # warns about public function might dereference a raw pointer, but nothing is + # actually public here + '-Aclippy::not_unsafe_ptr_arg_deref', + '-Anon_snake_case', +] + +libfgcc_c_files = files( + 'fgcc.h', + 'fgcc_nir.c', +) + +libfgcc_deps = [ + idep_mesautil, + idep_nir_headers, + idep_fg_headers, +] + +_fgcc_bindings_rs = rust.bindgen( + input : ['fgcc_bindings.h'], + output : 'fgcc_bindings.rs', + c_args : [ + pre_args, + ], + args : [ + bindgen_output_args, + compiler_rs_bindgen_blocklist, + '--raw-line', 'use compiler::bindings::*;', + #'--allowlist-type', 'drm.*', + '--allowlist-type', 'fgcc_.*', + #'--allowlist-type', 'nouveau_ws_.*', + #'--allowlist-var', 'DRM_.*', + '--allowlist-var', 'FGCC_.*', + #'--allowlist-var', 'NVIDIA_VENDOR_ID', + #'--allowlist-function', 'drm.*', + '--allowlist-function', 'fgcc_.*', + #'--allowlist-function', 'nouveau_ws_.*', + # provided through compiler::bindings::* + '--blocklist-type', 'glsl_.*', + '--no-prepend-enum-name', + '--with-derive-default', + ], + dependencies : [ + dep_libdrm, + libfgcc_deps, + ], +) + +_libfgcc_bindings_rs = static_library( + 'fgcc_bindings', + _fgcc_bindings_rs, + gnu_symbol_visibility : 'hidden', + dependencies : [ + idep_compiler_rs, + ], + rust_abi : 'rust', +) + +_libfgcc_rs = static_library( + 'fgcc_rs', + files('fgcc/lib.rs'), + gnu_symbol_visibility : 'hidden', + rust_abi : 'c', + rust_args : [ + fgcc_rust_args, + # Otherwise, rustc trips up on -pthread + '-Clink-arg=-Wno-unused-command-line-argument', + ], + dependencies : [ + #dep_paste, + #dep_rustc_hash, + #idep_bitview_rs, + idep_compiler_rs, + ], + link_with : [ + _libfgcc_bindings_rs, + #_libnak_ir_proc_rs, + ], +) + +_libfgcc = static_library( + 'fgcc', + [libfgcc_c_files], + include_directories: [inc_include, inc_src, inc_gallium], + dependencies : libfgcc_deps, + link_with : [_libfgcc_rs], + c_args : [no_override_init_args], + gnu_symbol_visibility : 'hidden', +) + +idep_fgcc = declare_dependency( + include_directories : include_directories('.'), + link_with : _libfgcc, +) diff --git a/src/frygon/headers/fg_device_info.h b/src/frygon/headers/fg_device_info.h new file mode 100644 index 00000000000..20a243f6c84 --- /dev/null +++ b/src/frygon/headers/fg_device_info.h @@ -0,0 +1,14 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#ifndef FG_DEVICE_INFO_H +#define FG_DEVICE_INFO_H 1 + +struct fg_device_info { + uint16_t device_id; + + char device_name[64]; +}; + +#endif diff --git a/src/frygon/headers/meson.build b/src/frygon/headers/meson.build new file mode 100644 index 00000000000..664363bed08 --- /dev/null +++ b/src/frygon/headers/meson.build @@ -0,0 +1,6 @@ +# Copyright © 2025 Lucas Francisco Fryzek +# SPDX-License-Identifier: MIT + +idep_fg_headers = declare_dependency( + include_directories : include_directories('.'), +) diff --git a/src/frygon/meson.build b/src/frygon/meson.build new file mode 100644 index 00000000000..fdfbf9e94d4 --- /dev/null +++ b/src/frygon/meson.build @@ -0,0 +1,18 @@ +# Copyright © 2025 Lucas Francisco Fryzek +# SPDX-License-Identifier: MIT + +#subdir('drm') +subdir('headers') +#subdir('winsys') +#subdir('rust') +#subdir('nil') +subdir('compiler') + +# Probably not needed until we have real HW +#if with_tools.contains('drm-shim') +# subdir('drm-shim') +#endif + +# We are always building vk +#subdir('mme') +subdir('vulkan') diff --git a/src/frygon/vulkan/fgvk_buffer.c b/src/frygon/vulkan/fgvk_buffer.c new file mode 100644 index 00000000000..f5b8f70758b --- /dev/null +++ b/src/frygon/vulkan/fgvk_buffer.c @@ -0,0 +1,89 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#include "fgvk_buffer.h" + +#include "fgvk_device.h" +#include "fgvk_device_memory.h" + +VKAPI_ATTR VkResult VKAPI_CALL +fgvk_CreateBuffer(VkDevice device, + const VkBufferCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkBuffer *pBuffer) +{ + VK_FROM_HANDLE(fgvk_device, dev, device); + struct fgvk_buffer *buffer; + + buffer = vk_buffer_create(&dev->vk, pCreateInfo, pAllocator, + sizeof(*buffer)); + + if (!buffer) + return vk_error(dev, VK_ERROR_OUT_OF_HOST_MEMORY); + + *pBuffer = fgvk_buffer_to_handle(buffer); + + return VK_SUCCESS; +} + +VKAPI_ATTR void VKAPI_CALL +fgvk_DestroyBuffer(VkDevice device, + VkBuffer _buffer, + const VkAllocationCallbacks *pAllocator) +{ + VK_FROM_HANDLE(fgvk_device, dev, device); + VK_FROM_HANDLE(fgvk_buffer, buffer, _buffer); + + if (!buffer) + return; + + vk_buffer_destroy(&dev->vk, pAllocator, &buffer->vk); +} + +VKAPI_ATTR void VKAPI_CALL +fgvk_GetDeviceBufferMemoryRequirements( + VkDevice device, + const VkDeviceBufferMemoryRequirements *pInfo, + VkMemoryRequirements2 *pMemoryRequirements) +{ + pMemoryRequirements->memoryRequirements = (VkMemoryRequirements) { + .size = align64(pInfo->pCreateInfo->size, 8), + .alignment = 8, + .memoryTypeBits = 1, + }; +} + +static VkResult +fgvk_bind_buffer_memory(struct fgvk_device *dev, + const VkBindBufferMemoryInfo *info) +{ + VK_FROM_HANDLE(fgvk_device_memory, mem, info->memory); + VK_FROM_HANDLE(fgvk_buffer, buffer, info->buffer); + VkResult result = VK_SUCCESS; + + return result; +} + +VKAPI_ATTR VkResult VKAPI_CALL +fgvk_BindBufferMemory2(VkDevice device, + uint32_t bindInfoCount, + const VkBindBufferMemoryInfo *pBindInfos) +{ + VK_FROM_HANDLE(fgvk_device, dev, device); + VkResult first_error_or_success = VK_SUCCESS; + + for (uint32_t i = 0; i < bindInfoCount; ++i) { + VkResult result = fgvk_bind_buffer_memory(dev, &pBindInfos[i]); + + const VkBindMemoryStatusKHR *status = + vk_find_struct_const(pBindInfos[i].pNext, BIND_MEMORY_STATUS_KHR); + if (status != NULL && status->pResult != NULL) + *status->pResult = result; + + if (first_error_or_success == VK_SUCCESS) + first_error_or_success = result; + } + + return first_error_or_success; +} diff --git a/src/frygon/vulkan/fgvk_buffer.h b/src/frygon/vulkan/fgvk_buffer.h new file mode 100644 index 00000000000..db287b587ea --- /dev/null +++ b/src/frygon/vulkan/fgvk_buffer.h @@ -0,0 +1,19 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#ifndef FGVK_BUFFER_H +#define FGVK_BUFFER_H 1 + +#include "fgvk_private.h" + +#include "vk_buffer.h" + +struct fgvk_buffer { + struct vk_buffer vk; +}; + +VK_DEFINE_NONDISP_HANDLE_CASTS(fgvk_buffer, vk.base, VkBuffer, + VK_OBJECT_TYPE_BUFFER) + +#endif diff --git a/src/frygon/vulkan/fgvk_cmd_buffer.c b/src/frygon/vulkan/fgvk_cmd_buffer.c new file mode 100644 index 00000000000..181a8f8e819 --- /dev/null +++ b/src/frygon/vulkan/fgvk_cmd_buffer.c @@ -0,0 +1,93 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#include "fgvk_cmd_buffer.h" + +#include "fgvk_cmd_pool.h" + +static VkResult +fgvk_create_cmd_buffer(struct vk_command_pool *vk_pool, + VkCommandBufferLevel level, + struct vk_command_buffer **cmd_buffer_out) +{ + struct fgvk_cmd_pool *pool = container_of(vk_pool, struct fgvk_cmd_pool, vk); + struct fgvk_device *dev = fgvk_cmd_pool_device(pool); + struct fgvk_cmd_buffer *cmd; + VkResult result; + + cmd = vk_zalloc(&pool->vk.alloc, sizeof(*cmd), 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + + if (cmd == NULL) + return vk_error(dev, VK_ERROR_OUT_OF_HOST_MEMORY); + + result = vk_command_buffer_init(&pool->vk, &cmd->vk, + &fgvk_cmd_buffer_ops, level); + if (result != VK_SUCCESS) { + vk_free(&pool->vk.alloc, cmd); + return result; + } + + cmd->vk.dynamic_graphics_state.vi = &cmd->state.gfx._dynamic_vi; + cmd->vk.dynamic_graphics_state.ms.sample_locations = &cmd->state.gfx._dynamic_sl; + + *cmd_buffer_out = &cmd->vk; + + return VK_SUCCESS; +} + +static void +fgvk_reset_cmd_buffer(struct vk_command_buffer *vk_cmd_buffer, + UNUSED VkCommandBufferResetFlags flags) +{ + struct fgvk_cmd_buffer *cmd = + container_of(vk_cmd_buffer, struct fgvk_cmd_buffer, vk); + + vk_command_buffer_reset(&cmd->vk); +} + +static void +fgvk_destroy_cmd_buffer(struct vk_command_buffer *vk_cmd_buffer) +{ + struct fgvk_cmd_buffer *cmd = + container_of(vk_cmd_buffer, struct fgvk_cmd_buffer, vk); + struct fgvk_cmd_pool *pool = fgvk_cmd_buffer_pool(cmd); + + vk_command_buffer_finish(&cmd->vk); + vk_free(&pool->vk.alloc, cmd); +} + +const struct vk_command_buffer_ops fgvk_cmd_buffer_ops = { + .create = fgvk_create_cmd_buffer, + .reset = fgvk_reset_cmd_buffer, + .destroy = fgvk_destroy_cmd_buffer, +}; + +void +fgvk_cmd_bind_shaders(struct vk_command_buffer *vk_cmd, + uint32_t stage_count, + const mesa_shader_stage *stages, + struct vk_shader ** const shaders) +{ + //UNREACHABLE("TODO"); +} + +VKAPI_ATTR VkResult VKAPI_CALL +fgvk_BeginCommandBuffer(VkCommandBuffer commandBuffer, + const VkCommandBufferBeginInfo *pBeginInfo) +{ + return VK_SUCCESS; +} + +VKAPI_ATTR VkResult VKAPI_CALL +fgvk_EndCommandBuffer(VkCommandBuffer commandBuffer) +{ + return VK_SUCCESS; +} + +VKAPI_ATTR void VKAPI_CALL +fgvk_CmdPipelineBarrier2(VkCommandBuffer commandBuffer, + const VkDependencyInfo *pDependencyInfo) +{ +} diff --git a/src/frygon/vulkan/fgvk_cmd_buffer.h b/src/frygon/vulkan/fgvk_cmd_buffer.h new file mode 100644 index 00000000000..151ed631166 --- /dev/null +++ b/src/frygon/vulkan/fgvk_cmd_buffer.h @@ -0,0 +1,42 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#ifndef FGVK_CMD_BUFFER_H +#define FGVK_CMD_BUFFER_H 1 + +#include "fgvk_private.h" + +#include "vk_command_buffer.h" +#include "vk_shader.h" + +struct fgvk_graphics_state { + struct vk_vertex_input_state _dynamic_vi; + struct vk_sample_locations_state _dynamic_sl; +}; + +struct fgvk_cmd_buffer { + struct vk_command_buffer vk; + + struct fgvk_cmd_state { + struct fgvk_graphics_state gfx; + } state; +}; + +VK_DEFINE_HANDLE_CASTS(fgvk_cmd_buffer, vk.base, VkCommandBuffer, + VK_OBJECT_TYPE_COMMAND_BUFFER) + +static inline struct fgvk_cmd_pool * +fgvk_cmd_buffer_pool(struct fgvk_cmd_buffer *cmd) +{ + return (struct fgvk_cmd_pool *)cmd->vk.pool; +} + +extern const struct vk_command_buffer_ops fgvk_cmd_buffer_ops; + +void fgvk_cmd_bind_shaders(struct vk_command_buffer *vk_cmd, + uint32_t stage_count, + const mesa_shader_stage *stages, + struct vk_shader ** const shaders); + +#endif diff --git a/src/frygon/vulkan/fgvk_cmd_clear.c b/src/frygon/vulkan/fgvk_cmd_clear.c new file mode 100644 index 00000000000..67702989769 --- /dev/null +++ b/src/frygon/vulkan/fgvk_cmd_clear.c @@ -0,0 +1,16 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#include "fgvk_cmd_buffer.h" + +VKAPI_ATTR void VKAPI_CALL +fgvk_CmdClearColorImage(VkCommandBuffer commandBuffer, + VkImage _image, + VkImageLayout imageLayout, + const VkClearColorValue *pColor, + uint32_t rangeCount, + const VkImageSubresourceRange *pRanges) +{ + // TODO actually get hardware to clear the image +} diff --git a/src/frygon/vulkan/fgvk_cmd_copy.c b/src/frygon/vulkan/fgvk_cmd_copy.c new file mode 100644 index 00000000000..5fe668264e8 --- /dev/null +++ b/src/frygon/vulkan/fgvk_cmd_copy.c @@ -0,0 +1,11 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#include <fgvk_cmd_buffer.h> + +VKAPI_ATTR void VKAPI_CALL +fgvk_CmdCopyImage2(VkCommandBuffer commandBuffer, + const VkCopyImageInfo2 *pCopyImageInfo) +{ +} diff --git a/src/frygon/vulkan/fgvk_cmd_draw.c b/src/frygon/vulkan/fgvk_cmd_draw.c new file mode 100644 index 00000000000..15f6b29c05c --- /dev/null +++ b/src/frygon/vulkan/fgvk_cmd_draw.c @@ -0,0 +1,37 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#include "fgvk_cmd_buffer.h" + +VKAPI_ATTR void VKAPI_CALL +fgvk_CmdBeginRendering(VkCommandBuffer commandBuffer, + const VkRenderingInfo *pRenderingInfo) +{ +} + +VKAPI_ATTR void VKAPI_CALL +fgvk_CmdEndRendering2KHR(VkCommandBuffer commandBuffer, + const VkRenderingEndInfoKHR *pRenderingEndInfo) +{ +} + +VKAPI_ATTR void VKAPI_CALL +fgvk_CmdBindVertexBuffers2(VkCommandBuffer commandBuffer, + uint32_t firstBinding, + uint32_t bindingCount, + const VkBuffer *pBuffers, + const VkDeviceSize *pOffsets, + const VkDeviceSize *pSizes, + const VkDeviceSize *pStrides) +{ +} + +VKAPI_ATTR void VKAPI_CALL +fgvk_CmdDraw(VkCommandBuffer commandBuffer, + uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance) +{ +} diff --git a/src/frygon/vulkan/fgvk_cmd_pool.c b/src/frygon/vulkan/fgvk_cmd_pool.c new file mode 100644 index 00000000000..37ffebc1de4 --- /dev/null +++ b/src/frygon/vulkan/fgvk_cmd_pool.c @@ -0,0 +1,5 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#include "fgvk_cmd_pool.h" diff --git a/src/frygon/vulkan/fgvk_cmd_pool.h b/src/frygon/vulkan/fgvk_cmd_pool.h new file mode 100644 index 00000000000..52e3c431be7 --- /dev/null +++ b/src/frygon/vulkan/fgvk_cmd_pool.h @@ -0,0 +1,25 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#ifndef FGVK_CMD_POOL_H +#define FGVK_CMD_POOL_H 1 + +#include "fgvk_private.h" + +#include "vk_command_pool.h" + +struct fgvk_cmd_pool { + struct vk_command_pool vk; +}; + +VK_DEFINE_NONDISP_HANDLE_CASTS(fgvk_cmd_pool, vk.base, VkCommandPool, + VK_OBJECT_TYPE_COMMAND_POOL) + +static inline struct fgvk_device * +fgvk_cmd_pool_device(struct fgvk_cmd_pool *pool) +{ + return (struct fgvk_device *)pool->vk.base.device; +} + +#endif diff --git a/src/frygon/vulkan/fgvk_debug.h b/src/frygon/vulkan/fgvk_debug.h new file mode 100644 index 00000000000..15b434a7828 --- /dev/null +++ b/src/frygon/vulkan/fgvk_debug.h @@ -0,0 +1,12 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#ifndef FGVK_DEBUG_H +#define FGVK_DEBUG_H 1 + +enum fgvk_debug { + FGVK_DEBUG_ALL = 1ull << 0, +}; + +#endif diff --git a/src/frygon/vulkan/fgvk_device.c b/src/frygon/vulkan/fgvk_device.c new file mode 100644 index 00000000000..6f36e725070 --- /dev/null +++ b/src/frygon/vulkan/fgvk_device.c @@ -0,0 +1,76 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#include "fgvk_device.h" + +#include "fgvk_physical_device.h" +#include "fgvk_cmd_buffer.h" +#include "fgvk_shader.h" +#include "fgvk_queue.h" + +VKAPI_ATTR VkResult VKAPI_CALL +fgvk_CreateDevice(VkPhysicalDevice physicalDevice, + const VkDeviceCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkDevice *pDevice) +{ + VK_FROM_HANDLE(fgvk_physical_device, pdev, physicalDevice); + VkResult result = VK_ERROR_OUT_OF_HOST_MEMORY; + struct fgvk_device *dev; + + dev = vk_zalloc2(&pdev->vk.instance->alloc, pAllocator, + sizeof(*dev), 8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); + + if (!dev) + return vk_error(pdev, VK_ERROR_OUT_OF_HOST_MEMORY); + + struct vk_device_dispatch_table dispatch_table; + vk_device_dispatch_table_from_entrypoints(&dispatch_table, + &fgvk_device_entrypoints, true); + //vk_device_dispatch_table_from_entrypoints(&dispatch_table, + // &wsi_device_entrypoints, false); + + result = vk_device_init(&dev->vk, &pdev->vk, &dispatch_table, + pCreateInfo, pAllocator); + + if (result != VK_SUCCESS) + goto fail_alloc; + + dev->vk.shader_ops = &fgvk_device_shader_ops; + dev->vk.command_buffer_ops = &fgvk_cmd_buffer_ops; + + for (unsigned i = 0; i < pCreateInfo->queueCreateInfoCount; i++) { + for (unsigned q = 0; q < pCreateInfo->pQueueCreateInfos[i].queueCount; q++) { + result = fgvk_queue_create(dev, &pCreateInfo->pQueueCreateInfos[i], q); + if (result != VK_SUCCESS) + goto fail_queues; + } + } + + *pDevice = fgvk_device_to_handle(dev); + + return result; + +fail_queues: + vk_foreach_queue_safe(iter, &dev->vk) { + struct fgvk_queue *queue = container_of(iter, struct fgvk_queue, vk); + fgvk_queue_destroy(dev, queue); + } +fail_alloc: + vk_free(&dev->vk.alloc, dev); + return result; +} + +VKAPI_ATTR void VKAPI_CALL +fgvk_DestroyDevice(VkDevice _device, const VkAllocationCallbacks *pAllocator) +{ + VK_FROM_HANDLE(fgvk_device, dev, _device); + + if (!dev) + return; + + // TODO we can't finish cause sync doesn't work + //vk_device_finish(&dev->vk); + vk_free(&dev->vk.alloc, dev); +} diff --git a/src/frygon/vulkan/fgvk_device.h b/src/frygon/vulkan/fgvk_device.h new file mode 100644 index 00000000000..51e6873612f --- /dev/null +++ b/src/frygon/vulkan/fgvk_device.h @@ -0,0 +1,19 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#ifndef FGVK_DEVICE_H +#define FGVK_DEVICE_H 1 + +#include "fgvk_private.h" + +#include "vk_device.h" + +struct fgvk_device { + struct vk_device vk; + int bleh; +}; + +VK_DEFINE_HANDLE_CASTS(fgvk_device, vk.base, VkDevice, VK_OBJECT_TYPE_DEVICE) + +#endif diff --git a/src/frygon/vulkan/fgvk_device_memory.c b/src/frygon/vulkan/fgvk_device_memory.c new file mode 100644 index 00000000000..d4b7b418a2c --- /dev/null +++ b/src/frygon/vulkan/fgvk_device_memory.c @@ -0,0 +1,81 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#include "fgvk_device_memory.h" + +#include "fgvk_device.h" + +VKAPI_ATTR VkResult VKAPI_CALL +fgvk_AllocateMemory(VkDevice device, + const VkMemoryAllocateInfo *pAllocateInfo, + const VkAllocationCallbacks *pAllocator, + VkDeviceMemory *pMem) +{ + VK_FROM_HANDLE(fgvk_device, dev, device); + VkResult result = VK_SUCCESS; + struct fgvk_device_memory *mem; + + mem = vk_device_memory_create(&dev->vk, pAllocateInfo, + pAllocator, sizeof(*mem)); + if (!mem) + return vk_error(dev, VK_ERROR_OUT_OF_HOST_MEMORY); + + mem->data = malloc(pAllocateInfo->allocationSize); + + if (!mem->data) + goto fail_alloc; + + *pMem = fgvk_device_memory_to_handle(mem); + + return VK_SUCCESS; + +fail_alloc: + vk_device_memory_destroy(&dev->vk, pAllocator, &mem->vk); + return result; +} + +VKAPI_ATTR void VKAPI_CALL +fgvk_FreeMemory(VkDevice device, + VkDeviceMemory _mem, + const VkAllocationCallbacks *pAllocator) +{ + VK_FROM_HANDLE(fgvk_device, dev, device); + VK_FROM_HANDLE(fgvk_device_memory, mem, _mem); + + vk_device_memory_destroy(&dev->vk, pAllocator, &mem->vk); +} + +VKAPI_ATTR VkResult VKAPI_CALL +fgvk_MapMemory2KHR(VkDevice device, + const VkMemoryMapInfoKHR *pMemoryMapInfo, + void **ppData) +{ + VK_FROM_HANDLE(fgvk_device_memory, mem, pMemoryMapInfo->memory); + + *ppData = mem->data; + return VK_SUCCESS; +} + +VKAPI_ATTR VkResult VKAPI_CALL +fgvk_UnmapMemory2KHR(VkDevice device, + const VkMemoryUnmapInfoKHR *pMemoryUnmapInfo) +{ + return VK_SUCCESS; +} + +VKAPI_ATTR VkResult VKAPI_CALL +fgvk_FlushMappedMemoryRanges(VkDevice device, + uint32_t memoryRangeCount, + const VkMappedMemoryRange *pMemoryRanges) +{ + return VK_SUCCESS; +} + +VKAPI_ATTR VkResult VKAPI_CALL +fgvk_InvalidateMappedMemoryRanges(VkDevice device, + uint32_t memoryRangeCount, + const VkMappedMemoryRange *pMemoryRanges) +{ + return VK_SUCCESS; +} diff --git a/src/frygon/vulkan/fgvk_device_memory.h b/src/frygon/vulkan/fgvk_device_memory.h new file mode 100644 index 00000000000..c07cdfc9339 --- /dev/null +++ b/src/frygon/vulkan/fgvk_device_memory.h @@ -0,0 +1,21 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#ifndef FGVK_DEVICE_MEMORY_H +#define FGVK_DEVICE_MEMORY_H 1 + +#include "fgvk_private.h" + +#include "vk_device_memory.h" + +struct fgvk_device_memory { + struct vk_device_memory vk; + + void *data; +}; + +VK_DEFINE_NONDISP_HANDLE_CASTS(fgvk_device_memory, vk.base, VkDeviceMemory, + VK_OBJECT_TYPE_DEVICE_MEMORY) + +#endif diff --git a/src/frygon/vulkan/fgvk_format.c b/src/frygon/vulkan/fgvk_format.c new file mode 100644 index 00000000000..08a5a15e963 --- /dev/null +++ b/src/frygon/vulkan/fgvk_format.c @@ -0,0 +1,21 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#include "fgvk_format.h" + +#include "fgvk_physical_device.h" + +VKAPI_ATTR void VKAPI_CALL +fgvk_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, + VkFormat format, + VkFormatProperties2 *pFormatProperties) +{ + VK_FROM_HANDLE(fgvk_physical_device, pdevice, physicalDevice); + + pFormatProperties->formatProperties = (VkFormatProperties) { + .linearTilingFeatures = 0, + .optimalTilingFeatures = 0, + .bufferFeatures = 0, + }; +} diff --git a/src/frygon/vulkan/fgvk_format.h b/src/frygon/vulkan/fgvk_format.h new file mode 100644 index 00000000000..ff667cd9f58 --- /dev/null +++ b/src/frygon/vulkan/fgvk_format.h @@ -0,0 +1,8 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#ifndef FGVK_FORMAT_H +#define FGVK_FORMAT_H 1 + +#endif diff --git a/src/frygon/vulkan/fgvk_image.c b/src/frygon/vulkan/fgvk_image.c new file mode 100644 index 00000000000..39129a31d48 --- /dev/null +++ b/src/frygon/vulkan/fgvk_image.c @@ -0,0 +1,113 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#include "fgvk_image.h" + +#include "fgvk_device.h" + +VKAPI_ATTR VkResult VKAPI_CALL +fgvk_CreateImage(VkDevice _device, + const VkImageCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkImage *pImage) +{ + VK_FROM_HANDLE(fgvk_device, dev, _device); + struct fgvk_image *image; + + image = vk_zalloc2(&dev->vk.alloc, pAllocator, sizeof(*image), 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!image) + return vk_error(dev, VK_ERROR_OUT_OF_HOST_MEMORY); + + vk_image_init(&dev->vk, &image->vk, pCreateInfo); + + *pImage = fgvk_image_to_handle(image); + + return VK_SUCCESS; +} + +VKAPI_ATTR void VKAPI_CALL +fgvk_DestroyImage(VkDevice device, + VkImage _image, + const VkAllocationCallbacks *pAllocator) +{ + VK_FROM_HANDLE(fgvk_device, dev, device); + VK_FROM_HANDLE(fgvk_image, image, _image); + + if (!image) + return; + + vk_free2(&dev->vk.alloc, pAllocator, image); +} + +VKAPI_ATTR void VKAPI_CALL +fgvk_GetImageMemoryRequirements2(VkDevice device, + const VkImageMemoryRequirementsInfo2 *pInfo, + VkMemoryRequirements2 *pMemoryRequirements) +{ + VK_FROM_HANDLE(fgvk_device, dev, device); + VK_FROM_HANDLE(fgvk_image, image, pInfo->image); + + pMemoryRequirements->memoryRequirements.memoryTypeBits = 1; + pMemoryRequirements->memoryRequirements.alignment = 8; + pMemoryRequirements->memoryRequirements.size = 4*1024*1024; +} + +static VkResult +fgvk_bind_image_memory(struct fgvk_device *dev, + const VkBindImageMemoryInfo *info) +{ + return VK_SUCCESS; +} + +VKAPI_ATTR VkResult VKAPI_CALL +fgvk_BindImageMemory2(VkDevice device, + uint32_t bindInfoCount, + const VkBindImageMemoryInfo *pBindInfos) +{ + VK_FROM_HANDLE(fgvk_device, dev, device); + VkResult first_error_or_success = VK_SUCCESS; + + for (uint32_t i = 0; i < bindInfoCount; ++i) { + VkResult result = fgvk_bind_image_memory(dev, &pBindInfos[i]); + + const VkBindMemoryStatusKHR *status = + vk_find_struct_const(pBindInfos[i].pNext, BIND_MEMORY_STATUS_KHR); + if (status != NULL && status->pResult != NULL) + *status->pResult = VK_SUCCESS; + + if (first_error_or_success == VK_SUCCESS) + first_error_or_success = result; + } + + return first_error_or_success; +} + +static void +fgvk_get_image_subresource_layout(struct fgvk_device *dev, + struct fgvk_image *image, + const VkImageSubresource2KHR *pSubresource, + VkSubresourceLayout2KHR *pLayout) +{ + const VkImageSubresource *isr = &pSubresource->imageSubresource; + pLayout->subresourceLayout = (VkSubresourceLayout) { + .offset = 0, + .size = image->vk.extent.width * image->vk.extent.height * 4, + .rowPitch = image->vk.extent.width * 4, + .arrayPitch = image->vk.extent.width * image->vk.extent.height * 4, + .depthPitch = 0, + }; +} + +VKAPI_ATTR void VKAPI_CALL +fgvk_GetImageSubresourceLayout2KHR(VkDevice device, + VkImage _image, + const VkImageSubresource2KHR *pSubresource, + VkSubresourceLayout2KHR *pLayout) +{ + VK_FROM_HANDLE(fgvk_device, dev, device); + VK_FROM_HANDLE(fgvk_image, image, _image); + + fgvk_get_image_subresource_layout(dev, image, pSubresource, pLayout); +} diff --git a/src/frygon/vulkan/fgvk_image.h b/src/frygon/vulkan/fgvk_image.h new file mode 100644 index 00000000000..d2592de32c6 --- /dev/null +++ b/src/frygon/vulkan/fgvk_image.h @@ -0,0 +1,18 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#ifndef FGVK_IMAGE_H +#define FGVK_IMAGE_H 1 + +#include "fgvk_private.h" + +#include "vk_image.h" + +struct fgvk_image { + struct vk_image vk; +}; + +VK_DEFINE_NONDISP_HANDLE_CASTS(fgvk_image, vk.base, VkImage, VK_OBJECT_TYPE_IMAGE) + +#endif diff --git a/src/frygon/vulkan/fgvk_image_view.c b/src/frygon/vulkan/fgvk_image_view.c new file mode 100644 index 00000000000..2a029265c33 --- /dev/null +++ b/src/frygon/vulkan/fgvk_image_view.c @@ -0,0 +1,42 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#include "fgvk_image_view.h" + +#include "fgvk_device.h" + +VKAPI_ATTR VkResult VKAPI_CALL +fgvk_CreateImageView(VkDevice _device, + const VkImageViewCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkImageView *pView) +{ + VK_FROM_HANDLE(fgvk_device, dev, _device); + struct fgvk_image_view *view; + + view = vk_alloc2(&dev->vk.alloc, pAllocator, sizeof(*view), 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!view) + return vk_error(dev, VK_ERROR_OUT_OF_HOST_MEMORY); + + vk_image_view_init(&dev->vk, &view->vk, pCreateInfo); + + *pView = fgvk_image_view_to_handle(view); + + return VK_SUCCESS; +} + +VKAPI_ATTR void VKAPI_CALL +fgvk_DestroyImageView(VkDevice _device, + VkImageView imageView, + const VkAllocationCallbacks *pAllocator) +{ + VK_FROM_HANDLE(fgvk_device, dev, _device); + VK_FROM_HANDLE(fgvk_image_view, view, imageView); + + if (!view) + return; + + vk_free2(&dev->vk.alloc, pAllocator, view); +} diff --git a/src/frygon/vulkan/fgvk_image_view.h b/src/frygon/vulkan/fgvk_image_view.h new file mode 100644 index 00000000000..dcb2acd90e5 --- /dev/null +++ b/src/frygon/vulkan/fgvk_image_view.h @@ -0,0 +1,19 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#ifndef FGVK_IMAGE_VIEW_H +#define FGVK_IMAGE_VIEW_H 1 + +#include "fgvk_private.h" + +#include "vk_image.h" + +struct fgvk_image_view { + struct vk_image_view vk; +}; + +VK_DEFINE_NONDISP_HANDLE_CASTS(fgvk_image_view, vk.base, VkImageView, + VK_OBJECT_TYPE_IMAGE_VIEW) + +#endif diff --git a/src/frygon/vulkan/fgvk_instance.c b/src/frygon/vulkan/fgvk_instance.c new file mode 100644 index 00000000000..c4d23e0c974 --- /dev/null +++ b/src/frygon/vulkan/fgvk_instance.c @@ -0,0 +1,128 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ + +#include "fgvk_instance.h" + +#include "fgvk_entrypoints.h" + +#include "vulkan/wsi/wsi_common.h" + +#include "util/build_id.h" + +VKAPI_ATTR VkResult VKAPI_CALL +fgvk_EnumerateInstanceVersion(uint32_t *pApiVersion) +{ + uint32_t version_override = vk_get_version_override(); + *pApiVersion = version_override ? version_override : + VK_MAKE_VERSION(1, 0, VK_HEADER_VERSION); + + return VK_SUCCESS; +} + +static const struct vk_instance_extension_table instance_extensions = { +}; + +VKAPI_ATTR VkResult VKAPI_CALL +fgvk_EnumerateInstanceExtensionProperties(const char *pLayerName, + uint32_t *pPropertyCount, + VkExtensionProperties *pProperties) +{ + if (pLayerName) + return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT); + + return vk_enumerate_instance_extension_properties( + &instance_extensions, pPropertyCount, pProperties); +} + +VKAPI_ATTR VkResult VKAPI_CALL +fgvk_CreateInstance(const VkInstanceCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkInstance *pInstance) +{ + struct fgvk_instance *instance; + VkResult result; + + if (pAllocator == NULL) + pAllocator = vk_default_allocator(); + + instance = vk_alloc(pAllocator, sizeof(*instance), 8, + VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); + if (!instance) + return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY); + + struct vk_instance_dispatch_table dispatch_table; + vk_instance_dispatch_table_from_entrypoints(&dispatch_table, + &fgvk_instance_entrypoints, + true); + vk_instance_dispatch_table_from_entrypoints(&dispatch_table, + &wsi_instance_entrypoints, + false); + + result = vk_instance_init(&instance->vk, &instance_extensions, + &dispatch_table, pCreateInfo, pAllocator); + if (result != VK_SUCCESS) + goto fail_alloc; + + //fgvk_init_debug_flags(instance); + + instance->vk.physical_devices.enumerate = fgvk_physical_device_enumerate; + instance->vk.physical_devices.destroy = fgvk_physical_device_destroy; + + const struct build_id_note *note = + build_id_find_nhdr_for_addr(fgvk_CreateInstance); + if (!note) { + result = vk_errorf(NULL, VK_ERROR_INITIALIZATION_FAILED, + "Failed to find build-id"); + goto fail_init; + } + + unsigned build_id_len = build_id_length(note); + if (build_id_len < SHA1_DIGEST_LENGTH) { + result = vk_errorf(NULL, VK_ERROR_INITIALIZATION_FAILED, + "build-id too short. It needs to be a SHA"); + goto fail_init; + } + + STATIC_ASSERT(sizeof(instance->driver_build_sha) == SHA1_DIGEST_LENGTH); + memcpy(instance->driver_build_sha, build_id_data(note), SHA1_DIGEST_LENGTH); + + *pInstance = fgvk_instance_to_handle(instance); + return VK_SUCCESS; + +fail_init: + vk_instance_finish(&instance->vk); +fail_alloc: + vk_free(pAllocator, instance); + + return result; +} + +VKAPI_ATTR void VKAPI_CALL +fgvk_DestroyInstance(VkInstance _instance, + const VkAllocationCallbacks *pAllocator) +{ + VK_FROM_HANDLE(fgvk_instance, instance, _instance); + + if (!instance) + return; + + vk_instance_finish(&instance->vk); + vk_free(&instance->vk.alloc, instance); +} + +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL +fgvk_GetInstanceProcAddr(VkInstance _instance, const char *pName) +{ + VK_FROM_HANDLE(fgvk_instance, instance, _instance); + return vk_instance_get_proc_addr(&instance->vk, + &fgvk_instance_entrypoints, + pName); +} + +PUBLIC VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL +vk_icdGetInstanceProcAddr(VkInstance instance, const char *pName) +{ + return fgvk_GetInstanceProcAddr(instance, pName); +} diff --git a/src/frygon/vulkan/fgvk_instance.h b/src/frygon/vulkan/fgvk_instance.h new file mode 100644 index 00000000000..e2c1c753a38 --- /dev/null +++ b/src/frygon/vulkan/fgvk_instance.h @@ -0,0 +1,25 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#ifndef FGVK_INSTANCE_H +#define FGVK_INSTANCE_H 1 + +#include "fgvk_private.h" + +#include "fgvk_debug.h" +#include "vk_instance.h" +#include "util/xmlconfig.h" + +struct fgvk_instance { + struct vk_instance vk; + + enum fgvk_debug debug_flags; + + uint8_t driver_build_sha[20]; + uint32_t force_vk_vendor; +}; + +VK_DEFINE_HANDLE_CASTS(fgvk_instance, vk.base, VkInstance, VK_OBJECT_TYPE_INSTANCE) + +#endif diff --git a/src/frygon/vulkan/fgvk_physical_device.c b/src/frygon/vulkan/fgvk_physical_device.c new file mode 100644 index 00000000000..44b9b63135e --- /dev/null +++ b/src/frygon/vulkan/fgvk_physical_device.c @@ -0,0 +1,573 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#include "fgvk_physical_device.h" + +#include "fgcc.h" +#include "vk_sync_dummy.h" + +static void +fgvk_get_device_info(struct fg_device_info *info) { + info->device_id = 0x0001; + snprintf(info->device_name, sizeof(info->device_name), "Frygon GFX1"); +} + +static void +fgvk_get_device_properties(const struct fgvk_instance *instance, + struct vk_properties *properties) +{ + *properties = (struct vk_properties) { + .apiVersion = VK_MAKE_VERSION(1, 0, VK_HEADER_VERSION), + .driverVersion = vk_get_driver_version(), + .vendorID = 0xF5C5, + .deviceID = 0x0001, + .deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, + + /* Vulkan 1.0 limits */ + .maxImageDimension1D = 16384, + .maxImageDimension2D = 16384, + .maxImageDimension3D = 16384, + .maxImageDimensionCube = 0x8000, + .maxImageArrayLayers = 2048, + .maxTexelBufferElements = 128 * 1024 * 1024, + .maxUniformBufferRange = 65536, + .maxStorageBufferRange = UINT32_MAX, + .maxPushConstantsSize = 4096, + .maxMemoryAllocationCount = 4096, + .maxSamplerAllocationCount = 4000, + .bufferImageGranularity = 0x10000, // TODO + .sparseAddressSpaceSize = 0, // TODO + .maxBoundDescriptorSets = 8, // TODO + .maxPerStageDescriptorSamplers = 8, // TODO + .maxPerStageDescriptorUniformBuffers = 8, // TODO + .maxPerStageDescriptorStorageBuffers = 8, // TODO + .maxPerStageDescriptorSampledImages = 8, // TODO + .maxPerStageDescriptorStorageImages = 8, // TODO + .maxPerStageDescriptorInputAttachments = 8, // TODO + .maxPerStageResources = UINT32_MAX, + .maxDescriptorSetSamplers = 8, // TODO + .maxDescriptorSetUniformBuffers = 8, // TODO + .maxDescriptorSetUniformBuffersDynamic = 0, // TODO + .maxDescriptorSetStorageBuffers = 8, // TODO + .maxDescriptorSetStorageBuffersDynamic = 0, // TODO + .maxDescriptorSetSampledImages = 8, // TODO + .maxDescriptorSetStorageImages = 8, // TODO + .maxDescriptorSetInputAttachments = 8, // TODO + .maxVertexInputAttributes = 32, + .maxVertexInputBindings = 32, + .maxVertexInputAttributeOffset = 2047, + .maxVertexInputBindingStride = 2048, + .maxVertexOutputComponents = 128, + .maxTessellationGenerationLevel = 64, + .maxTessellationPatchSize = 32, + .maxTessellationControlPerVertexInputComponents = 128, + .maxTessellationControlPerVertexOutputComponents = 128, + .maxTessellationControlPerPatchOutputComponents = 120, + .maxTessellationControlTotalOutputComponents = 4216, + .maxTessellationEvaluationInputComponents = 128, + .maxTessellationEvaluationOutputComponents = 128, + .maxGeometryShaderInvocations = 32, + .maxGeometryInputComponents = 128, + .maxGeometryOutputComponents = 128, + .maxGeometryOutputVertices = 1024, + .maxGeometryTotalOutputComponents = 1024, + .maxFragmentInputComponents = 128, + .maxFragmentOutputAttachments = 8, // TODO + .maxFragmentDualSrcAttachments = 1, + .maxFragmentCombinedOutputResources = 16, + /* Nvidia limits this to 48kB for consistency reasons, we could lift the + * limit if we wanted to. + */ + .maxComputeSharedMemorySize = 64 * 1024, // TODO + .maxComputeWorkGroupCount = {0x7fffffff, 65535, 65535}, + .maxComputeWorkGroupInvocations = 1024, + .maxComputeWorkGroupSize = {1024, 1024, 64}, + .subPixelPrecisionBits = 8, + .subTexelPrecisionBits = 8, + .mipmapPrecisionBits = 8, + .maxDrawIndexedIndexValue = UINT32_MAX, + .maxDrawIndirectCount = UINT32_MAX, + .maxSamplerLodBias = 15, + .maxSamplerAnisotropy = 16, + .maxViewports = 8, + .maxViewportDimensions = { 32768, 32768 }, + .viewportBoundsRange = { -65536, 65536 }, + .viewportSubPixelBits = 8, + .minMemoryMapAlignment = 4096, // TODO + .minTexelBufferOffsetAlignment = 8, + .minUniformBufferOffsetAlignment = 8, + .minStorageBufferOffsetAlignment = 8, + .minTexelOffset = -8, + .maxTexelOffset = 7, + .minTexelGatherOffset = -32, + .maxTexelGatherOffset = 31, + .minInterpolationOffset = -0.5, + .maxInterpolationOffset = 0.4375, + .subPixelInterpolationOffsetBits = 4, + .maxFramebufferHeight = 16384, + .maxFramebufferWidth = 16384, + .maxFramebufferLayers = 2048, + .framebufferColorSampleCounts = 1, + .framebufferDepthSampleCounts = 1, + .framebufferNoAttachmentsSampleCounts = 1, + .framebufferStencilSampleCounts = 1, + .maxColorAttachments = 8, + .sampledImageColorSampleCounts = 1, + .sampledImageIntegerSampleCounts = 1, + .sampledImageDepthSampleCounts = 1, + .sampledImageStencilSampleCounts = 1, + .storageImageSampleCounts = 1, + .maxSampleMaskWords = 1, + .timestampComputeAndGraphics = true, + /* FIXME: Is timestamp period actually 1? */ + .timestampPeriod = 1.0f, + .maxClipDistances = 8, + .maxCullDistances = 8, + .maxCombinedClipAndCullDistances = 8, + .discreteQueuePriorities = 2, + .pointSizeRange = { 1.0, 2047.94 }, + .lineWidthRange = { 1, 64 }, + .pointSizeGranularity = 0.0625, + .lineWidthGranularity = 0.0625, + .strictLines = true, + .standardSampleLocations = true, + .optimalBufferCopyOffsetAlignment = 1, + .optimalBufferCopyRowPitchAlignment = 1, + /* Default to 64 if we don't know the atom size */ + .nonCoherentAtomSize = 64, + + /* Vulkan 1.0 sparse properties */ + .sparseResidencyNonResidentStrict = true, + .sparseResidencyAlignedMipSize = VK_FALSE, + .sparseResidencyStandard2DBlockShape = true, + .sparseResidencyStandard2DMultisampleBlockShape = true, + .sparseResidencyStandard3DBlockShape = true, + +#if 0 + /* Vulkan 1.1 properties */ + .subgroupSize = 32, + .subgroupSupportedStages = VK_SHADER_STAGE_VERTEX_BIT | + VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | + VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | + VK_SHADER_STAGE_GEOMETRY_BIT | + VK_SHADER_STAGE_FRAGMENT_BIT | + VK_SHADER_STAGE_COMPUTE_BIT, + .subgroupSupportedOperations = VK_SUBGROUP_FEATURE_ARITHMETIC_BIT | + VK_SUBGROUP_FEATURE_BALLOT_BIT | + VK_SUBGROUP_FEATURE_BASIC_BIT | + VK_SUBGROUP_FEATURE_CLUSTERED_BIT | + VK_SUBGROUP_FEATURE_QUAD_BIT | + VK_SUBGROUP_FEATURE_ROTATE_BIT_KHR | + VK_SUBGROUP_FEATURE_ROTATE_CLUSTERED_BIT_KHR | + VK_SUBGROUP_FEATURE_SHUFFLE_BIT | + VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT | + VK_SUBGROUP_FEATURE_VOTE_BIT, + .subgroupQuadOperationsInAllStages = false, + .pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY, + .maxMultiviewViewCount = NVK_MAX_MULTIVIEW_VIEW_COUNT, + .maxMultiviewInstanceIndex = UINT32_MAX, + .maxPerSetDescriptors = UINT32_MAX, + .maxMemoryAllocationSize = (1u << 31), + + /* Vulkan 1.2 properties */ + .supportedDepthResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT | + VK_RESOLVE_MODE_AVERAGE_BIT | + VK_RESOLVE_MODE_MIN_BIT | + VK_RESOLVE_MODE_MAX_BIT, + .supportedStencilResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT | + VK_RESOLVE_MODE_MIN_BIT | + VK_RESOLVE_MODE_MAX_BIT, + .independentResolveNone = true, + .independentResolve = true, + .driverID = VK_DRIVER_ID_MESA_NVK, + .conformanceVersion = + nvk_is_conformant(info) ? (VkConformanceVersion) { 1, 4, 3, 0 } + : (VkConformanceVersion) { 0, 0, 0, 0 }, + .denormBehaviorIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL, + .roundingModeIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL, + .shaderSignedZeroInfNanPreserveFloat16 = true, + .shaderSignedZeroInfNanPreserveFloat32 = true, + .shaderSignedZeroInfNanPreserveFloat64 = true, + .shaderDenormPreserveFloat16 = true, + .shaderDenormPreserveFloat32 = true, + .shaderDenormPreserveFloat64 = true, + .shaderDenormFlushToZeroFloat16 = false, + .shaderDenormFlushToZeroFloat32 = true, + .shaderDenormFlushToZeroFloat64 = false, + .shaderRoundingModeRTEFloat16 = true, + .shaderRoundingModeRTEFloat32 = true, + .shaderRoundingModeRTEFloat64 = true, + .shaderRoundingModeRTZFloat16 = false, + .shaderRoundingModeRTZFloat32 = true, + .shaderRoundingModeRTZFloat64 = true, + .maxUpdateAfterBindDescriptorsInAllPools = UINT32_MAX, + .shaderUniformBufferArrayNonUniformIndexingNative = true, + .shaderSampledImageArrayNonUniformIndexingNative = info->cls_eng3d >= TURING_A, + .shaderStorageBufferArrayNonUniformIndexingNative = true, + .shaderStorageImageArrayNonUniformIndexingNative = info->cls_eng3d >= TURING_A, + .shaderInputAttachmentArrayNonUniformIndexingNative = false, + .robustBufferAccessUpdateAfterBind = true, + .quadDivergentImplicitLod = info->cls_eng3d >= TURING_A, + .maxPerStageDescriptorUpdateAfterBindSamplers = NVK_MAX_DESCRIPTORS, + .maxPerStageDescriptorUpdateAfterBindUniformBuffers = NVK_MAX_DESCRIPTORS, + .maxPerStageDescriptorUpdateAfterBindStorageBuffers = NVK_MAX_DESCRIPTORS, + .maxPerStageDescriptorUpdateAfterBindSampledImages = NVK_MAX_DESCRIPTORS, + .maxPerStageDescriptorUpdateAfterBindStorageImages = NVK_MAX_DESCRIPTORS, + .maxPerStageDescriptorUpdateAfterBindInputAttachments = NVK_MAX_DESCRIPTORS, + .maxPerStageUpdateAfterBindResources = UINT32_MAX, + .maxDescriptorSetUpdateAfterBindSamplers = NVK_MAX_DESCRIPTORS, + .maxDescriptorSetUpdateAfterBindUniformBuffers = NVK_MAX_DESCRIPTORS, + .maxDescriptorSetUpdateAfterBindUniformBuffersDynamic = NVK_MAX_DYNAMIC_BUFFERS / 2, + .maxDescriptorSetUpdateAfterBindStorageBuffers = NVK_MAX_DESCRIPTORS, + .maxDescriptorSetUpdateAfterBindStorageBuffersDynamic = NVK_MAX_DYNAMIC_BUFFERS / 2, + .maxDescriptorSetUpdateAfterBindSampledImages = NVK_MAX_DESCRIPTORS, + .maxDescriptorSetUpdateAfterBindStorageImages = NVK_MAX_DESCRIPTORS, + .maxDescriptorSetUpdateAfterBindInputAttachments = NVK_MAX_DESCRIPTORS, + .filterMinmaxSingleComponentFormats = info->cls_eng3d >= MAXWELL_B, + .filterMinmaxImageComponentMapping = info->cls_eng3d >= MAXWELL_B, + .maxTimelineSemaphoreValueDifference = UINT64_MAX, + .framebufferIntegerColorSampleCounts = sample_counts, + + /* Vulkan 1.3 properties */ + .minSubgroupSize = 32, + .maxSubgroupSize = 32, + .maxComputeWorkgroupSubgroups = 1024 / 32, + .requiredSubgroupSizeStages = 0, + .maxInlineUniformBlockSize = NVK_MAX_INLINE_UNIFORM_BLOCK_SIZE, + .maxPerStageDescriptorInlineUniformBlocks = 32, + .maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks = 32, + .maxDescriptorSetInlineUniformBlocks = 6 * 32, + .maxDescriptorSetUpdateAfterBindInlineUniformBlocks = 6 * 32, + .maxInlineUniformTotalSize = 1 << 16, + .integerDotProduct4x8BitPackedUnsignedAccelerated + = info->cls_eng3d >= VOLTA_A, + .integerDotProduct4x8BitPackedSignedAccelerated + = info->cls_eng3d >= VOLTA_A, + .integerDotProduct4x8BitPackedMixedSignednessAccelerated + = info->cls_eng3d >= VOLTA_A, + .storageTexelBufferOffsetAlignmentBytes = NVK_MIN_TEXEL_BUFFER_ALIGNMENT, + .storageTexelBufferOffsetSingleTexelAlignment = true, + .uniformTexelBufferOffsetAlignmentBytes = NVK_MIN_TEXEL_BUFFER_ALIGNMENT, + .uniformTexelBufferOffsetSingleTexelAlignment = true, + .maxBufferSize = NVK_MAX_BUFFER_SIZE, + + /* Vulkan 1.4 properties */ + .lineSubPixelPrecisionBits = 8, + .maxVertexAttribDivisor = UINT32_MAX, + .supportsNonZeroFirstInstance = true, + .maxPushDescriptors = NVK_MAX_PUSH_DESCRIPTORS, + .dynamicRenderingLocalReadDepthStencilAttachments = true, + .dynamicRenderingLocalReadMultisampledAttachments = true, + .earlyFragmentMultisampleCoverageAfterSampleCounting = true, + .earlyFragmentSampleMaskTestBeforeSampleCounting = true, + .depthStencilSwizzleOneSupport = true, + .polygonModePointSize = true, + .nonStrictSinglePixelWideLinesUseParallelogram = false, + .nonStrictWideLinesUseParallelogram = false, + .blockTexelViewCompatibleMultipleLayers = true, + .maxCombinedImageSamplerDescriptorCount = NVK_MAX_IMAGE_PLANES, + .fragmentShadingRateClampCombinerInputs = false, /* TODO */ + .defaultRobustnessStorageBuffers = + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT, + .defaultRobustnessUniformBuffers = + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT, + .defaultRobustnessVertexInputs = + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2_EXT, + .defaultRobustnessImages = + VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_2_EXT, + + /* VK_KHR_cooperative_matrix */ + .cooperativeMatrixSupportedStages = VK_SHADER_STAGE_COMPUTE_BIT, + + /* VK_KHR_discard_rectangles */ + .maxDiscardRectangles = NVK_MAX_DISCARD_RECTANGLES, + + /* VK_KHR_compute_shader_derivatives */ + .meshAndTaskShaderDerivatives = false, + + /* VK_KHR_pipeline_binary + * + * InternalCache properties are set by + * nvk_physical_device_init_pipeline_cache() + */ + .pipelineBinaryCompressedData = false, + + /* VK_EXT_conservative_rasterization */ + .primitiveOverestimationSize = info->cls_eng3d >= VOLTA_A ? 1.0f / 512.0f : 0.0, + .maxExtraPrimitiveOverestimationSize = 0.75, + .extraPrimitiveOverestimationSizeGranularity = 0.25, + .primitiveUnderestimation = info->cls_eng3d >= VOLTA_A, + .conservativePointAndLineRasterization = true, + .degenerateLinesRasterized = info->cls_eng3d >= VOLTA_A, + .degenerateTrianglesRasterized = info->cls_eng3d >= PASCAL_A, + .fullyCoveredFragmentShaderInputVariable = false, + .conservativeRasterizationPostDepthCoverage = info->cls_eng3d >= MAXWELL_B, + + /* VK_EXT_custom_border_color */ + .maxCustomBorderColorSamplers = 4000, + + /* VK_EXT_descriptor_buffer */ + .combinedImageSamplerDescriptorSingleArray = true, + .bufferlessPushDescriptors = true, + .allowSamplerImageViewPostSubmitCreation = false, + .descriptorBufferOffsetAlignment = nvk_min_cbuf_alignment(info), + .maxDescriptorBufferBindings = 32, + .maxResourceDescriptorBufferBindings = 32, + .maxSamplerDescriptorBufferBindings = 32, + .maxEmbeddedImmutableSamplerBindings = 32, + .maxEmbeddedImmutableSamplers = 4000, + .bufferCaptureReplayDescriptorDataSize = sizeof(uint64_t), + .imageCaptureReplayDescriptorDataSize = 0, + .imageViewCaptureReplayDescriptorDataSize = + sizeof(struct nvk_image_view_capture), + .samplerCaptureReplayDescriptorDataSize = + sizeof(struct nvk_sampler_capture), + .accelerationStructureCaptureReplayDescriptorDataSize = 0, // todo + .samplerDescriptorSize = sizeof(struct nvk_sampled_image_descriptor), + .combinedImageSamplerDescriptorSize = sizeof(struct nvk_sampled_image_descriptor), + .sampledImageDescriptorSize = sizeof(struct nvk_sampled_image_descriptor), + .storageImageDescriptorSize = sizeof(struct nvk_storage_image_descriptor), + .uniformTexelBufferDescriptorSize = sizeof(struct nvk_edb_buffer_view_descriptor), + .robustUniformTexelBufferDescriptorSize = sizeof(struct nvk_edb_buffer_view_descriptor), + .storageTexelBufferDescriptorSize = sizeof(struct nvk_edb_buffer_view_descriptor), + .robustStorageTexelBufferDescriptorSize = sizeof(struct nvk_edb_buffer_view_descriptor), + .uniformBufferDescriptorSize = sizeof(union nvk_buffer_descriptor), + .robustUniformBufferDescriptorSize = sizeof(union nvk_buffer_descriptor), + .storageBufferDescriptorSize = sizeof(union nvk_buffer_descriptor), + .robustStorageBufferDescriptorSize = sizeof(union nvk_buffer_descriptor), + .inputAttachmentDescriptorSize = sizeof(struct nvk_sampled_image_descriptor), + .accelerationStructureDescriptorSize = 0, + .maxSamplerDescriptorBufferRange = UINT32_MAX, + .maxResourceDescriptorBufferRange = UINT32_MAX, + .samplerDescriptorBufferAddressSpaceSize = UINT32_MAX, + .resourceDescriptorBufferAddressSpaceSize = UINT32_MAX, + .descriptorBufferAddressSpaceSize = UINT32_MAX, + + /* VK_EXT_device_generated_commands */ + .maxIndirectPipelineCount = UINT32_MAX, + .maxIndirectShaderObjectCount = UINT32_MAX, + .maxIndirectSequenceCount = 1 << 20, + .maxIndirectCommandsTokenCount = 16, + .maxIndirectCommandsTokenOffset = 2047, + .maxIndirectCommandsIndirectStride = 1 << 12, + .supportedIndirectCommandsInputModes = + VK_INDIRECT_COMMANDS_INPUT_MODE_VULKAN_INDEX_BUFFER_EXT | + VK_INDIRECT_COMMANDS_INPUT_MODE_DXGI_INDEX_BUFFER_EXT, + .supportedIndirectCommandsShaderStages = + NVK_SHADER_STAGE_GRAPHICS_BITS | VK_SHADER_STAGE_COMPUTE_BIT, + .supportedIndirectCommandsShaderStagesPipelineBinding = + NVK_SHADER_STAGE_GRAPHICS_BITS | VK_SHADER_STAGE_COMPUTE_BIT, + .supportedIndirectCommandsShaderStagesShaderBinding = + NVK_SHADER_STAGE_GRAPHICS_BITS | VK_SHADER_STAGE_COMPUTE_BIT, + .deviceGeneratedCommandsTransformFeedback = true, + .deviceGeneratedCommandsMultiDrawIndirectCount = info->cls_eng3d >= TURING_A, + + /* VK_EXT_extended_dynamic_state3 */ + .dynamicPrimitiveTopologyUnrestricted = true, + + /* VK_EXT_graphics_pipeline_library */ + .graphicsPipelineLibraryFastLinking = true, + .graphicsPipelineLibraryIndependentInterpolationDecoration = true, + + /* VK_KHR_maintenance7 */ + .robustFragmentShadingRateAttachmentAccess = false, + .separateDepthStencilAttachmentAccess = false, + .maxDescriptorSetTotalUniformBuffersDynamic = NVK_MAX_DYNAMIC_BUFFERS / 2, + .maxDescriptorSetTotalStorageBuffersDynamic = NVK_MAX_DYNAMIC_BUFFERS / 2, + .maxDescriptorSetTotalBuffersDynamic = NVK_MAX_DYNAMIC_BUFFERS, + .maxDescriptorSetUpdateAfterBindTotalUniformBuffersDynamic = NVK_MAX_DYNAMIC_BUFFERS / 2, + .maxDescriptorSetUpdateAfterBindTotalStorageBuffersDynamic = NVK_MAX_DYNAMIC_BUFFERS / 2, + .maxDescriptorSetUpdateAfterBindTotalBuffersDynamic = NVK_MAX_DYNAMIC_BUFFERS, + + /* VK_KHR_maintenance9 */ + .image2DViewOf3DSparse = false, + .defaultVertexAttributeValue = + VK_DEFAULT_VERTEX_ATTRIBUTE_VALUE_ZERO_ZERO_ZERO_ZERO_KHR, + + /* VK_KHR_maintenance10 */ + .rgba4OpaqueBlackSwizzled = true, + .resolveSrgbFormatAppliesTransferFunction = true, + .resolveSrgbFormatSupportsTransferFunctionControl = true, + + /* VK_EXT_legacy_vertex_attributes */ + .nativeUnalignedPerformance = true, + + /* VK_EXT_map_memory_placed */ + .minPlacedMemoryMapAlignment = os_page_size, + + /* VK_EXT_multi_draw */ + .maxMultiDrawCount = UINT32_MAX, + + /* VK_EXT_nested_command_buffer */ + .maxCommandBufferNestingLevel = UINT32_MAX, + + /* VK_EXT_pci_bus_info */ + .pciDomain = info->pci.domain, + .pciBus = info->pci.bus, + .pciDevice = info->pci.dev, + .pciFunction = info->pci.func, + + /* VK_EXT_physical_device_drm gets populated later */ + + /* VK_EXT_provoking_vertex */ + .provokingVertexModePerPipeline = true, + .transformFeedbackPreservesTriangleFanProvokingVertex = true, + + /* VK_EXT_robustness2 */ + .robustStorageBufferAccessSizeAlignment = NVK_SSBO_BOUNDS_CHECK_ALIGNMENT, + .robustUniformBufferAccessSizeAlignment = nvk_min_cbuf_alignment(info), + + /* VK_EXT_sample_locations + * + * There's a weird HW issue with per-sample interpolation for 1x. It + * always interpolates at (0.5, 0.5) so we just disable custom sample + * locations for 1x. + */ + .sampleLocationSampleCounts = sample_counts & ~VK_SAMPLE_COUNT_1_BIT, + .maxSampleLocationGridSize = (VkExtent2D){ 1, 1 }, + .sampleLocationCoordinateRange[0] = 0.0f, + .sampleLocationCoordinateRange[1] = 0.9375f, + .sampleLocationSubPixelBits = 4, + .variableSampleLocations = true, + + /* VK_EXT_shader_object */ + .shaderBinaryVersion = 0, + + /* VK_EXT_transform_feedback */ + .maxTransformFeedbackStreams = 4, + .maxTransformFeedbackBuffers = 4, + .maxTransformFeedbackBufferSize = UINT32_MAX, + .maxTransformFeedbackStreamDataSize = 2048, + .maxTransformFeedbackBufferDataSize = 512, + .maxTransformFeedbackBufferDataStride = 2048, + .transformFeedbackQueries = true, + .transformFeedbackStreamsLinesTriangles = false, + .transformFeedbackRasterizationStreamSelect = true, + .transformFeedbackDraw = true, + + /* VK_KHR_fragment_shader_barycentric */ + .triStripVertexOrderIndependentOfProvokingVertex = false, + + /* VK_KHR_fragment_shading_rate */ + .minFragmentShadingRateAttachmentTexelSize = { 16, 16 }, + .maxFragmentShadingRateAttachmentTexelSize = { 16, 16 }, + .maxFragmentShadingRateAttachmentTexelSizeAspectRatio = 1, + .primitiveFragmentShadingRateWithMultipleViewports = info->cls_eng3d >= AMPERE_B, + .layeredShadingRateAttachments = true, + .fragmentShadingRateNonTrivialCombinerOps = true, + .maxFragmentSize = { 4, 4 }, + .maxFragmentSizeAspectRatio = 2, + .maxFragmentShadingRateCoverageSamples = 16, + .maxFragmentShadingRateRasterizationSamples = 16, + .fragmentShadingRateWithShaderDepthStencilWrites = true, + .fragmentShadingRateWithSampleMask = true, + .fragmentShadingRateWithShaderSampleMask = true, + .fragmentShadingRateWithConservativeRasterization = true, + //.fragmentShadingRateWithFragmentShaderInterlock = true, + .fragmentShadingRateWithCustomSampleLocations = true, + .fragmentShadingRateStrictMultiplyCombiner = true, + + /* VK_MESA_image_alignment_control */ + .supportedImageAlignmentMask = (4 * 1024) | (16 * 1024) | (64 * 1024), + + /* VK_NV_shader_sm_builtins */ + .shaderSMCount = (uint32_t)info->tpc_count * info->mp_per_tpc, + .shaderWarpsPerSM = info->max_warps_per_mp, +#endif + }; + + snprintf(properties->deviceName, sizeof(properties->deviceName), "Frygon GFX1"); +} + +VkResult +fgvk_physical_device_enumerate(struct vk_instance *_instance) +{ + VkResult result = VK_SUCCESS; + struct fgvk_instance *instance = (struct fgvk_instance *)_instance; + + struct fgvk_physical_device *device = + vk_zalloc(&instance->vk.alloc, sizeof(*device), 8, + VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); + if (!device) + return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY); + + struct vk_physical_device_dispatch_table dispatch_table; + vk_physical_device_dispatch_table_from_entrypoints + (&dispatch_table, &fgvk_physical_device_entrypoints, true); + //vk_physical_device_dispatch_table_from_entrypoints( + // &dispatch_table, &wsi_physical_device_entrypoints, false); + + struct vk_properties properties; + fgvk_get_device_properties(instance, &properties); + + result = vk_physical_device_init(&device->vk, &instance->vk, NULL, NULL, + &properties, &dispatch_table); + if (result != VK_SUCCESS) + goto fail; + + fgvk_get_device_info(&device->info); + + device->fgcc = fgcc_compiler_create(&device->info); + device->sync_types[0] = &vk_sync_dummy_type; + device->sync_types[1] = NULL; + device->vk.supported_sync_types = device->sync_types; + + list_addtail(&device->vk.link, &instance->vk.physical_devices.list); + + return VK_SUCCESS; + +fail: + vk_physical_device_finish(&device->vk); + vk_free(&instance->vk.alloc, device); + return result; +} + +void +fgvk_physical_device_destroy(struct vk_physical_device *pdevice) +{ + struct fgvk_physical_device *pdev = + container_of(pdevice, struct fgvk_physical_device, vk); + + vk_physical_device_finish(&pdev->vk); + vk_free(&pdev->vk.instance->alloc, pdev); +} + +VKAPI_ATTR void VKAPI_CALL +fgvk_GetPhysicalDeviceMemoryProperties2( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceMemoryProperties2 *pMemoryProperties) +{ + //VK_FROM_HANDLE(fgvk_physical_device, pdev, physicalDevice); + + pMemoryProperties->memoryProperties.memoryHeapCount = 1; + pMemoryProperties->memoryProperties.memoryHeaps[0] = (VkMemoryHeap) { + .size = 256*1024*1024, + .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT, + }; + + pMemoryProperties->memoryProperties.memoryTypeCount = 1; + pMemoryProperties->memoryProperties.memoryTypes[0] = (VkMemoryType) { + .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + .heapIndex = 0, + }; +} + +VKAPI_ATTR void VKAPI_CALL +fgvk_GetPhysicalDeviceQueueFamilyProperties2( + VkPhysicalDevice physicalDevice, + uint32_t *pQueueFamilyPropertyCount, + VkQueueFamilyProperties2 *pQueueFamilyProperties) +{ + VK_OUTARRAY_MAKE_TYPED(VkQueueFamilyProperties2, out, pQueueFamilyProperties, + pQueueFamilyPropertyCount); + + vk_outarray_append_typed(VkQueueFamilyProperties2, &out, p) { + p->queueFamilyProperties.queueFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT; + p->queueFamilyProperties.queueCount = 1; + p->queueFamilyProperties.timestampValidBits = 64; + p->queueFamilyProperties.minImageTransferGranularity = (VkExtent3D){1, 1, 1}; + } +} diff --git a/src/frygon/vulkan/fgvk_physical_device.h b/src/frygon/vulkan/fgvk_physical_device.h new file mode 100644 index 00000000000..53ede1f495a --- /dev/null +++ b/src/frygon/vulkan/fgvk_physical_device.h @@ -0,0 +1,32 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#ifndef FGVK_PHYSICAL_DEVICE_H +#define FGVK_PHYSICAL_DEVICE_H 1 + +#include "fgvk_private.h" +#include "fgvk_instance.h" + +#include "fg_device_info.h" + +#include "vk_physical_device.h" +#include "vk_sync.h" + +struct fgcc_compiler; + +struct fgvk_physical_device { + struct vk_physical_device vk; + struct fg_device_info info; + + struct fgcc_compiler *fgcc; + + const struct vk_sync_type *sync_types[2]; +}; + +VK_DEFINE_HANDLE_CASTS(fgvk_physical_device, + vk.base, + VkPhysicalDevice, + VK_OBJECT_TYPE_PHYSICAL_DEVICE) + +#endif diff --git a/src/frygon/vulkan/fgvk_private.h b/src/frygon/vulkan/fgvk_private.h new file mode 100644 index 00000000000..4eafe7a616e --- /dev/null +++ b/src/frygon/vulkan/fgvk_private.h @@ -0,0 +1,19 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#ifndef FGVK_PRIVATE_H +#define FGVK_PRIVATE_H 1 + +#include <assert.h> + +#include "fgvk_entrypoints.h" + +#include "vk_alloc.h" +#include "vk_log.h" +#include "vk_util.h" + +VkResult fgvk_physical_device_enumerate(struct vk_instance *instance); +void fgvk_physical_device_destroy(struct vk_physical_device *pdevice); + +#endif diff --git a/src/frygon/vulkan/fgvk_queue.c b/src/frygon/vulkan/fgvk_queue.c new file mode 100644 index 00000000000..739de7f5bb4 --- /dev/null +++ b/src/frygon/vulkan/fgvk_queue.c @@ -0,0 +1,44 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#include "fgvk_queue.h" + +static VkResult +fgvk_queue_submit(struct vk_queue *vk_queue, + struct vk_queue_submit *submit) +{ + return VK_SUCCESS; +} + +VkResult +fgvk_queue_create(struct fgvk_device *dev, + const VkDeviceQueueCreateInfo *pCreateInfo, + uint32_t index_in_family) +{ + VkResult result; + struct fgvk_queue *queue = vk_zalloc(&dev->vk.alloc, sizeof(struct fgvk_queue), + 8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); + if (!queue) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + result = vk_queue_init(&queue->vk, &dev->vk, pCreateInfo, index_in_family); + if (result != VK_SUCCESS) + goto fail_alloc; + + queue->vk.driver_submit = fgvk_queue_submit; + + return VK_SUCCESS; + +fail_alloc: + vk_free(&dev->vk.alloc, queue); + + return result; +} + +void +fgvk_queue_destroy(struct fgvk_device *dev, struct fgvk_queue *queue) +{ + vk_queue_finish(&queue->vk); + vk_free(&dev->vk.alloc, queue); +} diff --git a/src/frygon/vulkan/fgvk_queue.h b/src/frygon/vulkan/fgvk_queue.h new file mode 100644 index 00000000000..1ba1f0054fc --- /dev/null +++ b/src/frygon/vulkan/fgvk_queue.h @@ -0,0 +1,22 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#ifndef FGVK_QUEUE_H +#define FGVK_QUEUE_H 1 + +#include "fgvk_device.h" + +#include "vk_queue.h" + +struct fgvk_queue { + struct vk_queue vk; +}; + +VkResult fgvk_queue_create(struct fgvk_device *dev, + const VkDeviceQueueCreateInfo *pCreateInfo, + uint32_t index_in_family); + +void fgvk_queue_destroy(struct fgvk_device *dev, struct fgvk_queue *queue); + +#endif diff --git a/src/frygon/vulkan/fgvk_shader.c b/src/frygon/vulkan/fgvk_shader.c new file mode 100644 index 00000000000..7cc871e0cbe --- /dev/null +++ b/src/frygon/vulkan/fgvk_shader.c @@ -0,0 +1,204 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#include "fgvk_shader.h" + +#include "fgvk_physical_device.h" +#include "fgvk_device.h" +#include "fgvk_cmd_buffer.h" + +static const nir_shader_compiler_options * +fgvk_get_nir_options(struct vk_physical_device *vk_pdev, + mesa_shader_stage stage, + UNUSED const struct vk_pipeline_robustness_state *rs) +{ + const struct fgvk_physical_device *pdev = + container_of(vk_pdev, struct fgvk_physical_device, vk); + return fgcc_nir_options(pdev->fgcc); +} + +static struct spirv_to_nir_options +fgvk_get_spirv_options(struct vk_physical_device *vk_pdev, + UNUSED mesa_shader_stage stage, + const struct vk_pipeline_robustness_state *rs) +{ + const struct fgvk_physical_device *pdev = + container_of(vk_pdev, struct fgvk_physical_device, vk); + + return (struct spirv_to_nir_options) {}; +} + +static void +fgvk_preprocess_nir(struct vk_physical_device *vk_pdev, + nir_shader *nir, + UNUSED const struct vk_pipeline_robustness_state *rs) +{ + const struct fgvk_physical_device *pdev = + container_of(vk_pdev, struct fgvk_physical_device, vk); + + fgcc_preprocess_nir(nir, pdev->fgcc); +} + +static void +fgvk_hash_state(struct vk_physical_device *device, + const struct vk_graphics_pipeline_state *state, + const struct vk_features *enabled_features, + VkShaderStageFlags stages, + blake3_hash blake3_out) +{ + // TODO need to figure out what state should get hashed into shaders + struct mesa_blake3 blake3_ctx; + _mesa_blake3_init(&blake3_ctx); + _mesa_blake3_final(&blake3_ctx, blake3_out); +} + +static const struct vk_shader_ops fgvk_shader_ops; + +static void +fgvk_shader_destroy(struct vk_device *vk_dev, + struct vk_shader *vk_shader, + const VkAllocationCallbacks* pAllocator) +{ + struct fgvk_device *dev = container_of(vk_dev, struct fgvk_device, vk); + struct fgvk_shader *shader = container_of(vk_shader, struct fgvk_shader, vk); + + vk_shader_free(&dev->vk, pAllocator, &shader->vk); +} + +static VkResult +fgvk_compile_shader(struct fgvk_device *dev, + struct vk_shader_compile_info *info, + const struct vk_graphics_pipeline_state *state, + const VkAllocationCallbacks* pAllocator, + struct vk_shader **shader_out) +{ + struct fgvk_shader *shader; + VkResult result = VK_SUCCESS; + + /* We consume the NIR, regardless of success or failure */ + nir_shader *nir = info->nir; + + shader = vk_shader_zalloc(&dev->vk, &fgvk_shader_ops, info->stage, + pAllocator, sizeof(*shader)); + + if (shader == NULL) { + ralloc_free(nir); + return vk_error(dev, VK_ERROR_OUT_OF_HOST_MEMORY); + } + + // TODO some shader compliation should happen here + + ralloc_free(nir); + if (result != VK_SUCCESS) { + fgvk_shader_destroy(&dev->vk, &shader->vk, pAllocator); + return result; + } + + *shader_out = &shader->vk; + + return VK_SUCCESS; +} + +static VkResult +fgvk_compile_shaders(struct vk_device *vk_dev, + uint32_t shader_count, + struct vk_shader_compile_info *infos, + const struct vk_graphics_pipeline_state *state, + const struct vk_features *enabled_features, + const VkAllocationCallbacks* pAllocator, + struct vk_shader **shaders_out) +{ + struct fgvk_device *dev = container_of(vk_dev, struct fgvk_device, vk); + + for (uint32_t i = 0; i < shader_count; i++) { + VkResult result = fgvk_compile_shader(dev, &infos[i], state, + pAllocator, &shaders_out[i]); + if (result != VK_SUCCESS) { + /* Clean up all the shaders before this point */ + for (uint32_t j = 0; j < i; j++) + fgvk_shader_destroy(&dev->vk, shaders_out[j], pAllocator); + + /* Clean up all the NIR after this point */ + for (uint32_t j = i + 1; j < shader_count; j++) + ralloc_free(infos[j].nir); + + /* Memset the output array */ + memset(shaders_out, 0, shader_count * sizeof(*shaders_out)); + + return result; + } + } + + return VK_SUCCESS; +} + +static bool +fgvk_shader_serialize(struct vk_device *vk_dev, + const struct vk_shader *vk_shader, + struct blob *blob) +{ + UNREACHABLE("TODO"); +} + +static VkResult +fgvk_deserialize_shader(struct vk_device *vk_dev, + struct blob_reader *blob, + uint32_t binary_version, + const VkAllocationCallbacks* pAllocator, + struct vk_shader **shader_out) +{ + UNREACHABLE("TODO"); +} + +static VkResult +fgvk_shader_get_executable_properties( + UNUSED struct vk_device *device, + const struct vk_shader *vk_shader, + uint32_t *executable_count, + VkPipelineExecutablePropertiesKHR *properties) +{ + UNREACHABLE("TODO"); +} + +static VkResult +fgvk_shader_get_executable_statistics( + UNUSED struct vk_device *device, + const struct vk_shader *vk_shader, + uint32_t executable_index, + uint32_t *statistic_count, + VkPipelineExecutableStatisticKHR *statistics) +{ + UNREACHABLE("TODO"); +} + +static VkResult +fgvk_shader_get_executable_internal_representations( + UNUSED struct vk_device *device, + const struct vk_shader *vk_shader, + uint32_t executable_index, + uint32_t *internal_representation_count, + VkPipelineExecutableInternalRepresentationKHR *internal_representations) +{ + UNREACHABLE("TODO"); +} + +static const struct vk_shader_ops fgvk_shader_ops = { + .destroy = fgvk_shader_destroy, + .serialize = fgvk_shader_serialize, + .get_executable_properties = fgvk_shader_get_executable_properties, + .get_executable_statistics = fgvk_shader_get_executable_statistics, + .get_executable_internal_representations = + fgvk_shader_get_executable_internal_representations, +}; + +const struct vk_device_shader_ops fgvk_device_shader_ops = { + .get_nir_options = fgvk_get_nir_options, + .get_spirv_options = fgvk_get_spirv_options, + .preprocess_nir = fgvk_preprocess_nir, + .hash_state = fgvk_hash_state, + .compile = fgvk_compile_shaders, + .deserialize = fgvk_deserialize_shader, + .cmd_set_dynamic_graphics_state = vk_cmd_set_dynamic_graphics_state, + .cmd_bind_shaders = fgvk_cmd_bind_shaders, +}; diff --git a/src/frygon/vulkan/fgvk_shader.h b/src/frygon/vulkan/fgvk_shader.h new file mode 100644 index 00000000000..5c57250827d --- /dev/null +++ b/src/frygon/vulkan/fgvk_shader.h @@ -0,0 +1,23 @@ +/* + * Copyright © 2025 Lucas Francisco Fryzek + * SPDX-License-Identifier: MIT + */ +#ifndef FGVK_SHADER_H +#define FGVK_SHADER_H 1 + +#include "fgvk_private.h" + +#include "vk_shader.h" + +#include "fgcc.h" + +struct fgvk_shader { + struct vk_shader vk; +}; + +VK_DEFINE_NONDISP_HANDLE_CASTS(fgvk_shader, vk.base, VkShaderEXT, + VK_OBJECT_TYPE_SHADER_EXT); + +extern const struct vk_device_shader_ops fgvk_device_shader_ops; + +#endif diff --git a/src/frygon/vulkan/meson.build b/src/frygon/vulkan/meson.build new file mode 100644 index 00000000000..44564edd2fc --- /dev/null +++ b/src/frygon/vulkan/meson.build @@ -0,0 +1,106 @@ +# Copyright © 2025 Lucas Francisco Fryzek +# SPDX-License-Identifier: MIT +fgvk_files = files( + 'fgvk_instance.c', + 'fgvk_physical_device.c', + 'fgvk_device.c', + 'fgvk_device_memory.c', + 'fgvk_buffer.c', + 'fgvk_format.c', + 'fgvk_image.c', + 'fgvk_image_view.c', + 'fgvk_cmd_buffer.c', + 'fgvk_cmd_clear.c', + 'fgvk_cmd_draw.c', + 'fgvk_cmd_copy.c', + 'fgvk_cmd_pool.c', + 'fgvk_shader.c', + 'fgvk_queue.c', +) + +fgvk_entrypoints = custom_target( + 'fgvk_entrypoints', + input : [vk_entrypoints_gen, vk_api_xml], + output : ['fgvk_entrypoints.h', 'fgvk_entrypoints.c'], + command : [ + prog_python, '@INPUT0@', '--xml', '@INPUT1@', '--proto', '--weak', + '--out-h', '@OUTPUT0@', '--out-c', '@OUTPUT1@', '--prefix', 'fgvk', + '--beta', with_vulkan_beta.to_string(), + ], + depend_files : vk_entrypoints_gen_depend_files, +) + +fgvk_deps = [ + idep_fgcc, + idep_nir, + idep_fg_headers, + idep_vulkan_runtime, + idep_vulkan_util, + idep_vulkan_wsi, + idep_vulkan_wsi_headers, +] + +fgvk_flags = [] + +libfgvk = static_library( + 'fgvk', + [ + fgvk_entrypoints, + fgvk_files + ], + include_directories : [ + inc_include, + inc_src, + ], + dependencies: fgvk_deps, + c_args : [no_override_init_args, fgvk_flags], + gnu_symbol_visibility : 'hidden', +) + +libvulkan_frygon = shared_library( + 'vulkan_frygon', + link_whole : [libfgvk], + link_args: [ld_args_build_id, ld_args_bsymbolic, ld_args_gc_sections], + gnu_symbol_visibility : 'hidden', + install : true, +) + +icd_file_name = libname_prefix + 'vulkan_frygon.' + libname_suffix + +frygon_icd = custom_target( + 'frygon_icd', + input : [vk_icd_gen, vk_api_xml], + output : 'frygon_icd.@0@.json'.format(host_machine.cpu()), + command : [ + prog_python, '@INPUT0@', + '--api-version', '1.0', '--xml', '@INPUT1@', + '--sizeof-pointer', sizeof_pointer, + '--lib-path', vulkan_icd_lib_path / icd_file_name, + '--out', '@OUTPUT@', + ], + build_by_default : true, + install_dir : with_vulkan_icd_dir, + install_tag : 'runtime', + install : true, +) + +_dev_icdname = 'frygon_devenv_icd.@0@.json'.format(host_machine.cpu()) +custom_target( + 'frygon_devenv_icd', + input : [vk_icd_gen, vk_api_xml], + output : _dev_icdname, + command : [ + prog_python, '@INPUT0@', + '--api-version', '1.4', '--xml', '@INPUT1@', + '--sizeof-pointer', sizeof_pointer, + '--lib-path', meson.current_build_dir() / icd_file_name, + '--out', '@OUTPUT@', + ], + build_by_default : true, +) + +devenv.append('VK_DRIVER_FILES', meson.current_build_dir() / _dev_icdname) +# Deprecated: replaced by VK_DRIVER_FILES above +devenv.append('VK_ICD_FILENAMES', meson.current_build_dir() / _dev_icdname) + + diff --git a/src/meson.build b/src/meson.build index f27dae33631..b2486b4e2fb 100644 --- a/src/meson.build +++ b/src/meson.build @@ -101,6 +101,9 @@ endif if with_any_nouveau subdir('nouveau') endif +if with_frygon_vk + subdir('frygon') +endif if with_gfxstream_vk dep_virtgpu_kumquat_ffi = null_dep if with_virtgpu_kumquat diff --git a/src/vulkan/runtime/vk_sync.c b/src/vulkan/runtime/vk_sync.c index e5eb1346f4d..9263cc6bdcd 100644 --- a/src/vulkan/runtime/vk_sync.c +++ b/src/vulkan/runtime/vk_sync.c @@ -666,7 +666,8 @@ vk_sync_signal_unwrap(struct vk_device *device, signal->signal_value = ++binary->next_point; } - assert(!vk_sync_type_is_dummy(signal->sync->type)); + // TODO uncomment when we have sync working in frygon + //assert(!vk_sync_type_is_dummy(signal->sync->type)); return VK_SUCCESS; } diff --git a/src/vulkan/runtime/vk_sync_dummy.c b/src/vulkan/runtime/vk_sync_dummy.c index 1cab72f491b..f27413d637c 100644 --- a/src/vulkan/runtime/vk_sync_dummy.c +++ b/src/vulkan/runtime/vk_sync_dummy.c @@ -46,14 +46,23 @@ vk_sync_dummy_wait_many(struct vk_device *device, return VK_SUCCESS; } +static VkResult +vk_sync_dummy_reset(struct vk_device *device, + struct vk_sync *sync) +{ + return VK_SUCCESS; +} + const struct vk_sync_type vk_sync_dummy_type = { .size = sizeof(struct vk_sync), .features = VK_SYNC_FEATURE_BINARY | VK_SYNC_FEATURE_GPU_WAIT | VK_SYNC_FEATURE_CPU_WAIT | + VK_SYNC_FEATURE_CPU_RESET | VK_SYNC_FEATURE_WAIT_ANY | VK_SYNC_FEATURE_WAIT_PENDING, .init = vk_sync_dummy_init, .finish = vk_sync_dummy_finish, + .reset = vk_sync_dummy_reset, .wait_many = vk_sync_dummy_wait_many, }; |