Skip to content

Commit

Permalink
Merge pull request H-uru#1326 from colincornaby/apple-metal
Browse files Browse the repository at this point in the history
Metal Rendering on macOS
  • Loading branch information
Hoikas authored Nov 29, 2023
2 parents 45bc9b7 + 245b00f commit 6491a18
Show file tree
Hide file tree
Showing 57 changed files with 13,172 additions and 21 deletions.
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ endif(PLASMA_EXTERNAL_RELEASE)
# Pipeline Renderers
cmake_dependent_option(PLASMA_PIPELINE_DX "Enable DirectX rendering pipeline?" ON "DirectX_FOUND" OFF)
cmake_dependent_option(PLASMA_PIPELINE_GL "Enable OpenGL rendering pipeline?" ON "TARGET epoxy::epoxy" OFF)
cmake_dependent_option(PLASMA_PIPELINE_METAL "Enable Metal rendering pipeline?" ON "APPLE" OFF)

if(PLASMA_PIPELINE_DX)
add_definitions(-DPLASMA_PIPELINE_DX)
Expand All @@ -156,6 +157,10 @@ if(PLASMA_PIPELINE_GL)
add_definitions(-DPLASMA_PIPELINE_GL)
endif(PLASMA_PIPELINE_GL)

if(PLASMA_PIPELINE_METAL)
add_definitions(-DPLASMA_PIPELINE_METAL)
endif(PLASMA_PIPELINE_METAL)

# Allow us to disable certain parts of the build
option(PLASMA_BUILD_CLIENT "Do we want to build plClient?" ON)
cmake_dependent_option(PLASMA_BUILD_MAX_PLUGIN "Do we want to build the 3ds Max plugin?" OFF "TARGET 3dsm" OFF)
Expand Down
12 changes: 11 additions & 1 deletion Sources/Plasma/Apps/plClient/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ elseif(APPLE)
Mac-Cocoa/PLSServerStatus.h
)
list(APPEND plClient_RESOURCES
Mac-Cocoa/Assets.xcassets
Mac-Cocoa/banner.png
Mac-Cocoa/[email protected]
Mac-Cocoa/MainMenu.xib
Expand Down Expand Up @@ -158,8 +157,17 @@ if(APPLE)
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/Mac-Cocoa/plClient.entitlements"
XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME "YES"
XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC "YES"
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER org.Huru.UruExplorer
)
target_compile_options(plClient PRIVATE -fobjc-arc)
target_sources(plClient PRIVATE Mac-Cocoa/Assets.xcassets)
set_source_files_properties(Mac-Cocoa/Assets.xcassets ${RESOURCES} PROPERTIES
MACOSX_PACKAGE_LOCATION Resources
)
install(
TARGETS plClient
DESTINATION client
)

