mirror of
https://github.com/rt64/rt64.git
synced 2025-03-14 04:19:02 +00:00
SDL Vulkan support.
This commit is contained in:
parent
67422c3b64
commit
76df0b4d9e
@ -3258,7 +3258,7 @@ namespace RT64 {
|
||||
D3D12MA::ALLOCATOR_DESC allocatorDesc = {};
|
||||
allocatorDesc.pDevice = d3d;
|
||||
allocatorDesc.pAdapter = adapter;
|
||||
allocatorDesc.Flags = D3D12MA::ALLOCATOR_FLAG_DEFAULT_POOLS_NOT_ZEROED;
|
||||
allocatorDesc.Flags = D3D12MA::ALLOCATOR_FLAG_DEFAULT_POOLS_NOT_ZEROED | D3D12MA::ALLOCATOR_FLAG_DONT_PREFER_SMALL_BUFFERS_COMMITTED;
|
||||
|
||||
res = D3D12MA::CreateAllocator(&allocatorDesc, &allocator);
|
||||
if (FAILED(res)) {
|
||||
|
@ -121,6 +121,8 @@ namespace RT64 {
|
||||
SDL_GetWindowWMInfo(sdlWindow, &wmInfo);
|
||||
# if defined(_WIN32)
|
||||
windowHandle = wmInfo.info.win.window;
|
||||
# elif defined(RT64_SDL_WINDOW_VULKAN)
|
||||
windowHandle = sdlWindow;
|
||||
# elif defined(__ANDROID__)
|
||||
static_assert(false && "Android unimplemented");
|
||||
# elif defined(__linux__)
|
||||
@ -236,6 +238,21 @@ namespace RT64 {
|
||||
if ((refreshRate % 10) == 9) {
|
||||
refreshRate++;
|
||||
}
|
||||
# elif defined(RT64_SDL_WINDOW_VULKAN)
|
||||
int displayIndex = SDL_GetWindowDisplayIndex(windowHandle);
|
||||
if (displayIndex < 0) {
|
||||
fprintf(stderr, "SDL_GetWindowDisplayIndex failed. Error: %s.\n", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_DisplayMode displayMode = {};
|
||||
int modeResult = SDL_GetCurrentDisplayMode(displayIndex, &displayMode);
|
||||
if (modeResult != 0) {
|
||||
fprintf(stderr, "SDL_GetCurrentDisplayMode failed. Error: %s.\n", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
refreshRate = displayMode.refresh_rate;
|
||||
# elif defined(__linux__)
|
||||
// Sourced from: https://stackoverflow.com/a/66865623
|
||||
XRRScreenResources *screenResources = XRRGetScreenResources(windowHandle.display, windowHandle.window);
|
||||
@ -287,6 +304,8 @@ namespace RT64 {
|
||||
GetWindowRect(windowHandle, &rect);
|
||||
newWindowLeft = rect.left;
|
||||
newWindowTop = rect.top;
|
||||
# elif defined(RT64_SDL_WINDOW_VULKAN)
|
||||
SDL_GetWindowPosition(windowHandle, &newWindowLeft, &newWindowTop);
|
||||
# elif defined(__linux__)
|
||||
XWindowAttributes attributes;
|
||||
XGetWindowAttributes(windowHandle.display, windowHandle.window, &attributes);
|
||||
|
@ -26,10 +26,16 @@
|
||||
typedef struct _NSWindow NSWindow;
|
||||
#endif
|
||||
|
||||
#ifdef RT64_SDL_WINDOW_VULKAN
|
||||
#include <SDL_vulkan.h>
|
||||
#endif
|
||||
|
||||
namespace RT64 {
|
||||
#if defined(_WIN64)
|
||||
// Native HWND handle to the target window.
|
||||
typedef HWND RenderWindow;
|
||||
#elif defined(RT64_SDL_WINDOW_VULKAN)
|
||||
typedef SDL_Window *RenderWindow;
|
||||
#elif defined(__ANDROID__)
|
||||
typedef ANativeWindow* RenderWindow;
|
||||
#elif defined(__linux__)
|
||||
|
@ -1921,6 +1921,13 @@ namespace RT64 {
|
||||
fprintf(stderr, "vkCreateWin32SurfaceKHR failed with error code 0x%X.\n", res);
|
||||
return;
|
||||
}
|
||||
# elif defined(RT64_SDL_WINDOW_VULKAN)
|
||||
VulkanInterface *renderInterface = commandQueue->device->renderInterface;
|
||||
SDL_bool sdlRes = SDL_Vulkan_CreateSurface(renderWindow, renderInterface->instance, &surface);
|
||||
if (sdlRes == SDL_FALSE) {
|
||||
fprintf(stderr, "SDL_Vulkan_CreateSurface failed with error %s.\n", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
# elif defined(__ANDROID__)
|
||||
assert(renderWindow != nullptr);
|
||||
VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo = {};
|
||||
@ -2056,6 +2063,12 @@ namespace RT64 {
|
||||
}
|
||||
|
||||
bool VulkanSwapChain::present(uint32_t textureIndex, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount) {
|
||||
constexpr uint64_t MaxFrameDelay = 1;
|
||||
if (commandQueue->device->capabilities.presentWait && (currentPresentId > MaxFrameDelay)) {
|
||||
constexpr uint64_t waitTimeout = 100000000;
|
||||
vkWaitForPresentKHR(commandQueue->device->vk, vk, currentPresentId - MaxFrameDelay, waitTimeout);
|
||||
}
|
||||
|
||||
thread_local std::vector<VkSemaphore> waitSemaphoresVector;
|
||||
waitSemaphoresVector.clear();
|
||||
for (uint32_t i = 0; i < waitSemaphoreCount; i++) {
|
||||
@ -2070,6 +2083,15 @@ namespace RT64 {
|
||||
presentInfo.pImageIndices = &textureIndex;
|
||||
presentInfo.pWaitSemaphores = !waitSemaphoresVector.empty() ? waitSemaphoresVector.data() : nullptr;
|
||||
presentInfo.waitSemaphoreCount = uint32_t(waitSemaphoresVector.size());
|
||||
|
||||
VkPresentIdKHR presentId = {};
|
||||
if (commandQueue->device->capabilities.presentWait) {
|
||||
currentPresentId++;
|
||||
presentId.sType = VK_STRUCTURE_TYPE_PRESENT_ID_KHR;
|
||||
presentId.pPresentIds = ¤tPresentId;
|
||||
presentId.swapchainCount = 1;
|
||||
presentInfo.pNext = &presentId;
|
||||
}
|
||||
|
||||
VkResult res;
|
||||
{
|
||||
@ -2228,6 +2250,8 @@ namespace RT64 {
|
||||
GetClientRect(renderWindow, &rect);
|
||||
dstWidth = rect.right - rect.left;
|
||||
dstHeight = rect.bottom - rect.top;
|
||||
# elif defined(RT64_SDL_WINDOW_VULKAN)
|
||||
SDL_GetWindowSize(renderWindow, (int *)(&dstWidth), (int *)(&dstHeight));
|
||||
# elif defined(__ANDROID__)
|
||||
dstWidth = ANativeWindow_getWidth(renderWindow);
|
||||
dstHeight = ANativeWindow_getHeight(renderWindow);
|
||||
@ -3968,7 +3992,11 @@ namespace RT64 {
|
||||
|
||||
// VulkanInterface
|
||||
|
||||
#if RT64_SDL_WINDOW_VULKAN
|
||||
VulkanInterface::VulkanInterface(RenderWindow sdlWindow) {
|
||||
#else
|
||||
VulkanInterface::VulkanInterface() {
|
||||
#endif
|
||||
VkResult res = volkInitialize();
|
||||
if (res != VK_SUCCESS) {
|
||||
fprintf(stderr, "volkInitialize failed with error code 0x%X.\n", res);
|
||||
@ -3995,11 +4023,31 @@ namespace RT64 {
|
||||
std::vector<VkExtensionProperties> availableExtensions(extensionCount);
|
||||
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, availableExtensions.data());
|
||||
|
||||
std::unordered_set<std::string> missingRequiredExtensions = RequiredInstanceExtensions;
|
||||
std::unordered_set<std::string> requiredExtensions = RequiredInstanceExtensions;
|
||||
std::unordered_set<std::string> supportedOptionalExtensions;
|
||||
# if DLSS_ENABLED
|
||||
const std::unordered_set<std::string> dlssExtensions = DLSS::getRequiredInstanceExtensionsVulkan();
|
||||
# endif
|
||||
|
||||
# if RT64_SDL_WINDOW_VULKAN
|
||||
// Push the extensions specified by SDL as required.
|
||||
// SDL2 has this awkward requirement for the window to pull the extensions from.
|
||||
// This can be removed when upgrading to SDL3.
|
||||
if (sdlWindow != nullptr) {
|
||||
uint32_t sdlVulkanExtensionCount = 0;
|
||||
if (SDL_Vulkan_GetInstanceExtensions(sdlWindow, &sdlVulkanExtensionCount, nullptr)) {
|
||||
std::vector<char *> sdlVulkanExtensions;
|
||||
sdlVulkanExtensions.resize(sdlVulkanExtensionCount);
|
||||
if (SDL_Vulkan_GetInstanceExtensions(sdlWindow, &sdlVulkanExtensionCount, (const char **)(sdlVulkanExtensions.data()))) {
|
||||
for (char *sdlVulkanExtension : sdlVulkanExtensions) {
|
||||
requiredExtensions.insert(sdlVulkanExtension);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
std::unordered_set<std::string> missingRequiredExtensions = requiredExtensions;
|
||||
for (uint32_t i = 0; i < extensionCount; i++) {
|
||||
const std::string extensionName(availableExtensions[i].extensionName);
|
||||
missingRequiredExtensions.erase(extensionName);
|
||||
@ -4024,7 +4072,7 @@ namespace RT64 {
|
||||
}
|
||||
|
||||
std::vector<const char *> enabledExtensions;
|
||||
for (const std::string &extension : RequiredInstanceExtensions) {
|
||||
for (const std::string &extension : requiredExtensions) {
|
||||
enabledExtensions.push_back(extension.c_str());
|
||||
}
|
||||
|
||||
@ -4087,8 +4135,15 @@ namespace RT64 {
|
||||
|
||||
// Global creation function.
|
||||
|
||||
#if RT64_SDL_WINDOW_VULKAN
|
||||
std::unique_ptr<RenderInterface> CreateVulkanInterface(RenderWindow sdlWindow) {
|
||||
std::unique_ptr<VulkanInterface> createdInterface = std::make_unique<VulkanInterface>(sdlWindow);
|
||||
return createdInterface->isValid() ? std::move(createdInterface) : nullptr;
|
||||
}
|
||||
#else
|
||||
std::unique_ptr<RenderInterface> CreateVulkanInterface() {
|
||||
std::unique_ptr<VulkanInterface> createdInterface = std::make_unique<VulkanInterface>();
|
||||
return createdInterface->isValid() ? std::move(createdInterface) : nullptr;
|
||||
}
|
||||
#endif
|
||||
};
|
@ -213,6 +213,7 @@ namespace RT64 {
|
||||
VkPresentModeKHR requiredPresentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||
VkCompositeAlphaFlagBitsKHR pickedAlphaFlag = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||
std::vector<VulkanTexture> textures;
|
||||
uint64_t currentPresentId = 0;
|
||||
bool immediatePresentModeSupported = false;
|
||||
|
||||
VulkanSwapChain(VulkanCommandQueue *commandQueue, RenderWindow renderWindow, uint32_t textureCount, RenderFormat format);
|
||||
@ -402,7 +403,11 @@ namespace RT64 {
|
||||
VkApplicationInfo appInfo = {};
|
||||
RenderInterfaceCapabilities capabilities;
|
||||
|
||||
# if RT64_SDL_WINDOW_VULKAN
|
||||
VulkanInterface(RenderWindow sdlWindow);
|
||||
#else
|
||||
VulkanInterface();
|
||||
# endif
|
||||
~VulkanInterface() override;
|
||||
std::unique_ptr<RenderDevice> createDevice() override;
|
||||
const RenderInterfaceCapabilities &getCapabilities() const override;
|
||||
|
Loading…
x
Reference in New Issue
Block a user