mirror of
https://github.com/rt64/rt64.git
synced 2025-03-14 04:19:02 +00:00
MoltenVK PoC
This commit is contained in:
parent
88c618c1f8
commit
c648adae38
2
.gitignore
vendored
2
.gitignore
vendored
@ -22,4 +22,6 @@
|
||||
build/
|
||||
.vscode/
|
||||
.idea
|
||||
.cache
|
||||
compile_commands.json
|
||||
cmake-build-debug*
|
||||
|
@ -1,8 +1,12 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(rt64)
|
||||
project(rt64 LANGUAGES C CXX)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
|
||||
if (APPLE)
|
||||
enable_language(OBJC OBJCXX)
|
||||
endif()
|
||||
|
||||
option(RT64_STATIC "Build RT64 as a static library" OFF)
|
||||
|
||||
option(RT64_BUILD_EXAMPLES "Build examples for RT64" OFF)
|
||||
@ -379,6 +383,13 @@ target_link_libraries(rt64 libzstd_static)
|
||||
add_subdirectory(src/tools/texture_hasher)
|
||||
add_subdirectory(src/tools/texture_packer)
|
||||
|
||||
# Add any Apple-specific source files and libraries
|
||||
if (APPLE)
|
||||
target_sources(rt64 PRIVATE
|
||||
"${PROJECT_SOURCE_DIR}/src/common/rt64_apple.mm"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Add any Windows-specific source files and libraries
|
||||
if (WIN32)
|
||||
target_sources(rt64 PRIVATE
|
||||
|
@ -9,6 +9,11 @@
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <SDL.h>
|
||||
#include <SDL_syswm.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN64
|
||||
#include "shaders/RenderInterfaceTestPS.hlsl.dxil.h"
|
||||
#include "shaders/RenderInterfaceTestRT.hlsl.dxil.h"
|
||||
@ -800,7 +805,54 @@ namespace RT64 {
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
void RenderInterfaceTest(RenderInterface* renderInterface) {
|
||||
assert(false);
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
||||
fprintf(stderr, "SDL_Init Error: %s\n", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_Window *window = SDL_CreateWindow("Render Interface Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_RESIZABLE | SDL_WINDOW_METAL);
|
||||
if (window == nullptr) {
|
||||
fprintf(stderr, "SDL_CreateWindow Error: %s\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup Metal view.
|
||||
SDL_MetalView view = SDL_Metal_CreateView(window);
|
||||
|
||||
// SDL_Window's handle can be used directly if needed
|
||||
SDL_SysWMinfo wmInfo;
|
||||
SDL_VERSION(&wmInfo.version);
|
||||
SDL_GetWindowWMInfo(window, &wmInfo);
|
||||
|
||||
TestInitialize(renderInterface, { wmInfo.info.cocoa.window, view });
|
||||
TestResize();
|
||||
|
||||
bool running = true;
|
||||
while (running) {
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_QUIT:
|
||||
running = false;
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT:
|
||||
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
|
||||
TestResize();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TestDraw();
|
||||
SDL_Delay(16); // Approximate 60 FPS
|
||||
}
|
||||
|
||||
TestShutdown();
|
||||
SDL_Metal_DestroyView(view);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
18
src/common/rt64_apple.h
Normal file
18
src/common/rt64_apple.h
Normal file
@ -0,0 +1,18 @@
|
||||
//
|
||||
// RT64
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
struct CocoaWindowAttributes {
|
||||
int x, y;
|
||||
int width, height;
|
||||
};
|
||||
|
||||
const char* GetHomeDirectory();
|
||||
|
||||
void GetWindowAttributes(void* window, CocoaWindowAttributes *attributes);
|
||||
int GetWindowRefreshRate(void* window);
|
||||
void WindowToggleFullscreen(void* window);
|
38
src/common/rt64_apple.mm
Normal file
38
src/common/rt64_apple.mm
Normal file
@ -0,0 +1,38 @@
|
||||
|
||||
#include "rt64_apple.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
const char* GetHomeDirectory() {
|
||||
return strdup([NSHomeDirectory() UTF8String]);
|
||||
}
|
||||
|
||||
void GetWindowAttributes(void* window, CocoaWindowAttributes *attributes) {
|
||||
NSWindow *nsWindow = (NSWindow *)window;
|
||||
NSRect contentFrame = [[nsWindow contentView] frame];
|
||||
attributes->x = contentFrame.origin.x;
|
||||
attributes->y = contentFrame.origin.y;
|
||||
attributes->width = contentFrame.size.width;
|
||||
attributes->height = contentFrame.size.height;
|
||||
}
|
||||
|
||||
int GetWindowRefreshRate(void* window) {
|
||||
NSWindow *nsWindow = (NSWindow *)window;
|
||||
NSScreen *screen = [nsWindow screen];
|
||||
|
||||
if (@available(macOS 12.0, *)) {
|
||||
return (int)[screen maximumFramesPerSecond];
|
||||
}
|
||||
|
||||
// TODO: Implement this.
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WindowToggleFullscreen(void* window) {
|
||||
// UI operations have to happen on the main thread.
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSWindow *nsWindow = (NSWindow *)window;
|
||||
[nsWindow toggleFullScreen:NULL];
|
||||
});
|
||||
}
|
@ -1,7 +1,11 @@
|
||||
// Disable SIMD on GCC due to UB when compiling with optimizations.
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
|
||||
#define HLSLPP_SCALAR
|
||||
#endif
|
||||
|
||||
// Disable SIMD on Apple Silicon due to UB when compiling with optimizations.
|
||||
#if defined(__APPLE__) && defined(__aarch64__)
|
||||
#define HLSLPP_SCALAR
|
||||
#endif
|
||||
|
||||
#include "hlsl++.h"
|
@ -9,6 +9,8 @@
|
||||
# include <pwd.h>
|
||||
#elif defined(_WIN32)
|
||||
# include <Shlobj.h>
|
||||
#elif defined(__APPLE__)
|
||||
# include "common/rt64_apple.h"
|
||||
#endif
|
||||
|
||||
namespace RT64 {
|
||||
@ -30,10 +32,14 @@ namespace RT64 {
|
||||
}
|
||||
|
||||
CoTaskMemFree(knownPath);
|
||||
# elif defined(__linux__)
|
||||
# elif defined(__linux__) || defined(__APPLE__)
|
||||
const char *homeDir = getenv("HOME");
|
||||
if (homeDir == nullptr) {
|
||||
#if defined(__linux__)
|
||||
homeDir = getpwuid(getuid())->pw_dir;
|
||||
#elif defined(__APPLE__)
|
||||
homeDir = GetHomeDirectory();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (homeDir != nullptr) {
|
||||
|
@ -13,6 +13,8 @@
|
||||
#elif defined(__linux__)
|
||||
# define Status int
|
||||
# include <X11/extensions/Xrandr.h>
|
||||
#elif defined(__APPLE__)
|
||||
# include "common/rt64_apple.h"
|
||||
#endif
|
||||
|
||||
#include "common/rt64_common.h"
|
||||
@ -198,6 +200,9 @@ namespace RT64 {
|
||||
}
|
||||
}
|
||||
|
||||
fullScreen = newFullScreen;
|
||||
# elif defined(__APPLE__)
|
||||
WindowToggleFullscreen(windowHandle.window);
|
||||
fullScreen = newFullScreen;
|
||||
# endif
|
||||
}
|
||||
@ -271,6 +276,8 @@ namespace RT64 {
|
||||
}
|
||||
|
||||
XRRFreeScreenResources(screenResources);
|
||||
# elif defined(__APPLE__)
|
||||
refreshRate = GetWindowRefreshRate(windowHandle.window);
|
||||
# endif
|
||||
}
|
||||
|
||||
@ -292,6 +299,11 @@ namespace RT64 {
|
||||
XGetWindowAttributes(windowHandle.display, windowHandle.window, &attributes);
|
||||
newWindowLeft = attributes.x;
|
||||
newWindowTop = attributes.y;
|
||||
# elif defined(__APPLE__)
|
||||
CocoaWindowAttributes attributes;
|
||||
GetWindowAttributes(windowHandle.window, &attributes);
|
||||
newWindowLeft = attributes.x;
|
||||
newWindowTop = attributes.y;
|
||||
# endif
|
||||
|
||||
if ((windowLeft != newWindowLeft) || (windowTop != newWindowTop)) {
|
||||
|
@ -43,7 +43,9 @@ namespace RT64 {
|
||||
};
|
||||
#elif defined(__APPLE__)
|
||||
struct RenderWindow {
|
||||
NSWindow* window;
|
||||
void* window;
|
||||
void* layer;
|
||||
|
||||
bool operator==(const struct RenderWindow& rhs) const {
|
||||
return window == rhs.window;
|
||||
}
|
||||
@ -1689,4 +1691,4 @@ namespace RT64 {
|
||||
struct RenderInterfaceCapabilities {
|
||||
RenderShaderFormat shaderFormat = RenderShaderFormat::UNKNOWN;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -21,6 +21,12 @@
|
||||
//# define VULKAN_OBJECT_NAMES_ENABLED
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "vulkan/vulkan_beta.h"
|
||||
#include "vulkan/vulkan_metal.h"
|
||||
#include "common/rt64_apple.h"
|
||||
#endif
|
||||
|
||||
// TODO:
|
||||
// - Fix resource pools.
|
||||
|
||||
@ -48,6 +54,9 @@ namespace RT64 {
|
||||
VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
|
||||
# elif defined(__linux__)
|
||||
VK_KHR_XLIB_SURFACE_EXTENSION_NAME,
|
||||
# elif defined(__APPLE__)
|
||||
VK_EXT_METAL_SURFACE_EXTENSION_NAME,
|
||||
VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME,
|
||||
# endif
|
||||
};
|
||||
|
||||
@ -58,6 +67,10 @@ namespace RT64 {
|
||||
static const std::unordered_set<std::string> RequiredDeviceExtensions = {
|
||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
||||
VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME,
|
||||
VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME,
|
||||
# ifdef __APPLE__
|
||||
VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME,
|
||||
# endif
|
||||
# ifdef VULKAN_OBJECT_NAMES_ENABLED
|
||||
VK_EXT_DEBUG_UTILS_EXTENSION_NAME
|
||||
# endif
|
||||
@ -73,6 +86,7 @@ namespace RT64 {
|
||||
VK_KHR_PRESENT_ID_EXTENSION_NAME,
|
||||
VK_KHR_PRESENT_WAIT_EXTENSION_NAME,
|
||||
VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
|
||||
VK_EXT_LAYER_SETTINGS_EXTENSION_NAME
|
||||
};
|
||||
|
||||
// Common functions.
|
||||
@ -546,7 +560,9 @@ namespace RT64 {
|
||||
flags |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT;
|
||||
flags |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
|
||||
flags |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT;
|
||||
#ifndef __APPLE__
|
||||
flags |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
|
||||
#endif
|
||||
flags |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||
flags |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
|
||||
flags |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
||||
@ -1909,6 +1925,19 @@ namespace RT64 {
|
||||
fprintf(stderr, "vkCreateXlibSurfaceKHR failed with error code 0x%X.\n", res);
|
||||
return;
|
||||
}
|
||||
# elif defined(__APPLE__)
|
||||
assert(renderWindow.window != 0);
|
||||
assert(renderWindow.layer != 0);
|
||||
VkMetalSurfaceCreateInfoEXT surfaceCreateInfo = {};
|
||||
surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT;
|
||||
surfaceCreateInfo.pLayer = renderWindow.layer;
|
||||
|
||||
VulkanInterface *renderInterface = commandQueue->device->renderInterface;
|
||||
res = vkCreateMetalSurfaceEXT(renderInterface->instance, &surfaceCreateInfo, nullptr, &surface);
|
||||
if (res != VK_SUCCESS) {
|
||||
fprintf(stderr, "vkCreateMetalSurfaceEXT failed with error code 0x%X.\n", res);
|
||||
return;
|
||||
}
|
||||
# endif
|
||||
|
||||
VkBool32 presentSupported = false;
|
||||
@ -2039,7 +2068,14 @@ namespace RT64 {
|
||||
}
|
||||
|
||||
// Handle the error silently.
|
||||
#if defined(__APPLE__)
|
||||
// Under MoltenVK, VK_SUBOPTIMAL_KHR does not result in a valid state for rendering. We intentionally
|
||||
// only check for this error during present to avoid having to synchronize manually against the semaphore
|
||||
// signalled by vkAcquireNextImageKHR.
|
||||
if (res != VK_SUCCESS) {
|
||||
#else
|
||||
if ((res != VK_SUCCESS) && (res != VK_SUBOPTIMAL_KHR)) {
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2183,6 +2219,11 @@ namespace RT64 {
|
||||
// The attributes width and height members do not include the border.
|
||||
dstWidth = attributes.width;
|
||||
dstHeight = attributes.height;
|
||||
# elif defined(__APPLE__)
|
||||
CocoaWindowAttributes attributes;
|
||||
GetWindowAttributes(renderWindow.window, &attributes);
|
||||
dstWidth = attributes.width;
|
||||
dstHeight = attributes.height;
|
||||
# endif
|
||||
}
|
||||
|
||||
@ -3919,6 +3960,10 @@ namespace RT64 {
|
||||
createInfo.ppEnabledLayerNames = nullptr;
|
||||
createInfo.enabledLayerCount = 0;
|
||||
|
||||
#ifdef __APPLE__
|
||||
createInfo.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
|
||||
#endif
|
||||
|
||||
// Check for extensions.
|
||||
uint32_t extensionCount;
|
||||
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
|
||||
@ -4022,4 +4067,4 @@ namespace RT64 {
|
||||
std::unique_ptr<VulkanInterface> createdInterface = std::make_unique<VulkanInterface>();
|
||||
return createdInterface->isValid() ? std::move(createdInterface) : nullptr;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -17,6 +17,8 @@
|
||||
#define VK_USE_PLATFORM_ANDROID_KHR
|
||||
#elif defined(__linux__)
|
||||
#define VK_USE_PLATFORM_XLIB_KHR
|
||||
#elif defined(__APPLE__)
|
||||
#define VK_USE_PLATFORM_METAL_EXT
|
||||
#endif
|
||||
|
||||
#include "volk/volk.h"
|
||||
@ -403,4 +405,4 @@ namespace RT64 {
|
||||
const RenderInterfaceCapabilities &getCapabilities() const override;
|
||||
bool isValid() const;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user