if(PLASMA_APPLE_DEVELOPMENT_TEAM_ID)
set_target_properties(plClient PROPERTIES
Expand Down Expand Up @@ -229,6 +237,8 @@ target_link_libraries(
pfPython
$<$<BOOL:${PLASMA_PIPELINE_DX}>:pfDXPipeline>
$<$<BOOL:${PLASMA_PIPELINE_GL}>:pfGLPipeline>
$<$<BOOL:${PLASMA_PIPELINE_METAL}>:pfMetalPipeline>
$<$<BOOL:${PLASMA_PIPELINE_METAL}>:pfMetalPipelineShaders>
CURL::libcurl
"$<$<PLATFORM_ID:Darwin>:-framework Cocoa>"
"$<$<PLATFORM_ID:Darwin>:-framework QuartzCore>"
Expand Down
6 changes: 6 additions & 0 deletions Sources/Plasma/Apps/plClient/Mac-Cocoa/PLSServerStatus.mm
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ - (void)loadServerStatus
{
NSString* urlString = [NSString stringWithSTString:GetServerStatusUrl()];
NSURL* url = [NSURL URLWithString:urlString];

if (!url || !url.host) {
self.serverStatusString = @"";
return;
}

NSURLSessionConfiguration* URLSessionConfiguration =
[NSURLSessionConfiguration ephemeralSessionConfiguration];
NSURLSession* session = [NSURLSession sessionWithConfiguration:URLSessionConfiguration
Expand Down
6 changes: 0 additions & 6 deletions Sources/Plasma/Apps/plClient/Mac-Cocoa/PLSView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -276,12 +276,6 @@ - (void)resizeDrawable:(CGFloat)scaleFactor
}

#if PLASMA_PIPELINE_METAL
if (newSize.width == _metalLayer.drawableSize.width &&
newSize.height == _metalLayer.drawableSize.height)
{
return;
}

_metalLayer.drawableSize = newSize;
#endif
[self.delegate renderView:self
Expand Down
67 changes: 58 additions & 9 deletions Sources/Plasma/Apps/plClient/Mac-Cocoa/main.mm
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@

// System Frameworks
#import <Cocoa/Cocoa.h>
#ifdef PLASMA_PIPELINE_GL
#import <OpenGL/gl.h>
#endif
#ifdef PLASMA_PIPELINE_METAL
#import <Metal/Metal.h>
#endif
#import <QuartzCore/QuartzCore.h>

// Cocoa client
Expand All @@ -63,7 +69,13 @@
#include "plCmdParser.h"
#include "pfConsoleCore/pfConsoleEngine.h"
#include "pfGameGUIMgr/pfGameGUIMgr.h"
#ifdef PLASMA_PIPELINE_GL
#include "pfGLPipeline/plGLPipeline.h"
#endif
#include "plInputCore/plInputDevice.h"
#ifdef PLASMA_PIPELINE_METAL
#include "pfMetalPipeline/plMetalPipeline.h"
#endif
#include "plMessage/plDisplayScaleChangedMsg.h"
#include "plMessageBox/hsMessageBox.h"
#include "plNetClient/plNetClientMgr.h"
Expand Down Expand Up @@ -162,6 +174,8 @@ @interface AppDelegate : NSWindowController <NSApplicationDelegate,

@implementation AppDelegate

static void* const DeviceDidChangeContext = (void*)&DeviceDidChangeContext;

- (id)init
{
// Style flags
Expand All @@ -181,6 +195,9 @@ - (id)init
self.plsView = view;
window.contentView = view;
[window setDelegate:self];

gClient.SetClientWindow((__bridge void *)view.layer);
gClient.SetClientDisplay((hsWindowHndl)NULL);

self = [super initWithWindow:window];
self.window.acceptsMouseMovedEvents = YES;
Expand Down Expand Up @@ -445,17 +462,15 @@ - (void)startClient

// Window controller
[self.window setContentSize:NSMakeSize(800, 600)];
// #if 0
// allow this executation path to start in full screen
//[self.window toggleFullScreen:self];
// #endif
[self.window center];
[self.window makeKeyAndOrderFront:self];
self.renderLayer = self.window.contentView.layer;

gClient.SetClientWindow((hsWindowHndl)(__bridge void*)self.window);
gClient.SetClientDisplay((hsWindowHndl)NULL);


[self.renderLayer addObserver:self
forKeyPath:@"device"
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial
context:DeviceDidChangeContext];

if (!gClient) {
exit(0);
}
Expand All @@ -473,8 +488,25 @@ - (void)startClient

- (void)updateWindowTitle
{
NSString* productTitle = [NSString stringWithSTString:plProduct::LongName()];
#ifdef PLASMA_PIPELINE_METAL
NSString *productTitle = [NSString stringWithSTString:plProduct::LongName()];
id<MTLDevice> device = ((CAMetalLayer *) self.window.contentView.layer).device;
#ifdef HS_DEBUGGING
[self.window setTitle:[NSString stringWithFormat:@"%@ - %@, %@",
productTitle,
#ifdef __arm64__
@"ARM64",
#else
@"x86_64",
#endif
device.name]];
#else
[self.window setTitle:productTitle];
#endif

#else
[NSString stringWithSTString:plProduct::LongName()];
#endif
}

- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender
Expand Down Expand Up @@ -517,6 +549,23 @@ - (NSApplicationPresentationOptions)window:(NSWindow*)window
NSApplicationPresentationAutoHideMenuBar;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (context == DeviceDidChangeContext) {
// this may not happen on the main queue
dispatch_async(dispatch_get_main_queue(), ^{
[self updateWindowTitle];
});
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}

- (void)dealloc
{
[_renderLayer removeObserver:self forKeyPath:@"device" context:DeviceDidChangeContext];
}

@end

void PumpMessageQueueProc()
Expand Down
8 changes: 8 additions & 0 deletions Sources/Plasma/Apps/plClient/plClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ You can contact Cyan Worlds, Inc. by email [email protected]
#ifdef PLASMA_PIPELINE_GL
#include "pfGLPipeline/plGLPipeline.h"
#endif
#ifdef PLASMA_PIPELINE_METAL
#include "pfMetalPipeline/plMetalPipeline.h"
#endif
#include "pfJournalBook/pfJournalBook.h"
#include "pfLocalizationMgr/pfLocalizationMgr.h"
#include "pfMoviePlayer/plMoviePlayer.h"
Expand Down Expand Up @@ -428,6 +431,11 @@ plPipeline* plClient::ICreatePipeline(hsWindowHndl disp, hsWindowHndl hWnd, cons
if (renderer == hsG3DDeviceSelector::kDevTypeOpenGL)
return new plGLPipeline(disp, hWnd, devMode);
#endif

#ifdef PLASMA_PIPELINE_METAL
if (renderer == hsG3DDeviceSelector::kDevTypeMetal)
return new plMetalPipeline(disp, hWnd, devMode);
#endif

return new plNullPipeline(disp, hWnd, devMode);
}
Expand Down
3 changes: 3 additions & 0 deletions Sources/Plasma/CoreLib/HeadSpin.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ You can contact Cyan Worlds, Inc. by email [email protected]
typedef HINSTANCE HMODULE;
typedef long HRESULT;
typedef void* HANDLE;
#elif HS_BUILD_FOR_MACOS
typedef void* hsWindowHndl;
typedef void* hsWindowInst;
#else
typedef int32_t* hsWindowHndl;
typedef int32_t* hsWindowInst;
Expand Down
1 change: 1 addition & 0 deletions Sources/Plasma/CoreLib/plQuality.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class plQuality
friend class plClient;
friend class plQualitySlider;
friend class plDXPipeline;
friend class plMetalPipeline;

// Set by the app according to user preference.
static void SetQuality(int q);
Expand Down
3 changes: 3 additions & 0 deletions Sources/Plasma/FeatureLib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ add_subdirectory(pfGameScoreMgr)
if(PLASMA_PIPELINE_GL)
add_subdirectory(pfGLPipeline)
endif()
if(PLASMA_PIPELINE_METAL)
add_subdirectory(pfMetalPipeline)
endif()
add_subdirectory(pfJournalBook)
add_subdirectory(pfLocalizationMgr)
add_subdirectory(pfMessage)
Expand Down
3 changes: 3 additions & 0 deletions Sources/Plasma/FeatureLib/inc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ target_link_libraries(pfFeatureInc
pfGameMgr
pfJournalBook
pfMessage
$<$<BOOL:${PLASMA_PIPELINE_DX}>:pfDXPipeline>
$<$<BOOL:${PLASMA_PIPELINE_GL}>:pfGLPipeline>
$<$<BOOL:${PLASMA_PIPELINE_METAL}>:pfMetalPipeline>
pfPython
pfSurface
)
Expand Down
4 changes: 4 additions & 0 deletions Sources/Plasma/FeatureLib/inc/pfAllCreatables.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ You can contact Cyan Worlds, Inc. by email [email protected]
#include "pfGLPipeline/pfGLPipelineCreatable.h"
#endif

#ifdef PLASMA_PIPELINE_METAL
#include "pfMetalPipeline/pfMetalPipelineCreatable.h"
#endif

#include "pfJournalBook/pfJournalBookCreatable.h"
#include "pfMessage/pfMessageCreatable.h"
#include "pfPython/pfPythonCreatable.h"
Expand Down
82 changes: 82 additions & 0 deletions Sources/Plasma/FeatureLib/pfMetalPipeline/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
include(FetchContent)

FetchContent_Declare(
metalcpp
URL_HASH_SHA256 0afd87ca851465191ae4e3980aa036c7e9e02fe32e7c760ac1a74244aae6023b
URL "https://developer.apple.com/metal/cpp/files/metal-cpp_macOS13.3_iOS16.4.zip"
)

FetchContent_MakeAvailable(metalcpp)

set(pfMetalPipeline_SOURCES
plMetalDevice.cpp
plMetalDeviceRefs.cpp
plMetalMaterialShaderRef.cpp
plMetalPipeline.cpp
plMetalPipelineState.cpp
plMetalPlateManager.cpp
plMetalShader.cpp
plMetalFragmentShader.cpp
plMetalVertexShader.cpp
plMetalTextFont.cpp
plMetalEnumerate.mm
plMetalDevicePerformanceShaders.mm
)

set(pfMetalPipeline_HEADERS
plMetalDevice.h
plMetalDeviceRef.h
plMetalMaterialShaderRef.h
plMetalPipeline.h
plMetalPipelineState.h
plMetalPlateManager.h
plMetalShader.h
plMetalTextFont.h
plMetalFragmentShader.h
plMetalVertexShader.h
ShaderSrc/ShaderTypes.h
ShaderSrc/ShaderVertex.h
pfMetalPipelineCreatable.h
)

plasma_library(pfMetalPipeline SOURCES ${pfMetalPipeline_SOURCES} ${pfMetalPipeline_HEADERS})
target_link_libraries(pfMetalPipeline
PUBLIC
CoreLib
pnNucleusInc
plPipeline
"-framework Metal"
"-framework MetalPerformanceShaders"
PRIVATE
plStatusLog
INTERFACE
pnFactory
)

target_include_directories(pfMetalPipeline PUBLIC ${metalcpp_SOURCE_DIR})
target_include_directories(pfMetalPipeline PUBLIC "ShaderSrc")

source_group("Source Files" FILES ${pfMetalPipeline_SOURCES})
source_group("Header Files" FILES ${pfMetalPipeline_HEADERS})

add_library(pfMetalPipelineShaders INTERFACE)
set(pfMetalPipeline_SHADERS
ShaderSrc/FixedPipelineShaders.metal
ShaderSrc/PlateShaders.metal
ShaderSrc/BiasNormals.metal
ShaderSrc/CompCosines.metal
ShaderSrc/WaveSet7.metal
ShaderSrc/Grass.metal
ShaderSrc/WaveDecEnv.metal
ShaderSrc/Avatar.metal
ShaderSrc/WaveDec1Lay_7.metal
ShaderSrc/WaveRip.metal
ShaderSrc/Clear.metal
ShaderSrc/GammaCorrection.metal
ShaderSrc/TextFontShader.metal
)
set_source_files_properties(${pfMetalPipeline_SHADERS} TARGET_DIRECTORY plClient PROPERTIES LANGUAGE METAL)
# source group does not work with an interface library in Xcode, but maybe someday...
source_group("Metal Shaders" FILES ${pfMetalPipeline_SHADERS})

target_sources(pfMetalPipelineShaders INTERFACE ${pfMetalPipeline_SHADERS})
Loading

0 comments on commit 6491a18

Please sign in to comment.