Compare commits
18 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
04714c26d7 | ||
|
|
e57c9be21f | ||
|
|
930b10878a | ||
|
|
d8a9618a62 | ||
|
|
0ca23681fc | ||
|
|
d72afe2ac0 | ||
|
|
f89e096617 | ||
|
|
d28e0f51fa | ||
|
|
0079a09305 | ||
|
|
7763f62f93 | ||
|
|
29c1772097 | ||
|
|
1f4b5f7a73 | ||
|
|
a21690f3f7 | ||
|
|
6a02f655aa | ||
|
|
c272931f23 | ||
|
|
ad7e5c84d4 | ||
|
|
a4fcd02ee7 | ||
|
|
da4640a016 |
@@ -6,7 +6,16 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/find-module
|
||||
include(DownloadExternals)
|
||||
include(CMakeDependentOption)
|
||||
|
||||
project(yuzu)
|
||||
if (APPLE)
|
||||
project(yuzu C CXX ASM)
|
||||
option(OSX_USE_DEFAULT_SEARCH_PATH "Don't prioritize system library paths" OFF)
|
||||
else()
|
||||
project(yuzu)
|
||||
endif()
|
||||
|
||||
# Pin build to minimum supported OSX version.
|
||||
# 10.15 supports metal 3 so has additional unsupported MVK extensions
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.14.0" CACHE STRING "")
|
||||
|
||||
# Set bundled sdl2/qt as dependent options.
|
||||
# OFF by default, but if ENABLE_SDL2 and MSVC are true then ON
|
||||
@@ -414,6 +423,30 @@ if (APPLE)
|
||||
# Umbrella framework for everything GUI-related
|
||||
find_library(COCOA_LIBRARY Cocoa)
|
||||
set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY})
|
||||
if(NOT OSX_USE_DEFAULT_SEARCH_PATH)
|
||||
# Hack up the path to prioritize the path to built-in OS libraries to
|
||||
# increase the chance of not depending on a bunch of copies of them
|
||||
# installed by MacPorts, Fink, Homebrew, etc, and ending up copying
|
||||
# them into the bundle. Since we optionally depend on libraries which
|
||||
# are not part of OS X (ffmpeg, etc.), however, don't remove the default
|
||||
# path entirely as was done in a previous version of this file. This is
|
||||
# still kinda evil, since it defeats the user's path settings...
|
||||
# See http://www.cmake.org/cmake/help/v3.0/command/find_program.html
|
||||
list(APPEND CMAKE_PREFIX_PATH "/usr")
|
||||
endif()
|
||||
|
||||
# Linker flags.
|
||||
# Drop unreachable code and data.
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-dead_strip,-dead_strip_dylibs")
|
||||
|
||||
find_library(APPKIT_LIBRARY AppKit)
|
||||
find_library(APPSERV_LIBRARY ApplicationServices)
|
||||
find_library(CARBON_LIBRARY Carbon)
|
||||
find_library(COCOA_LIBRARY Cocoa)
|
||||
find_library(COREFOUNDATION_LIBRARY CoreFoundation)
|
||||
find_library(CORESERV_LIBRARY CoreServices)
|
||||
find_library(FOUNDATION_LIBRARY Foundation)
|
||||
find_library(IOK_LIBRARY IOKit)
|
||||
elseif (WIN32)
|
||||
# WSAPoll and SHGetKnownFolderPath (AppData/Roaming) didn't exist before WinNT 6.x (Vista)
|
||||
add_definitions(-D_WIN32_WINNT=0x0600 -DWINVER=0x0600)
|
||||
|
||||
46
CMakeModules/PostprocessBundle.cmake
Normal file
46
CMakeModules/PostprocessBundle.cmake
Normal file
@@ -0,0 +1,46 @@
|
||||
# This module can be used in two different ways.
|
||||
#
|
||||
# When invoked as `cmake -P PostprocessBundle.cmake`, it fixes up an
|
||||
# application folder to be standalone. It bundles all required libraries from
|
||||
# the system and fixes up library IDs. Any additional shared libraries, like
|
||||
# plugins, that are found under Contents/MacOS/ will be made standalone as well.
|
||||
#
|
||||
# When called with `include(PostprocessBundle)`, it defines a helper
|
||||
# function `postprocess_bundle` that sets up the command form of the
|
||||
# module as a post-build step.
|
||||
|
||||
if(CMAKE_GENERATOR)
|
||||
# Being called as include(PostprocessBundle), so define a helper function.
|
||||
set(_POSTPROCESS_BUNDLE_MODULE_LOCATION "${CMAKE_CURRENT_LIST_FILE}")
|
||||
function(postprocess_bundle target)
|
||||
add_custom_command(TARGET ${target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -DBUNDLE_PATH="$<TARGET_FILE_DIR:${target}>/../.."
|
||||
-P "${_POSTPROCESS_BUNDLE_MODULE_LOCATION}"
|
||||
)
|
||||
endfunction()
|
||||
return()
|
||||
endif()
|
||||
|
||||
get_filename_component(BUNDLE_PATH "${BUNDLE_PATH}" REALPATH)
|
||||
message(STATUS "Fixing up application bundle: ${BUNDLE_PATH}")
|
||||
|
||||
# Make sure to fix up any additional shared libraries (like plugins) that are
|
||||
# needed.
|
||||
file(GLOB_RECURSE extra_libs "${BUNDLE_PATH}/Contents/MacOS/*.dylib")
|
||||
|
||||
# BundleUtilities doesn't support DYLD_FALLBACK_LIBRARY_PATH behavior, which
|
||||
# makes it sometimes break on libraries that do weird things with @rpath. Specify
|
||||
# equivalent search directories until https://gitlab.kitware.com/cmake/cmake/issues/16625
|
||||
# is fixed and in our minimum CMake version.
|
||||
set(extra_dirs "/usr/local/lib" "/lib" "/usr/lib")
|
||||
|
||||
# BundleUtilities is overly verbose, so disable most of its messages
|
||||
function(message)
|
||||
if(NOT ARGV MATCHES "^STATUS;")
|
||||
_message(${ARGV})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
include(BundleUtilities)
|
||||
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
||||
fixup_bundle("${BUNDLE_PATH}" "${extra_libs}" "${extra_dirs}")
|
||||
7
externals/MoltenVK/Resources/vulkan/icd.d/MoltenVK_icd.json
vendored
Normal file
7
externals/MoltenVK/Resources/vulkan/icd.d/MoltenVK_icd.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"file_format_version": "1.0.0",
|
||||
"ICD": {
|
||||
"library_path": "../../../lib/libMoltenVK.dylib",
|
||||
"api_version": "1.0.0"
|
||||
}
|
||||
}
|
||||
468
externals/MoltenVK/include/MoltenVK/mvk_datatypes.h
vendored
Normal file
468
externals/MoltenVK/include/MoltenVK/mvk_datatypes.h
vendored
Normal file
@@ -0,0 +1,468 @@
|
||||
/*
|
||||
* mvk_datatypes.h
|
||||
*
|
||||
* Copyright (c) 2015-2020 The Brenwill Workshop Ltd. (http://www.brenwill.com)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This file contains functions for converting between Vulkan and Metal data types.
|
||||
*
|
||||
* The functions here are used internally by MoltenVK, and are exposed here
|
||||
* as a convenience for use elsewhere within applications using MoltenVK.
|
||||
*/
|
||||
|
||||
#ifndef __mvkDataTypes_h_
|
||||
#define __mvkDataTypes_h_ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#include "mvk_vulkan.h"
|
||||
|
||||
#import <Metal/Metal.h>
|
||||
#import <CoreGraphics/CoreGraphics.h>
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Image properties
|
||||
|
||||
#pragma mark Texture formats
|
||||
|
||||
/** Enumerates the data type of a format. */
|
||||
typedef enum {
|
||||
kMVKFormatNone, /**< Format type is unknown. */
|
||||
kMVKFormatColorHalf, /**< A 16-bit floating point color. */
|
||||
kMVKFormatColorFloat, /**< A 32-bit floating point color. */
|
||||
kMVKFormatColorInt8, /**< A signed 8-bit integer color. */
|
||||
kMVKFormatColorUInt8, /**< An unsigned 8-bit integer color. */
|
||||
kMVKFormatColorInt16, /**< A signed 16-bit integer color. */
|
||||
kMVKFormatColorUInt16, /**< An unsigned 16-bit integer color. */
|
||||
kMVKFormatColorInt32, /**< A signed 32-bit integer color. */
|
||||
kMVKFormatColorUInt32, /**< An unsigned 32-bit integer color. */
|
||||
kMVKFormatDepthStencil, /**< A depth and stencil value. */
|
||||
kMVKFormatCompressed, /**< A block-compressed color. */
|
||||
} MVKFormatType;
|
||||
|
||||
/** Returns whether the VkFormat is supported by this implementation. */
|
||||
bool mvkVkFormatIsSupported(VkFormat vkFormat);
|
||||
|
||||
/** Returns whether the MTLPixelFormat is supported by this implementation. */
|
||||
bool mvkMTLPixelFormatIsSupported(MTLPixelFormat mtlFormat);
|
||||
|
||||
/** Returns the format type corresponding to the specified Vulkan VkFormat, */
|
||||
MVKFormatType mvkFormatTypeFromVkFormat(VkFormat vkFormat);
|
||||
|
||||
/** Returns the format type corresponding to the specified Metal MTLPixelFormat, */
|
||||
MVKFormatType mvkFormatTypeFromMTLPixelFormat(MTLPixelFormat mtlFormat);
|
||||
|
||||
/**
|
||||
* Returns the Metal MTLPixelFormat corresponding to the specified Vulkan VkFormat,
|
||||
* or returns MTLPixelFormatInvalid if no corresponding MTLPixelFormat exists.
|
||||
*
|
||||
* Not all MTLPixelFormats returned by this function are supported by all GPU's,
|
||||
* and, internally, MoltenVK may substitute and use a different MTLPixelFormat than
|
||||
* is returned by this function for a particular Vulkan VkFormat value.
|
||||
*
|
||||
* Not all macOS GPU's support the MTLPixelFormatDepth24Unorm_Stencil8 pixel format.
|
||||
* Even though this function will return that value when passed the corresponding
|
||||
* VkFormat value, internally, MoltenVK will use the MTLPixelFormatDepth32Float_Stencil8
|
||||
* instead when a GPU does not support the MTLPixelFormatDepth24Unorm_Stencil8 pixel format.
|
||||
* On an macOS device that has more than one GPU, one of the GPU's may support the
|
||||
* MTLPixelFormatDepth24Unorm_Stencil8 pixel format while another may not.
|
||||
*/
|
||||
MTLPixelFormat mvkMTLPixelFormatFromVkFormat(VkFormat vkFormat);
|
||||
|
||||
/**
|
||||
* Returns the Vulkan VkFormat corresponding to the specified Metal MTLPixelFormat,
|
||||
* or returns VK_FORMAT_UNDEFINED if no corresponding VkFormat exists.
|
||||
*/
|
||||
VkFormat mvkVkFormatFromMTLPixelFormat(MTLPixelFormat mtlFormat);
|
||||
|
||||
/**
|
||||
* Returns the size, in bytes, of a texel block of the specified Vulkan format.
|
||||
* For uncompressed formats, the returned value corresponds to the size in bytes of a single texel.
|
||||
*/
|
||||
uint32_t mvkVkFormatBytesPerBlock(VkFormat vkFormat);
|
||||
|
||||
/**
|
||||
* Returns the size, in bytes, of a texel block of the specified Metal format.
|
||||
* For uncompressed formats, the returned value corresponds to the size in bytes of a single texel.
|
||||
*/
|
||||
uint32_t mvkMTLPixelFormatBytesPerBlock(MTLPixelFormat mtlFormat);
|
||||
|
||||
/**
|
||||
* Returns the size of the compression block, measured in texels for a Vulkan format.
|
||||
* The returned value will be {1, 1} for non-compressed formats.
|
||||
*/
|
||||
VkExtent2D mvkVkFormatBlockTexelSize(VkFormat vkFormat);
|
||||
|
||||
/**
|
||||
* Returns the size of the compression block, measured in texels for a Metal format.
|
||||
* The returned value will be {1, 1} for non-compressed formats.
|
||||
*/
|
||||
VkExtent2D mvkMTLPixelFormatBlockTexelSize(MTLPixelFormat mtlFormat);
|
||||
|
||||
/**
|
||||
* Returns the size, in bytes, of a texel of the specified Vulkan format.
|
||||
* The returned value may be fractional for certain compressed formats.
|
||||
*/
|
||||
float mvkVkFormatBytesPerTexel(VkFormat vkFormat);
|
||||
|
||||
/**
|
||||
* Returns the size, in bytes, of a texel of the specified Metal format.
|
||||
* The returned value may be fractional for certain compressed formats.
|
||||
*/
|
||||
float mvkMTLPixelFormatBytesPerTexel(MTLPixelFormat mtlFormat);
|
||||
|
||||
/**
|
||||
* Returns the size, in bytes, of a row of texels of the specified Vulkan format.
|
||||
*
|
||||
* For compressed formats, this takes into consideration the compression block size,
|
||||
* and texelsPerRow should specify the width in texels, not blocks. The result is rounded
|
||||
* up if texelsPerRow is not an integer multiple of the compression block width.
|
||||
*/
|
||||
size_t mvkVkFormatBytesPerRow(VkFormat vkFormat, uint32_t texelsPerRow);
|
||||
|
||||
/**
|
||||
* Returns the size, in bytes, of a row of texels of the specified Metal format.
|
||||
*
|
||||
* For compressed formats, this takes into consideration the compression block size,
|
||||
* and texelsPerRow should specify the width in texels, not blocks. The result is rounded
|
||||
* up if texelsPerRow is not an integer multiple of the compression block width.
|
||||
*/
|
||||
size_t mvkMTLPixelFormatBytesPerRow(MTLPixelFormat mtlFormat, uint32_t texelsPerRow);
|
||||
|
||||
/**
|
||||
* Returns the size, in bytes, of a texture layer of the specified Vulkan format.
|
||||
*
|
||||
* For compressed formats, this takes into consideration the compression block size,
|
||||
* and texelRowsPerLayer should specify the height in texels, not blocks. The result is
|
||||
* rounded up if texelRowsPerLayer is not an integer multiple of the compression block height.
|
||||
*/
|
||||
size_t mvkVkFormatBytesPerLayer(VkFormat vkFormat, size_t bytesPerRow, uint32_t texelRowsPerLayer);
|
||||
|
||||
/**
|
||||
* Returns the size, in bytes, of a texture layer of the specified Metal format.
|
||||
* For compressed formats, this takes into consideration the compression block size,
|
||||
* and texelRowsPerLayer should specify the height in texels, not blocks. The result is
|
||||
* rounded up if texelRowsPerLayer is not an integer multiple of the compression block height.
|
||||
*/
|
||||
size_t mvkMTLPixelFormatBytesPerLayer(MTLPixelFormat mtlFormat, size_t bytesPerRow, uint32_t texelRowsPerLayer);
|
||||
|
||||
/** Returns the default properties for the specified Vulkan format. */
|
||||
VkFormatProperties mvkVkFormatProperties(VkFormat vkFormat);
|
||||
|
||||
/** Returns the name of the specified Vulkan format. */
|
||||
const char* mvkVkFormatName(VkFormat vkFormat);
|
||||
|
||||
/** Returns the name of the specified Metal pixel format. */
|
||||
const char* mvkMTLPixelFormatName(MTLPixelFormat mtlFormat);
|
||||
|
||||
/**
|
||||
* Returns the MTLClearColor value corresponding to the color value in the VkClearValue,
|
||||
* extracting the color value that is VkFormat for the VkFormat.
|
||||
*/
|
||||
MTLClearColor mvkMTLClearColorFromVkClearValue(VkClearValue vkClearValue,
|
||||
VkFormat vkFormat);
|
||||
|
||||
/** Returns the Metal depth value corresponding to the depth value in the specified VkClearValue. */
|
||||
double mvkMTLClearDepthFromVkClearValue(VkClearValue vkClearValue);
|
||||
|
||||
/** Returns the Metal stencil value corresponding to the stencil value in the specified VkClearValue. */
|
||||
uint32_t mvkMTLClearStencilFromVkClearValue(VkClearValue vkClearValue);
|
||||
|
||||
/** Returns whether the specified Metal MTLPixelFormat can be used as a depth format. */
|
||||
bool mvkMTLPixelFormatIsDepthFormat(MTLPixelFormat mtlFormat);
|
||||
|
||||
/** Returns whether the specified Metal MTLPixelFormat can be used as a stencil format. */
|
||||
bool mvkMTLPixelFormatIsStencilFormat(MTLPixelFormat mtlFormat);
|
||||
|
||||
/** Returns whether the specified Metal MTLPixelFormat is a PVRTC format. */
|
||||
bool mvkMTLPixelFormatIsPVRTCFormat(MTLPixelFormat mtlFormat);
|
||||
|
||||
/** Returns the Metal texture type from the specified Vulkan image properties. */
|
||||
MTLTextureType mvkMTLTextureTypeFromVkImageType(VkImageType vkImageType,
|
||||
uint32_t arraySize,
|
||||
bool isMultisample);
|
||||
|
||||
/** Returns the Vulkan image type from the Metal texture type. */
|
||||
VkImageType mvkVkImageTypeFromMTLTextureType(MTLTextureType mtlTextureType);
|
||||
|
||||
/** Returns the Metal MTLTextureType corresponding to the Vulkan VkImageViewType. */
|
||||
MTLTextureType mvkMTLTextureTypeFromVkImageViewType(VkImageViewType vkImageViewType, bool isMultisample);
|
||||
|
||||
/** Returns the Metal texture usage from the Vulkan image usage taking into considertion usage limits for the pixel format. */
|
||||
MTLTextureUsage mvkMTLTextureUsageFromVkImageUsageFlags(VkImageUsageFlags vkImageUsageFlags, MTLPixelFormat mtlPixFmt);
|
||||
|
||||
/** Returns the Vulkan image usage from the Metal texture usage and format. */
|
||||
VkImageUsageFlags mvkVkImageUsageFlagsFromMTLTextureUsage(MTLTextureUsage mtlUsage, MTLPixelFormat mtlFormat);
|
||||
|
||||
/**
|
||||
* Returns the numeric sample count corresponding to the specified Vulkan sample count flag.
|
||||
*
|
||||
* The specified flags value should have only one bit set, otherwise an invalid numeric value will be returned.
|
||||
*/
|
||||
uint32_t mvkSampleCountFromVkSampleCountFlagBits(VkSampleCountFlagBits vkSampleCountFlag);
|
||||
|
||||
/** Returns the Vulkan bit flags corresponding to the numeric sample count, which must be a PoT value. */
|
||||
VkSampleCountFlagBits mvkVkSampleCountFlagBitsFromSampleCount(NSUInteger sampleCount);
|
||||
|
||||
/** Returns the Metal texture swizzle from the Vulkan component swizzle. */
|
||||
MTLTextureSwizzle mvkMTLTextureSwizzleFromVkComponentSwizzle(VkComponentSwizzle vkSwizzle);
|
||||
|
||||
/** Returns all four Metal texture swizzles from the Vulkan component mapping. */
|
||||
MTLTextureSwizzleChannels mvkMTLTextureSwizzleChannelsFromVkComponentMapping(VkComponentMapping vkMapping);
|
||||
|
||||
|
||||
#pragma mark Mipmaps
|
||||
|
||||
/**
|
||||
* Returns the number of mipmap levels available to an image with the specified side dimension.
|
||||
*
|
||||
* If the specified dimension is a power-of-two, the value returned is (log2(dim) + 1).
|
||||
* If the specified dimension is NOT a power-of-two, the value returned is 0, indicating
|
||||
* that the image cannot support mipmaps.
|
||||
*/
|
||||
uint32_t mvkMipmapLevels(uint32_t dim);
|
||||
|
||||
/**
|
||||
* Returns the number of mipmap levels available to an image with the specified extent.
|
||||
*
|
||||
* If each dimension in the specified extent is a power-of-two, the value returned
|
||||
* is MAX(log2(dim) + 1) across both dimensions. If either dimension in the specified
|
||||
* extent is NOT a power-of-two, the value returned is 1, indicating that the image
|
||||
* cannot support mipmaps, and that only the base mip level can be used.
|
||||
*/
|
||||
uint32_t mvkMipmapLevels2D(VkExtent2D extent);
|
||||
|
||||
/**
|
||||
* Returns the number of mipmap levels available to an image with the specified extent.
|
||||
*
|
||||
* If each dimension in the specified extent is a power-of-two, the value returned
|
||||
* is MAX(log2(dim) + 1) across all dimensions. If either dimension in the specified
|
||||
* extent is NOT a power-of-two, the value returned is 1, indicating that the image
|
||||
* cannot support mipmaps, and that only the base mip level can be used.
|
||||
*/
|
||||
uint32_t mvkMipmapLevels3D(VkExtent3D extent);
|
||||
|
||||
/**
|
||||
* Returns the size of the specified zero-based mipmap level,
|
||||
* when the size of the base level is the specified size.
|
||||
*/
|
||||
VkExtent2D mvkMipmapLevelSizeFromBaseSize2D(VkExtent2D baseSize, uint32_t level);
|
||||
|
||||
/**
|
||||
* Returns the size of the specified zero-based mipmap level,
|
||||
* when the size of the base level is the specified size.
|
||||
*/
|
||||
VkExtent3D mvkMipmapLevelSizeFromBaseSize3D(VkExtent3D baseSize, uint32_t level);
|
||||
|
||||
/**
|
||||
* Returns the size of the mipmap base level, when the size of
|
||||
* the specified zero-based mipmap level is the specified size.
|
||||
*/
|
||||
VkExtent2D mvkMipmapBaseSizeFromLevelSize2D(VkExtent2D levelSize, uint32_t level);
|
||||
|
||||
/**
|
||||
* Returns the size of the mipmap base level, when the size of
|
||||
* the specified zero-based mipmap level is the specified size.
|
||||
*/
|
||||
VkExtent3D mvkMipmapBaseSizeFromLevelSize3D(VkExtent3D levelSize, uint32_t level);
|
||||
|
||||
|
||||
#pragma mark Samplers
|
||||
|
||||
/**
|
||||
* Returns the Metal MTLSamplerAddressMode corresponding to the specified Vulkan VkSamplerAddressMode,
|
||||
* or returns MTLSamplerAddressModeMirrorClampToEdge if no corresponding MTLSamplerAddressMode exists.
|
||||
*/
|
||||
MTLSamplerAddressMode mvkMTLSamplerAddressModeFromVkSamplerAddressMode(VkSamplerAddressMode vkMode);
|
||||
|
||||
#ifdef __MAC_OS_X_VERSION_MAX_ALLOWED
|
||||
/**
|
||||
* Returns the Metal MTLSamplerBorderColor corresponding to the specified Vulkan VkBorderColor,
|
||||
* or returns MTLSamplerBorderColorTransparentBlack if no corresponding MTLSamplerBorderColor exists.
|
||||
*/
|
||||
MTLSamplerBorderColor mvkMTLSamplerBorderColorFromVkBorderColor(VkBorderColor vkColor);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns the Metal MTLSamplerMinMagFilter corresponding to the specified Vulkan VkFilter,
|
||||
* or returns MTLSamplerMinMagFilterNearest if no corresponding MTLSamplerMinMagFilter exists.
|
||||
*/
|
||||
MTLSamplerMinMagFilter mvkMTLSamplerMinMagFilterFromVkFilter(VkFilter vkFilter);
|
||||
|
||||
/**
|
||||
* Returns the Metal MTLSamplerMipFilter corresponding to the specified Vulkan VkSamplerMipmapMode,
|
||||
* or returns MTLSamplerMipFilterNotMipmapped if no corresponding MTLSamplerMipFilter exists.
|
||||
*/
|
||||
MTLSamplerMipFilter mvkMTLSamplerMipFilterFromVkSamplerMipmapMode(VkSamplerMipmapMode vkMode);
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Render pipeline
|
||||
|
||||
/** Identifies a particular shading stage in a pipeline. */
|
||||
typedef enum {
|
||||
kMVKShaderStageVertex = 0,
|
||||
kMVKShaderStageTessCtl,
|
||||
kMVKShaderStageTessEval,
|
||||
kMVKShaderStageFragment,
|
||||
kMVKShaderStageCompute,
|
||||
kMVKShaderStageMax
|
||||
} MVKShaderStage;
|
||||
|
||||
/** Returns the Metal MTLColorWriteMask corresponding to the specified Vulkan VkColorComponentFlags. */
|
||||
MTLColorWriteMask mvkMTLColorWriteMaskFromVkChannelFlags(VkColorComponentFlags vkWriteFlags);
|
||||
|
||||
/** Returns the Metal MTLBlendOperation corresponding to the specified Vulkan VkBlendOp. */
|
||||
MTLBlendOperation mvkMTLBlendOperationFromVkBlendOp(VkBlendOp vkBlendOp);
|
||||
|
||||
/** Returns the Metal MTLBlendFactor corresponding to the specified Vulkan VkBlendFactor. */
|
||||
MTLBlendFactor mvkMTLBlendFactorFromVkBlendFactor(VkBlendFactor vkBlendFactor);
|
||||
|
||||
/**
|
||||
* Returns the Metal MTLVertexFormat corresponding to the specified
|
||||
* Vulkan VkFormat as used as a vertex attribute format.
|
||||
*/
|
||||
MTLVertexFormat mvkMTLVertexFormatFromVkFormat(VkFormat vkFormat);
|
||||
|
||||
/** Returns the Metal MTLVertexStepFunction corresponding to the specified Vulkan VkVertexInputRate. */
|
||||
MTLVertexStepFunction mvkMTLVertexStepFunctionFromVkVertexInputRate(VkVertexInputRate vkVtxStep);
|
||||
|
||||
/** Returns the Metal MTLPrimitiveType corresponding to the specified Vulkan VkPrimitiveTopology. */
|
||||
MTLPrimitiveType mvkMTLPrimitiveTypeFromVkPrimitiveTopology(VkPrimitiveTopology vkTopology);
|
||||
|
||||
/** Returns the Metal MTLPrimitiveTopologyClass corresponding to the specified Vulkan VkPrimitiveTopology. */
|
||||
MTLPrimitiveTopologyClass mvkMTLPrimitiveTopologyClassFromVkPrimitiveTopology(VkPrimitiveTopology vkTopology);
|
||||
|
||||
/** Returns the Metal MTLTriangleFillMode corresponding to the specified Vulkan VkPolygonMode, */
|
||||
MTLTriangleFillMode mvkMTLTriangleFillModeFromVkPolygonMode(VkPolygonMode vkFillMode);
|
||||
|
||||
/** Returns the Metal MTLLoadAction corresponding to the specified Vulkan VkAttachmentLoadOp. */
|
||||
MTLLoadAction mvkMTLLoadActionFromVkAttachmentLoadOp(VkAttachmentLoadOp vkLoadOp);
|
||||
|
||||
/** Returns the Metal MTLStoreAction corresponding to the specified Vulkan VkAttachmentStoreOp. */
|
||||
MTLStoreAction mvkMTLStoreActionFromVkAttachmentStoreOp(VkAttachmentStoreOp vkStoreOp, bool hasResolveAttachment);
|
||||
|
||||
/** Returns the Metal MTLViewport corresponding to the specified Vulkan VkViewport. */
|
||||
MTLViewport mvkMTLViewportFromVkViewport(VkViewport vkViewport);
|
||||
|
||||
/** Returns the Metal MTLScissorRect corresponding to the specified Vulkan VkRect2D. */
|
||||
MTLScissorRect mvkMTLScissorRectFromVkRect2D(VkRect2D vkRect);
|
||||
|
||||
/** Returns the Metal MTLCompareFunction corresponding to the specified Vulkan VkCompareOp, */
|
||||
MTLCompareFunction mvkMTLCompareFunctionFromVkCompareOp(VkCompareOp vkOp);
|
||||
|
||||
/** Returns the Metal MTLStencilOperation corresponding to the specified Vulkan VkStencilOp, */
|
||||
MTLStencilOperation mvkMTLStencilOperationFromVkStencilOp(VkStencilOp vkOp);
|
||||
|
||||
/** Returns the Metal MTLCullMode corresponding to the specified Vulkan VkCullModeFlags, */
|
||||
MTLCullMode mvkMTLCullModeFromVkCullModeFlags(VkCullModeFlags vkCull);
|
||||
|
||||
/** Returns the Metal MTLWinding corresponding to the specified Vulkan VkFrontFace, */
|
||||
MTLWinding mvkMTLWindingFromVkFrontFace(VkFrontFace vkWinding);
|
||||
|
||||
/** Returns the Metal MTLIndexType corresponding to the specified Vulkan VkIndexType, */
|
||||
MTLIndexType mvkMTLIndexTypeFromVkIndexType(VkIndexType vkIdxType);
|
||||
|
||||
/** Returns the size, in bytes, of a vertex index of the specified type. */
|
||||
size_t mvkMTLIndexTypeSizeInBytes(MTLIndexType mtlIdxType);
|
||||
|
||||
/** Returns the MoltenVK MVKShaderStage corresponding to the specified Vulkan VkShaderStageFlagBits. */
|
||||
MVKShaderStage mvkShaderStageFromVkShaderStageFlagBits(VkShaderStageFlagBits vkStage);
|
||||
|
||||
/** Returns the Vulkan VkShaderStageFlagBits corresponding to the specified MoltenVK MVKShaderStage. */
|
||||
VkShaderStageFlagBits mvkVkShaderStageFlagBitsFromMVKShaderStage(MVKShaderStage mvkStage);
|
||||
|
||||
/** Returns the Metal MTLWinding corresponding to the specified SPIR-V spv::ExecutionMode. */
|
||||
MTLWinding mvkMTLWindingFromSpvExecutionMode(uint32_t spvMode);
|
||||
|
||||
/** Returns the Metal MTLTessellationPartitionMode corresponding to the specified SPIR-V spv::ExecutionMode. */
|
||||
MTLTessellationPartitionMode mvkMTLTessellationPartitionModeFromSpvExecutionMode(uint32_t spvMode);
|
||||
|
||||
/**
|
||||
* Returns the combination of Metal MTLRenderStage bits corresponding to the specified Vulkan VkPiplineStageFlags,
|
||||
* taking into consideration whether the barrier is to be placed before or after the specified pipeline stages.
|
||||
*/
|
||||
MTLRenderStages mvkMTLRenderStagesFromVkPipelineStageFlags(VkPipelineStageFlags vkStages, bool placeBarrierBefore);
|
||||
|
||||
/** Returns the combination of Metal MTLBarrierScope bits corresponding to the specified Vulkan VkAccessFlags. */
|
||||
MTLBarrierScope mvkMTLBarrierScopeFromVkAccessFlags(VkAccessFlags vkAccess);
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Geometry conversions
|
||||
|
||||
/** Returns a VkExtent2D that corresponds to the specified CGSize. */
|
||||
static inline VkExtent2D mvkVkExtent2DFromCGSize(CGSize cgSize) {
|
||||
VkExtent2D vkExt;
|
||||
vkExt.width = cgSize.width;
|
||||
vkExt.height = cgSize.height;
|
||||
return vkExt;
|
||||
}
|
||||
|
||||
/** Returns a Metal MTLOrigin constructed from a VkOffset3D. */
|
||||
static inline MTLOrigin mvkMTLOriginFromVkOffset3D(VkOffset3D vkOffset) {
|
||||
return MTLOriginMake(vkOffset.x, vkOffset.y, vkOffset.z);
|
||||
}
|
||||
|
||||
/** Returns a Vulkan VkOffset3D constructed from a Metal MTLOrigin. */
|
||||
static inline VkOffset3D mvkVkOffset3DFromMTLSize(MTLOrigin mtlOrigin) {
|
||||
return { (int32_t)mtlOrigin.x, (int32_t)mtlOrigin.y, (int32_t)mtlOrigin.z };
|
||||
}
|
||||
|
||||
/** Returns a Metal MTLSize constructed from a VkExtent3D. */
|
||||
static inline MTLSize mvkMTLSizeFromVkExtent3D(VkExtent3D vkExtent) {
|
||||
return MTLSizeMake(vkExtent.width, vkExtent.height, vkExtent.depth);
|
||||
}
|
||||
|
||||
/** Returns a Vulkan VkExtent3D constructed from a Metal MTLSize. */
|
||||
static inline VkExtent3D mvkVkExtent3DFromMTLSize(MTLSize mtlSize) {
|
||||
return { (uint32_t)mtlSize.width, (uint32_t)mtlSize.height, (uint32_t)mtlSize.depth };
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Memory options
|
||||
|
||||
/** Macro indicating the Vulkan memory type bits corresponding to Metal private memory (not host visible). */
|
||||
#define MVK_VK_MEMORY_TYPE_METAL_PRIVATE (VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
|
||||
|
||||
/** Macro indicating the Vulkan memory type bits corresponding to Metal shared memory (host visible and coherent). */
|
||||
#define MVK_VK_MEMORY_TYPE_METAL_SHARED (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
|
||||
|
||||
/** Macro indicating the Vulkan memory type bits corresponding to Metal managed memory (host visible and non-coherent). */
|
||||
#define MVK_VK_MEMORY_TYPE_METAL_MANAGED (VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT)
|
||||
|
||||
/** Macro indicating the Vulkan memory type bits corresponding to Metal memoryless memory (not host visible and lazily allocated). */
|
||||
#define MVK_VK_MEMORY_TYPE_METAL_MEMORYLESS (VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
|
||||
|
||||
/** Returns the Metal storage mode corresponding to the specified Vulkan memory flags. */
|
||||
MTLStorageMode mvkMTLStorageModeFromVkMemoryPropertyFlags(VkMemoryPropertyFlags vkFlags);
|
||||
|
||||
/** Returns the Metal CPU cache mode corresponding to the specified Vulkan memory flags. */
|
||||
MTLCPUCacheMode mvkMTLCPUCacheModeFromVkMemoryPropertyFlags(VkMemoryPropertyFlags vkFlags);
|
||||
|
||||
/** Returns the Metal resource option flags corresponding to the Metal storage mode and cache mode. */
|
||||
MTLResourceOptions mvkMTLResourceOptions(MTLStorageMode mtlStorageMode, MTLCPUCacheMode mtlCPUCacheMode);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
49
externals/MoltenVK/include/MoltenVK/mvk_vulkan.h
vendored
Normal file
49
externals/MoltenVK/include/MoltenVK/mvk_vulkan.h
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* mvk_vulkan.h
|
||||
*
|
||||
* Copyright (c) 2015-2020 The Brenwill Workshop Ltd. (http://www.brenwill.com)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* This is a convenience header file that loads vulkan.h with the appropriate Vulkan platform extensions.
|
||||
*
|
||||
* This header automatically enables the VK_EXT_metal_surface Vulkan extension.
|
||||
*
|
||||
* When building for iOS, this header also automatically enables the obsolete VK_MVK_ios_surface Vulkan extension.
|
||||
* When building for macOS, this header also automatically enables the obsolete VK_MVK_macos_surface Vulkan extension.
|
||||
* Both of these extensions are obsolete. Consider using the portable VK_EXT_metal_surface extension instead.
|
||||
*/
|
||||
|
||||
#ifndef __mvk_vulkan_h_
|
||||
#define __mvk_vulkan_h_ 1
|
||||
|
||||
|
||||
#include <Availability.h>
|
||||
|
||||
#define VK_USE_PLATFORM_METAL_EXT 1
|
||||
|
||||
#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
|
||||
# define VK_USE_PLATFORM_IOS_MVK 1
|
||||
#endif
|
||||
|
||||
#ifdef __MAC_OS_X_VERSION_MAX_ALLOWED
|
||||
# define VK_USE_PLATFORM_MACOS_MVK 1
|
||||
#endif
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <vulkan-portability/vk_extx_portability_subset.h>
|
||||
|
||||
#endif
|
||||
1034
externals/MoltenVK/include/MoltenVK/vk_mvk_moltenvk.h
vendored
Normal file
1034
externals/MoltenVK/include/MoltenVK/vk_mvk_moltenvk.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
76
externals/MoltenVK/include/vulkan-portability/vk_extx_portability_subset.h
vendored
Normal file
76
externals/MoltenVK/include/vulkan-portability/vk_extx_portability_subset.h
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
#ifndef VK_EXTX_PORTABILITY_SUBSET_H_
|
||||
#define VK_EXTX_PORTABILITY_SUBSET_H_ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Copyright (c) 2018 The Khronos Group Inc.
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Please Note: This extension is currently defined as "EXTX", meaning "multivendor experimental".
|
||||
That means the definition of this extension is in active development, and may break compatibility
|
||||
between point releases (defined as any increment of VK_EXTX_PORTABILITY_SUBSET_SPEC_VERSION).
|
||||
You are free to explore the extension and provide feedback, but it is not recommended to use this
|
||||
extension for shipping applications, particularly applications that require the driver implementing this
|
||||
extension to be linked dynamically and potentially "dropped-in" to the application execution environment.
|
||||
*/
|
||||
|
||||
#include "vulkan/vulkan.h"
|
||||
|
||||
#define VK_EXTX_PORTABILITY_SUBSET_SPEC_VERSION 1
|
||||
#define VK_EXTX_PORTABILITY_SUBSET_EXTENSION_NAME "VK_EXTX_portability_subset"
|
||||
|
||||
#define VK_EXTX_PORTABILITY_SUBSET_EXTENSION_ID 164
|
||||
// See enum_offset() from https://www.khronos.org/registry/vulkan/specs/1.1/styleguide.html#_assigning_extension_token_values
|
||||
#define VK_EXTX_PORTABILITY_SUBSET_STYPE_ID(x) \
|
||||
((VkStructureType)(1000000000 + 1000 * (VK_EXTX_PORTABILITY_SUBSET_EXTENSION_ID - 1) + x))
|
||||
#define VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_EXTX VK_EXTX_PORTABILITY_SUBSET_STYPE_ID(0)
|
||||
#define VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_EXTX VK_EXTX_PORTABILITY_SUBSET_STYPE_ID(1)
|
||||
#define VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_SUPPORT_EXTX VK_EXTX_PORTABILITY_SUBSET_STYPE_ID(2)
|
||||
|
||||
typedef struct VkPhysicalDevicePortabilitySubsetFeaturesEXTX {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
VkBool32 triangleFans;
|
||||
VkBool32 separateStencilMaskRef;
|
||||
VkBool32 events;
|
||||
VkBool32 standardImageViews;
|
||||
VkBool32 samplerMipLodBias;
|
||||
} VkPhysicalDevicePortabilitySubsetFeaturesEXTX;
|
||||
|
||||
typedef struct VkPhysicalDevicePortabilitySubsetPropertiesEXTX {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
uint32_t minVertexInputBindingStrideAlignment;
|
||||
} VkPhysicalDevicePortabilitySubsetPropertiesEXTX;
|
||||
|
||||
typedef struct VkPhysicalDeviceImageViewSupportEXTX {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
VkImageViewCreateFlags flags;
|
||||
VkImageViewType viewType;
|
||||
VkFormat format;
|
||||
VkComponentMapping components;
|
||||
VkImageAspectFlags aspectMask;
|
||||
} VkPhysicalDeviceImageViewSupportEXTX;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // VK_EXTX_PORTABILITY_SUBSET_H_
|
||||
BIN
externals/MoltenVK/lib/libMoltenVK.dylib
vendored
Executable file
BIN
externals/MoltenVK/lib/libMoltenVK.dylib
vendored
Executable file
Binary file not shown.
BIN
externals/MoltenVK/lib/libVkLayer_khronos_validation.dylib
vendored
Executable file
BIN
externals/MoltenVK/lib/libVkLayer_khronos_validation.dylib
vendored
Executable file
Binary file not shown.
BIN
externals/MoltenVK/lib/libvulkan.dylib
vendored
Executable file
BIN
externals/MoltenVK/lib/libvulkan.dylib
vendored
Executable file
Binary file not shown.
@@ -62,10 +62,6 @@ else()
|
||||
-Wno-unused-parameter
|
||||
)
|
||||
|
||||
if (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL Clang)
|
||||
add_compile_options("-stdlib=libc++")
|
||||
endif()
|
||||
|
||||
# Set file offset size to 64 bits.
|
||||
#
|
||||
# On modern Unixes, this is typically already the case. The lone exception is
|
||||
|
||||
@@ -14,12 +14,7 @@ namespace Core::Frontend {
|
||||
|
||||
/// Information for the Graphics Backends signifying what type of screen pointer is in
|
||||
/// WindowInformation
|
||||
enum class WindowSystemType {
|
||||
Headless,
|
||||
Windows,
|
||||
X11,
|
||||
Wayland,
|
||||
};
|
||||
enum class WindowSystemType { Headless, Windows, X11, Wayland, MacOS };
|
||||
|
||||
/**
|
||||
* Represents a drawing context that supports graphics operations.
|
||||
@@ -156,6 +151,14 @@ public:
|
||||
return window_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns drawing area raw pointer
|
||||
* Unsafe version for MoltenVK to modify pointer
|
||||
*/
|
||||
void*& GetRenderSurface() {
|
||||
return window_info.render_surface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the framebuffer layout (width, height, and screen regions)
|
||||
* @note This method is thread-safe
|
||||
|
||||
@@ -258,3 +258,7 @@ if (MSVC)
|
||||
else()
|
||||
target_compile_options(video_core PRIVATE -Werror=conversion -Wno-error=sign-conversion)
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
target_include_directories(video_core PRIVATE ../../externals/MoltenVK/include)
|
||||
endif()
|
||||
|
||||
@@ -40,6 +40,13 @@
|
||||
#include <vulkan/vulkan_win32.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define VK_USE_PLATFORM_METAL_EXT
|
||||
#include <objc/message.h>
|
||||
#include "vulkan/vulkan_macos.h"
|
||||
#include "vulkan/vulkan_metal.h"
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
#include <X11/Xlib.h>
|
||||
#include <vulkan/vulkan_wayland.h>
|
||||
@@ -118,6 +125,11 @@ vk::Instance CreateInstance(Common::DynamicLibrary& library, vk::InstanceDispatc
|
||||
extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
|
||||
break;
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
case Core::Frontend::WindowSystemType::MacOS:
|
||||
extensions.push_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME);
|
||||
break;
|
||||
#endif
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
case Core::Frontend::WindowSystemType::X11:
|
||||
extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
|
||||
@@ -137,7 +149,7 @@ vk::Instance CreateInstance(Common::DynamicLibrary& library, vk::InstanceDispatc
|
||||
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
}
|
||||
extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
|
||||
|
||||
extensions.push_back(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME);
|
||||
const std::optional properties = vk::EnumerateInstanceExtensionProperties(dld);
|
||||
if (!properties) {
|
||||
LOG_ERROR(Render_Vulkan, "Failed to query extension properties");
|
||||
@@ -155,7 +167,7 @@ vk::Instance CreateInstance(Common::DynamicLibrary& library, vk::InstanceDispatc
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr std::array layers_data{"VK_LAYER_LUNARG_standard_validation"};
|
||||
static constexpr std::array layers_data{"VK_LAYER_KHRONOS_validation"};
|
||||
vk::Span<const char*> layers = layers_data;
|
||||
if (!enable_layers) {
|
||||
layers = {};
|
||||
@@ -264,20 +276,56 @@ bool RendererVulkan::TryPresent(int /*timeout_ms*/) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void PrepareMetalWindow([[maybe_unused]] void*& render_surface) {
|
||||
#if defined(VK_USE_PLATFORM_METAL_EXT)
|
||||
// Hackish: avoids having to write Objective C++ just to create a metal layer.
|
||||
id view = reinterpret_cast<id>(render_surface);
|
||||
Class clsCAMetalLayer = objc_getClass("CAMetalLayer");
|
||||
if (!clsCAMetalLayer) {
|
||||
LOG_ERROR(Render_Vulkan, "Failed to get CAMetalLayer class.");
|
||||
return;
|
||||
}
|
||||
|
||||
// [CAMetalLayer layer]
|
||||
id layer = reinterpret_cast<id (*)(Class, SEL)>(objc_msgSend)(objc_getClass("CAMetalLayer"),
|
||||
sel_getUid("layer"));
|
||||
if (!layer) {
|
||||
LOG_ERROR(Render_Vulkan, "Failed to create Metal layer.");
|
||||
return;
|
||||
}
|
||||
// [view setWantsLayer:YES]
|
||||
reinterpret_cast<void (*)(id, SEL, BOOL)>(objc_msgSend)(view, sel_getUid("setWantsLayer:"),
|
||||
YES);
|
||||
// [view setLayer:layer]
|
||||
reinterpret_cast<void (*)(id, SEL, id)>(objc_msgSend)(view, sel_getUid("setLayer:"), layer);
|
||||
// NSScreen* screen = [NSScreen mainScreen]
|
||||
id screen = reinterpret_cast<id (*)(Class, SEL)>(objc_msgSend)(objc_getClass("NSScreen"),
|
||||
sel_getUid("mainScreen"));
|
||||
// CGFloat factor = [screen backingScaleFactor]
|
||||
double factor = reinterpret_cast<double (*)(id, SEL)>(objc_msgSend)(
|
||||
screen, sel_getUid("backingScaleFactor"));
|
||||
// layer.contentsScale = factor
|
||||
reinterpret_cast<void (*)(id, SEL, double)>(objc_msgSend)(
|
||||
layer, sel_getUid("setContentsScale:"), factor);
|
||||
// Store layer ptr, so MoltenVK doesn't call [NSView layer] outside main thread.
|
||||
render_surface = layer;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool RendererVulkan::Init() {
|
||||
#ifdef __APPLE__
|
||||
PrepareMetalWindow(render_window.GetRenderSurface());
|
||||
#endif
|
||||
library = OpenVulkanLibrary();
|
||||
instance = CreateInstance(library, dld, render_window.GetWindowInfo().type,
|
||||
Settings::values.renderer_debug);
|
||||
if (!instance || !CreateDebugCallback() || !CreateSurface() || !PickDevices()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Report();
|
||||
|
||||
memory_manager = std::make_unique<VKMemoryManager>(*device);
|
||||
|
||||
resource_manager = std::make_unique<VKResourceManager>(*device);
|
||||
|
||||
const auto& framebuffer = render_window.GetFramebufferLayout();
|
||||
swapchain = std::make_unique<VKSwapchain>(*surface, *device);
|
||||
swapchain->Create(framebuffer.width, framebuffer.height, false);
|
||||
@@ -329,7 +377,6 @@ bool RendererVulkan::CreateDebugCallback() {
|
||||
bool RendererVulkan::CreateSurface() {
|
||||
[[maybe_unused]] const auto& window_info = render_window.GetWindowInfo();
|
||||
VkSurfaceKHR unsafe_surface = nullptr;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (window_info.type == Core::Frontend::WindowSystemType::Windows) {
|
||||
const HWND hWnd = static_cast<HWND>(window_info.render_surface);
|
||||
@@ -372,12 +419,26 @@ bool RendererVulkan::CreateSurface() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_METAL_EXT
|
||||
if (window_info.type == Core::Frontend::WindowSystemType::MacOS) {
|
||||
VkMetalSurfaceCreateInfoEXT surface_create_info = {
|
||||
VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT, nullptr, 0,
|
||||
static_cast<const CAMetalLayer*>(window_info.render_surface)};
|
||||
const auto vkCreateMetalSurfaceEXT = reinterpret_cast<PFN_vkCreateMetalSurfaceEXT>(
|
||||
dld.vkGetInstanceProcAddr(*instance, "vkCreateMetalSurfaceEXT"));
|
||||
if (!vkCreateMetalSurfaceEXT ||
|
||||
vkCreateMetalSurfaceEXT(*instance, &surface_create_info, nullptr, &unsafe_surface) !=
|
||||
VK_SUCCESS) {
|
||||
LOG_ERROR(Render_Vulkan, "Failed to initialize Metal surface");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!unsafe_surface) {
|
||||
LOG_ERROR(Render_Vulkan, "Presentation not supported on this platform");
|
||||
return false;
|
||||
}
|
||||
|
||||
surface = vk::SurfaceKHR(unsafe_surface, *instance, dld);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ struct VKScreenInfo {
|
||||
bool is_srgb{};
|
||||
};
|
||||
|
||||
void PrepareMetalWindow([[maybe_unused]] void*& render_surface);
|
||||
|
||||
class RendererVulkan final : public VideoCore::RendererBase {
|
||||
public:
|
||||
explicit RendererVulkan(Core::Frontend::EmuWindow& window, Core::System& system);
|
||||
|
||||
@@ -33,12 +33,17 @@ constexpr std::array REQUIRED_EXTENSIONS = {
|
||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
||||
VK_KHR_16BIT_STORAGE_EXTENSION_NAME,
|
||||
VK_KHR_8BIT_STORAGE_EXTENSION_NAME,
|
||||
VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME,
|
||||
VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME,
|
||||
VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME,
|
||||
VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME,
|
||||
// If device doesn't support draw_parameters there's no chance it runs anything
|
||||
VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME,
|
||||
#ifndef __APPLE__
|
||||
VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME,
|
||||
// Subgroup ballot/vote will be supported by MoltenVK shortly
|
||||
VK_EXT_SHADER_SUBGROUP_BALLOT_EXTENSION_NAME,
|
||||
VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME,
|
||||
VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME,
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@@ -180,7 +185,11 @@ bool VKDevice::Create() {
|
||||
features.fullDrawIndexUint32 = false;
|
||||
features.imageCubeArray = false;
|
||||
features.independentBlend = true;
|
||||
#ifdef __APPLE__
|
||||
features.geometryShader = false;
|
||||
#else
|
||||
features.geometryShader = true;
|
||||
#endif
|
||||
features.tessellationShader = true;
|
||||
features.sampleRateShading = false;
|
||||
features.dualSrcBlend = false;
|
||||
@@ -495,13 +504,15 @@ bool VKDevice::IsSuitable(vk::PhysicalDevice physical, VkSurfaceKHR surface) {
|
||||
std::make_pair(features.largePoints, "largePoints"),
|
||||
std::make_pair(features.multiViewport, "multiViewport"),
|
||||
std::make_pair(features.depthBiasClamp, "depthBiasClamp"),
|
||||
std::make_pair(features.geometryShader, "geometryShader"),
|
||||
std::make_pair(features.tessellationShader, "tessellationShader"),
|
||||
std::make_pair(features.occlusionQueryPrecise, "occlusionQueryPrecise"),
|
||||
std::make_pair(features.fragmentStoresAndAtomics, "fragmentStoresAndAtomics"),
|
||||
std::make_pair(features.shaderImageGatherExtended, "shaderImageGatherExtended"),
|
||||
std::make_pair(features.shaderStorageImageWriteWithoutFormat,
|
||||
"shaderStorageImageWriteWithoutFormat"),
|
||||
#ifndef __APPLE__
|
||||
std::make_pair(features.geometryShader, "geometryShader"),
|
||||
#endif
|
||||
};
|
||||
for (const auto& [supported, name] : feature_report) {
|
||||
if (supported) {
|
||||
|
||||
@@ -595,8 +595,11 @@ void RasterizerVulkan::WaitForIdle() {
|
||||
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT |
|
||||
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
#ifndef __APPLE__
|
||||
flags = flags | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
|
||||
#endif
|
||||
if (device.IsExtTransformFeedbackSupported()) {
|
||||
flags |= VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT;
|
||||
}
|
||||
|
||||
@@ -276,14 +276,19 @@ class SPIRVDecompiler final : public Sirit::Module {
|
||||
public:
|
||||
explicit SPIRVDecompiler(const VKDevice& device, const ShaderIR& ir, ShaderType stage,
|
||||
const Registry& registry, const Specialization& specialization)
|
||||
: Module(0x00010300), device{device}, ir{ir}, stage{stage}, header{ir.GetHeader()},
|
||||
:
|
||||
#ifdef __APPLE__
|
||||
Module(0x00010000),
|
||||
#else
|
||||
Module(0x00010300),
|
||||
#endif
|
||||
device{device}, ir{ir}, stage{stage}, header{ir.GetHeader()},
|
||||
registry{registry}, specialization{specialization} {
|
||||
if (stage != ShaderType::Compute) {
|
||||
transform_feedback = BuildTransformFeedback(registry.GetGraphicsInfo());
|
||||
}
|
||||
|
||||
AddCapability(spv::Capability::Shader);
|
||||
AddCapability(spv::Capability::UniformAndStorageBuffer16BitAccess);
|
||||
AddCapability(spv::Capability::ImageQuery);
|
||||
AddCapability(spv::Capability::Image1D);
|
||||
AddCapability(spv::Capability::ImageBuffer);
|
||||
@@ -291,13 +296,19 @@ public:
|
||||
AddCapability(spv::Capability::SampledBuffer);
|
||||
AddCapability(spv::Capability::StorageImageWriteWithoutFormat);
|
||||
AddCapability(spv::Capability::DrawParameters);
|
||||
AddCapability(spv::Capability::UniformAndStorageBuffer16BitAccess);
|
||||
#ifndef __APPLE__
|
||||
// These can be added back when MoltenVK finally supports vk 1.1
|
||||
AddCapability(spv::Capability::SubgroupBallotKHR);
|
||||
AddCapability(spv::Capability::SubgroupVoteKHR);
|
||||
AddExtension("SPV_KHR_shader_ballot");
|
||||
AddExtension("SPV_KHR_subgroup_vote");
|
||||
AddExtension("SPV_KHR_storage_buffer_storage_class");
|
||||
#endif
|
||||
// Uniform 16bit Storage should only be added if version < 1.1
|
||||
AddExtension(VK_KHR_16BIT_STORAGE_EXTENSION_NAME);
|
||||
AddExtension(VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME);
|
||||
AddExtension(VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME);
|
||||
AddExtension("SPV_KHR_variable_pointers");
|
||||
AddExtension("SPV_KHR_shader_draw_parameters");
|
||||
|
||||
if (!transform_feedback.empty()) {
|
||||
if (device.IsExtTransformFeedbackSupported()) {
|
||||
@@ -514,6 +525,8 @@ private:
|
||||
}
|
||||
|
||||
void DeclareCommon() {
|
||||
#ifndef __APPLE__
|
||||
//subgrouplocalinvocationId requires VK_EXT_shader_subgroup_ballot - isn't in metal yet
|
||||
thread_id =
|
||||
DeclareInputBuiltIn(spv::BuiltIn::SubgroupLocalInvocationId, t_in_uint, "thread_id");
|
||||
thread_masks[0] =
|
||||
@@ -526,6 +539,7 @@ private:
|
||||
DeclareInputBuiltIn(spv::BuiltIn::SubgroupLeMask, t_in_uint4, "thread_le_mask");
|
||||
thread_masks[4] =
|
||||
DeclareInputBuiltIn(spv::BuiltIn::SubgroupLtMask, t_in_uint4, "thread_lt_mask");
|
||||
#endif
|
||||
}
|
||||
|
||||
void DeclareVertex() {
|
||||
@@ -631,7 +645,11 @@ private:
|
||||
|
||||
void DeclareRegisters() {
|
||||
for (const u32 gpr : ir.GetRegisters()) {
|
||||
#ifdef __APPLE__
|
||||
const Id id = OpVariable(t_prv_float, spv::StorageClass::Private);
|
||||
#else
|
||||
const Id id = OpVariable(t_prv_float, spv::StorageClass::Private, v_float_zero);
|
||||
#endif
|
||||
Name(id, fmt::format("gpr_{}", gpr));
|
||||
registers.emplace(gpr, AddGlobalVariable(id));
|
||||
}
|
||||
@@ -640,7 +658,11 @@ private:
|
||||
void DeclareCustomVariables() {
|
||||
const u32 num_custom_variables = ir.GetNumCustomVariables();
|
||||
for (u32 i = 0; i < num_custom_variables; ++i) {
|
||||
#ifdef __APPLE__
|
||||
const Id id = OpVariable(t_prv_float, spv::StorageClass::Private);
|
||||
#else
|
||||
const Id id = OpVariable(t_prv_float, spv::StorageClass::Private, v_float_zero);
|
||||
#endif
|
||||
Name(id, fmt::format("custom_var_{}", i));
|
||||
custom_variables.emplace(i, AddGlobalVariable(id));
|
||||
}
|
||||
@@ -648,7 +670,11 @@ private:
|
||||
|
||||
void DeclarePredicates() {
|
||||
for (const auto pred : ir.GetPredicates()) {
|
||||
#ifdef __APPLE__
|
||||
const Id id = OpVariable(t_prv_bool, spv::StorageClass::Private);
|
||||
#else
|
||||
const Id id = OpVariable(t_prv_bool, spv::StorageClass::Private, v_false);
|
||||
#endif
|
||||
Name(id, fmt::format("pred_{}", static_cast<u32>(pred)));
|
||||
predicates.emplace(pred, AddGlobalVariable(id));
|
||||
}
|
||||
@@ -656,7 +682,11 @@ private:
|
||||
|
||||
void DeclareFlowVariables() {
|
||||
for (u32 i = 0; i < ir.GetASTNumVariables(); i++) {
|
||||
#ifdef __APPLE__
|
||||
const Id id = OpVariable(t_prv_bool, spv::StorageClass::Private);
|
||||
#else
|
||||
const Id id = OpVariable(t_prv_bool, spv::StorageClass::Private, v_false);
|
||||
#endif
|
||||
Name(id, fmt::format("flow_var_{}", static_cast<u32>(i)));
|
||||
flow_variables.emplace(i, AddGlobalVariable(id));
|
||||
}
|
||||
@@ -703,7 +733,11 @@ private:
|
||||
constexpr std::array names = {"zero", "sign", "carry", "overflow"};
|
||||
for (std::size_t flag = 0; flag < INTERNAL_FLAGS_COUNT; ++flag) {
|
||||
const auto flag_code = static_cast<InternalFlag>(flag);
|
||||
#ifdef __APPLE__
|
||||
const Id id = OpVariable(t_prv_bool, spv::StorageClass::Private);
|
||||
#else
|
||||
const Id id = OpVariable(t_prv_bool, spv::StorageClass::Private, v_false);
|
||||
#endif
|
||||
internal_flags[flag] = AddGlobalVariable(Name(id, names[flag]));
|
||||
}
|
||||
}
|
||||
@@ -1327,10 +1361,11 @@ private:
|
||||
}
|
||||
|
||||
if (const auto comment = std::get_if<CommentNode>(&*node)) {
|
||||
#ifndef __APPLE__ // This doesn't work at all on moltenVK
|
||||
Name(OpUndef(t_void), comment->GetText());
|
||||
#endif
|
||||
return {};
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -373,7 +373,11 @@ Instance Instance::Create(Span<const char*> layers, Span<const char*> extensions
|
||||
application_info.applicationVersion = VK_MAKE_VERSION(0, 1, 0);
|
||||
application_info.pEngineName = "yuzu Emulator";
|
||||
application_info.engineVersion = VK_MAKE_VERSION(0, 1, 0);
|
||||
#ifdef __APPLE__
|
||||
application_info.apiVersion = VK_API_VERSION_1_0;
|
||||
#else
|
||||
application_info.apiVersion = VK_API_VERSION_1_1;
|
||||
#endif
|
||||
|
||||
VkInstanceCreateInfo ci;
|
||||
ci.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
#define VK_NO_PROTOTYPES
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <MoltenVK/vk_mvk_moltenvk.h>
|
||||
#endif
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Vulkan::vk {
|
||||
|
||||
@@ -216,3 +216,47 @@ if (ENABLE_VULKAN)
|
||||
target_include_directories(yuzu PRIVATE ../../externals/Vulkan-Headers/include)
|
||||
target_compile_definitions(yuzu PRIVATE HAS_VULKAN)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
target_include_directories(yuzu PRIVATE ../../externals/MoltenVK/include)
|
||||
|
||||
#include(BundleUtilities)
|
||||
set(BUNDLE_PATH ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/yuzu.app)
|
||||
|
||||
# Ask for an application bundle.
|
||||
set_target_properties(yuzu PROPERTIES
|
||||
MACOSX_BUNDLE true
|
||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
|
||||
)
|
||||
|
||||
# Copy Qt plugins into the bundle
|
||||
get_target_property(qtcocoa_location Qt5::QCocoaIntegrationPlugin LOCATION)
|
||||
target_sources(yuzu PRIVATE "${qtcocoa_location}")
|
||||
set_source_files_properties("${qtcocoa_location}" PROPERTIES MACOSX_PACKAGE_LOCATION MacOS/platforms)
|
||||
|
||||
get_target_property(qtmacstyle_location Qt5::QMacStylePlugin LOCATION)
|
||||
target_sources(yuzu PRIVATE "${qtmacstyle_location}")
|
||||
set_source_files_properties("${qtmacstyle_location}" PROPERTIES MACOSX_PACKAGE_LOCATION MacOS/styles)
|
||||
|
||||
# Copy MoltenVK into the bundle
|
||||
target_sources(yuzu PRIVATE "${CMAKE_SOURCE_DIR}/externals/MoltenVK/lib/libMoltenVK.dylib")
|
||||
set_source_files_properties("${CMAKE_SOURCE_DIR}/externals/MoltenVK/lib/libMoltenVK.dylib" PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks)
|
||||
target_sources(yuzu PRIVATE "${CMAKE_SOURCE_DIR}/externals/MoltenVK/lib/libvulkan.dylib")
|
||||
set_source_files_properties("${CMAKE_SOURCE_DIR}/externals/MoltenVK/lib/libvulkan.dylib" PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks)
|
||||
|
||||
# Copy validation layers as well
|
||||
target_sources(yuzu PRIVATE "${CMAKE_SOURCE_DIR}/externals/MoltenVK/lib/libVkLayer_khronos_validation.dylib")
|
||||
set_source_files_properties("${CMAKE_SOURCE_DIR}/externals/MoltenVK/lib/libVkLayer_khronos_validation.dylib" PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks)
|
||||
target_sources(yuzu PRIVATE "${CMAKE_SOURCE_DIR}/externals/MoltenVK/Resources/vulkan/icd.d/MoltenVK_icd.json")
|
||||
set_source_files_properties("${CMAKE_SOURCE_DIR}/externals/MoltenVK/Resources/vulkan/icd.d/MoltenVK_icd.json" PROPERTIES MACOSX_PACKAGE_LOCATION "Resources/vulkan/icd.d")
|
||||
|
||||
|
||||
# Update library references to make the bundle portable
|
||||
include(PostprocessBundle)
|
||||
#postprocess_bundle(yuzu)
|
||||
# Fix rpath
|
||||
add_custom_command(TARGET yuzu
|
||||
POST_BUILD COMMAND
|
||||
${CMAKE_INSTALL_NAME_TOOL} -add_rpath "@executable_path/../Frameworks/"
|
||||
$<TARGET_FILE:yuzu>)
|
||||
endif()
|
||||
|
||||
@@ -261,6 +261,8 @@ static Core::Frontend::WindowSystemType GetWindowSystemType() {
|
||||
return Core::Frontend::WindowSystemType::X11;
|
||||
else if (platform_name == QStringLiteral("wayland"))
|
||||
return Core::Frontend::WindowSystemType::Wayland;
|
||||
else if (platform_name == QStringLiteral("cocoa"))
|
||||
return Core::Frontend::WindowSystemType::MacOS;
|
||||
|
||||
LOG_CRITICAL(Frontend, "Unknown Qt platform!");
|
||||
return Core::Frontend::WindowSystemType::Windows;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <thread>
|
||||
#ifdef __APPLE__
|
||||
#include <unistd.h> // for chdir
|
||||
#include <stdlib.h> // for setenv
|
||||
#endif
|
||||
|
||||
// VFS includes must be before glad as they will conflict with Windows file api, which uses defines.
|
||||
@@ -2442,6 +2443,9 @@ int main(int argc, char* argv[]) {
|
||||
QCoreApplication::setApplicationName(QStringLiteral("yuzu"));
|
||||
|
||||
#ifdef __APPLE__
|
||||
// Set MoltenVK Environment Variable. Done before anything else so before graphics backend init
|
||||
// This avoids a nightmare of calling vk_mvk_moltenvk to set config settings
|
||||
setenv("MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE", "1", 1);
|
||||
// If you start a bundle (binary) on OSX without the Terminal, the working directory is "/".
|
||||
// But since we require the working directory to be the executable path for the location of the
|
||||
// user folder in the Qt Frontend, we need to cd into that working directory
|
||||
|
||||
@@ -43,3 +43,7 @@ if (MSVC)
|
||||
copy_yuzu_SDL_deps(yuzu-cmd)
|
||||
copy_yuzu_unicorn_deps(yuzu-cmd)
|
||||
endif()
|
||||
|
||||
if (APPLE AND ENABLE_VULKAN)
|
||||
target_include_directories(yuzu-cmd PRIVATE ../../externals/MoltenVK/include)
|
||||
endif()
|
||||
|
||||
Reference in New Issue
Block a user