Last active
July 2, 2024 18:26
-
-
Save thatcosmonaut/16c3dc5259f6d5ddb7a685f789fe6f23 to your computer and use it in GitHub Desktop.
Automated backporting from SDL3 -> Refresh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import argparse | |
sdl_license_text = """/* | |
Simple DirectMedia Layer | |
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org> | |
This software is provided 'as-is', without any express or implied | |
warranty. In no event will the authors be held liable for any damages | |
arising from the use of this software. | |
Permission is granted to anyone to use this software for any purpose, | |
including commercial applications, and to alter it and redistribute it | |
freely, subject to the following restrictions: | |
1. The origin of this software must not be misrepresented; you must not | |
claim that you wrote the original software. If you use this software | |
in a product, an acknowledgment in the product documentation would be | |
appreciated but is not required. | |
2. Altered source versions must be plainly marked as such, and must not be | |
misrepresented as being the original software. | |
3. This notice may not be removed or altered from any source distribution. | |
*/""" | |
refresh_license_text = """/* Refresh - a cross-platform hardware-accelerated graphics library with modern capabilities | |
* | |
* Copyright (c) 2020-2024 Evan Hemsley | |
* | |
* This software is provided 'as-is', without any express or implied warranty. | |
* In no event will the authors be held liable for any damages arising from | |
* the use of this software. | |
* | |
* Permission is granted to anyone to use this software for any purpose, | |
* including commercial applications, and to alter it and redistribute it | |
* freely, subject to the following restrictions: | |
* | |
* 1. The origin of this software must not be misrepresented; you must not | |
* claim that you wrote the original software. If you use this software in a | |
* product, an acknowledgment in the product documentation would be | |
* appreciated but is not required. | |
* | |
* 2. Altered source versions must be plainly marked as such, and must not be | |
* misrepresented as being the original software. | |
* | |
* 3. This notice may not be removed or altered from any source distribution. | |
* | |
* Evan "cosmonaut" Hemsley <evan@moonside.games> | |
* | |
*/ | |
""" | |
sdl_alternate_license_text = '''/* | |
Simple DirectMedia Layer | |
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org> | |
This software is provided 'as-is', without any express or implied | |
warranty. In no event will the authors be held liable for any damages | |
arising from the use of this software. | |
Permission is granted to anyone to use this software for any purpose, | |
including commercial applications, and to alter it and redistribute it | |
freely, subject to the following restrictions: | |
1. The origin of this software must not be misrepresented; you must not | |
claim that you wrote the original software. If you use this software | |
in a product, an acknowledgment in the product documentation would be | |
appreciated but is not required. | |
2. Altered source versions must be plainly marked as such, and must not be | |
misrepresented as being the original software. | |
3. This notice may not be removed or altered from any source distribution. | |
*/''' | |
sdl_even_more_alternate_license_text = '''/* | |
Simple DirectMedia Layer | |
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org> | |
This software is provided 'as-is', without any express or implied | |
warranty. In no event will the authors be held liable for any damages | |
arising from the use of this software. | |
Permission is granted to anyone to use this software for any purpose, | |
including commercial applications, and to alter it and redistribute it | |
freely, subject to the following restrictions: | |
1. The origin of this software must not be misrepresented; you must not | |
claim that you wrote the original software. If you use this software | |
in a product, an acknowledgment in the product documentation would be | |
appreciated but is not required. | |
2. Altered source versions must be plainly marked as such, and must not be | |
misrepresented as being the original software. | |
3. This notice may not be removed or altered from any source distribution. | |
*/''' | |
include_h_find = '''#define SDL_GPU_H | |
#include <SDL3/SDL_stdinc.h> | |
''' | |
include_h_replace = '''#define REFRESH_H | |
#include "SDL.h" | |
#include <SDL_stdinc.h> | |
#ifdef _WIN32 | |
#define REFRESHAPI __declspec(dllexport) | |
#define REFRESHCALL __cdecl | |
#else | |
#define REFRESHAPI | |
#define REFRESHCALL | |
#endif | |
/* -Wpedantic nameless union/struct silencing */ | |
#ifndef REFRESHNAMELESS | |
#ifdef __GNUC__ | |
#define REFRESHNAMELESS __extension__ | |
#else | |
#define REFRESHNAMELESS | |
#endif /* __GNUC__ */ | |
#endif /* REFRESHNAMELESS */ | |
''' | |
create_device_find = ''' SDL_VideoDevice *_this = SDL_GetVideoDevice(); | |
if (_this == NULL) { | |
SDL_SetError("Video subsystem not initialized"); | |
return NULL; | |
} | |
selectedBackend = SDL_GpuSelectBackend(_this, preferredBackends); | |
''' | |
create_device_replace = ''' | |
selectedBackend = Refresh_SelectBackend(preferredBackends); | |
''' | |
vulkan_c_app_info_find = ''' appInfo.pEngineName = "SDLGPU"; | |
appInfo.engineVersion = SDL_VERSION;''' | |
vulkan_c_app_info_replace = ''' appInfo.pEngineName = "Refresh"; | |
appInfo.engineVersion = ((2 * 100 * 100) + (0 * 100) + (0));''' | |
vulkan_c_include_find = '''#define VK_NO_PROTOTYPES | |
#include "../../video/khronos/vulkan/vulkan.h" | |
#include "SDL_hashtable.h" | |
#include <SDL3/SDL_vulkan.h> | |
#include "../SDL_gpu_driver.h"''' | |
vulkan_c_include_replace = '''#define VK_NO_PROTOTYPES | |
#include <vulkan/vulkan.h> | |
#include <SDL.h> | |
#include <SDL_video.h> | |
#include <SDL_vulkan.h> | |
#include "Refresh_driver.h"''' | |
vulkan_c_create_surface_find = ''' if (!SDL_Vulkan_CreateSurface( | |
dummyWindowHandle, | |
renderer->instance, | |
NULL, /* FIXME: VAllocationCallbacks */ | |
&surface)) { | |
''' | |
vulkan_c_create_surface_replace = ''' if (!SDL_Vulkan_CreateSurface( | |
dummyWindowHandle, | |
renderer->instance, | |
&surface)) { | |
''' | |
vulkan_c_create_window_find = ''' dummyWindowHandle = SDL_CreateWindow( | |
"SDL_Gpu Vulkan", | |
128, | |
128, | |
SDL_WINDOW_VULKAN | SDL_WINDOW_HIDDEN);''' | |
vulkan_c_create_window_replace = ''' dummyWindowHandle = SDL_CreateWindow( | |
"Refresh Vulkan", | |
0, 0, | |
128, 128, | |
SDL_WINDOW_VULKAN | SDL_WINDOW_HIDDEN);''' | |
vulkan_c_dummy_surface_find = ''' if (_this->Vulkan_CreateSurface( | |
_this, | |
window, | |
renderer->instance, | |
NULL, | |
&surface) < 0) { | |
return SDL_FALSE; | |
}''' | |
vulkan_c_dummy_surface_replace = ''' if (!SDL_Vulkan_CreateSurface( | |
window, | |
renderer->instance, | |
&surface)) { | |
return SDL_FALSE; | |
}''' | |
vulkan_c_destroy_surface_one_indent_find = ''' SDL_Vulkan_DestroySurface( | |
renderer->instance, | |
surface, | |
NULL);''' | |
vulkan_c_destroy_surface_one_indent_replace = ''' renderer->vkDestroySurfaceKHR( | |
renderer->instance, | |
surface, | |
NULL);''' | |
vulkan_c_destroy_surface_two_indent_find = ''' SDL_Vulkan_DestroySurface( | |
renderer->instance, | |
surface, | |
NULL);''' | |
vulkan_c_destroy_surface_two_indent_replace = ''' renderer->vkDestroySurfaceKHR( | |
renderer->instance, | |
surface, | |
NULL);''' | |
vulkan_c_assert_video_device_find = ''' SDL_assert(_this && _this->Vulkan_CreateSurface); | |
''' | |
vulkan_c_assert_video_device_replace = '' | |
vulkan_c_create_surface_from_video_device_find = ''' if (_this->Vulkan_CreateSurface( | |
_this, | |
windowData->window, | |
renderer->instance, | |
NULL, /* FIXME: VAllocationCallbacks */ | |
&swapchainData->surface) < 0) { | |
SDL_free(swapchainData); | |
SDL_LogError( | |
SDL_LOG_CATEGORY_APPLICATION, | |
"Vulkan_CreateSurface failed: %s", | |
SDL_GetError()); | |
return SDL_FALSE; | |
}''' | |
vulkan_c_create_surface_from_video_device_replace = ''' if (!SDL_Vulkan_CreateSurface( | |
windowData->window, | |
renderer->instance, | |
&swapchainData->surface)) { | |
SDL_free(swapchainData); | |
SDL_LogError( | |
SDL_LOG_CATEGORY_APPLICATION, | |
"Vulkan_CreateSurface failed: %s", | |
SDL_GetError()); | |
return SDL_FALSE; | |
}''' | |
vulkan_c_create_surface_null_check_find = ''' if (_this->Vulkan_CreateSurface == NULL) { | |
return SDL_FALSE; | |
} | |
''' | |
vulkan_c_create_surface_null_check_replace = '' | |
vulkan_c_original_extension_names_find = ''' const char *const *originalInstanceExtensionNames; | |
''' | |
vulkan_c_original_extension_names_replace = '' | |
vulkan_c_get_instance_extension_find = ''' originalInstanceExtensionNames = SDL_Vulkan_GetInstanceExtensions(&instanceExtensionCount); | |
if (!originalInstanceExtensionNames) { | |
SDL_LogError( | |
SDL_LOG_CATEGORY_APPLICATION, | |
"SDL_Vulkan_GetInstanceExtensions(): getExtensionCount: %s", | |
SDL_GetError()); | |
return 0; | |
}''' | |
vulkan_c_get_instance_extension_replace = ''' if (!SDL_Vulkan_GetInstanceExtensions( | |
(SDL_Window *)deviceWindowHandle, | |
&instanceExtensionCount, | |
NULL)) { | |
SDL_LogError( | |
SDL_LOG_CATEGORY_APPLICATION, | |
"SDL_Vulkan_GetInstanceExtensions(): getExtensionCount: %s", | |
SDL_GetError()); | |
return SDL_FALSE; | |
}''' | |
vulkan_c_copy_instance_extension_find = ''' SDL_memcpy(instanceExtensionNames, originalInstanceExtensionNames, instanceExtensionCount * sizeof(const char *)); | |
''' | |
vulkan_c_copy_instance_extension_replace = ''' | |
if (!SDL_Vulkan_GetInstanceExtensions( | |
deviceWindowHandle, | |
&instanceExtensionCount, | |
instanceExtensionNames)) { | |
SDL_LogError( | |
SDL_LOG_CATEGORY_APPLICATION, | |
"SDL_Vulkan_GetInstanceExtensions(): %s", | |
SDL_GetError()); | |
} | |
''' | |
vulkan_c_create_surface_abi_break_find = ''' if (SDL_Vulkan_CreateSurface( | |
dummyWindowHandle, | |
renderer->instance, | |
NULL, /* FIXME: VAllocationCallbacks */ | |
&surface) < 0) {''' | |
vulkan_c_create_surface_abi_break_replace = ''' if (!SDL_Vulkan_CreateSurface( | |
dummyWindowHandle, | |
renderer->instance, | |
&surface)) {''' | |
vulkan_c_fetch_window_data_find = ''' SDL_PropertiesID properties = SDL_GetWindowProperties(window); | |
return (WindowData *)SDL_GetProperty(properties, WINDOW_PROPERTY_DATA, NULL); | |
''' | |
vulkan_c_fetch_window_data_replace = ''' return (WindowData *)SDL_GetWindowData(window, WINDOW_PROPERTY_DATA); | |
''' | |
vulkan_c_set_window_data_find = '''SDL_SetProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA, windowData);''' | |
vulkan_c_set_window_data_replace = '''SDL_SetWindowData(window, WINDOW_PROPERTY_DATA, windowData);''' | |
vulkan_c_clear_window_data_find = '''SDL_ClearProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA);''' | |
vulkan_c_clear_window_data_replace = '''SDL_SetWindowData(window, WINDOW_PROPERTY_DATA, NULL);''' | |
vulkan_c_thread_id_find = ''' SDL_ThreadID threadID = SDL_GetCurrentThreadID(); | |
''' | |
vulkan_c_thread_id_replace = ''' SDL_threadID threadID = SDL_ThreadID(); | |
''' | |
vulkan_c_sync_window_find = ''' /* Sync now to be sure that our swapchain size is correct */ | |
SDL_SyncWindow(windowData->window);''' | |
vulkan_c_sync_window_replace = ''' /* Should sync now to be sure that our swapchain size is correct */ | |
/* TODO: how to backport SyncWindow? */ | |
''' | |
vulkan_c_prepare_driver_find = '''static Uint8 VULKAN_PrepareDriver(SDL_VideoDevice *_this)''' | |
vulkan_c_prepare_driver_replace = '''static SDL_bool VULKAN_PrepareDriver()''' | |
d3d11_c_dxgi_find = '''#ifdef _WIN32 | |
dxgiHandle = (HWND)SDL_GetProperty(SDL_GetWindowProperties(windowData->window), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL); | |
#else''' | |
d3d11_c_dxgi_replace = '''#ifdef _WIN32 | |
SDL_SysWMinfo info; | |
SDL_VERSION(&info.version); | |
SDL_GetWindowWMInfo((SDL_Window *)windowData->window, &info); | |
dxgiHandle = info.info.win.window; | |
#else | |
''' | |
d3d11_c_include_syswm_find = '''#include <dxgidebug.h>''' | |
d3d11_c_include_syswm_replace = '''#include <dxgidebug.h> | |
#ifdef _WIN32 | |
#include <SDL_syswm.h> | |
#endif''' | |
d3d11_c_fetch_window_data_find = ''' SDL_PropertiesID properties = SDL_GetWindowProperties(window); | |
return (D3D11WindowData *)SDL_GetProperty(properties, WINDOW_PROPERTY_DATA, NULL); | |
''' | |
d3d11_c_fetch_window_data_replace = ''' return (D3D11WindowData *)SDL_GetWindowData(window, WINDOW_PROPERTY_DATA); | |
''' | |
d3d11_c_prepare_driver_find = '''static Uint8 D3D11_PrepareDriver(SDL_VideoDevice *_this)''' | |
d3d11_c_prepare_driver_replace = '''static SDL_bool D3D11_PrepareDriver()''' | |
metal_m_fetch_window_data_find = ''' SDL_PropertiesID properties = SDL_GetWindowProperties(window); | |
return (MetalWindowData *)SDL_GetProperty(properties, WINDOW_PROPERTY_DATA, NULL); | |
''' | |
metal_m_fetch_window_data_replace = ''' return (MetalWindowData*) SDL_GetWindowData(window, WINDOW_PROPERTY_DATA); | |
''' | |
metal_m_prepare_driver_find = '''static SDL_bool METAL_PrepareDriver(SDL_VideoDevice *_this) | |
{ | |
/* FIXME: Add a macOS / iOS version check! Maybe support >= 10.14? */ | |
return (_this->Metal_CreateView != NULL); | |
}''' | |
metal_m_prepare_driver_replace = '''static SDL_bool METAL_PrepareDriver() | |
{ | |
/* FIXME: Add a macOS / iOS version check! Maybe support >= 10.14? */ | |
return SDL_TRUE; | |
}''' | |
filepaths = [ | |
['include/SDL3/SDL_gpu.h', 'include/Refresh.h'], | |
['src/gpu/SDL_gpu.c', 'src/Refresh.c'], | |
['src/gpu/SDL_gpu_driver.h', 'src/Refresh_driver.h'], | |
['src/gpu/SDL_gpu_spirv_c.h', 'src/Refresh_spirv_c.h'], | |
['src/gpu/SDL_gpu_spirv.c', 'src/Refresh_spirv.c'], | |
['src/gpu/vulkan/SDL_gpu_vulkan.c', 'src/vulkan/Refresh_vulkan.c'], | |
['src/gpu/metal/SDL_gpu_metal.m', 'src/metal/Refresh_metal.m'], | |
['src/gpu/d3d11/SDL_gpu_d3d11.c', 'src/d3d11/Refresh_d3d11.c'], | |
] | |
def backport_to_refresh(sdl_dir, refresh_dir, sdl_filepath, refresh_filepath): | |
sdl_filepath = sdl_dir + sdl_filepath | |
refresh_filepath = refresh_dir + refresh_filepath | |
with open(sdl_filepath, 'r') as file: | |
filedata = file.read() | |
# license and include fixups | |
filedata = filedata.replace(sdl_license_text, refresh_license_text) | |
filedata = filedata.replace(sdl_alternate_license_text, refresh_license_text) | |
filedata = filedata.replace(sdl_even_more_alternate_license_text, refresh_license_text) | |
filedata = filedata.replace('#include "SDL_internal.h"\n', '') | |
# include .h fixups | |
filedata = filedata.replace(include_h_find, include_h_replace) | |
filedata = filedata.replace('\n/**\n * \\file SDL_gpu.h\n *\n * Include file for SDL GPU API functions\n */\n\n', '') | |
filedata = filedata.replace('extern SDL_DECLSPEC', 'REFRESHAPI') | |
filedata = filedata.replace('SDLCALL ', '') | |
filedata = filedata.replace('since SDL 3.x.x', 'since Refresh 2.0.0') | |
# driver.h fixups | |
filedata = filedata.replace('Uint8 (*PrepareDriver)(SDL_VideoDevice *_this)', 'SDL_bool (*PrepareDriver)()') | |
filedata = filedata.replace('#define SDL_GPU_DRIVER_H\n\n', '#define REFRESH_DRIVER_H\n\n#include "Refresh.h"\n\n') | |
filedata = filedata.replace('#include "../video/SDL_sysvideo.h"\n\n', '') | |
# Refresh.c fixups | |
filedata = filedata.replace(create_device_find, create_device_replace) | |
# vulkan.c fixups | |
filedata = filedata.replace(vulkan_c_include_find, vulkan_c_include_replace) | |
filedata = filedata.replace(vulkan_c_app_info_find, vulkan_c_app_info_replace) | |
filedata = filedata.replace(vulkan_c_create_surface_find, vulkan_c_create_surface_replace) | |
filedata = filedata.replace(vulkan_c_create_window_find, vulkan_c_create_window_replace) | |
filedata = filedata.replace(vulkan_c_dummy_surface_find, vulkan_c_dummy_surface_replace) | |
filedata = filedata.replace(vulkan_c_assert_video_device_find, vulkan_c_assert_video_device_replace) | |
filedata = filedata.replace(vulkan_c_create_surface_from_video_device_find, vulkan_c_create_surface_from_video_device_replace) | |
filedata = filedata.replace(vulkan_c_create_surface_null_check_find, vulkan_c_create_surface_null_check_replace) | |
filedata = filedata.replace(vulkan_c_destroy_surface_one_indent_find, vulkan_c_destroy_surface_one_indent_replace) | |
filedata = filedata.replace(vulkan_c_destroy_surface_two_indent_find, vulkan_c_destroy_surface_two_indent_replace) | |
filedata = filedata.replace(vulkan_c_original_extension_names_find, vulkan_c_original_extension_names_replace) | |
filedata = filedata.replace(vulkan_c_get_instance_extension_find, vulkan_c_get_instance_extension_replace) | |
filedata = filedata.replace(vulkan_c_copy_instance_extension_find, vulkan_c_copy_instance_extension_replace) | |
filedata = filedata.replace(vulkan_c_create_surface_abi_break_find, vulkan_c_create_surface_abi_break_replace) | |
filedata = filedata.replace(vulkan_c_fetch_window_data_find, vulkan_c_fetch_window_data_replace) | |
filedata = filedata.replace(vulkan_c_set_window_data_find, vulkan_c_set_window_data_replace) | |
filedata = filedata.replace(vulkan_c_clear_window_data_find, vulkan_c_clear_window_data_replace) | |
filedata = filedata.replace(vulkan_c_sync_window_find, vulkan_c_sync_window_replace) | |
filedata = filedata.replace(vulkan_c_thread_id_find, vulkan_c_thread_id_replace) | |
filedata = filedata.replace(vulkan_c_sync_window_find, vulkan_c_sync_window_replace) | |
filedata = filedata.replace(vulkan_c_prepare_driver_find, vulkan_c_prepare_driver_replace) | |
# d3d11.c fixups | |
filedata = filedata.replace(d3d11_c_include_syswm_find, d3d11_c_include_syswm_replace) | |
filedata = filedata.replace(d3d11_c_dxgi_find, d3d11_c_dxgi_replace) | |
filedata = filedata.replace(d3d11_c_fetch_window_data_find, d3d11_c_fetch_window_data_replace) | |
filedata = filedata.replace(d3d11_c_prepare_driver_find, d3d11_c_prepare_driver_replace) | |
# metal.m fixups | |
filedata = filedata.replace(metal_m_fetch_window_data_find, metal_m_fetch_window_data_replace) | |
filedata = filedata.replace(metal_m_prepare_driver_find, metal_m_prepare_driver_replace) | |
# namespace fixups | |
filedata = filedata.replace('SDL_Gpu', 'Refresh_') | |
filedata = filedata.replace('SDL_gpu_', 'Refresh_') | |
filedata = filedata.replace('SDL_GPU_', 'REFRESH_') | |
filedata = filedata.replace('SDLTo', 'RefreshTo') | |
# video device fixups | |
filedata = filedata.replace('SDL_VideoDevice *_this = SDL_GetVideoDevice();\n', '') | |
filedata = filedata.replace('_this = SDL_GetVideoDevice();', '') | |
filedata = filedata.replace('SDL_VideoDevice *_this, ', '') | |
filedata = filedata.replace('SDL_VideoDevice *_this;', '') | |
filedata = filedata.replace('SDL_VideoDevice *_this', '') | |
filedata = filedata.replace('_this', '') | |
# hint fixups | |
filedata = filedata.replace('"SDL_HINT_GPU_BACKEND %s', '"REFRESH_HINT_BACKEND %s') | |
filedata = filedata.replace('SDL_HINT_GPU_BACKEND', '"REFRESH_HINT_BACKEND"') | |
# SDL3 -> SDL2 fixups | |
filedata = filedata.replace('SDL_AtomicInt', 'SDL_atomic_t') | |
filedata = filedata.replace('SDL_Mutex', 'SDL_mutex') | |
filedata = filedata.replace('SDL_ThreadID', 'SDL_threadID') | |
filedata = filedata.replace('SDL_threadID()', 'SDL_ThreadID()') # lol | |
with open(refresh_filepath, 'w') as file: | |
file.write(filedata) | |
parser = argparse.ArgumentParser("refresh_backport") | |
parser.add_argument("sdl_dir") | |
parser.add_argument("refresh_dir") | |
args = parser.parse_args() | |
for filepath in filepaths: | |
backport_to_refresh(args.sdl_dir, args.refresh_dir, filepath[0], filepath[1]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment