aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwildcard <wildcard@eden-emu.dev>2026-02-04 19:15:10 +0100
committercrueter <crueter@eden-emu.dev>2026-02-04 19:15:10 +0100
commit48ba1f3f241123ca4950fed5965fe78bb804849c (patch)
tree738184813f82851bbb7729b7dfbb3534d3935358
parentd59fcf01bf9a7b3779e537adbbf5be483db8d381 (diff)
[vk, cmake] Bump minimum VulkanTools to 1.4.317 and add UnifiedImageLayouts (#3318)
It seems too easy, the specification does not state anything more to be done for it towork. Requires performance testing on android. Co-authored-by: DraVee <dravee@eden-emu.dev> Co-authored-by: crueter <crueter@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3318 Reviewed-by: DraVee <dravee@eden-emu.dev> Reviewed-by: CamilleLaVey <camillelavey99@gmail.com> Co-authored-by: wildcard <wildcard@eden-emu.dev> Co-committed-by: wildcard <wildcard@eden-emu.dev>
-rw-r--r--CMakeModules/CPMUtil.cmake315
-rw-r--r--docs/CPMUtil/AddDependentPackage.md41
-rw-r--r--docs/CPMUtil/README.md4
-rw-r--r--externals/CMakeLists.txt8
-rw-r--r--externals/cpmfile.json2
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp4
-rw-r--r--src/video_core/vulkan_common/vulkan_device.h4
-rwxr-xr-xtools/cpm/common.sh2
8 files changed, 246 insertions, 134 deletions
diff --git a/CMakeModules/CPMUtil.cmake b/CMakeModules/CPMUtil.cmake
index 834e07e665..4c9b645d16 100644
--- a/CMakeModules/CPMUtil.cmake
+++ b/CMakeModules/CPMUtil.cmake
@@ -41,6 +41,11 @@ function(cpm_utils_message level name message)
message(${level} "[CPMUtil] ${name}: ${message}")
endfunction()
+# propagate a variable to parent scope
+macro(Propagate var)
+ set(${var} ${${var}} PARENT_SCOPE)
+endmacro()
+
function(array_to_list array length out)
math(EXPR range "${length} - 1")
@@ -72,6 +77,159 @@ function(get_json_element object out member default)
set("${out}" "${outvar}" PARENT_SCOPE)
endfunction()
+# Determine whether or not a package has a viable system candidate.
+function(SystemPackageViable JSON_NAME)
+ string(JSON object GET "${CPMFILE_CONTENT}" "${JSON_NAME}")
+
+ parse_object(${object})
+
+ string(REPLACE " " ";" find_args "${find_args}")
+ find_package(${package} ${version} ${find_args} QUIET NO_POLICY_SCOPE)
+
+ set(${pkg}_VIABLE ${${package}_FOUND} PARENT_SCOPE)
+ set(${pkg}_PACKAGE ${package} PARENT_SCOPE)
+endfunction()
+
+# Add several packages such that if one is bundled,
+# all the rest must also be bundled.
+function(AddDependentPackages)
+ set(_some_system OFF)
+ set(_some_bundled OFF)
+
+ foreach(pkg ${ARGN})
+ SystemPackageViable(${pkg})
+
+ if (${pkg}_VIABLE)
+ set(_some_system ON)
+ list(APPEND _system_pkgs ${${pkg}_PACKAGE})
+ else()
+ set(_some_bundled ON)
+ list(APPEND _bundled_pkgs ${${pkg}_PACKAGE})
+ endif()
+ endforeach()
+
+ if (_some_system AND _some_bundled)
+ foreach(pkg ${ARGN})
+ list(APPEND package_names ${${pkg}_PACKAGE})
+ endforeach()
+
+ string(REPLACE ";" ", " package_names "${package_names}")
+ string(REPLACE ";" ", " bundled_names "${_bundled_pkgs}")
+ foreach(sys ${_system_pkgs})
+ list(APPEND system_names ${sys}_FORCE_BUNDLED)
+ endforeach()
+
+ string(REPLACE ";" ", " system_names "${system_names}")
+
+ message(FATAL_ERROR "Partial dependency installation detected "
+ "for the following packages:\n${package_names}\n"
+ "You can solve this in one of two ways:\n"
+ "1. Install the following packages to your system if available:"
+ "\n\t${bundled_names}\n"
+ "2. Set the following variables to ON:"
+ "\n\t${system_names}\n"
+ "This may also be caused by a version mismatch, "
+ "such as one package being newer than the other.")
+ endif()
+
+ foreach(pkg ${ARGN})
+ AddJsonPackage(${pkg})
+ endforeach()
+endfunction()
+
+# json util
+macro(parse_object object)
+ get_json_element("${object}" package package ${JSON_NAME})
+ get_json_element("${object}" repo repo "")
+ get_json_element("${object}" ci ci OFF)
+ get_json_element("${object}" version version "")
+
+ if(ci)
+ get_json_element("${object}" name name "${JSON_NAME}")
+ get_json_element("${object}" extension extension "tar.zst")
+ get_json_element("${object}" min_version min_version "")
+ get_json_element("${object}" raw_disabled disabled_platforms "")
+
+ if(raw_disabled)
+ array_to_list("${raw_disabled}"
+ ${raw_disabled_LENGTH} disabled_platforms)
+ else()
+ set(disabled_platforms "")
+ endif()
+ else()
+ get_json_element("${object}" hash hash "")
+ get_json_element("${object}" hash_suffix hash_suffix "")
+ get_json_element("${object}" sha sha "")
+ get_json_element("${object}" url url "")
+ get_json_element("${object}" key key "")
+ get_json_element("${object}" tag tag "")
+ get_json_element("${object}" artifact artifact "")
+ get_json_element("${object}" git_version git_version "")
+ get_json_element("${object}" git_host git_host "")
+ get_json_element("${object}" source_subdir source_subdir "")
+ get_json_element("${object}" bundled bundled "unset")
+ get_json_element("${object}" find_args find_args "")
+ get_json_element("${object}" raw_patches patches "")
+
+ # okay here comes the fun part: REPLACEMENTS!
+ # first: tag gets %VERSION% replaced if applicable,
+ # with either git_version (preferred) or version
+ # second: artifact gets %VERSION% and %TAG% replaced
+ # accordingly (same rules for VERSION)
+
+ if(git_version)
+ set(version_replace ${git_version})
+ else()
+ set(version_replace ${version})
+ endif()
+
+ # TODO(crueter): fmt module for cmake
+ if(tag)
+ string(REPLACE "%VERSION%" "${version_replace}" tag ${tag})
+ endif()
+
+ if(artifact)
+ string(REPLACE "%VERSION%" "${version_replace}"
+ artifact ${artifact})
+ string(REPLACE "%TAG%" "${tag}" artifact ${artifact})
+ endif()
+
+ # format patchdir
+ if(raw_patches)
+ math(EXPR range "${raw_patches_LENGTH} - 1")
+
+ foreach(IDX RANGE ${range})
+ string(JSON _patch GET "${raw_patches}" "${IDX}")
+
+ set(full_patch
+ "${PROJECT_SOURCE_DIR}/.patch/${JSON_NAME}/${_patch}")
+ if(NOT EXISTS ${full_patch})
+ cpm_utils_message(FATAL_ERROR ${JSON_NAME}
+ "specifies patch ${full_patch} which does not exist")
+ endif()
+
+ list(APPEND patches "${full_patch}")
+ endforeach()
+ endif()
+ # end format patchdir
+
+ # options
+ get_json_element("${object}" raw_options options "")
+
+ if(raw_options)
+ array_to_list("${raw_options}" ${raw_options_LENGTH} options)
+ endif()
+
+ set(options ${options} ${JSON_OPTIONS})
+ # end options
+
+ # system/bundled
+ if(bundled STREQUAL "unset" AND DEFINED JSON_BUNDLED_PACKAGE)
+ set(bundled ${JSON_BUNDLED_PACKAGE})
+ endif()
+ endif()
+endmacro()
+
# The preferred usage
function(AddJsonPackage)
set(oneValueArgs
@@ -80,7 +238,8 @@ function(AddJsonPackage)
# these are overrides that can be generated at runtime,
# so can be defined separately from the json
DOWNLOAD_ONLY
- BUNDLED_PACKAGE)
+ BUNDLED_PACKAGE
+ FORCE_BUNDLED_PACKAGE)
set(multiValueArgs OPTIONS)
@@ -111,24 +270,9 @@ function(AddJsonPackage)
cpm_utils_message(FATAL_ERROR ${JSON_NAME} "Not found in cpmfile")
endif()
- get_json_element("${object}" package package ${JSON_NAME})
- get_json_element("${object}" repo repo "")
- get_json_element("${object}" ci ci OFF)
- get_json_element("${object}" version version "")
+ parse_object(${object})
if(ci)
- get_json_element("${object}" name name "${JSON_NAME}")
- get_json_element("${object}" extension extension "tar.zst")
- get_json_element("${object}" min_version min_version "")
- get_json_element("${object}" raw_disabled disabled_platforms "")
-
- if(raw_disabled)
- array_to_list("${raw_disabled}"
- ${raw_disabled_LENGTH} disabled_platforms)
- else()
- set(disabled_platforms "")
- endif()
-
AddCIPackage(
VERSION ${version}
NAME ${name}
@@ -138,116 +282,38 @@ function(AddJsonPackage)
MIN_VERSION ${min_version}
DISABLED_PLATFORMS ${disabled_platforms})
- # pass stuff to parent scope
- set(${package}_ADDED "${${package}_ADDED}"
- PARENT_SCOPE)
- set(${package}_SOURCE_DIR "${${package}_SOURCE_DIR}"
- PARENT_SCOPE)
- set(${package}_BINARY_DIR "${${package}_BINARY_DIR}"
- PARENT_SCOPE)
-
- return()
- endif()
-
- get_json_element("${object}" hash hash "")
- get_json_element("${object}" hash_suffix hash_suffix "")
- get_json_element("${object}" sha sha "")
- get_json_element("${object}" url url "")
- get_json_element("${object}" key key "")
- get_json_element("${object}" tag tag "")
- get_json_element("${object}" artifact artifact "")
- get_json_element("${object}" git_version git_version "")
- get_json_element("${object}" git_host git_host "")
- get_json_element("${object}" source_subdir source_subdir "")
- get_json_element("${object}" bundled bundled "unset")
- get_json_element("${object}" find_args find_args "")
- get_json_element("${object}" raw_patches patches "")
-
- # okay here comes the fun part: REPLACEMENTS!
- # first: tag gets %VERSION% replaced if applicable,
- # with either git_version (preferred) or version
- # second: artifact gets %VERSION% and %TAG% replaced
- # accordingly (same rules for VERSION)
-
- if(git_version)
- set(version_replace ${git_version})
else()
- set(version_replace ${version})
- endif()
-
- # TODO(crueter): fmt module for cmake
- if(tag)
- string(REPLACE "%VERSION%" "${version_replace}" tag ${tag})
- endif()
-
- if(artifact)
- string(REPLACE "%VERSION%" "${version_replace}" artifact ${artifact})
- string(REPLACE "%TAG%" "${tag}" artifact ${artifact})
- endif()
-
- # format patchdir
- if(raw_patches)
- math(EXPR range "${raw_patches_LENGTH} - 1")
-
- foreach(IDX RANGE ${range})
- string(JSON _patch GET "${raw_patches}" "${IDX}")
-
- set(full_patch
- "${PROJECT_SOURCE_DIR}/.patch/${JSON_NAME}/${_patch}")
- if(NOT EXISTS ${full_patch})
- cpm_utils_message(FATAL_ERROR ${JSON_NAME}
- "specifies patch ${full_patch} which does not exist")
- endif()
-
- list(APPEND patches "${full_patch}")
- endforeach()
- endif()
- # end format patchdir
-
- # options
- get_json_element("${object}" raw_options options "")
-
- if(raw_options)
- array_to_list("${raw_options}" ${raw_options_LENGTH} options)
- endif()
-
- set(options ${options} ${JSON_OPTIONS})
- # end options
+ if (NOT DEFINED JSON_FORCE_BUNDLED_PACKAGE)
+ set(JSON_FORCE_BUNDLED_PACKAGE OFF)
+ endif()
- # system/bundled
- if(bundled STREQUAL "unset" AND DEFINED JSON_BUNDLED_PACKAGE)
- set(bundled ${JSON_BUNDLED_PACKAGE})
+ AddPackage(
+ NAME "${package}"
+ VERSION "${version}"
+ URL "${url}"
+ HASH "${hash}"
+ HASH_SUFFIX "${hash_suffix}"
+ SHA "${sha}"
+ REPO "${repo}"
+ KEY "${key}"
+ PATCHES "${patches}"
+ OPTIONS "${options}"
+ FIND_PACKAGE_ARGUMENTS "${find_args}"
+ BUNDLED_PACKAGE "${bundled}"
+ FORCE_BUNDLED_PACKAGE "${JSON_FORCE_BUNDLED_PACKAGE}"
+ SOURCE_SUBDIR "${source_subdir}"
+
+ GIT_VERSION ${git_version}
+ GIT_HOST ${git_host}
+
+ ARTIFACT ${artifact}
+ TAG ${tag})
endif()
- AddPackage(
- NAME "${package}"
- VERSION "${version}"
- URL "${url}"
- HASH "${hash}"
- HASH_SUFFIX "${hash_suffix}"
- SHA "${sha}"
- REPO "${repo}"
- KEY "${key}"
- PATCHES "${patches}"
- OPTIONS "${options}"
- FIND_PACKAGE_ARGUMENTS "${find_args}"
- BUNDLED_PACKAGE "${bundled}"
- SOURCE_SUBDIR "${source_subdir}"
-
- GIT_VERSION ${git_version}
- GIT_HOST ${git_host}
-
- ARTIFACT ${artifact}
- TAG ${tag})
-
# pass stuff to parent scope
- set(${package}_ADDED "${${package}_ADDED}"
- PARENT_SCOPE)
- set(${package}_SOURCE_DIR "${${package}_SOURCE_DIR}"
- PARENT_SCOPE)
- set(${package}_BINARY_DIR "${${package}_BINARY_DIR}"
- PARENT_SCOPE)
-
+ Propagate(${package}_ADDED)
+ Propagate(${package}_SOURCE_DIR)
+ Propagate(${package}_BINARY_DIR)
endfunction()
function(AddPackage)
@@ -343,7 +409,7 @@ function(AddPackage)
if(DEFINED PKG_ARGS_ARTIFACT)
set(pkg_url
- ${pkg_git_url}/releases/download/${PKG_ARGS_TAG}/${PKG_ARGS_ARTIFACT})
+ "${pkg_git_url}/releases/download/${PKG_ARGS_TAG}/${PKG_ARGS_ARTIFACT}")
else()
set(pkg_url
${pkg_git_url}/archive/refs/tags/${PKG_ARGS_TAG}.tar.gz)
@@ -625,7 +691,8 @@ function(AddCIPackage)
endif()
if (DEFINED pkgname AND NOT "${pkgname}" IN_LIST DISABLED_PLATFORMS)
- set(ARTIFACT "${ARTIFACT_NAME}-${pkgname}-${ARTIFACT_VERSION}.${ARTIFACT_EXT}")
+ set(ARTIFACT
+ "${ARTIFACT_NAME}-${pkgname}-${ARTIFACT_VERSION}.${ARTIFACT_EXT}")
AddPackage(
NAME ${ARTIFACT_PACKAGE}
diff --git a/docs/CPMUtil/AddDependentPackage.md b/docs/CPMUtil/AddDependentPackage.md
new file mode 100644
index 0000000000..bb6651e4b8
--- /dev/null
+++ b/docs/CPMUtil/AddDependentPackage.md
@@ -0,0 +1,41 @@
+# AddDependentPackage
+
+Use `AddDependentPackage` when you have multiple packages that are required to all be from the system, OR bundled. This is useful in cases where e.g. versions must absolutely match.
+
+## Versioning
+
+Versioning must be handled by the package itself.
+
+## Examples
+
+### Vulkan
+
+`cpmfile.json`
+
+```json
+{
+ "vulkan-headers": {
+ "repo": "KhronosGroup/Vulkan-Headers",
+ "package": "VulkanHeaders",
+ "version": "1.4.317",
+ "hash": "26e0ad8fa34ab65a91ca62ddc54cc4410d209a94f64f2817dcdb8061dc621539a4262eab6387e9b9aa421db3dbf2cf8e2a4b041b696d0d03746bae1f25191272",
+ "git_version": "1.4.342",
+ "tag": "v%VERSION%"
+ },
+ "vulkan-utility-libraries": {
+ "repo": "KhronosGroup/Vulkan-Utility-Libraries",
+ "package": "VulkanUtilityLibraries",
+ "hash": "8147370f964fd82c315d6bb89adeda30186098427bf3efaa641d36282d42a263f31e96e4586bfd7ae0410ff015379c19aa4512ba160630444d3d8553afd1ec14",
+ "git_version": "1.4.342",
+ "tag": "v%VERSION%"
+ }
+}
+```
+
+`CMakeLists.txt`:
+
+```cmake
+AddDependentPackages(vulkan-headers vulkan-utility-libraries)
+```
+
+If Vulkan Headers are installed, but NOT Vulkan Utility Libraries, then CPMUtil will throw an error.
diff --git a/docs/CPMUtil/README.md b/docs/CPMUtil/README.md
index ff19cb4f76..dbc5f0922a 100644
--- a/docs/CPMUtil/README.md
+++ b/docs/CPMUtil/README.md
@@ -31,6 +31,10 @@ The core of CPMUtil is the [`AddPackage`](./AddPackage.md) function. [`AddPackag
[`AddJsonPackage`](./AddJsonPackage.md) is the recommended method of usage for CPMUtil.
+## AddDependentPackage
+
+[`AddDependentPackage`](./AddDependentPackage.md) allows you to add multiple packages such that all of them must be from the system OR bundled.
+
## AddQt
[`AddQt`](./AddQt.md) adds a specific version of Qt to your project.
diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt
index b57c52d151..980d8f668d 100644
--- a/externals/CMakeLists.txt
+++ b/externals/CMakeLists.txt
@@ -84,13 +84,7 @@ endif()
AddJsonPackage(mcl)
# Vulkan stuff
-AddJsonPackage(vulkan-headers)
-AddJsonPackage(vulkan-utility-libraries)
-
-# small hack
-if (NOT VulkanUtilityLibraries_ADDED)
- find_package(VulkanHeaders 1.3.274 REQUIRED)
-endif()
+AddDependentPackages(vulkan-headers vulkan-utility-libraries)
# frozen
AddJsonPackage(frozen)
diff --git a/externals/cpmfile.json b/externals/cpmfile.json
index 2f900e4ebe..7c04e389e2 100644
--- a/externals/cpmfile.json
+++ b/externals/cpmfile.json
@@ -276,7 +276,7 @@
"vulkan-headers": {
"repo": "KhronosGroup/Vulkan-Headers",
"package": "VulkanHeaders",
- "version": "1.3.274",
+ "version": "1.4.317",
"hash": "26e0ad8fa34ab65a91ca62ddc54cc4410d209a94f64f2817dcdb8061dc621539a4262eab6387e9b9aa421db3dbf2cf8e2a4b041b696d0d03746bae1f25191272",
"git_version": "1.4.342",
"tag": "v%VERSION%"
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index 0b3aea6d2e..ab4e5b1b65 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -1230,6 +1230,10 @@ void Device::RemoveUnsuitableExtensions() {
}
RemoveExtensionFeatureIfUnsuitable(extensions.custom_border_color, features.custom_border_color,
VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME);
+ // VK_KHR_unified_image_layouts
+ extensions.unified_image_layouts = features.unified_image_layouts.unifiedImageLayouts;
+ RemoveExtensionFeatureIfUnsuitable(extensions.unified_image_layouts, features.unified_image_layouts,
+ VK_KHR_UNIFIED_IMAGE_LAYOUTS_EXTENSION_NAME);
// VK_EXT_depth_bias_control
extensions.depth_bias_control =
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h
index 744b5f827e..73a232ddee 100644
--- a/src/video_core/vulkan_common/vulkan_device.h
+++ b/src/video_core/vulkan_common/vulkan_device.h
@@ -70,7 +70,9 @@ VK_DEFINE_HANDLE(VmaAllocator)
FEATURE(KHR, PipelineExecutableProperties, PIPELINE_EXECUTABLE_PROPERTIES, \
pipeline_executable_properties) \
FEATURE(KHR, WorkgroupMemoryExplicitLayout, WORKGROUP_MEMORY_EXPLICIT_LAYOUT, \
- workgroup_memory_explicit_layout)
+ workgroup_memory_explicit_layout) \
+ FEATURE(KHR, UnifiedImageLayouts, UNIFIED_IMAGE_LAYOUTS, unified_image_layouts)
+
// Define miscellaneous extensions which may be used by the implementation here.
#define FOR_EACH_VK_EXTENSION(EXTENSION) \
diff --git a/tools/cpm/common.sh b/tools/cpm/common.sh
index 2dc3a477d4..97a2fed003 100755
--- a/tools/cpm/common.sh
+++ b/tools/cpm/common.sh
@@ -23,7 +23,7 @@ MAXDEPTH=3
# For your project you'll want to change this to define what dirs you have cpmfiles in
# Remember to account for the MAXDEPTH variable!
# Adding ./ before each will help to remove duplicates
-CPMFILES=$(find . src -maxdepth "$MAXDEPTH" -name cpmfile.json | sort | uniq)
+CPMFILES=$(find . -maxdepth "$MAXDEPTH" -name cpmfile.json | sort | uniq)
# shellcheck disable=SC2016
PACKAGES=$(echo "$CPMFILES" | xargs jq -s 'reduce .[] as $item ({}; . * $item)')