├── src ├── parallel-rdp │ ├── COMMIT │ ├── parallel-rdp │ │ ├── shaders │ │ │ ├── fb_formats.h │ │ │ ├── load_span_offsets.h │ │ │ ├── load_attribute_setup.h │ │ │ ├── vi_deinterlace.frag │ │ │ ├── load_scissor_state.h │ │ │ ├── clear_indirect_buffer.comp │ │ │ ├── clear_super_sampled_write_mask.comp │ │ │ ├── fullscreen.vert │ │ │ ├── vi_blend_fields.frag │ │ │ ├── clear_write_mask.comp │ │ │ ├── vi_deinterlace.vert │ │ │ ├── load_depth_blend_state.h │ │ │ ├── load_span_setup.h │ │ │ ├── load_static_raster_state.h │ │ │ ├── load_triangle_setup.h │ │ │ ├── store_span_setup.h │ │ │ ├── load_tile_info.h │ │ │ ├── z_encode.h │ │ │ ├── load_derived_setup.h │ │ │ ├── vi_debug.h │ │ │ ├── masked_rdram_resolve.comp │ │ │ ├── noise.h │ │ │ ├── vi_status.h │ │ │ ├── clamping.h │ │ │ ├── coverage.h │ │ │ ├── dither.h │ │ │ ├── slangmosh.json │ │ │ ├── vi_divot.frag │ │ │ ├── small_types.h │ │ │ ├── extract_vram.comp │ │ │ ├── update_upscaled_domain_post.comp │ │ │ └── ubershader.comp │ │ ├── command_ring.hpp │ │ └── worker_thread.hpp │ ├── util │ │ ├── thread_name.cpp │ │ ├── thread_name.hpp │ │ ├── thread_id.hpp │ │ ├── enum_cast.hpp │ │ ├── logging.cpp │ │ ├── thread_id.cpp │ │ ├── stack_allocator.hpp │ │ ├── timer.hpp │ │ ├── aligned_alloc.hpp │ │ ├── timeline_trace_file.hpp │ │ ├── aligned_alloc.cpp │ │ ├── hash.hpp │ │ ├── read_write_lock.hpp │ │ ├── bitops.hpp │ │ ├── timer.cpp │ │ └── object_pool.hpp │ ├── LICENSE │ ├── vulkan │ │ ├── cookie.cpp │ │ ├── pipeline_event.cpp │ │ ├── fence_manager.hpp │ │ ├── semaphore_manager.hpp │ │ ├── event_manager.hpp │ │ ├── limits.hpp │ │ ├── sampler.cpp │ │ ├── cookie.hpp │ │ ├── fence_manager.cpp │ │ ├── vulkan_common.hpp │ │ ├── quirks.hpp │ │ ├── semaphore_manager.cpp │ │ ├── command_pool.hpp │ │ ├── pipeline_event.hpp │ │ ├── event_manager.cpp │ │ ├── vulkan_headers.hpp │ │ ├── buffer.cpp │ │ ├── semaphore.cpp │ │ ├── fence.hpp │ │ ├── vulkan_prerotate.hpp │ │ ├── sampler.hpp │ │ ├── buffer_pool.hpp │ │ ├── fence.cpp │ │ ├── renderdoc_capture.cpp │ │ └── semaphore.hpp │ ├── vulkan-headers │ │ └── include │ │ │ └── vulkan │ │ │ ├── vulkan_vi.h │ │ │ ├── vulkan_ios.h │ │ │ ├── vulkan_macos.h │ │ │ ├── vulkan_xlib_xrandr.h │ │ │ ├── vulkan_metal.h │ │ │ ├── vulkan_fuchsia.h │ │ │ ├── vulkan.h │ │ │ ├── vulkan_beta.h │ │ │ ├── vulkan_ggp.h │ │ │ ├── vulkan_directfb.h │ │ │ ├── vulkan_wayland.h │ │ │ ├── vulkan_xlib.h │ │ │ ├── vulkan_xcb.h │ │ │ ├── vk_sdk_platform.h │ │ │ └── vk_platform.h │ └── config.mk ├── config_gui.h ├── gfx_m64p.h ├── ini.h ├── parallel_imp.h ├── config.h ├── glguts.h ├── ini.c ├── config.c ├── gfxstructdefs.h ├── config_gui_resources.h └── wgl_ext.h ├── .gitmodules └── README.md /src/parallel-rdp/COMMIT: -------------------------------------------------------------------------------- 1 | b2d44663a416c7f3ccb79918b5d8203f58e1802f 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/parallel-rdp"] 2 | path = src/parallel-rdp 3 | url = https://github.com/Themaister/parallel-rdp-standalone.git 4 | -------------------------------------------------------------------------------- /src/config_gui.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_GUI 2 | #define CONFIG_GUI 3 | 4 | extern HMODULE config_gui_hInstance; 5 | extern void config_gui_open(HWND hParent); 6 | 7 | #endif // CONFIG_GUI -------------------------------------------------------------------------------- /src/gfx_m64p.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef _WIN32 4 | #define DLSYM(a, b) GetProcAddress(a, b) 5 | #else 6 | #include 7 | #define DLSYM(a, b) dlsym(a, b) 8 | #endif 9 | 10 | 11 | extern uint32_t rdram_size; 12 | extern GFX_INFO gfx; 13 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/fb_formats.h: -------------------------------------------------------------------------------- 1 | #ifndef FB_FORMATS_H_ 2 | #define FB_FORMATS_H_ 3 | 4 | const int FB_FMT_I4 = 0; 5 | const int FB_FMT_I8 = 1; 6 | const int FB_FMT_RGBA5551 = 2; 7 | const int FB_FMT_IA88 = 3; 8 | const int FB_FMT_RGBA8888 = 4; 9 | 10 | #endif -------------------------------------------------------------------------------- /src/ini.h: -------------------------------------------------------------------------------- 1 | #ifndef INI_H 2 | #define INI_H 3 | 4 | #include 5 | #include 6 | 7 | extern char ini_file[MAX_PATH]; 8 | 9 | extern void ini_init(); 10 | extern bool ini_set_value(const char* key, int value); 11 | extern bool ini_get_value(const char* key, int* value); 12 | 13 | #endif // INI_H 14 | -------------------------------------------------------------------------------- /src/parallel-rdp/util/thread_name.cpp: -------------------------------------------------------------------------------- 1 | #include "thread_name.hpp" 2 | 3 | #ifdef __linux__ 4 | #include 5 | #endif 6 | 7 | namespace Util 8 | { 9 | void set_current_thread_name(const char *name) 10 | { 11 | #ifdef __linux__ 12 | pthread_setname_np(pthread_self(), name); 13 | #else 14 | // TODO: Kinda messy. 15 | (void)name; 16 | #endif 17 | } 18 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pj64-parallelrdp 2 | 3 | Implementation of Themaister's Parallel-RDP simulator for PJ64. 4 | Vulkan is used as the GPU compute backend, and OpenGL 3.3 is 5 | used for the blitting of image buffers captured from the backend. 6 | 7 | Made after a few days of messing around with GCC and some misc. sources. 8 | 9 | To compile using MSYS2 10 | 1) Clone/fork the Github repo only. 11 | 2) use "make all platform=win" 12 | 13 | For best results: use cxd4's RSP plugin. Zilmar's RSP has several LLE GFX bugs. -------------------------------------------------------------------------------- /src/parallel_imp.h: -------------------------------------------------------------------------------- 1 | 2 | #include "gfx_1.3.h" 3 | #include "glguts.h" 4 | #include "gfxstructdefs.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" 8 | { 9 | #endif 10 | 11 | extern int32_t vk_rescaling; 12 | extern bool vk_ssreadbacks; 13 | extern bool vk_ssdither; 14 | 15 | extern unsigned vk_overscan; 16 | extern unsigned vk_downscaling_steps; 17 | extern bool vk_native_texture_lod; 18 | extern bool vk_native_tex_rect; 19 | extern bool vk_synchronous, vk_divot_filter, vk_gamma_dither; 20 | extern bool vk_vi_aa, vk_vi_scale, vk_dither_filter; 21 | extern bool vk_interlacing; 22 | 23 | void vk_rasterize(); 24 | void vk_process_commands(); 25 | bool vk_init(); 26 | void vk_destroy(); 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | -------------------------------------------------------------------------------- /src/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | #define KEY_FULLSCREEN 0 5 | #define KEY_UPSCALING 1 6 | #define KEY_SCREEN_WIDTH 2 7 | #define KEY_SCREEN_HEIGHT 3 8 | #define KEY_SSREADBACKS 4 9 | #define KEY_SSDITHER 5 10 | #define KEY_DEINTERLACE 6 11 | #define KEY_INTEGER 7 12 | #define KEY_OVERSCANCROP 8 13 | #define KEY_AA 9 14 | #define KEY_DIVOT 10 15 | #define KEY_GAMMADITHER 11 16 | #define KEY_VIBILERP 12 17 | #define KEY_VIDITHER 13 18 | #define KEY_NATIVETEXTLOD 14 19 | #define KEY_NATIVETEXTRECT 15 20 | #define KEY_VSYNC 16 21 | #define KEY_DOWNSCALING 17 22 | #define KEY_WIDESCREEN 18 23 | #define KEY_SYNCHRONOUS 19 24 | #define NUM_CONFIGVARS 20 25 | 26 | struct settingkey_t 27 | { 28 | char name[255]; 29 | int val; 30 | }; 31 | 32 | extern struct settingkey_t settings[NUM_CONFIGVARS]; 33 | 34 | extern void config_init(); 35 | extern void config_save(); 36 | extern void config_load(); 37 | 38 | #endif // CONFIG_H 39 | -------------------------------------------------------------------------------- /src/parallel-rdp/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Themaister 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /src/glguts.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | #include 5 | #include 6 | 7 | #ifdef __cplusplus 8 | extern "C" 9 | { 10 | #endif 11 | 12 | struct video_pixel 13 | { 14 | uint8_t r; 15 | uint8_t g; 16 | uint8_t b; 17 | uint8_t a; 18 | }; 19 | 20 | struct frame_buffer 21 | { 22 | struct video_pixel *pixels; 23 | uint32_t width; 24 | uint32_t height; 25 | uint32_t pitch; 26 | bool valid; 27 | }; 28 | 29 | void msg_error(const char * err, ...); 30 | void msg_warning(const char* err, ...); 31 | void msg_debug(const char* err, ...); 32 | 33 | void screen_write(struct frame_buffer *fb); 34 | void screen_read(struct frame_buffer *fb, bool alpha); 35 | void screen_init(); 36 | void screen_update(void); 37 | void screen_toggle_fullscreen(void); 38 | void screen_close(void); 39 | void screen_swap(bool blank); 40 | uint8_t* screen_get_texture_data(); 41 | 42 | extern int32_t window_width; 43 | extern int32_t window_height; 44 | extern int32_t window_fullscreen; 45 | extern bool window_integerscale; 46 | extern bool window_vsync; 47 | extern bool window_widescreen; 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | -------------------------------------------------------------------------------- /src/parallel-rdp/util/thread_name.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | namespace Util 26 | { 27 | void set_current_thread_name(const char *name); 28 | } 29 | -------------------------------------------------------------------------------- /src/parallel-rdp/util/thread_id.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | namespace Util 26 | { 27 | unsigned get_current_thread_index(); 28 | void register_thread_index(unsigned thread_index); 29 | } -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/cookie.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "cookie.hpp" 24 | #include "device.hpp" 25 | 26 | namespace Vulkan 27 | { 28 | Cookie::Cookie(Device *device) 29 | : cookie(device->allocate_cookie()) 30 | { 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/load_span_offsets.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Themaister 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef LOAD_SPAN_OFFSETS_H_ 24 | #define LOAD_SPAN_OFFSETS_H_ 25 | 26 | SpanInfoOffsets load_span_offsets(uint index) 27 | { 28 | return span_offsets.elems[index]; 29 | } 30 | 31 | #endif -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/load_attribute_setup.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Themaister 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef LOAD_ATTRIBUTE_SETUP_H_ 24 | #define LOAD_ATTRIBUTE_SETUP_H_ 25 | 26 | AttributeSetup load_attribute_setup(uint index) 27 | { 28 | return attribute_setup.elems[index]; 29 | } 30 | 31 | #endif -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan-headers/include/vulkan/vulkan_vi.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_VI_H_ 2 | #define VULKAN_VI_H_ 1 3 | 4 | /* 5 | ** Copyright (c) 2015-2020 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_NN_vi_surface 1 23 | #define VK_NN_VI_SURFACE_SPEC_VERSION 1 24 | #define VK_NN_VI_SURFACE_EXTENSION_NAME "VK_NN_vi_surface" 25 | typedef VkFlags VkViSurfaceCreateFlagsNN; 26 | typedef struct VkViSurfaceCreateInfoNN { 27 | VkStructureType sType; 28 | const void* pNext; 29 | VkViSurfaceCreateFlagsNN flags; 30 | void* window; 31 | } VkViSurfaceCreateInfoNN; 32 | 33 | typedef VkResult (VKAPI_PTR *PFN_vkCreateViSurfaceNN)(VkInstance instance, const VkViSurfaceCreateInfoNN* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); 34 | 35 | #ifndef VK_NO_PROTOTYPES 36 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateViSurfaceNN( 37 | VkInstance instance, 38 | const VkViSurfaceCreateInfoNN* pCreateInfo, 39 | const VkAllocationCallbacks* pAllocator, 40 | VkSurfaceKHR* pSurface); 41 | #endif 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/vi_deinterlace.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | /* Copyright (c) 2020 Themaister 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files (the 6 | * "Software"), to deal in the Software without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | layout(location = 0) in vec2 vUV; 25 | layout(set = 0, binding = 0) uniform sampler2D uSampler; 26 | layout(location = 0) out vec4 FragColor; 27 | 28 | void main() 29 | { 30 | FragColor = textureLod(uSampler, vUV, 0.0); 31 | } -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan-headers/include/vulkan/vulkan_ios.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_IOS_H_ 2 | #define VULKAN_IOS_H_ 1 3 | 4 | /* 5 | ** Copyright (c) 2015-2020 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_MVK_ios_surface 1 23 | #define VK_MVK_IOS_SURFACE_SPEC_VERSION 3 24 | #define VK_MVK_IOS_SURFACE_EXTENSION_NAME "VK_MVK_ios_surface" 25 | typedef VkFlags VkIOSSurfaceCreateFlagsMVK; 26 | typedef struct VkIOSSurfaceCreateInfoMVK { 27 | VkStructureType sType; 28 | const void* pNext; 29 | VkIOSSurfaceCreateFlagsMVK flags; 30 | const void* pView; 31 | } VkIOSSurfaceCreateInfoMVK; 32 | 33 | typedef VkResult (VKAPI_PTR *PFN_vkCreateIOSSurfaceMVK)(VkInstance instance, const VkIOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); 34 | 35 | #ifndef VK_NO_PROTOTYPES 36 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateIOSSurfaceMVK( 37 | VkInstance instance, 38 | const VkIOSSurfaceCreateInfoMVK* pCreateInfo, 39 | const VkAllocationCallbacks* pAllocator, 40 | VkSurfaceKHR* pSurface); 41 | #endif 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/ini.c: -------------------------------------------------------------------------------- 1 | #include "ini.h" 2 | #include 3 | #include 4 | #include 5 | 6 | EXTERN_C IMAGE_DOS_HEADER __ImageBase; 7 | 8 | char ini_file[MAX_PATH]; 9 | 10 | // extracts directory from full file path 11 | static void file_to_dir(char* file_path, char* directory, size_t size) 12 | { 13 | char dir_buf[MAX_PATH] = { 0 }; 14 | 15 | char* str = strtok(file_path, "\\"); 16 | char* str2 = NULL; 17 | while (str != NULL) 18 | { 19 | str2 = strtok(NULL, "\\"); 20 | if (str2 == NULL) 21 | { // no more '\' found 22 | break; 23 | } 24 | 25 | strcat(dir_buf, str); 26 | strcat(dir_buf, "\\"); 27 | 28 | str = str2; 29 | } 30 | 31 | strncpy(directory, dir_buf, size); 32 | } 33 | 34 | void ini_init() 35 | { 36 | char buf[MAX_PATH] = { 0 }; 37 | GetModuleFileNameA((HINSTANCE)&__ImageBase, buf, MAX_PATH); 38 | 39 | file_to_dir(buf, ini_file, MAX_PATH); 40 | strcat(ini_file, "\\pj64-parallelrdp.ini"); 41 | } 42 | 43 | bool ini_set_value(const char* key, int value) 44 | { 45 | char num_str[10]; 46 | itoa(value, num_str, 10); 47 | return WritePrivateProfileStringA("Settings", key, num_str, ini_file); 48 | } 49 | 50 | bool ini_get_value(const char* key, int* value) 51 | { 52 | char buf[MAX_PATH]; 53 | GetPrivateProfileStringA("Settings", key, NULL, buf, MAX_PATH, ini_file); 54 | if (buf == NULL) 55 | { 56 | *value = 0; 57 | return false; 58 | } 59 | 60 | *value = atoi(buf); 61 | return true; 62 | } 63 | 64 | -------------------------------------------------------------------------------- /src/parallel-rdp/util/enum_cast.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include 26 | 27 | namespace Util 28 | { 29 | template 30 | constexpr typename std::underlying_type::type ecast(T x) 31 | { 32 | return static_cast::type>(x); 33 | } 34 | } -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/load_scissor_state.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Themaister 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef LOAD_SCISSOR_STATE_H_ 24 | #define LOAD_SCISSOR_STATE_H_ 25 | 26 | ScissorState load_scissor_state(uint index) 27 | { 28 | ivec4 values = scissor_state.elems[index]; 29 | return ScissorState(values.x, values.y, values.z, values.w); 30 | } 31 | 32 | #endif -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/clear_indirect_buffer.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | /* Copyright (c) 2020 Themaister 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files (the 6 | * "Software"), to deal in the Software without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | layout(local_size_x_id = 0) in; 24 | 25 | layout(set = 0, binding = 0, std430) writeonly buffer ClearIndirectBuffer 26 | { 27 | uvec4 indirects[]; 28 | }; 29 | 30 | void main() 31 | { 32 | indirects[gl_GlobalInvocationID.x] = uvec4(0, 1, 1, 0); 33 | } -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/clear_super_sampled_write_mask.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | /* Copyright (c) 2020 Themaister 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files (the 6 | * "Software"), to deal in the Software without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | layout(local_size_x_id = 0) in; 25 | 26 | layout(set = 0, binding = 0, std430) writeonly buffer ToClear 27 | { 28 | uint elems[]; 29 | } mask_ram; 30 | 31 | void main() 32 | { 33 | mask_ram.elems[gl_GlobalInvocationID.x] = 0u; 34 | } 35 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan-headers/include/vulkan/vulkan_macos.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_MACOS_H_ 2 | #define VULKAN_MACOS_H_ 1 3 | 4 | /* 5 | ** Copyright (c) 2015-2020 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_MVK_macos_surface 1 23 | #define VK_MVK_MACOS_SURFACE_SPEC_VERSION 3 24 | #define VK_MVK_MACOS_SURFACE_EXTENSION_NAME "VK_MVK_macos_surface" 25 | typedef VkFlags VkMacOSSurfaceCreateFlagsMVK; 26 | typedef struct VkMacOSSurfaceCreateInfoMVK { 27 | VkStructureType sType; 28 | const void* pNext; 29 | VkMacOSSurfaceCreateFlagsMVK flags; 30 | const void* pView; 31 | } VkMacOSSurfaceCreateInfoMVK; 32 | 33 | typedef VkResult (VKAPI_PTR *PFN_vkCreateMacOSSurfaceMVK)(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); 34 | 35 | #ifndef VK_NO_PROTOTYPES 36 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateMacOSSurfaceMVK( 37 | VkInstance instance, 38 | const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, 39 | const VkAllocationCallbacks* pAllocator, 40 | VkSurfaceKHR* pSurface); 41 | #endif 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/fullscreen.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | /* Copyright (c) 2020 Themaister 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files (the 6 | * "Software"), to deal in the Software without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | void main() 25 | { 26 | if (gl_VertexIndex == 0) 27 | gl_Position = vec4(-1.0, -1.0, 0.0, 1.0); 28 | else if (gl_VertexIndex == 1) 29 | gl_Position = vec4(-1.0, +3.0, 0.0, 1.0); 30 | else 31 | gl_Position = vec4(+3.0, -1.0, 0.0, 1.0); 32 | } 33 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan-headers/include/vulkan/vulkan_xlib_xrandr.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_XLIB_XRANDR_H_ 2 | #define VULKAN_XLIB_XRANDR_H_ 1 3 | 4 | /* 5 | ** Copyright (c) 2015-2020 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_EXT_acquire_xlib_display 1 23 | #define VK_EXT_ACQUIRE_XLIB_DISPLAY_SPEC_VERSION 1 24 | #define VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME "VK_EXT_acquire_xlib_display" 25 | typedef VkResult (VKAPI_PTR *PFN_vkAcquireXlibDisplayEXT)(VkPhysicalDevice physicalDevice, Display* dpy, VkDisplayKHR display); 26 | typedef VkResult (VKAPI_PTR *PFN_vkGetRandROutputDisplayEXT)(VkPhysicalDevice physicalDevice, Display* dpy, RROutput rrOutput, VkDisplayKHR* pDisplay); 27 | 28 | #ifndef VK_NO_PROTOTYPES 29 | VKAPI_ATTR VkResult VKAPI_CALL vkAcquireXlibDisplayEXT( 30 | VkPhysicalDevice physicalDevice, 31 | Display* dpy, 32 | VkDisplayKHR display); 33 | 34 | VKAPI_ATTR VkResult VKAPI_CALL vkGetRandROutputDisplayEXT( 35 | VkPhysicalDevice physicalDevice, 36 | Display* dpy, 37 | RROutput rrOutput, 38 | VkDisplayKHR* pDisplay); 39 | #endif 40 | 41 | #ifdef __cplusplus 42 | } 43 | #endif 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/config.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "config.h" 3 | #include "ini.h" 4 | 5 | struct settingkey_t settings[NUM_CONFIGVARS] = 6 | { 7 | {"KEY_FULLSCREEN", 0}, 8 | {"KEY_UPSCALING", 0}, 9 | {"KEY_SCREEN_WIDTH", 640}, 10 | {"KEY_SCREEN_HEIGHT", 480}, 11 | {"KEY_SSREADBACKS", 0}, 12 | {"KEY_SSDITHER", 0}, 13 | {"KEY_DEINTERLACE", 0}, 14 | {"KEY_INTEGER", 0}, 15 | {"KEY_OVERSCANCROP", 0}, 16 | {"KEY_AA", 0}, 17 | {"KEY_DIVOT", 1}, 18 | {"KEY_GAMMADITHER", 1}, 19 | {"KEY_VIBILERP", 1}, 20 | {"KEY_VIDITHER", 1}, 21 | {"KEY_NATIVETEXTLOD", 0}, 22 | {"KEY_NATIVETEXTRECT", 1}, 23 | {"KEY_VSYNC", 1}, 24 | {"KEY_DOWNSCALE", 1}, 25 | {"KEY_WIDESCREEN", 0}, 26 | {"KEY_SYNCHRONOUS", 1} 27 | }; 28 | 29 | void config_init() 30 | { 31 | // initialize ini parser 32 | ini_init(); 33 | 34 | FILE* file = fopen(ini_file, "r"); 35 | if (file == NULL) 36 | { // file doesn't exist, create it 37 | config_save(); 38 | } 39 | else 40 | { // file exists, read it 41 | config_load(); 42 | fclose(file); 43 | } 44 | } 45 | 46 | void config_save() 47 | { 48 | for (int i = 0; i < NUM_CONFIGVARS; i++) 49 | { 50 | ini_set_value(settings[i].name, settings[i].val); 51 | } 52 | } 53 | 54 | void config_load() 55 | { 56 | for (int i = 0; i < NUM_CONFIGVARS; i++) 57 | { 58 | int value = -1; 59 | bool ret = ini_get_value(settings[i].name, &value); 60 | if (ret) 61 | { 62 | settings[i].val = value; 63 | } 64 | } 65 | } 66 | 67 | -------------------------------------------------------------------------------- /src/gfxstructdefs.h: -------------------------------------------------------------------------------- 1 | #ifndef __Z64_H__ 2 | #define __Z64_H__ 3 | 4 | #include 5 | #include 6 | 7 | #define SP_INTERRUPT 0x1 8 | #define SI_INTERRUPT 0x2 9 | #define AI_INTERRUPT 0x4 10 | #define VI_INTERRUPT 0x8 11 | #define PI_INTERRUPT 0x10 12 | #define DP_INTERRUPT 0x20 13 | 14 | #define SP_STATUS_HALT 0x0001 15 | #define SP_STATUS_BROKE 0x0002 16 | #define SP_STATUS_DMABUSY 0x0004 17 | #define SP_STATUS_DMAFULL 0x0008 18 | #define SP_STATUS_IOFULL 0x0010 19 | #define SP_STATUS_SSTEP 0x0020 20 | #define SP_STATUS_INTR_BREAK 0x0040 21 | #define SP_STATUS_SIGNAL0 0x0080 22 | #define SP_STATUS_SIGNAL1 0x0100 23 | #define SP_STATUS_SIGNAL2 0x0200 24 | #define SP_STATUS_SIGNAL3 0x0400 25 | #define SP_STATUS_SIGNAL4 0x0800 26 | #define SP_STATUS_SIGNAL5 0x1000 27 | #define SP_STATUS_SIGNAL6 0x2000 28 | #define SP_STATUS_SIGNAL7 0x4000 29 | 30 | #define DP_STATUS_XBUS_DMA 0x01 31 | #define DP_STATUS_FREEZE 0x02 32 | #define DP_STATUS_FLUSH 0x04 33 | #define DP_STATUS_START_GCLK 0x008 34 | #define DP_STATUS_TMEM_BUSY 0x010 35 | #define DP_STATUS_PIPE_BUSY 0x020 36 | #define DP_STATUS_CMD_BUSY 0x040 37 | #define DP_STATUS_CBUF_READY 0x080 38 | #define DP_STATUS_DMA_BUSY 0x100 39 | #define DP_STATUS_END_VALID 0x200 40 | #define DP_STATUS_START_VALID 0x400 41 | 42 | #define GET_GFX_INFO(member) (gfx.member) 43 | 44 | #define DRAM GET_GFX_INFO(RDRAM) 45 | #define SP_DMEM GET_GFX_INFO(DMEM) 46 | #define SP_IMEM GET_GFX_INFO(IMEM) 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan-headers/include/vulkan/vulkan_metal.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_METAL_H_ 2 | #define VULKAN_METAL_H_ 1 3 | 4 | /* 5 | ** Copyright (c) 2015-2020 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_EXT_metal_surface 1 23 | 24 | #ifdef __OBJC__ 25 | @class CAMetalLayer; 26 | #else 27 | typedef void CAMetalLayer; 28 | #endif 29 | 30 | #define VK_EXT_METAL_SURFACE_SPEC_VERSION 1 31 | #define VK_EXT_METAL_SURFACE_EXTENSION_NAME "VK_EXT_metal_surface" 32 | typedef VkFlags VkMetalSurfaceCreateFlagsEXT; 33 | typedef struct VkMetalSurfaceCreateInfoEXT { 34 | VkStructureType sType; 35 | const void* pNext; 36 | VkMetalSurfaceCreateFlagsEXT flags; 37 | const CAMetalLayer* pLayer; 38 | } VkMetalSurfaceCreateInfoEXT; 39 | 40 | typedef VkResult (VKAPI_PTR *PFN_vkCreateMetalSurfaceEXT)(VkInstance instance, const VkMetalSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); 41 | 42 | #ifndef VK_NO_PROTOTYPES 43 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateMetalSurfaceEXT( 44 | VkInstance instance, 45 | const VkMetalSurfaceCreateInfoEXT* pCreateInfo, 46 | const VkAllocationCallbacks* pAllocator, 47 | VkSurfaceKHR* pSurface); 48 | #endif 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan-headers/include/vulkan/vulkan_fuchsia.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_FUCHSIA_H_ 2 | #define VULKAN_FUCHSIA_H_ 1 3 | 4 | /* 5 | ** Copyright (c) 2015-2020 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_FUCHSIA_imagepipe_surface 1 23 | #define VK_FUCHSIA_IMAGEPIPE_SURFACE_SPEC_VERSION 1 24 | #define VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME "VK_FUCHSIA_imagepipe_surface" 25 | typedef VkFlags VkImagePipeSurfaceCreateFlagsFUCHSIA; 26 | typedef struct VkImagePipeSurfaceCreateInfoFUCHSIA { 27 | VkStructureType sType; 28 | const void* pNext; 29 | VkImagePipeSurfaceCreateFlagsFUCHSIA flags; 30 | zx_handle_t imagePipeHandle; 31 | } VkImagePipeSurfaceCreateInfoFUCHSIA; 32 | 33 | typedef VkResult (VKAPI_PTR *PFN_vkCreateImagePipeSurfaceFUCHSIA)(VkInstance instance, const VkImagePipeSurfaceCreateInfoFUCHSIA* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); 34 | 35 | #ifndef VK_NO_PROTOTYPES 36 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateImagePipeSurfaceFUCHSIA( 37 | VkInstance instance, 38 | const VkImagePipeSurfaceCreateInfoFUCHSIA* pCreateInfo, 39 | const VkAllocationCallbacks* pAllocator, 40 | VkSurfaceKHR* pSurface); 41 | #endif 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/vi_blend_fields.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | /* Copyright (c) 2020 Themaister 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files (the 6 | * "Software"), to deal in the Software without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #extension GL_EXT_samplerless_texture_functions : require 24 | 25 | layout(location = 0) out vec4 FragColor; 26 | layout(set = 0, binding = 0) uniform texture2D uImage; 27 | 28 | void main() 29 | { 30 | // A persistent pixel does not propagate more than one frame. 31 | vec4 input_pixel = texelFetch(uImage, ivec2(gl_FragCoord.xy), 0); 32 | FragColor = vec4(input_pixel.rgb * input_pixel.a, 0.0); 33 | } -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/pipeline_event.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "pipeline_event.hpp" 24 | #include "device.hpp" 25 | 26 | namespace Vulkan 27 | { 28 | EventHolder::~EventHolder() 29 | { 30 | if (event) 31 | { 32 | if (internal_sync) 33 | device->destroy_event_nolock(event); 34 | else 35 | device->destroy_event(event); 36 | } 37 | } 38 | 39 | void EventHolderDeleter::operator()(Vulkan::EventHolder *event) 40 | { 41 | event->device->handle_pool.events.free(event); 42 | } 43 | } -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/fence_manager.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "vulkan_headers.hpp" 26 | #include 27 | 28 | namespace Vulkan 29 | { 30 | class Device; 31 | class FenceManager 32 | { 33 | public: 34 | void init(Device *device); 35 | ~FenceManager(); 36 | 37 | VkFence request_cleared_fence(); 38 | void recycle_fence(VkFence fence); 39 | 40 | private: 41 | Device *device = nullptr; 42 | const VolkDeviceTable *table = nullptr; 43 | std::vector fences; 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /src/parallel-rdp/util/logging.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "logging.hpp" 24 | 25 | namespace Util 26 | { 27 | static thread_local LoggingInterface *logging_iface; 28 | 29 | bool interface_log(const char *tag, const char *fmt, ...) 30 | { 31 | if (!logging_iface) 32 | return false; 33 | 34 | va_list va; 35 | va_start(va, fmt); 36 | bool ret = logging_iface->log(tag, fmt, va); 37 | va_end(va); 38 | return ret; 39 | } 40 | 41 | void set_thread_logging_interface(LoggingInterface *iface) 42 | { 43 | logging_iface = iface; 44 | } 45 | } -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/semaphore_manager.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "vulkan_headers.hpp" 26 | #include 27 | 28 | namespace Vulkan 29 | { 30 | class Device; 31 | class SemaphoreManager 32 | { 33 | public: 34 | void init(Device *device); 35 | ~SemaphoreManager(); 36 | 37 | VkSemaphore request_cleared_semaphore(); 38 | void recycle(VkSemaphore semaphore); 39 | 40 | private: 41 | Device *device = nullptr; 42 | const VolkDeviceTable *table = nullptr; 43 | std::vector semaphores; 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /src/parallel-rdp/util/thread_id.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "thread_id.hpp" 24 | #include "logging.hpp" 25 | 26 | namespace Util 27 | { 28 | static thread_local unsigned thread_id_to_index = ~0u; 29 | 30 | unsigned get_current_thread_index() 31 | { 32 | auto ret = thread_id_to_index; 33 | if (ret == ~0u) 34 | { 35 | LOGE("Thread does not exist in thread manager or is not the main thread.\n"); 36 | return 0; 37 | } 38 | return ret; 39 | } 40 | 41 | void register_thread_index(unsigned index) 42 | { 43 | thread_id_to_index = index; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/event_manager.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "vulkan_headers.hpp" 26 | #include 27 | 28 | namespace Vulkan 29 | { 30 | class Device; 31 | class EventManager 32 | { 33 | public: 34 | void init(Device *device); 35 | ~EventManager(); 36 | 37 | VkEvent request_cleared_event(); 38 | void recycle(VkEvent event); 39 | 40 | private: 41 | Device *device = nullptr; 42 | const VolkDeviceTable *table = nullptr; 43 | std::vector events; 44 | uint64_t workaround_counter = 0; 45 | bool workaround = false; 46 | }; 47 | } -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/clear_write_mask.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | /* Copyright (c) 2020 Themaister 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files (the 6 | * "Software"), to deal in the Software without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | layout(local_size_x_id = 0) in; 25 | layout(constant_id = 1) const int PAGE_STRIDE = 256; 26 | 27 | layout(set = 0, binding = 0, std430) writeonly buffer SSBO 28 | { 29 | uint write_mask[]; 30 | }; 31 | 32 | layout(set = 1, binding = 0, std140) uniform UBO 33 | { 34 | uvec4 offsets[1024]; 35 | }; 36 | 37 | void main() 38 | { 39 | uint offset = offsets[gl_WorkGroupID.x >> 2u][gl_WorkGroupID.x & 3u]; 40 | offset *= PAGE_STRIDE; 41 | write_mask[offset + gl_LocalInvocationIndex] = 0u; 42 | } 43 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/vi_deinterlace.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | /* Copyright (c) 2020 Themaister 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files (the 6 | * "Software"), to deal in the Software without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | layout(location = 0) out vec2 vUV; 25 | 26 | layout(push_constant) uniform UBO 27 | { 28 | float y_offset; 29 | } registers; 30 | 31 | void main() 32 | { 33 | if (gl_VertexIndex == 0) 34 | gl_Position = vec4(-1.0, -1.0, 0.0, 1.0); 35 | else if (gl_VertexIndex == 1) 36 | gl_Position = vec4(-1.0, +3.0, 0.0, 1.0); 37 | else 38 | gl_Position = vec4(+3.0, -1.0, 0.0, 1.0); 39 | 40 | vUV = vec2(gl_Position.x * 0.5 + 0.5, gl_Position.y * 0.5 + 0.5 + registers.y_offset); 41 | } 42 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/load_depth_blend_state.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Themaister 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef LOAD_DEPTH_BLEND_STATE_H_ 24 | #define LOAD_DEPTH_BLEND_STATE_H_ 25 | 26 | DepthBlendState load_depth_blend_state(uint index) 27 | { 28 | #if SMALL_TYPES 29 | return depth_blend_state.elems[index]; 30 | #else 31 | return DepthBlendState( 32 | u8x4(depth_blend_state.elems[index].blend_modes0), 33 | u8x4(depth_blend_state.elems[index].blend_modes1), 34 | depth_blend_state.elems[index].flags, 35 | u8(depth_blend_state.elems[index].coverage_mode), 36 | u8(depth_blend_state.elems[index].z_mode), 37 | u8(0), u8(0)); 38 | #endif 39 | } 40 | 41 | #endif -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan-headers/include/vulkan/vulkan.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_H_ 2 | #define VULKAN_H_ 1 3 | 4 | /* 5 | ** Copyright (c) 2015-2020 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | #include "vk_platform.h" 11 | #include "vulkan_core.h" 12 | 13 | #ifdef VK_USE_PLATFORM_ANDROID_KHR 14 | #include "vulkan_android.h" 15 | #endif 16 | 17 | #ifdef VK_USE_PLATFORM_FUCHSIA 18 | #include 19 | #include "vulkan_fuchsia.h" 20 | #endif 21 | 22 | #ifdef VK_USE_PLATFORM_IOS_MVK 23 | #include "vulkan_ios.h" 24 | #endif 25 | 26 | 27 | #ifdef VK_USE_PLATFORM_MACOS_MVK 28 | #include "vulkan_macos.h" 29 | #endif 30 | 31 | #ifdef VK_USE_PLATFORM_METAL_EXT 32 | #include "vulkan_metal.h" 33 | #endif 34 | 35 | #ifdef VK_USE_PLATFORM_VI_NN 36 | #include "vulkan_vi.h" 37 | #endif 38 | 39 | 40 | #ifdef VK_USE_PLATFORM_WAYLAND_KHR 41 | #include 42 | #include "vulkan_wayland.h" 43 | #endif 44 | 45 | 46 | #ifdef VK_USE_PLATFORM_WIN32_KHR 47 | #include 48 | #include "vulkan_win32.h" 49 | #endif 50 | 51 | 52 | #ifdef VK_USE_PLATFORM_XCB_KHR 53 | #include 54 | #include "vulkan_xcb.h" 55 | #endif 56 | 57 | 58 | #ifdef VK_USE_PLATFORM_XLIB_KHR 59 | #include 60 | #include "vulkan_xlib.h" 61 | #endif 62 | 63 | 64 | #ifdef VK_USE_PLATFORM_DIRECTFB_EXT 65 | #include 66 | #include "vulkan_directfb.h" 67 | #endif 68 | 69 | 70 | #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT 71 | #include 72 | #include 73 | #include "vulkan_xlib_xrandr.h" 74 | #endif 75 | 76 | 77 | #ifdef VK_USE_PLATFORM_GGP 78 | #include 79 | #include "vulkan_ggp.h" 80 | #endif 81 | 82 | 83 | #ifdef VK_ENABLE_BETA_EXTENSIONS 84 | #include "vulkan_beta.h" 85 | #endif 86 | 87 | #endif // VULKAN_H_ 88 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/limits.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | namespace Vulkan 26 | { 27 | constexpr unsigned VULKAN_NUM_DESCRIPTOR_SETS = 4; 28 | constexpr unsigned VULKAN_NUM_BINDINGS = 16; 29 | constexpr unsigned VULKAN_NUM_BINDINGS_BINDLESS_VARYING = 64 * 1024; 30 | constexpr unsigned VULKAN_NUM_BINDINGS_BINDLESS = 4 * 1024; 31 | constexpr unsigned VULKAN_NUM_ATTACHMENTS = 8; 32 | constexpr unsigned VULKAN_NUM_VERTEX_ATTRIBS = 16; 33 | constexpr unsigned VULKAN_NUM_VERTEX_BUFFERS = 4; 34 | constexpr unsigned VULKAN_PUSH_CONSTANT_SIZE = 128; 35 | constexpr unsigned VULKAN_MAX_UBO_SIZE = 16 * 1024; 36 | constexpr unsigned VULKAN_NUM_SPEC_CONSTANTS = 8; 37 | } 38 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan-headers/include/vulkan/vulkan_beta.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_BETA_H_ 2 | #define VULKAN_BETA_H_ 1 3 | 4 | /* 5 | ** Copyright (c) 2015-2020 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_KHR_portability_subset 1 23 | #define VK_KHR_PORTABILITY_SUBSET_SPEC_VERSION 1 24 | #define VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME "VK_KHR_portability_subset" 25 | typedef struct VkPhysicalDevicePortabilitySubsetFeaturesKHR { 26 | VkStructureType sType; 27 | void* pNext; 28 | VkBool32 constantAlphaColorBlendFactors; 29 | VkBool32 events; 30 | VkBool32 imageViewFormatReinterpretation; 31 | VkBool32 imageViewFormatSwizzle; 32 | VkBool32 imageView2DOn3DImage; 33 | VkBool32 multisampleArrayImage; 34 | VkBool32 mutableComparisonSamplers; 35 | VkBool32 pointPolygons; 36 | VkBool32 samplerMipLodBias; 37 | VkBool32 separateStencilMaskRef; 38 | VkBool32 shaderSampleRateInterpolationFunctions; 39 | VkBool32 tessellationIsolines; 40 | VkBool32 tessellationPointMode; 41 | VkBool32 triangleFans; 42 | VkBool32 vertexAttributeAccessBeyondStride; 43 | } VkPhysicalDevicePortabilitySubsetFeaturesKHR; 44 | 45 | typedef struct VkPhysicalDevicePortabilitySubsetPropertiesKHR { 46 | VkStructureType sType; 47 | void* pNext; 48 | uint32_t minVertexInputBindingStrideAlignment; 49 | } VkPhysicalDevicePortabilitySubsetPropertiesKHR; 50 | 51 | 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/sampler.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "sampler.hpp" 24 | #include "device.hpp" 25 | 26 | namespace Vulkan 27 | { 28 | Sampler::Sampler(Device *device_, VkSampler sampler_, const SamplerCreateInfo &info) 29 | : Cookie(device_) 30 | , device(device_) 31 | , sampler(sampler_) 32 | , create_info(info) 33 | { 34 | } 35 | 36 | Sampler::~Sampler() 37 | { 38 | if (sampler) 39 | { 40 | if (internal_sync) 41 | device->destroy_sampler_nolock(sampler); 42 | else 43 | device->destroy_sampler(sampler); 44 | } 45 | } 46 | 47 | void SamplerDeleter::operator()(Sampler *sampler) 48 | { 49 | sampler->device->handle_pool.samplers.free(sampler); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/load_span_setup.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Themaister 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef LOAD_SPAN_SETUP_H_ 24 | #define LOAD_SPAN_SETUP_H_ 25 | 26 | SpanSetup load_span_setup(uint index) 27 | { 28 | #if SMALL_TYPES 29 | return span_setups.elems[index]; 30 | #else 31 | return SpanSetup( 32 | span_setups.elems[index].rgba, 33 | span_setups.elems[index].stzw, 34 | u16x4(uvec4(span_setups.elems[index].xleft)), 35 | u16x4(uvec4(span_setups.elems[index].xright)), 36 | span_setups.elems[index].interpolation_base_x, 37 | span_setups.elems[index].start_x, 38 | span_setups.elems[index].end_x, 39 | i16(span_setups.elems[index].lodlength), 40 | u16(span_setups.elems[index].valid_line)); 41 | #endif 42 | } 43 | 44 | #endif -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/cookie.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include 26 | #include "hash.hpp" 27 | #include "intrusive_hash_map.hpp" 28 | 29 | namespace Vulkan 30 | { 31 | class Device; 32 | 33 | class Cookie 34 | { 35 | public: 36 | Cookie(Device *device); 37 | 38 | uint64_t get_cookie() const 39 | { 40 | return cookie; 41 | } 42 | 43 | private: 44 | uint64_t cookie; 45 | }; 46 | 47 | template 48 | using HashedObject = Util::IntrusiveHashMapEnabled; 49 | 50 | class InternalSyncEnabled 51 | { 52 | public: 53 | void set_internal_sync_object() 54 | { 55 | internal_sync = true; 56 | } 57 | 58 | protected: 59 | bool internal_sync = false; 60 | }; 61 | } 62 | -------------------------------------------------------------------------------- /src/parallel-rdp/util/stack_allocator.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include 26 | 27 | namespace Util 28 | { 29 | template 30 | class StackAllocator 31 | { 32 | public: 33 | T *allocate(size_t count) 34 | { 35 | if (count == 0) 36 | return nullptr; 37 | if (offset + count > N) 38 | return nullptr; 39 | 40 | T *ret = buffer + offset; 41 | offset += count; 42 | return ret; 43 | } 44 | 45 | T *allocate_cleared(size_t count) 46 | { 47 | T *ret = allocate(count); 48 | if (ret) 49 | std::fill(ret, ret + count, T()); 50 | return ret; 51 | } 52 | 53 | void reset() 54 | { 55 | offset = 0; 56 | } 57 | 58 | private: 59 | T buffer[N]; 60 | size_t offset = 0; 61 | }; 62 | } -------------------------------------------------------------------------------- /src/parallel-rdp/util/timer.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include 26 | 27 | namespace Util 28 | { 29 | class FrameTimer 30 | { 31 | public: 32 | FrameTimer(); 33 | 34 | void reset(); 35 | double frame(); 36 | double frame(double frame_time); 37 | double get_elapsed() const; 38 | double get_frame_time() const; 39 | 40 | void enter_idle(); 41 | void leave_idle(); 42 | 43 | private: 44 | int64_t start; 45 | int64_t last; 46 | int64_t last_period; 47 | int64_t idle_start; 48 | int64_t idle_time = 0; 49 | int64_t get_time(); 50 | }; 51 | 52 | class Timer 53 | { 54 | public: 55 | void start(); 56 | double end(); 57 | 58 | private: 59 | int64_t t = 0; 60 | }; 61 | 62 | int64_t get_current_time_nsecs(); 63 | } -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/load_static_raster_state.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Themaister 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef LOAD_STATIC_RASTER_STATE_H_ 24 | #define LOAD_STATIC_RASTER_STATE_H_ 25 | 26 | StaticRasterizationState load_static_rasterization_state(uint index) 27 | { 28 | #if SMALL_TYPES 29 | return static_raster_state.elems[index]; 30 | #else 31 | return StaticRasterizationState( 32 | u8x4(static_raster_state.elems[index].combiner_inputs_rgb0), 33 | u8x4(static_raster_state.elems[index].combiner_inputs_alpha0), 34 | u8x4(static_raster_state.elems[index].combiner_inputs_rgb1), 35 | u8x4(static_raster_state.elems[index].combiner_inputs_alpha1), 36 | static_raster_state.elems[index].flags, 37 | static_raster_state.elems[index].dither, 38 | 0, 0); 39 | #endif 40 | } 41 | 42 | #endif -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/load_triangle_setup.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Themaister 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef LOAD_TRIANGLE_SETUP_H_ 24 | #define LOAD_TRIANGLE_SETUP_H_ 25 | 26 | TriangleSetup load_triangle_setup(uint index) 27 | { 28 | #if SMALL_TYPES 29 | return triangle_setup.elems[index]; 30 | #else 31 | return TriangleSetup( 32 | triangle_setup.elems[index].xh, 33 | triangle_setup.elems[index].xm, 34 | triangle_setup.elems[index].xl, 35 | i16(triangle_setup.elems[index].yh), 36 | i16(triangle_setup.elems[index].ym), 37 | triangle_setup.elems[index].dxhdy, 38 | triangle_setup.elems[index].dxmdy, 39 | triangle_setup.elems[index].dxldy, 40 | i16(triangle_setup.elems[index].yl), 41 | u8(triangle_setup.elems[index].flags), 42 | u8(triangle_setup.elems[index].tile)); 43 | #endif 44 | } 45 | 46 | #endif -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan-headers/include/vulkan/vulkan_ggp.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_GGP_H_ 2 | #define VULKAN_GGP_H_ 1 3 | 4 | /* 5 | ** Copyright (c) 2015-2020 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_GGP_stream_descriptor_surface 1 23 | #define VK_GGP_STREAM_DESCRIPTOR_SURFACE_SPEC_VERSION 1 24 | #define VK_GGP_STREAM_DESCRIPTOR_SURFACE_EXTENSION_NAME "VK_GGP_stream_descriptor_surface" 25 | typedef VkFlags VkStreamDescriptorSurfaceCreateFlagsGGP; 26 | typedef struct VkStreamDescriptorSurfaceCreateInfoGGP { 27 | VkStructureType sType; 28 | const void* pNext; 29 | VkStreamDescriptorSurfaceCreateFlagsGGP flags; 30 | GgpStreamDescriptor streamDescriptor; 31 | } VkStreamDescriptorSurfaceCreateInfoGGP; 32 | 33 | typedef VkResult (VKAPI_PTR *PFN_vkCreateStreamDescriptorSurfaceGGP)(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); 34 | 35 | #ifndef VK_NO_PROTOTYPES 36 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateStreamDescriptorSurfaceGGP( 37 | VkInstance instance, 38 | const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo, 39 | const VkAllocationCallbacks* pAllocator, 40 | VkSurfaceKHR* pSurface); 41 | #endif 42 | 43 | 44 | #define VK_GGP_frame_token 1 45 | #define VK_GGP_FRAME_TOKEN_SPEC_VERSION 1 46 | #define VK_GGP_FRAME_TOKEN_EXTENSION_NAME "VK_GGP_frame_token" 47 | typedef struct VkPresentFrameTokenGGP { 48 | VkStructureType sType; 49 | const void* pNext; 50 | GgpFrameToken frameToken; 51 | } VkPresentFrameTokenGGP; 52 | 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/store_span_setup.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Themaister 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef STORE_SPAN_SETUP_H_ 24 | #define STORE_SPAN_SETUP_H_ 25 | 26 | void store_span_setup(uint index, SpanSetup setup) 27 | { 28 | #if SMALL_TYPES 29 | span_setups.elems[index] = setup; 30 | #else 31 | span_setups.elems[index].rgba = setup.rgba; 32 | span_setups.elems[index].stzw = setup.stzw; 33 | span_setups.elems[index].xleft = mem_u16x4(uvec4(setup.xleft)); 34 | span_setups.elems[index].xright = mem_u16x4(uvec4(setup.xright)); 35 | span_setups.elems[index].interpolation_base_x = setup.interpolation_base_x; 36 | span_setups.elems[index].start_x = setup.start_x; 37 | span_setups.elems[index].end_x = setup.end_x; 38 | span_setups.elems[index].lodlength = mem_i16(setup.lodlength); 39 | span_setups.elems[index].valid_line = mem_u16(setup.valid_line); 40 | #endif 41 | } 42 | 43 | #endif -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/load_tile_info.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Themaister 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef LOAD_TILE_INFO_H_ 24 | #define LOAD_TILE_INFO_H_ 25 | 26 | TileInfo load_tile_info(uint index) 27 | { 28 | #if SMALL_TYPES 29 | return tile_infos.elems[index]; 30 | #else 31 | return TileInfo( 32 | tile_infos.elems[index].slo, 33 | tile_infos.elems[index].shi, 34 | tile_infos.elems[index].tlo, 35 | tile_infos.elems[index].thi, 36 | tile_infos.elems[index].offset, 37 | tile_infos.elems[index].stride, 38 | u8(tile_infos.elems[index].fmt), 39 | u8(tile_infos.elems[index].size), 40 | u8(tile_infos.elems[index].palette), 41 | u8(tile_infos.elems[index].mask_s), 42 | u8(tile_infos.elems[index].shift_s), 43 | u8(tile_infos.elems[index].mask_t), 44 | u8(tile_infos.elems[index].shift_t), 45 | u8(tile_infos.elems[index].flags)); 46 | #endif 47 | } 48 | 49 | #endif -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan-headers/include/vulkan/vulkan_directfb.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_DIRECTFB_H_ 2 | #define VULKAN_DIRECTFB_H_ 1 3 | 4 | /* 5 | ** Copyright (c) 2015-2020 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_EXT_directfb_surface 1 23 | #define VK_EXT_DIRECTFB_SURFACE_SPEC_VERSION 1 24 | #define VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME "VK_EXT_directfb_surface" 25 | typedef VkFlags VkDirectFBSurfaceCreateFlagsEXT; 26 | typedef struct VkDirectFBSurfaceCreateInfoEXT { 27 | VkStructureType sType; 28 | const void* pNext; 29 | VkDirectFBSurfaceCreateFlagsEXT flags; 30 | IDirectFB* dfb; 31 | IDirectFBSurface* surface; 32 | } VkDirectFBSurfaceCreateInfoEXT; 33 | 34 | typedef VkResult (VKAPI_PTR *PFN_vkCreateDirectFBSurfaceEXT)(VkInstance instance, const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); 35 | typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceDirectFBPresentationSupportEXT)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, IDirectFB* dfb); 36 | 37 | #ifndef VK_NO_PROTOTYPES 38 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateDirectFBSurfaceEXT( 39 | VkInstance instance, 40 | const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo, 41 | const VkAllocationCallbacks* pAllocator, 42 | VkSurfaceKHR* pSurface); 43 | 44 | VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceDirectFBPresentationSupportEXT( 45 | VkPhysicalDevice physicalDevice, 46 | uint32_t queueFamilyIndex, 47 | IDirectFB* dfb); 48 | #endif 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan-headers/include/vulkan/vulkan_wayland.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_WAYLAND_H_ 2 | #define VULKAN_WAYLAND_H_ 1 3 | 4 | /* 5 | ** Copyright (c) 2015-2020 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_KHR_wayland_surface 1 23 | #define VK_KHR_WAYLAND_SURFACE_SPEC_VERSION 6 24 | #define VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME "VK_KHR_wayland_surface" 25 | typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; 26 | typedef struct VkWaylandSurfaceCreateInfoKHR { 27 | VkStructureType sType; 28 | const void* pNext; 29 | VkWaylandSurfaceCreateFlagsKHR flags; 30 | struct wl_display* display; 31 | struct wl_surface* surface; 32 | } VkWaylandSurfaceCreateInfoKHR; 33 | 34 | typedef VkResult (VKAPI_PTR *PFN_vkCreateWaylandSurfaceKHR)(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); 35 | typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct wl_display* display); 36 | 37 | #ifndef VK_NO_PROTOTYPES 38 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR( 39 | VkInstance instance, 40 | const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, 41 | const VkAllocationCallbacks* pAllocator, 42 | VkSurfaceKHR* pSurface); 43 | 44 | VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWaylandPresentationSupportKHR( 45 | VkPhysicalDevice physicalDevice, 46 | uint32_t queueFamilyIndex, 47 | struct wl_display* display); 48 | #endif 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan-headers/include/vulkan/vulkan_xlib.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_XLIB_H_ 2 | #define VULKAN_XLIB_H_ 1 3 | 4 | /* 5 | ** Copyright (c) 2015-2020 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_KHR_xlib_surface 1 23 | #define VK_KHR_XLIB_SURFACE_SPEC_VERSION 6 24 | #define VK_KHR_XLIB_SURFACE_EXTENSION_NAME "VK_KHR_xlib_surface" 25 | typedef VkFlags VkXlibSurfaceCreateFlagsKHR; 26 | typedef struct VkXlibSurfaceCreateInfoKHR { 27 | VkStructureType sType; 28 | const void* pNext; 29 | VkXlibSurfaceCreateFlagsKHR flags; 30 | Display* dpy; 31 | Window window; 32 | } VkXlibSurfaceCreateInfoKHR; 33 | 34 | typedef VkResult (VKAPI_PTR *PFN_vkCreateXlibSurfaceKHR)(VkInstance instance, const VkXlibSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); 35 | typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display* dpy, VisualID visualID); 36 | 37 | #ifndef VK_NO_PROTOTYPES 38 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateXlibSurfaceKHR( 39 | VkInstance instance, 40 | const VkXlibSurfaceCreateInfoKHR* pCreateInfo, 41 | const VkAllocationCallbacks* pAllocator, 42 | VkSurfaceKHR* pSurface); 43 | 44 | VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXlibPresentationSupportKHR( 45 | VkPhysicalDevice physicalDevice, 46 | uint32_t queueFamilyIndex, 47 | Display* dpy, 48 | VisualID visualID); 49 | #endif 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan-headers/include/vulkan/vulkan_xcb.h: -------------------------------------------------------------------------------- 1 | #ifndef VULKAN_XCB_H_ 2 | #define VULKAN_XCB_H_ 1 3 | 4 | /* 5 | ** Copyright (c) 2015-2020 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | /* 11 | ** This header is generated from the Khronos Vulkan XML API Registry. 12 | ** 13 | */ 14 | 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | 21 | 22 | #define VK_KHR_xcb_surface 1 23 | #define VK_KHR_XCB_SURFACE_SPEC_VERSION 6 24 | #define VK_KHR_XCB_SURFACE_EXTENSION_NAME "VK_KHR_xcb_surface" 25 | typedef VkFlags VkXcbSurfaceCreateFlagsKHR; 26 | typedef struct VkXcbSurfaceCreateInfoKHR { 27 | VkStructureType sType; 28 | const void* pNext; 29 | VkXcbSurfaceCreateFlagsKHR flags; 30 | xcb_connection_t* connection; 31 | xcb_window_t window; 32 | } VkXcbSurfaceCreateInfoKHR; 33 | 34 | typedef VkResult (VKAPI_PTR *PFN_vkCreateXcbSurfaceKHR)(VkInstance instance, const VkXcbSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); 35 | typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, xcb_connection_t* connection, xcb_visualid_t visual_id); 36 | 37 | #ifndef VK_NO_PROTOTYPES 38 | VKAPI_ATTR VkResult VKAPI_CALL vkCreateXcbSurfaceKHR( 39 | VkInstance instance, 40 | const VkXcbSurfaceCreateInfoKHR* pCreateInfo, 41 | const VkAllocationCallbacks* pAllocator, 42 | VkSurfaceKHR* pSurface); 43 | 44 | VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceXcbPresentationSupportKHR( 45 | VkPhysicalDevice physicalDevice, 46 | uint32_t queueFamilyIndex, 47 | xcb_connection_t* connection, 48 | xcb_visualid_t visual_id); 49 | #endif 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/fence_manager.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "fence_manager.hpp" 24 | #include "device.hpp" 25 | 26 | namespace Vulkan 27 | { 28 | void FenceManager::init(Device *device_) 29 | { 30 | device = device_; 31 | table = &device->get_device_table(); 32 | } 33 | 34 | VkFence FenceManager::request_cleared_fence() 35 | { 36 | if (!fences.empty()) 37 | { 38 | auto ret = fences.back(); 39 | fences.pop_back(); 40 | return ret; 41 | } 42 | else 43 | { 44 | VkFence fence; 45 | VkFenceCreateInfo info = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO }; 46 | table->vkCreateFence(device->get_device(), &info, nullptr, &fence); 47 | return fence; 48 | } 49 | } 50 | 51 | void FenceManager::recycle_fence(VkFence fence) 52 | { 53 | fences.push_back(fence); 54 | } 55 | 56 | FenceManager::~FenceManager() 57 | { 58 | for (auto &fence : fences) 59 | table->vkDestroyFence(device->get_device(), fence, nullptr); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/vulkan_common.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "intrusive.hpp" 26 | #include "object_pool.hpp" 27 | #include "intrusive_hash_map.hpp" 28 | 29 | namespace Vulkan 30 | { 31 | #ifdef GRANITE_VULKAN_MT 32 | using HandleCounter = Util::MultiThreadCounter; 33 | #else 34 | using HandleCounter = Util::SingleThreadCounter; 35 | #endif 36 | 37 | #ifdef GRANITE_VULKAN_MT 38 | template 39 | using VulkanObjectPool = Util::ThreadSafeObjectPool; 40 | template 41 | using VulkanCache = Util::ThreadSafeIntrusiveHashMapReadCached; 42 | template 43 | using VulkanCacheReadWrite = Util::ThreadSafeIntrusiveHashMap; 44 | #else 45 | template 46 | using VulkanObjectPool = Util::ObjectPool; 47 | template 48 | using VulkanCache = Util::IntrusiveHashMap; 49 | template 50 | using VulkanCacheReadWrite = Util::IntrusiveHashMap; 51 | #endif 52 | } -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/z_encode.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Themaister 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef Z_ENCODE_H_ 24 | #define Z_ENCODE_H_ 25 | 26 | // The Z compression is kind of clever, and uses inverted FP, with more precision close to 1. 27 | // The compressed Z result is 14 bits, and decompresses to 18-bit UNORM. 28 | int z_decompress(u16 z_) 29 | { 30 | int z = int(z_); 31 | int exponent = z >> 11; 32 | int mantissa = z & 0x7ff; 33 | int shift = max(6 - exponent, 0); 34 | int base = 0x40000 - (0x40000 >> exponent); 35 | return (mantissa << shift) + base; 36 | } 37 | 38 | u16 z_compress(int z) 39 | { 40 | int inv_z = max(0x3ffff - z, 1); 41 | int exponent = 17 - findMSB(inv_z); 42 | exponent = clamp(exponent, 0, 7); 43 | int shift = max(6 - exponent, 0); 44 | int mantissa = (z >> shift) & 0x7ff; 45 | return u16((exponent << 11) + mantissa); 46 | } 47 | 48 | int dz_decompress(int dz) 49 | { 50 | return 1 << dz; 51 | } 52 | 53 | int dz_compress(int dz) 54 | { 55 | return max(findMSB(dz), 0); 56 | } 57 | 58 | #endif -------------------------------------------------------------------------------- /src/config_gui_resources.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Kickstart.rc 4 | // 5 | #define FormKickstart 101 6 | #define KickstartIcon 108 7 | #define ButtonRun 1001 8 | #define ButtonQuit 1002 9 | #define ComboResolution 1003 10 | #define ComboAspect 1004 11 | #define ComboUpscaler 1005 12 | #define CheckFullscreen 1006 13 | #define CheckVerticalSync 1007 14 | #define CheckMultisampling 1008 15 | #define SSDITHER 1008 16 | #define StaticResolution 1009 17 | #define StaticScreen 1010 18 | #define SSREADS 1010 19 | #define StaticAspect 1011 20 | #define CheckLoop 1012 21 | #define Upscaling 1012 22 | #define CheckTest 1013 23 | #define ComboDeinterlace 1013 24 | #define WelcomeControl 1014 25 | #define Upscaling2 1014 26 | #define INTEGERSCALE 1015 27 | #define VIAA 1016 28 | #define StaticMultisampling 1017 29 | #define VIBilinear 1017 30 | #define StaticVerticalSync 1018 31 | #define VIDIVOT 1018 32 | #define StaticFullscreen 1019 33 | #define VDEDITHER 1019 34 | #define NATIVETEXLOD 1020 35 | #define NATIVETEXRECT 1021 36 | #define ComboUpscaler2 1022 37 | #define Upscaling3 1023 38 | #define CheckVerticalSync2 1024 39 | #define CheckWidescreen 1024 40 | #define CheckSynchronous 1025 41 | 42 | // Next default values for new objects 43 | // 44 | #ifdef APSTUDIO_INVOKED 45 | #ifndef APSTUDIO_READONLY_SYMBOLS 46 | #define _APS_NEXT_RESOURCE_VALUE 112 47 | #define _APS_NEXT_COMMAND_VALUE 40001 48 | #define _APS_NEXT_CONTROL_VALUE 1017 49 | #define _APS_NEXT_SYMED_VALUE 101 50 | #endif 51 | #endif 52 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/quirks.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | namespace Vulkan 26 | { 27 | struct ImplementationQuirks 28 | { 29 | bool instance_deferred_lights = true; 30 | bool merge_subpasses = true; 31 | bool use_transient_color = true; 32 | bool use_transient_depth_stencil = true; 33 | bool clustering_list_iteration = false; 34 | bool clustering_force_cpu = false; 35 | bool queue_wait_on_submission = false; 36 | bool staging_need_device_local = false; 37 | bool use_async_compute_post = true; 38 | bool render_graph_force_single_queue = false; 39 | bool force_no_subgroups = false; 40 | 41 | static ImplementationQuirks &get() 42 | { 43 | static ImplementationQuirks quirks; 44 | return quirks; 45 | } 46 | }; 47 | 48 | struct ImplementationWorkarounds 49 | { 50 | bool emulate_event_as_pipeline_barrier = false; 51 | bool wsi_acquire_barrier_is_expensive = false; 52 | bool optimize_all_graphics_barrier = false; 53 | bool force_store_in_render_pass = false; 54 | bool broken_color_write_mask = false; 55 | }; 56 | } 57 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/semaphore_manager.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "semaphore_manager.hpp" 24 | #include "device.hpp" 25 | 26 | namespace Vulkan 27 | { 28 | void SemaphoreManager::init(Device *device_) 29 | { 30 | device = device_; 31 | table = &device->get_device_table(); 32 | } 33 | 34 | SemaphoreManager::~SemaphoreManager() 35 | { 36 | for (auto &sem : semaphores) 37 | table->vkDestroySemaphore(device->get_device(), sem, nullptr); 38 | } 39 | 40 | void SemaphoreManager::recycle(VkSemaphore sem) 41 | { 42 | if (sem != VK_NULL_HANDLE) 43 | semaphores.push_back(sem); 44 | } 45 | 46 | VkSemaphore SemaphoreManager::request_cleared_semaphore() 47 | { 48 | if (semaphores.empty()) 49 | { 50 | VkSemaphore semaphore; 51 | VkSemaphoreCreateInfo info = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; 52 | table->vkCreateSemaphore(device->get_device(), &info, nullptr, &semaphore); 53 | return semaphore; 54 | } 55 | else 56 | { 57 | auto sem = semaphores.back(); 58 | semaphores.pop_back(); 59 | return sem; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/parallel-rdp/util/aligned_alloc.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | namespace Util 30 | { 31 | void *memalign_alloc(size_t boundary, size_t size); 32 | void *memalign_calloc(size_t boundary, size_t size); 33 | void memalign_free(void *ptr); 34 | 35 | template 36 | struct AlignedAllocation 37 | { 38 | static void *operator new(size_t size) 39 | { 40 | void *ret = ::Util::memalign_alloc(alignof(T), size); 41 | if (!ret) throw std::bad_alloc(); 42 | return ret; 43 | } 44 | 45 | static void *operator new[](size_t size) 46 | { 47 | void *ret = ::Util::memalign_alloc(alignof(T), size); 48 | if (!ret) throw std::bad_alloc(); 49 | return ret; 50 | } 51 | 52 | static void operator delete(void *ptr) 53 | { 54 | return ::Util::memalign_free(ptr); 55 | } 56 | 57 | static void operator delete[](void *ptr) 58 | { 59 | return ::Util::memalign_free(ptr); 60 | } 61 | }; 62 | } 63 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan-headers/include/vulkan/vk_sdk_platform.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: vk_sdk_platform.h 3 | // 4 | /* 5 | * Copyright (c) 2015-2016 The Khronos Group Inc. 6 | * Copyright (c) 2015-2016 Valve Corporation 7 | * Copyright (c) 2015-2016 LunarG, Inc. 8 | * 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | */ 21 | 22 | #ifndef VK_SDK_PLATFORM_H 23 | #define VK_SDK_PLATFORM_H 24 | 25 | #if defined(_WIN32) 26 | #define NOMINMAX 27 | #ifndef __cplusplus 28 | #undef inline 29 | #define inline __inline 30 | #endif // __cplusplus 31 | 32 | #if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) 33 | // C99: 34 | // Microsoft didn't implement C99 in Visual Studio; but started adding it with 35 | // VS2013. However, VS2013 still didn't have snprintf(). The following is a 36 | // work-around (Note: The _CRT_SECURE_NO_WARNINGS macro must be set in the 37 | // "CMakeLists.txt" file). 38 | // NOTE: This is fixed in Visual Studio 2015. 39 | #define snprintf _snprintf 40 | #endif 41 | 42 | #define strdup _strdup 43 | 44 | #endif // _WIN32 45 | 46 | // Check for noexcept support using clang, with fallback to Windows or GCC version numbers 47 | #ifndef NOEXCEPT 48 | #if defined(__clang__) 49 | #if __has_feature(cxx_noexcept) 50 | #define HAS_NOEXCEPT 51 | #endif 52 | #else 53 | #if defined(__GXX_EXPERIMENTAL_CXX0X__) && __GNUC__ * 10 + __GNUC_MINOR__ >= 46 54 | #define HAS_NOEXCEPT 55 | #else 56 | #if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023026 && defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS 57 | #define HAS_NOEXCEPT 58 | #endif 59 | #endif 60 | #endif 61 | 62 | #ifdef HAS_NOEXCEPT 63 | #define NOEXCEPT noexcept 64 | #else 65 | #define NOEXCEPT 66 | #endif 67 | #endif 68 | 69 | #endif // VK_SDK_PLATFORM_H 70 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/command_ring.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Themaister 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #ifdef PARALLEL_RDP_SHADER_DIR 31 | #include "global_managers.hpp" 32 | #endif 33 | 34 | namespace RDP 35 | { 36 | class CommandProcessor; 37 | class CommandRing 38 | { 39 | public: 40 | void init( 41 | #ifdef PARALLEL_RDP_SHADER_DIR 42 | Granite::Global::GlobalManagersHandle global_handles, 43 | #endif 44 | CommandProcessor *processor, unsigned count); 45 | ~CommandRing(); 46 | void drain(); 47 | 48 | void enqueue_command(unsigned num_words, const uint32_t *words); 49 | 50 | private: 51 | CommandProcessor *processor = nullptr; 52 | std::thread thr; 53 | std::mutex lock; 54 | std::condition_variable cond; 55 | 56 | std::vector ring; 57 | uint64_t write_count = 0; 58 | uint64_t read_count = 0; 59 | uint64_t completed_count = 0; 60 | 61 | void thread_loop(); 62 | void teardown_thread(); 63 | #ifdef PARALLEL_RDP_SHADER_DIR 64 | Granite::Global::GlobalManagersHandle global_handles; 65 | #endif 66 | }; 67 | } 68 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/load_derived_setup.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Themaister 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef LOAD_DERIVED_SETUP_H_ 24 | #define LOAD_DERIVED_SETUP_H_ 25 | 26 | DerivedSetup load_derived_setup(uint index) 27 | { 28 | #if SMALL_TYPES 29 | return derived_setup.elems[index]; 30 | #else 31 | return DerivedSetup( 32 | u8x4(derived_setup.elems[index].constant_muladd0), 33 | u8x4(derived_setup.elems[index].constant_mulsub0), 34 | u8x4(derived_setup.elems[index].constant_mul0), 35 | u8x4(derived_setup.elems[index].constant_add0), 36 | u8x4(derived_setup.elems[index].constant_muladd1), 37 | u8x4(derived_setup.elems[index].constant_mulsub1), 38 | u8x4(derived_setup.elems[index].constant_mul1), 39 | u8x4(derived_setup.elems[index].constant_add1), 40 | u8x4(derived_setup.elems[index].fog_color), 41 | u8x4(derived_setup.elems[index].blend_color), 42 | uint(derived_setup.elems[index].fill_color), 43 | u16(derived_setup.elems[index].dz), 44 | u8(derived_setup.elems[index].dz_compressed), 45 | u8(derived_setup.elems[index].min_lod), 46 | i16x4(derived_setup.elems[index].factors)); 47 | #endif 48 | } 49 | 50 | #endif -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/command_pool.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "vulkan_headers.hpp" 26 | #include 27 | #include 28 | 29 | namespace Vulkan 30 | { 31 | class Device; 32 | class CommandPool 33 | { 34 | public: 35 | CommandPool(Device *device, uint32_t queue_family_index); 36 | ~CommandPool(); 37 | 38 | CommandPool(CommandPool &&) noexcept; 39 | CommandPool &operator=(CommandPool &&) noexcept; 40 | CommandPool(const CommandPool &) = delete; 41 | void operator=(const CommandPool &) = delete; 42 | 43 | void begin(); 44 | void trim(); 45 | VkCommandBuffer request_command_buffer(); 46 | VkCommandBuffer request_secondary_command_buffer(); 47 | void signal_submitted(VkCommandBuffer cmd); 48 | 49 | private: 50 | Device *device; 51 | const VolkDeviceTable *table; 52 | VkCommandPool pool = VK_NULL_HANDLE; 53 | std::vector buffers; 54 | std::vector secondary_buffers; 55 | #ifdef VULKAN_DEBUG 56 | std::unordered_set in_flight; 57 | #endif 58 | unsigned index = 0; 59 | unsigned secondary_index = 0; 60 | }; 61 | } 62 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/vi_debug.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Themaister 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef VI_DEBUG_H_ 24 | #define VI_DEBUG_H_ 25 | 26 | #if defined(DEBUG_ENABLE) && DEBUG_ENABLE 27 | #include "debug_channel.h" 28 | 29 | void GENERIC_MESSAGE_(int line) 30 | { 31 | add_debug_message(0, uvec3(gl_FragCoord.xy, 0), line); 32 | } 33 | 34 | void GENERIC_MESSAGE_(int line, uint v) 35 | { 36 | add_debug_message(0, uvec3(gl_FragCoord.xy, 0), uvec2(line, v)); 37 | } 38 | 39 | void GENERIC_MESSAGE_(int line, uvec2 v) 40 | { 41 | add_debug_message(0, uvec3(gl_FragCoord.xy, 0), uvec3(line, v)); 42 | } 43 | 44 | void GENERIC_MESSAGE_(int line, uvec3 v) 45 | { 46 | add_debug_message(0, uvec3(gl_FragCoord.xy, 0), uvec4(line, v)); 47 | } 48 | 49 | #define GENERIC_MESSAGE0() GENERIC_MESSAGE_(__LINE__) 50 | #define GENERIC_MESSAGE1(a) GENERIC_MESSAGE_(__LINE__, a) 51 | #define GENERIC_MESSAGE2(a, b) GENERIC_MESSAGE_(__LINE__, uvec2(a, b)) 52 | #define GENERIC_MESSAGE3(a, b, c) GENERIC_MESSAGE_(__LINE__, uvec3(a, b, c)) 53 | #else 54 | #define GENERIC_MESSAGE0() 55 | #define GENERIC_MESSAGE1(a) 56 | #define GENERIC_MESSAGE2(a, b) 57 | #define GENERIC_MESSAGE3(a, b, c) 58 | #endif 59 | 60 | #endif -------------------------------------------------------------------------------- /src/parallel-rdp/util/timeline_trace_file.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include "object_pool.hpp" 32 | 33 | namespace Util 34 | { 35 | class TimelineTraceFile 36 | { 37 | public: 38 | explicit TimelineTraceFile(const std::string &path); 39 | ~TimelineTraceFile(); 40 | 41 | static void set_tid(const char *tid); 42 | static TimelineTraceFile *get_per_thread(); 43 | static void set_per_thread(TimelineTraceFile *file); 44 | 45 | struct Event 46 | { 47 | char desc[256]; 48 | char tid[32]; 49 | uint32_t pid; 50 | uint64_t start_ns, end_ns; 51 | 52 | void set_desc(const char *desc); 53 | void set_tid(const char *tid); 54 | }; 55 | Event *begin_event(const char *desc, uint32_t pid = 0); 56 | void end_event(Event *e); 57 | 58 | Event *allocate_event(); 59 | void submit_event(Event *e); 60 | 61 | private: 62 | void looper(std::string path); 63 | std::thread thr; 64 | std::mutex lock; 65 | std::condition_variable cond; 66 | 67 | ThreadSafeObjectPool event_pool; 68 | std::queue queued_events; 69 | }; 70 | } 71 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/pipeline_event.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "vulkan_headers.hpp" 26 | #include "vulkan_common.hpp" 27 | #include "cookie.hpp" 28 | #include "object_pool.hpp" 29 | 30 | namespace Vulkan 31 | { 32 | class Device; 33 | class EventHolder; 34 | 35 | struct EventHolderDeleter 36 | { 37 | void operator()(EventHolder *event); 38 | }; 39 | 40 | class EventHolder : public Util::IntrusivePtrEnabled, 41 | public InternalSyncEnabled 42 | { 43 | public: 44 | friend struct EventHolderDeleter; 45 | 46 | ~EventHolder(); 47 | 48 | const VkEvent &get_event() const 49 | { 50 | return event; 51 | } 52 | 53 | VkPipelineStageFlags get_stages() const 54 | { 55 | return stages; 56 | } 57 | 58 | void set_stages(VkPipelineStageFlags stages_) 59 | { 60 | stages = stages_; 61 | } 62 | 63 | private: 64 | friend class Util::ObjectPool; 65 | EventHolder(Device *device_, VkEvent event_) 66 | : device(device_) 67 | , event(event_) 68 | { 69 | } 70 | 71 | Device *device; 72 | VkEvent event; 73 | VkPipelineStageFlags stages = 0; 74 | }; 75 | 76 | using PipelineEvent = Util::IntrusivePtr; 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/masked_rdram_resolve.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | /* Copyright (c) 2020 Themaister 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files (the 6 | * "Software"), to deal in the Software without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | layout(local_size_x_id = 0) in; 25 | layout(constant_id = 1) const int PAGE_STRIDE = 256; 26 | 27 | layout(set = 0, binding = 0, std430) buffer RDRAM 28 | { 29 | uint rdram[]; 30 | }; 31 | 32 | layout(set = 0, binding = 1, std430) readonly buffer StagingRDRAM 33 | { 34 | uint staging_rdram[]; 35 | }; 36 | 37 | layout(set = 0, binding = 2, std430) readonly buffer WriteMaskRDRAM 38 | { 39 | uint writemask[]; 40 | }; 41 | 42 | layout(set = 1, binding = 0, std140) uniform UBO 43 | { 44 | uvec4 offsets[1024]; 45 | }; 46 | 47 | void main() 48 | { 49 | uint offset = offsets[gl_WorkGroupID.x >> 2u][gl_WorkGroupID.x & 3u]; 50 | offset *= PAGE_STRIDE; 51 | offset += gl_LocalInvocationIndex; 52 | uint mask = writemask[offset]; 53 | 54 | if (mask == ~0u) 55 | { 56 | return; 57 | } 58 | else if (mask == 0u) 59 | { 60 | uint staging = staging_rdram[offset]; 61 | rdram[offset] = staging; 62 | } 63 | else 64 | { 65 | uint word = rdram[offset]; 66 | uint staging = staging_rdram[offset]; 67 | word = (word & mask) | (staging & ~mask); 68 | rdram[offset] = word; 69 | } 70 | } -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/event_manager.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "event_manager.hpp" 24 | #include "device.hpp" 25 | 26 | namespace Vulkan 27 | { 28 | EventManager::~EventManager() 29 | { 30 | if (!workaround) 31 | for (auto &event : events) 32 | table->vkDestroyEvent(device->get_device(), event, nullptr); 33 | } 34 | 35 | void EventManager::recycle(VkEvent event) 36 | { 37 | if (!workaround && event != VK_NULL_HANDLE) 38 | { 39 | table->vkResetEvent(device->get_device(), event); 40 | events.push_back(event); 41 | } 42 | } 43 | 44 | VkEvent EventManager::request_cleared_event() 45 | { 46 | if (workaround) 47 | { 48 | // Can't use reinterpret_cast because of MSVC. 49 | return (VkEvent) ++workaround_counter; 50 | } 51 | else if (events.empty()) 52 | { 53 | VkEvent event; 54 | VkEventCreateInfo info = { VK_STRUCTURE_TYPE_EVENT_CREATE_INFO }; 55 | table->vkCreateEvent(device->get_device(), &info, nullptr, &event); 56 | return event; 57 | } 58 | else 59 | { 60 | auto event = events.back(); 61 | events.pop_back(); 62 | return event; 63 | } 64 | } 65 | 66 | void EventManager::init(Device *device_) 67 | { 68 | device = device_; 69 | table = &device->get_device_table(); 70 | workaround = device_->get_workarounds().emulate_event_as_pipeline_barrier; 71 | } 72 | } -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/vulkan_headers.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #if defined(_WIN32) && !defined(VK_USE_PLATFORM_WIN32_KHR) 26 | #define VK_USE_PLATFORM_WIN32_KHR 27 | #endif 28 | 29 | #include "volk.h" 30 | #include 31 | #include "logging.hpp" 32 | #include 33 | 34 | #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT 35 | // Workaround silly Xlib headers that define macros for these globally :( 36 | #undef None 37 | #undef Bool 38 | #endif 39 | 40 | #ifdef VULKAN_DEBUG 41 | #define VK_ASSERT(x) \ 42 | do \ 43 | { \ 44 | if (!bool(x)) \ 45 | { \ 46 | LOGE("Vulkan error at %s:%d.\n", __FILE__, __LINE__); \ 47 | abort(); \ 48 | } \ 49 | } while (0) 50 | #else 51 | #define VK_ASSERT(x) ((void)0) 52 | #endif 53 | 54 | namespace Vulkan 55 | { 56 | struct NoCopyNoMove 57 | { 58 | NoCopyNoMove() = default; 59 | NoCopyNoMove(const NoCopyNoMove &) = delete; 60 | void operator=(const NoCopyNoMove &) = delete; 61 | }; 62 | } 63 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/noise.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Themaister 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef NOISE_H_ 24 | #define NOISE_H_ 25 | 26 | u16 seeded_noise = U16_C(0); 27 | 28 | // From: https://www.shadertoy.com/view/XlXcW4 with slight modifications. 29 | void reseed_noise(uint x, uint y, uint primitive_offset) 30 | { 31 | const uint NOISE_PRIME = 1103515245u; 32 | uvec3 seed = uvec3(x, y, primitive_offset); 33 | seed = ((seed >> 8u) ^ seed.yzx) * NOISE_PRIME; 34 | seed = ((seed >> 8u) ^ seed.yzx) * NOISE_PRIME; 35 | seed = ((seed >> 8u) ^ seed.yzx) * NOISE_PRIME; 36 | seeded_noise = u16(seed.x >> 16u); 37 | } 38 | 39 | i16 noise_get_combiner() 40 | { 41 | return i16(((seeded_noise & U16_C(7u)) << U16_C(6u)) | U16_C(0x20u)); 42 | } 43 | 44 | int noise_get_dither_alpha() 45 | { 46 | return int(seeded_noise & U16_C(7u)); 47 | } 48 | 49 | int noise_get_dither_color() 50 | { 51 | // 3 bits of noise for RGB separately. 52 | return int(seeded_noise & U16_C(0x1ff)); 53 | } 54 | 55 | u8 noise_get_blend_threshold() 56 | { 57 | return u8(seeded_noise & U16_C(0xffu)); 58 | } 59 | 60 | uvec3 noise_get_full_gamma_dither() 61 | { 62 | uint seed = seeded_noise; 63 | return uvec3(seed & 0x3f, (seed >> 6u) & 0x3f, ((seed >> 9u) & 0x38) | (seed & 7u)); 64 | } 65 | 66 | uvec3 noise_get_partial_gamma_dither() 67 | { 68 | return (uvec3(seeded_noise) >> uvec3(0, 1, 2)) & 1u; 69 | } 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/vi_status.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Themaister 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef VI_STATUS_H_ 24 | #define VI_STATUS_H_ 25 | 26 | layout(constant_id = 1) const int VI_STATUS = 0; 27 | const int VI_CONTROL_TYPE_BLANK_BIT = 0 << 0; 28 | const int VI_CONTROL_TYPE_RESERVED_BIT = 1 << 0; 29 | const int VI_CONTROL_TYPE_RGBA5551_BIT = 2 << 0; 30 | const int VI_CONTROL_TYPE_RGBA8888_BIT = 3 << 0; 31 | const int VI_CONTROL_TYPE_MASK = 3 << 0; 32 | const int VI_CONTROL_GAMMA_DITHER_ENABLE_BIT = 1 << 2; 33 | const int VI_CONTROL_GAMMA_ENABLE_BIT = 1 << 3; 34 | const int VI_CONTROL_DIVOT_ENABLE_BIT = 1 << 4; 35 | const int VI_CONTROL_SERRATE_BIT = 1 << 6; 36 | const int VI_CONTROL_DITHER_FILTER_ENABLE_BIT = 1 << 16; 37 | const int VI_CONTROL_META_AA_BIT = 1 << 17; 38 | const int VI_CONTROL_META_SCALE_BIT = 1 << 18; 39 | 40 | const bool FMT_RGBA5551 = (VI_STATUS & VI_CONTROL_TYPE_MASK) == VI_CONTROL_TYPE_RGBA5551_BIT; 41 | const bool FMT_RGBA8888 = (VI_STATUS & VI_CONTROL_TYPE_MASK) == VI_CONTROL_TYPE_RGBA8888_BIT; 42 | const bool DITHER_ENABLE = (VI_STATUS & VI_CONTROL_DITHER_FILTER_ENABLE_BIT) != 0; 43 | const bool FETCH_AA = (VI_STATUS & VI_CONTROL_META_AA_BIT) != 0; 44 | const bool SCALE_AA = (VI_STATUS & VI_CONTROL_META_SCALE_BIT) != 0; 45 | const bool GAMMA_ENABLE = (VI_STATUS & VI_CONTROL_GAMMA_ENABLE_BIT) != 0; 46 | const bool GAMMA_DITHER = (VI_STATUS & VI_CONTROL_GAMMA_DITHER_ENABLE_BIT) != 0; 47 | 48 | #endif -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/buffer.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "buffer.hpp" 24 | #include "device.hpp" 25 | 26 | namespace Vulkan 27 | { 28 | Buffer::Buffer(Device *device_, VkBuffer buffer_, const DeviceAllocation &alloc_, const BufferCreateInfo &info_) 29 | : Cookie(device_) 30 | , device(device_) 31 | , buffer(buffer_) 32 | , alloc(alloc_) 33 | , info(info_) 34 | { 35 | } 36 | 37 | Buffer::~Buffer() 38 | { 39 | if (internal_sync) 40 | { 41 | device->destroy_buffer_nolock(buffer); 42 | device->free_memory_nolock(alloc); 43 | } 44 | else 45 | { 46 | device->destroy_buffer(buffer); 47 | device->free_memory(alloc); 48 | } 49 | } 50 | 51 | void BufferDeleter::operator()(Buffer *buffer) 52 | { 53 | buffer->device->handle_pool.buffers.free(buffer); 54 | } 55 | 56 | BufferView::BufferView(Device *device_, VkBufferView view_, const BufferViewCreateInfo &create_info_) 57 | : Cookie(device_) 58 | , device(device_) 59 | , view(view_) 60 | , info(create_info_) 61 | { 62 | } 63 | 64 | BufferView::~BufferView() 65 | { 66 | if (view != VK_NULL_HANDLE) 67 | { 68 | if (internal_sync) 69 | device->destroy_buffer_view_nolock(view); 70 | else 71 | device->destroy_buffer_view(view); 72 | } 73 | } 74 | 75 | void BufferViewDeleter::operator()(BufferView *view) 76 | { 77 | view->device->handle_pool.buffer_views.free(view); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/semaphore.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "semaphore.hpp" 24 | #include "device.hpp" 25 | 26 | namespace Vulkan 27 | { 28 | SemaphoreHolder::~SemaphoreHolder() 29 | { 30 | recycle_semaphore(); 31 | } 32 | 33 | void SemaphoreHolder::recycle_semaphore() 34 | { 35 | if (timeline == 0 && semaphore) 36 | { 37 | if (internal_sync) 38 | { 39 | if (is_signalled()) 40 | device->destroy_semaphore_nolock(semaphore); 41 | else 42 | device->recycle_semaphore_nolock(semaphore); 43 | } 44 | else 45 | { 46 | if (is_signalled()) 47 | device->destroy_semaphore(semaphore); 48 | else 49 | device->recycle_semaphore(semaphore); 50 | } 51 | } 52 | } 53 | 54 | SemaphoreHolder &SemaphoreHolder::operator=(SemaphoreHolder &&other) noexcept 55 | { 56 | if (this == &other) 57 | return *this; 58 | 59 | assert(device == other.device); 60 | recycle_semaphore(); 61 | 62 | semaphore = other.semaphore; 63 | timeline = other.timeline; 64 | signalled = other.signalled; 65 | pending = other.pending; 66 | should_destroy_on_consume = other.should_destroy_on_consume; 67 | 68 | other.semaphore = VK_NULL_HANDLE; 69 | other.timeline = 0; 70 | other.signalled = false; 71 | other.pending = false; 72 | other.should_destroy_on_consume = false; 73 | 74 | return *this; 75 | } 76 | 77 | void SemaphoreHolderDeleter::operator()(Vulkan::SemaphoreHolder *semaphore) 78 | { 79 | semaphore->device->handle_pool.semaphores.free(semaphore); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/parallel-rdp/config.mk: -------------------------------------------------------------------------------- 1 | # For use in standalone implementations. 2 | 3 | PARALLEL_RDP_CFLAGS := 4 | PARALLEL_RDP_CXXFLAGS := -DGRANITE_VULKAN_MT 5 | 6 | PARALLEL_RDP_SOURCES_CXX := \ 7 | $(wildcard $(PARALLEL_RDP_IMPLEMENTATION)/parallel-rdp/*.cpp) \ 8 | $(PARALLEL_RDP_IMPLEMENTATION)/vulkan/buffer.cpp \ 9 | $(PARALLEL_RDP_IMPLEMENTATION)/vulkan/buffer_pool.cpp \ 10 | $(PARALLEL_RDP_IMPLEMENTATION)/vulkan/command_buffer.cpp \ 11 | $(PARALLEL_RDP_IMPLEMENTATION)/vulkan/command_pool.cpp \ 12 | $(PARALLEL_RDP_IMPLEMENTATION)/vulkan/context.cpp \ 13 | $(PARALLEL_RDP_IMPLEMENTATION)/vulkan/cookie.cpp \ 14 | $(PARALLEL_RDP_IMPLEMENTATION)/vulkan/descriptor_set.cpp \ 15 | $(PARALLEL_RDP_IMPLEMENTATION)/vulkan/device.cpp \ 16 | $(PARALLEL_RDP_IMPLEMENTATION)/vulkan/event_manager.cpp \ 17 | $(PARALLEL_RDP_IMPLEMENTATION)/vulkan/fence.cpp \ 18 | $(PARALLEL_RDP_IMPLEMENTATION)/vulkan/fence_manager.cpp \ 19 | $(PARALLEL_RDP_IMPLEMENTATION)/vulkan/image.cpp \ 20 | $(PARALLEL_RDP_IMPLEMENTATION)/vulkan/memory_allocator.cpp \ 21 | $(PARALLEL_RDP_IMPLEMENTATION)/vulkan/pipeline_event.cpp \ 22 | $(PARALLEL_RDP_IMPLEMENTATION)/vulkan/query_pool.cpp \ 23 | $(PARALLEL_RDP_IMPLEMENTATION)/vulkan/render_pass.cpp \ 24 | $(PARALLEL_RDP_IMPLEMENTATION)/vulkan/sampler.cpp \ 25 | $(PARALLEL_RDP_IMPLEMENTATION)/vulkan/semaphore.cpp \ 26 | $(PARALLEL_RDP_IMPLEMENTATION)/vulkan/semaphore_manager.cpp \ 27 | $(PARALLEL_RDP_IMPLEMENTATION)/vulkan/shader.cpp \ 28 | $(PARALLEL_RDP_IMPLEMENTATION)/vulkan/texture_format.cpp \ 29 | $(PARALLEL_RDP_IMPLEMENTATION)/util/logging.cpp \ 30 | $(PARALLEL_RDP_IMPLEMENTATION)/util/thread_id.cpp \ 31 | $(PARALLEL_RDP_IMPLEMENTATION)/util/aligned_alloc.cpp \ 32 | $(PARALLEL_RDP_IMPLEMENTATION)/util/timer.cpp \ 33 | $(PARALLEL_RDP_IMPLEMENTATION)/util/timeline_trace_file.cpp \ 34 | $(PARALLEL_RDP_IMPLEMENTATION)/util/thread_name.cpp 35 | 36 | PARALLEL_RDP_SOURCES_C := \ 37 | $(PARALLEL_RDP_IMPLEMENTATION)/volk/volk.c 38 | 39 | PARALLEL_RDP_INCLUDE_DIRS := \ 40 | -I$(PARALLEL_RDP_IMPLEMENTATION)/parallel-rdp \ 41 | -I$(PARALLEL_RDP_IMPLEMENTATION)/volk \ 42 | -I$(PARALLEL_RDP_IMPLEMENTATION)/vulkan \ 43 | -I$(PARALLEL_RDP_IMPLEMENTATION)/vulkan-headers/include \ 44 | -I$(PARALLEL_RDP_IMPLEMENTATION)/util 45 | 46 | PARALLEL_RDP_LDFLAGS := -pthread 47 | ifeq (,$(findstring win,$(platform))) 48 | PARALLEL_RDP_LDFLAGS += -ldl 49 | else 50 | PARALLEL_RDP_CFLAGS += -DVK_USE_PLATFORM_WIN32_KHR 51 | endif 52 | 53 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/fence.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "vulkan_common.hpp" 26 | #include "vulkan_headers.hpp" 27 | #include "object_pool.hpp" 28 | #include "cookie.hpp" 29 | #ifdef GRANITE_VULKAN_MT 30 | #include 31 | #endif 32 | 33 | namespace Vulkan 34 | { 35 | class Device; 36 | 37 | class FenceHolder; 38 | struct FenceHolderDeleter 39 | { 40 | void operator()(FenceHolder *fence); 41 | }; 42 | 43 | class FenceHolder : public Util::IntrusivePtrEnabled, public InternalSyncEnabled 44 | { 45 | public: 46 | friend struct FenceHolderDeleter; 47 | friend class WSI; 48 | 49 | ~FenceHolder(); 50 | void wait(); 51 | bool wait_timeout(uint64_t nsec); 52 | 53 | private: 54 | friend class Util::ObjectPool; 55 | FenceHolder(Device *device_, VkFence fence_) 56 | : device(device_), 57 | fence(fence_), 58 | timeline_semaphore(VK_NULL_HANDLE), 59 | timeline_value(0) 60 | { 61 | } 62 | 63 | FenceHolder(Device *device_, uint64_t value, VkSemaphore timeline_semaphore_) 64 | : device(device_), 65 | fence(VK_NULL_HANDLE), 66 | timeline_semaphore(timeline_semaphore_), 67 | timeline_value(value) 68 | { 69 | VK_ASSERT(value > 0); 70 | } 71 | 72 | VkFence get_fence() const; 73 | 74 | Device *device; 75 | VkFence fence; 76 | VkSemaphore timeline_semaphore; 77 | uint64_t timeline_value; 78 | bool observed_wait = false; 79 | #ifdef GRANITE_VULKAN_MT 80 | std::mutex lock; 81 | #endif 82 | }; 83 | 84 | using Fence = Util::IntrusivePtr; 85 | } 86 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/clamping.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Themaister 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CLAMPING_H_ 24 | #define CLAMPING_H_ 25 | 26 | #if SMALL_TYPES && 0 27 | // This path is buggy on RADV LLVM, disable for time being. 28 | i16x4 clamp_9bit_notrunc(i16x4 color) 29 | { 30 | // [-129, -256] should clamp to 0xff, subtracting by 0x80 will underflow back to positive numbers. 31 | // [-128, -1] should clamp to 0. 32 | color -= I16_C(0x80); 33 | // Sign-extend to 9-bit. 34 | color <<= I16_C(7); 35 | color >>= I16_C(7); 36 | color += I16_C(0x80); 37 | return clamp(color, i16x4(0), i16x4(0xff)); 38 | } 39 | #else 40 | i16x4 clamp_9bit_notrunc(ivec4 color) 41 | { 42 | // [-129, -256] should clamp to 0xff, subtracting by 0x80 will underflow back to positive numbers. 43 | // [-128, -1] should clamp to 0. 44 | color -= 0x80; 45 | // Sign-extend to 9-bit. 46 | color = bitfieldExtract(color, 0, 9); 47 | color += 0x80; 48 | return i16x4(clamp(color, ivec4(0), ivec4(0xff))); 49 | } 50 | #endif 51 | 52 | u8x4 clamp_9bit(i16x4 color) 53 | { 54 | return u8x4(clamp_9bit_notrunc(color)); 55 | } 56 | 57 | int clamp_9bit(int color) 58 | { 59 | return clamp(bitfieldExtract(color - 0x80, 0, 9) + 0x80, 0, 0xff); 60 | } 61 | 62 | // Returns 18-bit UNORM depth. 63 | int clamp_z(int z) 64 | { 65 | // Similar to RGBA, we reserve an extra bit to deal with overflow and underflow. 66 | z -= (1 << 17); 67 | z <<= (31 - 18); 68 | z >>= (31 - 18); 69 | z += (1 << 17); 70 | 71 | // [0x00000, 0x3ffff] maps to self. 72 | // [0x40000, 0x5ffff] maps to 0x3ffff. 73 | // [0x60000, 0x7ffff] maps to 0. 74 | 75 | return clamp(z, 0, 0x3ffff); 76 | } 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/vulkan_prerotate.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "vulkan_headers.hpp" 26 | 27 | namespace Vulkan 28 | { 29 | static inline bool surface_transform_swaps_xy(VkSurfaceTransformFlagBitsKHR transform) 30 | { 31 | return (transform & ( 32 | VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR | 33 | VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR | 34 | VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR | 35 | VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR)) != 0; 36 | } 37 | 38 | static inline void viewport_swap_xy(VkViewport &vp) 39 | { 40 | std::swap(vp.x, vp.y); 41 | std::swap(vp.width, vp.height); 42 | } 43 | 44 | static inline void rect2d_swap_xy(VkRect2D &rect) 45 | { 46 | std::swap(rect.offset.x, rect.offset.y); 47 | std::swap(rect.extent.width, rect.extent.height); 48 | } 49 | 50 | static inline void build_prerotate_matrix_2x2(VkSurfaceTransformFlagBitsKHR pre_rotate, float mat[4]) 51 | { 52 | // TODO: HORIZONTAL_MIRROR. 53 | switch (pre_rotate) 54 | { 55 | default: 56 | mat[0] = 1.0f; 57 | mat[1] = 0.0f; 58 | mat[2] = 0.0f; 59 | mat[3] = 1.0f; 60 | break; 61 | 62 | case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR: 63 | mat[0] = 0.0f; 64 | mat[1] = 1.0f; 65 | mat[2] = -1.0f; 66 | mat[3] = 0.0f; 67 | break; 68 | 69 | case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR: 70 | mat[0] = 0.0f; 71 | mat[1] = -1.0f; 72 | mat[2] = 1.0f; 73 | mat[3] = 0.0f; 74 | break; 75 | 76 | case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR: 77 | mat[0] = -1.0f; 78 | mat[1] = 0.0f; 79 | mat[2] = 0.0f; 80 | mat[3] = -1.0f; 81 | break; 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/parallel-rdp/util/aligned_alloc.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "aligned_alloc.hpp" 24 | #include 25 | #include 26 | #ifdef _WIN32 27 | #include 28 | #endif 29 | 30 | namespace Util 31 | { 32 | void *memalign_alloc(size_t boundary, size_t size) 33 | { 34 | #if defined(_WIN32) 35 | return _aligned_malloc(size, boundary); 36 | #elif defined(_ISOC11_SOURCE) 37 | return aligned_alloc(boundary, size); 38 | #elif (_POSIX_C_SOURCE >= 200112L) || (_XOPEN_SOURCE >= 600) 39 | void *ptr = nullptr; 40 | if (posix_memalign(&ptr, boundary, size) < 0) 41 | return nullptr; 42 | return ptr; 43 | #else 44 | // Align stuff ourselves. Kinda ugly, but will work anywhere. 45 | void **place; 46 | uintptr_t addr = 0; 47 | void *ptr = malloc(boundary + size + sizeof(uintptr_t)); 48 | 49 | if (ptr == nullptr) 50 | return nullptr; 51 | 52 | addr = ((uintptr_t)ptr + sizeof(uintptr_t) + boundary) & ~(boundary - 1); 53 | place = (void **) addr; 54 | place[-1] = ptr; 55 | 56 | return (void *) addr; 57 | #endif 58 | } 59 | 60 | void *memalign_calloc(size_t boundary, size_t size) 61 | { 62 | void *ret = memalign_alloc(boundary, size); 63 | if (ret) 64 | memset(ret, 0, size); 65 | return ret; 66 | } 67 | 68 | void memalign_free(void *ptr) 69 | { 70 | #if defined(_WIN32) 71 | _aligned_free(ptr); 72 | #elif !defined(_ISOC11_SOURCE) && !((_POSIX_C_SOURCE >= 200112L) || (_XOPEN_SOURCE >= 600)) 73 | if (ptr != nullptr) 74 | { 75 | void **p = (void **) ptr; 76 | free(p[-1]); 77 | } 78 | #else 79 | free(ptr); 80 | #endif 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/parallel-rdp/util/hash.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | #include 25 | #include 26 | 27 | namespace Util 28 | { 29 | using Hash = uint64_t; 30 | 31 | class Hasher 32 | { 33 | public: 34 | explicit Hasher(Hash h_) 35 | : h(h_) 36 | { 37 | } 38 | 39 | Hasher() = default; 40 | 41 | template 42 | inline void data(const T *data_, size_t size) 43 | { 44 | size /= sizeof(*data_); 45 | for (size_t i = 0; i < size; i++) 46 | h = (h * 0x100000001b3ull) ^ data_[i]; 47 | } 48 | 49 | inline void u32(uint32_t value) 50 | { 51 | h = (h * 0x100000001b3ull) ^ value; 52 | } 53 | 54 | inline void s32(int32_t value) 55 | { 56 | u32(uint32_t(value)); 57 | } 58 | 59 | inline void f32(float value) 60 | { 61 | union 62 | { 63 | float f32; 64 | uint32_t u32; 65 | } u; 66 | u.f32 = value; 67 | u32(u.u32); 68 | } 69 | 70 | inline void u64(uint64_t value) 71 | { 72 | u32(value & 0xffffffffu); 73 | u32(value >> 32); 74 | } 75 | 76 | template 77 | inline void pointer(T *ptr) 78 | { 79 | u64(reinterpret_cast(ptr)); 80 | } 81 | 82 | inline void string(const char *str) 83 | { 84 | char c; 85 | u32(0xff); 86 | while ((c = *str++) != '\0') 87 | u32(uint8_t(c)); 88 | } 89 | 90 | inline void string(const std::string &str) 91 | { 92 | u32(0xff); 93 | for (auto &c : str) 94 | u32(uint8_t(c)); 95 | } 96 | 97 | inline Hash get() const 98 | { 99 | return h; 100 | } 101 | 102 | private: 103 | Hash h = 0xcbf29ce484222325ull; 104 | }; 105 | } 106 | -------------------------------------------------------------------------------- /src/parallel-rdp/util/read_write_lock.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include 26 | 27 | #ifdef __SSE2__ 28 | #include 29 | #endif 30 | 31 | namespace Util 32 | { 33 | class RWSpinLock 34 | { 35 | public: 36 | enum { Reader = 2, Writer = 1 }; 37 | RWSpinLock() 38 | { 39 | counter.store(0); 40 | } 41 | 42 | inline void lock_read() 43 | { 44 | unsigned v = counter.fetch_add(Reader, std::memory_order_acquire); 45 | while ((v & Writer) != 0) 46 | { 47 | #ifdef __SSE2__ 48 | _mm_pause(); 49 | #endif 50 | v = counter.load(std::memory_order_acquire); 51 | } 52 | } 53 | 54 | inline void unlock_read() 55 | { 56 | counter.fetch_sub(Reader, std::memory_order_release); 57 | } 58 | 59 | inline void lock_write() 60 | { 61 | uint32_t expected = 0; 62 | while (!counter.compare_exchange_weak(expected, Writer, 63 | std::memory_order_acquire, 64 | std::memory_order_relaxed)) 65 | { 66 | #ifdef __SSE2__ 67 | _mm_pause(); 68 | #endif 69 | expected = 0; 70 | } 71 | } 72 | 73 | inline void unlock_write() 74 | { 75 | counter.fetch_and(~Writer, std::memory_order_release); 76 | } 77 | 78 | inline void promote_reader_to_writer() 79 | { 80 | uint32_t expected = Reader; 81 | if (!counter.compare_exchange_strong(expected, Writer, 82 | std::memory_order_acquire, 83 | std::memory_order_relaxed)) 84 | { 85 | unlock_read(); 86 | lock_write(); 87 | } 88 | } 89 | 90 | private: 91 | std::atomic counter; 92 | }; 93 | } 94 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/coverage.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Themaister 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef COVERAGE_H_ 24 | #define COVERAGE_H_ 25 | 26 | #include "data_structures.h" 27 | 28 | const int SUBPIXELS_LOG2 = 2; 29 | const int SUBPIXELS = 1 << SUBPIXELS_LOG2; 30 | 31 | u8 compute_coverage(u16x4 xleft, u16x4 xright, int x) 32 | { 33 | u16x4 xshift = u16x4(0, 4, 2, 6) + (u16(x) << U16_C(3)); 34 | bvec4 clip_lo_x01 = lessThan(xshift, xleft.xxyy); 35 | bvec4 clip_lo_x23 = lessThan(xshift, xleft.zzww); 36 | bvec4 clip_hi_x01 = greaterThanEqual(xshift, xright.xxyy); 37 | bvec4 clip_hi_x23 = greaterThanEqual(xshift, xright.zzww); 38 | 39 | u8x4 clip_x0 = u8x4(clip_lo_x01) | u8x4(clip_hi_x01); 40 | u8x4 clip_x1 = u8x4(clip_lo_x23) | u8x4(clip_hi_x23); 41 | u8x4 clip_x = clip_x0 * u8x4(1, 2, 4, 8) + clip_x1 * u8x4(16, 32, 64, 128); 42 | u8 clip_coverage = (clip_x.x | clip_x.y) | (clip_x.z | clip_x.w); 43 | return ~clip_coverage & U8_C(0xff); 44 | } 45 | 46 | const int COVERAGE_CLAMP = 0; 47 | const int COVERAGE_WRAP = 1; 48 | const int COVERAGE_ZAP = 2; 49 | const int COVERAGE_SAVE = 3; 50 | 51 | int blend_coverage(int coverage, int memory_coverage, bool blend_en, int mode) 52 | { 53 | int res = 0; 54 | switch (mode) 55 | { 56 | case COVERAGE_CLAMP: 57 | { 58 | if (blend_en) 59 | res = min(7, memory_coverage + coverage); // image_read_en to read memory coverage, otherwise, it's 7. 60 | else 61 | res = (coverage - 1) & 7; 62 | break; 63 | } 64 | 65 | case COVERAGE_WRAP: 66 | res = (coverage + memory_coverage) & 7; 67 | break; 68 | 69 | case COVERAGE_ZAP: 70 | res = 7; 71 | break; 72 | 73 | case COVERAGE_SAVE: 74 | res = memory_coverage; 75 | break; 76 | } 77 | 78 | return res; 79 | } 80 | 81 | #endif -------------------------------------------------------------------------------- /src/wgl_ext.h: -------------------------------------------------------------------------------- 1 | #ifndef POINTER_C_GENERATED_HEADER_WINDOWSGL_H 2 | #define POINTER_C_GENERATED_HEADER_WINDOWSGL_H 3 | 4 | #ifdef __wglext_h_ 5 | #error Attempt to include auto-generated WGL header after wglext.h 6 | #endif 7 | 8 | #define __wglext_h_ 9 | 10 | #ifndef WIN32_LEAN_AND_MEAN 11 | #define WIN32_LEAN_AND_MEAN 1 12 | #endif 13 | #ifndef NOMINMAX 14 | #define NOMINMAX 15 | #endif 16 | #include 17 | 18 | #ifdef CODEGEN_FUNCPTR 19 | #undef CODEGEN_FUNCPTR 20 | #endif /*CODEGEN_FUNCPTR*/ 21 | #define CODEGEN_FUNCPTR WINAPI 22 | 23 | 24 | 25 | #ifndef GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS 26 | #define GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS 27 | 28 | 29 | #endif /*GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS*/ 30 | 31 | 32 | struct _GPU_DEVICE { 33 | DWORD cb; 34 | CHAR DeviceName[32]; 35 | CHAR DeviceString[128]; 36 | DWORD Flags; 37 | RECT rcVirtualScreen; 38 | }; 39 | DECLARE_HANDLE(HPBUFFERARB); 40 | DECLARE_HANDLE(HPBUFFEREXT); 41 | DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); 42 | DECLARE_HANDLE(HPVIDEODEV); 43 | DECLARE_HANDLE(HGPUNV); 44 | DECLARE_HANDLE(HVIDEOINPUTDEVICENV); 45 | typedef struct _GPU_DEVICE *PGPU_DEVICE; 46 | 47 | #ifdef __cplusplus 48 | extern "C" { 49 | #endif /*__cplusplus*/ 50 | 51 | extern int wgl_ext_EXT_swap_control; 52 | extern int wgl_ext_ARB_create_context; 53 | extern int wgl_ext_ARB_create_context_profile; 54 | 55 | #define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001 56 | #define WGL_CONTEXT_FLAGS_ARB 0x2094 57 | #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 58 | #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 59 | #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 60 | #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 61 | #define WGL_ERROR_INVALID_VERSION_ARB 0x2095 62 | 63 | #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 64 | #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 65 | #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 66 | #define WGL_ERROR_INVALID_PROFILE_ARB 0x2096 67 | 68 | #ifndef WGL_EXT_swap_control 69 | #define WGL_EXT_swap_control 1 70 | extern int (CODEGEN_FUNCPTR *_ptrc_wglGetSwapIntervalEXT)(void); 71 | #define wglGetSwapIntervalEXT _ptrc_wglGetSwapIntervalEXT 72 | extern BOOL (CODEGEN_FUNCPTR *_ptrc_wglSwapIntervalEXT)(int interval); 73 | #define wglSwapIntervalEXT _ptrc_wglSwapIntervalEXT 74 | #endif /*WGL_EXT_swap_control*/ 75 | 76 | #ifndef WGL_ARB_create_context 77 | #define WGL_ARB_create_context 1 78 | extern HGLRC (CODEGEN_FUNCPTR *_ptrc_wglCreateContextAttribsARB)(HDC hDC, HGLRC hShareContext, const int * attribList); 79 | #define wglCreateContextAttribsARB _ptrc_wglCreateContextAttribsARB 80 | #endif /*WGL_ARB_create_context*/ 81 | 82 | 83 | enum wgl_LoadStatus 84 | { 85 | wgl_LOAD_FAILED = 0, 86 | wgl_LOAD_SUCCEEDED = 1, 87 | }; 88 | 89 | int wgl_LoadFunctions(HDC hdc); 90 | 91 | 92 | #ifdef __cplusplus 93 | } 94 | #endif /*__cplusplus*/ 95 | 96 | #endif /*POINTER_C_GENERATED_HEADER_WINDOWSGL_H*/ 97 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/dither.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Themaister 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef DITHER_H_ 24 | #define DITHER_H_ 25 | 26 | const u8 dither_matrices[2][16] = u8[][]( 27 | u8[](U8_C(0), U8_C(6), U8_C(1), U8_C(7), U8_C(4), U8_C(2), U8_C(5), U8_C(3), U8_C(3), U8_C(5), U8_C(2), U8_C(4), U8_C(7), U8_C(1), U8_C(6), U8_C(0)), 28 | u8[](U8_C(0), U8_C(4), U8_C(1), U8_C(5), U8_C(4), U8_C(0), U8_C(5), U8_C(1), U8_C(3), U8_C(7), U8_C(2), U8_C(6), U8_C(7), U8_C(3), U8_C(6), U8_C(2))); 29 | 30 | u8x3 rgb_dither(ivec3 orig_rgb, int dith) 31 | { 32 | ivec3 rgb_dith = (ivec3(dith) >> ivec3(0, 3, 6)) & 7; 33 | ivec3 rgb = mix((orig_rgb & 0xf8) + 8, ivec3(255), greaterThan(orig_rgb, ivec3(247))); 34 | ivec3 replace_sign = (rgb_dith - (orig_rgb & 7)) >> 31; 35 | ivec3 dither_diff = rgb - orig_rgb; 36 | rgb = orig_rgb + (dither_diff & replace_sign); 37 | return u8x3(rgb & 0xff); 38 | } 39 | 40 | void dither_coefficients(int x, int y, int dither_mode_rgb, int dither_mode_alpha, out int rgb_dither, out int alpha_dither) 41 | { 42 | const int DITHER_SPLAT = (1 << 0) | (1 << 3) | (1 << 6); 43 | 44 | if (dither_mode_rgb < 2) 45 | rgb_dither = int(dither_matrices[dither_mode_rgb][(y & 3) * 4 + (x & 3)]) * DITHER_SPLAT; 46 | else if (dither_mode_rgb == 2) 47 | rgb_dither = noise_get_dither_color(); 48 | else 49 | rgb_dither = 0; 50 | 51 | if (dither_mode_alpha == 3) 52 | alpha_dither = 0; 53 | else 54 | { 55 | if (dither_mode_alpha == 2) 56 | { 57 | alpha_dither = noise_get_dither_alpha(); 58 | } 59 | else 60 | { 61 | alpha_dither = dither_mode_rgb >= 2 ? 62 | int(dither_matrices[dither_mode_rgb & 1][(y & 3) * 4 + (x & 3)]) : (rgb_dither & 7); 63 | 64 | if (dither_mode_alpha == 1) 65 | alpha_dither = ~alpha_dither & 7; 66 | } 67 | } 68 | } 69 | 70 | #endif -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/sampler.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "cookie.hpp" 26 | #include "vulkan_common.hpp" 27 | #include "vulkan_headers.hpp" 28 | #include "object_pool.hpp" 29 | 30 | namespace Vulkan 31 | { 32 | enum class StockSampler 33 | { 34 | NearestClamp, 35 | LinearClamp, 36 | TrilinearClamp, 37 | NearestWrap, 38 | LinearWrap, 39 | TrilinearWrap, 40 | NearestShadow, 41 | LinearShadow, 42 | LinearYUV420P, 43 | LinearYUV422P, 44 | LinearYUV444P, 45 | Count 46 | }; 47 | 48 | struct SamplerCreateInfo 49 | { 50 | VkFilter mag_filter; 51 | VkFilter min_filter; 52 | VkSamplerMipmapMode mipmap_mode; 53 | VkSamplerAddressMode address_mode_u; 54 | VkSamplerAddressMode address_mode_v; 55 | VkSamplerAddressMode address_mode_w; 56 | float mip_lod_bias; 57 | VkBool32 anisotropy_enable; 58 | float max_anisotropy; 59 | VkBool32 compare_enable; 60 | VkCompareOp compare_op; 61 | float min_lod; 62 | float max_lod; 63 | VkBorderColor border_color; 64 | VkBool32 unnormalized_coordinates; 65 | }; 66 | 67 | class Sampler; 68 | struct SamplerDeleter 69 | { 70 | void operator()(Sampler *sampler); 71 | }; 72 | 73 | class Sampler : public Util::IntrusivePtrEnabled, 74 | public Cookie, public InternalSyncEnabled 75 | { 76 | public: 77 | friend struct SamplerDeleter; 78 | ~Sampler(); 79 | 80 | VkSampler get_sampler() const 81 | { 82 | return sampler; 83 | } 84 | 85 | const SamplerCreateInfo &get_create_info() const 86 | { 87 | return create_info; 88 | } 89 | 90 | private: 91 | friend class Util::ObjectPool; 92 | Sampler(Device *device, VkSampler sampler, const SamplerCreateInfo &info); 93 | 94 | Device *device; 95 | VkSampler sampler; 96 | SamplerCreateInfo create_info; 97 | }; 98 | using SamplerHandle = Util::IntrusivePtr; 99 | } 100 | -------------------------------------------------------------------------------- /src/parallel-rdp/util/bitops.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #ifdef _MSC_VER 26 | #include 27 | #endif 28 | 29 | namespace Util 30 | { 31 | #ifdef __GNUC__ 32 | #define leading_zeroes(x) ((x) == 0 ? 32 : __builtin_clz(x)) 33 | #define trailing_zeroes(x) ((x) == 0 ? 32 : __builtin_ctz(x)) 34 | #define trailing_ones(x) __builtin_ctz(~uint32_t(x)) 35 | #elif defined(_MSC_VER) 36 | namespace Internal 37 | { 38 | static inline uint32_t clz(uint32_t x) 39 | { 40 | unsigned long result; 41 | if (_BitScanReverse(&result, x)) 42 | return 31 - result; 43 | else 44 | return 32; 45 | } 46 | 47 | static inline uint32_t ctz(uint32_t x) 48 | { 49 | unsigned long result; 50 | if (_BitScanForward(&result, x)) 51 | return result; 52 | else 53 | return 32; 54 | } 55 | } 56 | 57 | #define leading_zeroes(x) ::Util::Internal::clz(x) 58 | #define trailing_zeroes(x) ::Util::Internal::ctz(x) 59 | #define trailing_ones(x) ::Util::Internal::ctz(~uint32_t(x)) 60 | #else 61 | #error "Implement me." 62 | #endif 63 | 64 | template 65 | inline void for_each_bit(uint32_t value, const T &func) 66 | { 67 | while (value) 68 | { 69 | uint32_t bit = trailing_zeroes(value); 70 | func(bit); 71 | value &= ~(1u << bit); 72 | } 73 | } 74 | 75 | template 76 | inline void for_each_bit_range(uint32_t value, const T &func) 77 | { 78 | if (value == ~0u) 79 | { 80 | func(0, 32); 81 | return; 82 | } 83 | 84 | uint32_t bit_offset = 0; 85 | while (value) 86 | { 87 | uint32_t bit = trailing_zeroes(value); 88 | bit_offset += bit; 89 | value >>= bit; 90 | uint32_t range = trailing_ones(value); 91 | func(bit_offset, range); 92 | value &= ~((1u << range) - 1); 93 | } 94 | } 95 | 96 | inline uint32_t next_pow2(uint32_t v) 97 | { 98 | v--; 99 | v |= v >> 16; 100 | v |= v >> 8; 101 | v |= v >> 4; 102 | v |= v >> 2; 103 | v |= v >> 1; 104 | return v + 1; 105 | } 106 | } -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan-headers/include/vulkan/vk_platform.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: vk_platform.h 3 | // 4 | /* 5 | ** Copyright (c) 2014-2020 The Khronos Group Inc. 6 | ** 7 | ** SPDX-License-Identifier: Apache-2.0 8 | */ 9 | 10 | 11 | #ifndef VK_PLATFORM_H_ 12 | #define VK_PLATFORM_H_ 13 | 14 | #ifdef __cplusplus 15 | extern "C" 16 | { 17 | #endif // __cplusplus 18 | 19 | /* 20 | *************************************************************************************************** 21 | * Platform-specific directives and type declarations 22 | *************************************************************************************************** 23 | */ 24 | 25 | /* Platform-specific calling convention macros. 26 | * 27 | * Platforms should define these so that Vulkan clients call Vulkan commands 28 | * with the same calling conventions that the Vulkan implementation expects. 29 | * 30 | * VKAPI_ATTR - Placed before the return type in function declarations. 31 | * Useful for C++11 and GCC/Clang-style function attribute syntax. 32 | * VKAPI_CALL - Placed after the return type in function declarations. 33 | * Useful for MSVC-style calling convention syntax. 34 | * VKAPI_PTR - Placed between the '(' and '*' in function pointer types. 35 | * 36 | * Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void); 37 | * Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void); 38 | */ 39 | #if defined(_WIN32) 40 | // On Windows, Vulkan commands use the stdcall convention 41 | #define VKAPI_ATTR 42 | #define VKAPI_CALL __stdcall 43 | #define VKAPI_PTR VKAPI_CALL 44 | #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7 45 | #error "Vulkan isn't supported for the 'armeabi' NDK ABI" 46 | #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE) 47 | // On Android 32-bit ARM targets, Vulkan functions use the "hardfloat" 48 | // calling convention, i.e. float parameters are passed in registers. This 49 | // is true even if the rest of the application passes floats on the stack, 50 | // as it does by default when compiling for the armeabi-v7a NDK ABI. 51 | #define VKAPI_ATTR __attribute__((pcs("aapcs-vfp"))) 52 | #define VKAPI_CALL 53 | #define VKAPI_PTR VKAPI_ATTR 54 | #else 55 | // On other platforms, use the default calling convention 56 | #define VKAPI_ATTR 57 | #define VKAPI_CALL 58 | #define VKAPI_PTR 59 | #endif 60 | 61 | #if !defined(VK_NO_STDDEF_H) 62 | #include 63 | #endif // !defined(VK_NO_STDDEF_H) 64 | 65 | #if !defined(VK_NO_STDINT_H) 66 | #if defined(_MSC_VER) && (_MSC_VER < 1600) 67 | typedef signed __int8 int8_t; 68 | typedef unsigned __int8 uint8_t; 69 | typedef signed __int16 int16_t; 70 | typedef unsigned __int16 uint16_t; 71 | typedef signed __int32 int32_t; 72 | typedef unsigned __int32 uint32_t; 73 | typedef signed __int64 int64_t; 74 | typedef unsigned __int64 uint64_t; 75 | #else 76 | #include 77 | #endif 78 | #endif // !defined(VK_NO_STDINT_H) 79 | 80 | #ifdef __cplusplus 81 | } // extern "C" 82 | #endif // __cplusplus 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/slangmosh.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ "../../Granite/assets/shaders/inc" ], 3 | "shaders": [ 4 | { 5 | "name": "tmem_update", 6 | "compute": true, 7 | "path": "tmem_update.comp" 8 | }, 9 | { 10 | 11 | "name": "span_setup", 12 | "compute": true, 13 | "path": "span_setup.comp" 14 | }, 15 | { 16 | "name": "clear_indirect_buffer", 17 | "compute": true, 18 | "path": "clear_indirect_buffer.comp" 19 | }, 20 | { 21 | "name": "tile_binning_combined", 22 | "compute": true, 23 | "path": "tile_binning_combined.comp", 24 | "variants": [ 25 | { "define": "SUBGROUP", "count": 2, "resolve": true }, 26 | { "define": "UBERSHADER", "count": 2, "resolve": true }, 27 | { "define": "SMALL_TYPES", "count": 2, "resolve": true } 28 | ] 29 | }, 30 | { 31 | "name": "ubershader", 32 | "path": "ubershader.comp", 33 | "compute": true, 34 | "variants": [ 35 | { "define": "SUBGROUP", "count": 2, "resolve": true }, 36 | { "define": "SMALL_TYPES", "count": 2, "resolve": true } 37 | ] 38 | }, 39 | { 40 | "name": "depth_blend", 41 | "path": "depth_blend.comp", 42 | "compute": true, 43 | "variants": [ 44 | { "define": "SUBGROUP", "count": 2, "resolve": true }, 45 | { "define": "SMALL_TYPES", "count": 2, "resolve": true } 46 | ] 47 | }, 48 | { 49 | "name": "rasterizer", 50 | "path": "rasterizer.comp", 51 | "compute": true, 52 | "variants": [ 53 | { "define": "SMALL_TYPES", "count": 2, "resolve": true } 54 | ] 55 | }, 56 | { 57 | "name": "fullscreen", 58 | "path": "fullscreen.vert" 59 | }, 60 | { 61 | "name": "vi_scale", 62 | "path": "vi_scale.frag" 63 | }, 64 | { 65 | "name": "vi_divot", 66 | "path": "vi_divot.frag", 67 | "variants": [ 68 | { "define": "FETCH_BUG", "count": 2 } 69 | ] 70 | }, 71 | { 72 | "name": "vi_fetch", 73 | "path": "vi_fetch.frag", 74 | "variants": [ 75 | { "define": "FETCH_BUG", "count": 2 } 76 | ] 77 | }, 78 | { 79 | "name": "vi_blend_fields", 80 | "path": "vi_blend_fields.frag" 81 | }, 82 | { 83 | "name": "extract_vram", 84 | "path": "extract_vram.comp", 85 | "compute": true 86 | }, 87 | { 88 | "name": "masked_rdram_resolve", 89 | "path": "masked_rdram_resolve.comp", 90 | "compute": true 91 | }, 92 | { 93 | "name": "clear_write_mask", 94 | "path": "clear_write_mask.comp", 95 | "compute": true 96 | }, 97 | { 98 | "name": "update_upscaled_domain_post", 99 | "path": "update_upscaled_domain_post.comp", 100 | "compute": true 101 | }, 102 | { 103 | "name": "update_upscaled_domain_pre", 104 | "path": "update_upscaled_domain_pre.comp", 105 | "compute": true 106 | }, 107 | { 108 | "name": "update_upscaled_domain_resolve", 109 | "path": "update_upscaled_domain_resolve.comp", 110 | "compute": true 111 | }, 112 | { 113 | "name": "clear_super_sampled_write_mask", 114 | "path": "clear_super_sampled_write_mask.comp", 115 | "compute": true 116 | }, 117 | { 118 | "name": "vi_deinterlace_vert", 119 | "path": "vi_deinterlace.vert" 120 | }, 121 | { 122 | "name": "vi_deinterlace_frag", 123 | "path": "vi_deinterlace.frag" 124 | } 125 | ] 126 | } 127 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/vi_divot.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | /* Copyright (c) 2020 Themaister 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files (the 6 | * "Software"), to deal in the Software without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #extension GL_EXT_samplerless_texture_functions : require 24 | 25 | #include "vi_debug.h" 26 | 27 | layout(location = 0) out uvec4 FragColor; 28 | #if defined(FETCH_BUG) && FETCH_BUG 29 | layout(location = 1) out uvec4 FragColorFetchBug; 30 | #endif 31 | 32 | layout(set = 0, binding = 0) uniform mediump utexture2DArray uFetchCache; 33 | 34 | void swap(inout uint a, inout uint b) 35 | { 36 | uint tmp = a; 37 | a = b; 38 | b = tmp; 39 | } 40 | 41 | uint median3(uint left, uint center, uint right) 42 | { 43 | if (left < center) 44 | swap(left, center); 45 | if (center < right) 46 | swap(center, right); 47 | if (left < center) 48 | swap(left, center); 49 | 50 | return center; 51 | } 52 | 53 | void main() 54 | { 55 | ivec2 pix = ivec2(gl_FragCoord.xy); 56 | 57 | uvec4 left = texelFetch(uFetchCache, ivec3(pix, 0), 0); 58 | uvec4 mid = texelFetchOffset(uFetchCache, ivec3(pix, 0), 0, ivec2(1, 0)); 59 | uvec4 right = texelFetchOffset(uFetchCache, ivec3(pix, 0), 0, ivec2(2, 0)); 60 | 61 | if ((left.a & mid.a & right.a) == 7u) 62 | { 63 | FragColor = mid; 64 | } 65 | else 66 | { 67 | // Median filter. TODO: Optimize with mid3? 68 | uint r = median3(left.r, mid.r, right.r); 69 | uint g = median3(left.g, mid.g, right.g); 70 | uint b = median3(left.b, mid.b, right.b); 71 | FragColor = uvec4(r, g, b, mid.a); 72 | } 73 | 74 | #if defined(FETCH_BUG) && FETCH_BUG 75 | left = texelFetch(uFetchCache, ivec3(pix, 1), 0); 76 | mid = texelFetchOffset(uFetchCache, ivec3(pix, 1), 0, ivec2(1, 0)); 77 | right = texelFetchOffset(uFetchCache, ivec3(pix, 1), 0, ivec2(2, 0)); 78 | 79 | if ((left.a & mid.a & right.a) == 7u) 80 | { 81 | FragColorFetchBug = mid; 82 | } 83 | else 84 | { 85 | // Median filter. TODO: Optimize with mid3? 86 | uint r = median3(left.r, mid.r, right.r); 87 | uint g = median3(left.g, mid.g, right.g); 88 | uint b = median3(left.b, mid.b, right.b); 89 | FragColorFetchBug = uvec4(r, g, b, mid.a); 90 | } 91 | #endif 92 | } -------------------------------------------------------------------------------- /src/parallel-rdp/util/timer.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "timer.hpp" 24 | 25 | #ifdef _WIN32 26 | #define WIN32_LEAN_AND_MEAN 27 | #include 28 | #else 29 | #include 30 | #endif 31 | 32 | namespace Util 33 | { 34 | FrameTimer::FrameTimer() 35 | { 36 | reset(); 37 | } 38 | 39 | void FrameTimer::reset() 40 | { 41 | start = get_time(); 42 | last = start; 43 | last_period = 0; 44 | } 45 | 46 | void FrameTimer::enter_idle() 47 | { 48 | idle_start = get_time(); 49 | } 50 | 51 | void FrameTimer::leave_idle() 52 | { 53 | auto idle_end = get_time(); 54 | idle_time += idle_end - idle_start; 55 | } 56 | 57 | double FrameTimer::get_frame_time() const 58 | { 59 | return double(last_period) * 1e-9; 60 | } 61 | 62 | double FrameTimer::frame() 63 | { 64 | auto new_time = get_time() - idle_time; 65 | last_period = new_time - last; 66 | last = new_time; 67 | return double(last_period) * 1e-9; 68 | } 69 | 70 | double FrameTimer::frame(double frame_time) 71 | { 72 | last_period = int64_t(frame_time * 1e9); 73 | last += last_period; 74 | return frame_time; 75 | } 76 | 77 | double FrameTimer::get_elapsed() const 78 | { 79 | return double(last - start) * 1e-9; 80 | } 81 | 82 | int64_t FrameTimer::get_time() 83 | { 84 | return get_current_time_nsecs(); 85 | } 86 | 87 | #ifdef _WIN32 88 | struct QPCFreq 89 | { 90 | QPCFreq() 91 | { 92 | LARGE_INTEGER freq; 93 | QueryPerformanceFrequency(&freq); 94 | inv_freq = 1e9 / double(freq.QuadPart); 95 | } 96 | 97 | double inv_freq; 98 | } static static_qpc_freq; 99 | #endif 100 | 101 | int64_t get_current_time_nsecs() 102 | { 103 | #ifdef _WIN32 104 | LARGE_INTEGER li; 105 | if (!QueryPerformanceCounter(&li)) 106 | return 0; 107 | return int64_t(double(li.QuadPart) * static_qpc_freq.inv_freq); 108 | #else 109 | struct timespec ts = {}; 110 | if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) 111 | return 0; 112 | return ts.tv_sec * 1000000000ll + ts.tv_nsec; 113 | #endif 114 | } 115 | 116 | void Timer::start() 117 | { 118 | t = get_current_time_nsecs(); 119 | } 120 | 121 | double Timer::end() 122 | { 123 | auto nt = get_current_time_nsecs(); 124 | return double(nt - t) * 1e-9; 125 | } 126 | } -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/buffer_pool.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "vulkan_headers.hpp" 26 | #include "intrusive.hpp" 27 | #include 28 | #include 29 | 30 | namespace Vulkan 31 | { 32 | class Device; 33 | class Buffer; 34 | 35 | struct BufferBlockAllocation 36 | { 37 | uint8_t *host; 38 | VkDeviceSize offset; 39 | VkDeviceSize padded_size; 40 | }; 41 | 42 | struct BufferBlock 43 | { 44 | ~BufferBlock(); 45 | Util::IntrusivePtr gpu; 46 | Util::IntrusivePtr cpu; 47 | VkDeviceSize offset = 0; 48 | VkDeviceSize alignment = 0; 49 | VkDeviceSize size = 0; 50 | VkDeviceSize spill_size = 0; 51 | uint8_t *mapped = nullptr; 52 | 53 | BufferBlockAllocation allocate(VkDeviceSize allocate_size) 54 | { 55 | auto aligned_offset = (offset + alignment - 1) & ~(alignment - 1); 56 | if (aligned_offset + allocate_size <= size) 57 | { 58 | auto *ret = mapped + aligned_offset; 59 | offset = aligned_offset + allocate_size; 60 | 61 | VkDeviceSize padded_size = std::max(allocate_size, spill_size); 62 | padded_size = std::min(padded_size, size - aligned_offset); 63 | 64 | return { ret, aligned_offset, padded_size }; 65 | } 66 | else 67 | return { nullptr, 0, 0 }; 68 | } 69 | }; 70 | 71 | class BufferPool 72 | { 73 | public: 74 | ~BufferPool(); 75 | void init(Device *device, VkDeviceSize block_size, VkDeviceSize alignment, VkBufferUsageFlags usage, bool need_device_local); 76 | void reset(); 77 | 78 | // Used for allocating UBOs, where we want to specify a fixed size for range, 79 | // and we need to make sure we don't allocate beyond the block. 80 | void set_spill_region_size(VkDeviceSize spill_size); 81 | 82 | VkDeviceSize get_block_size() const 83 | { 84 | return block_size; 85 | } 86 | 87 | BufferBlock request_block(VkDeviceSize minimum_size); 88 | void recycle_block(BufferBlock &&block); 89 | 90 | private: 91 | Device *device = nullptr; 92 | VkDeviceSize block_size = 0; 93 | VkDeviceSize alignment = 0; 94 | VkDeviceSize spill_size = 0; 95 | VkBufferUsageFlags usage = 0; 96 | std::vector blocks; 97 | BufferBlock allocate_block(VkDeviceSize size); 98 | bool need_device_local = false; 99 | }; 100 | } -------------------------------------------------------------------------------- /src/parallel-rdp/util/object_pool.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include "aligned_alloc.hpp" 31 | 32 | //#define OBJECT_POOL_DEBUG 33 | 34 | namespace Util 35 | { 36 | template 37 | class ObjectPool 38 | { 39 | public: 40 | template 41 | T *allocate(P &&... p) 42 | { 43 | #ifndef OBJECT_POOL_DEBUG 44 | if (vacants.empty()) 45 | { 46 | unsigned num_objects = 64u << memory.size(); 47 | T *ptr = static_cast(memalign_alloc(std::max(size_t(64), alignof(T)), 48 | num_objects * sizeof(T))); 49 | if (!ptr) 50 | return nullptr; 51 | 52 | for (unsigned i = 0; i < num_objects; i++) 53 | vacants.push_back(&ptr[i]); 54 | 55 | memory.emplace_back(ptr); 56 | } 57 | 58 | T *ptr = vacants.back(); 59 | vacants.pop_back(); 60 | new(ptr) T(std::forward

(p)...); 61 | return ptr; 62 | #else 63 | return new T(std::forward

(p)...); 64 | #endif 65 | } 66 | 67 | void free(T *ptr) 68 | { 69 | #ifndef OBJECT_POOL_DEBUG 70 | ptr->~T(); 71 | vacants.push_back(ptr); 72 | #else 73 | delete ptr; 74 | #endif 75 | } 76 | 77 | void clear() 78 | { 79 | #ifndef OBJECT_POOL_DEBUG 80 | vacants.clear(); 81 | memory.clear(); 82 | #endif 83 | } 84 | 85 | protected: 86 | #ifndef OBJECT_POOL_DEBUG 87 | std::vector vacants; 88 | 89 | struct MallocDeleter 90 | { 91 | void operator()(T *ptr) 92 | { 93 | memalign_free(ptr); 94 | } 95 | }; 96 | 97 | std::vector> memory; 98 | #endif 99 | }; 100 | 101 | template 102 | class ThreadSafeObjectPool : private ObjectPool 103 | { 104 | public: 105 | template 106 | T *allocate(P &&... p) 107 | { 108 | std::lock_guard holder{lock}; 109 | return ObjectPool::allocate(std::forward

(p)...); 110 | } 111 | 112 | void free(T *ptr) 113 | { 114 | #ifndef OBJECT_POOL_DEBUG 115 | ptr->~T(); 116 | std::lock_guard holder{lock}; 117 | this->vacants.push_back(ptr); 118 | #else 119 | delete ptr; 120 | #endif 121 | } 122 | 123 | void clear() 124 | { 125 | std::lock_guard holder{lock}; 126 | ObjectPool::clear(); 127 | } 128 | 129 | private: 130 | std::mutex lock; 131 | }; 132 | } 133 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/fence.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "fence.hpp" 24 | #include "device.hpp" 25 | 26 | namespace Vulkan 27 | { 28 | FenceHolder::~FenceHolder() 29 | { 30 | if (fence != VK_NULL_HANDLE) 31 | { 32 | if (internal_sync) 33 | device->reset_fence_nolock(fence, observed_wait); 34 | else 35 | device->reset_fence(fence, observed_wait); 36 | } 37 | } 38 | 39 | VkFence FenceHolder::get_fence() const 40 | { 41 | return fence; 42 | } 43 | 44 | void FenceHolder::wait() 45 | { 46 | auto &table = device->get_device_table(); 47 | 48 | #ifdef GRANITE_VULKAN_MT 49 | // Waiting for the same VkFence in parallel is not allowed, and there seems to be some shenanigans on Intel 50 | // when waiting for a timeline semaphore in parallel with same value as well. 51 | std::lock_guard holder{lock}; 52 | #endif 53 | if (observed_wait) 54 | return; 55 | 56 | if (timeline_value != 0) 57 | { 58 | VK_ASSERT(timeline_semaphore); 59 | VkSemaphoreWaitInfoKHR info = { VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR }; 60 | info.semaphoreCount = 1; 61 | info.pSemaphores = &timeline_semaphore; 62 | info.pValues = &timeline_value; 63 | if (table.vkWaitSemaphoresKHR(device->get_device(), &info, UINT64_MAX) != VK_SUCCESS) 64 | LOGE("Failed to wait for timeline semaphore!\n"); 65 | else 66 | observed_wait = true; 67 | } 68 | else 69 | { 70 | if (table.vkWaitForFences(device->get_device(), 1, &fence, VK_TRUE, UINT64_MAX) != VK_SUCCESS) 71 | LOGE("Failed to wait for fence!\n"); 72 | else 73 | observed_wait = true; 74 | } 75 | } 76 | 77 | bool FenceHolder::wait_timeout(uint64_t timeout) 78 | { 79 | bool ret = false; 80 | auto &table = device->get_device_table(); 81 | if (timeline_value != 0) 82 | { 83 | VK_ASSERT(timeline_semaphore); 84 | VkSemaphoreWaitInfoKHR info = { VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR }; 85 | info.semaphoreCount = 1; 86 | info.pSemaphores = &timeline_semaphore; 87 | info.pValues = &timeline_value; 88 | ret = table.vkWaitSemaphoresKHR(device->get_device(), &info, timeout) == VK_SUCCESS; 89 | } 90 | else 91 | ret = table.vkWaitForFences(device->get_device(), 1, &fence, VK_TRUE, timeout) == VK_SUCCESS; 92 | 93 | if (ret) 94 | observed_wait = true; 95 | return ret; 96 | } 97 | 98 | void FenceHolderDeleter::operator()(Vulkan::FenceHolder *fence) 99 | { 100 | fence->device->handle_pool.fences.free(fence); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/worker_thread.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Themaister 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #ifdef PARALLEL_RDP_SHADER_DIR 32 | #include "global_managers.hpp" 33 | #endif 34 | 35 | namespace RDP 36 | { 37 | template 38 | class WorkerThread 39 | { 40 | public: 41 | explicit WorkerThread( 42 | #ifdef PARALLEL_RDP_SHADER_DIR 43 | Granite::Global::GlobalManagersHandle globals, 44 | #endif 45 | Executor exec) 46 | : executor(std::move(exec)) 47 | #ifdef PARALLEL_RDP_SHADER_DIR 48 | , handles(std::move(globals)) 49 | #endif 50 | { 51 | thr = std::thread(&WorkerThread::main_loop, this); 52 | } 53 | 54 | ~WorkerThread() 55 | { 56 | if (thr.joinable()) 57 | { 58 | { 59 | std::lock_guard holder{to_thread_mutex}; 60 | work_queue.push({}); 61 | to_thread_cond.notify_one(); 62 | } 63 | thr.join(); 64 | } 65 | } 66 | 67 | template 68 | void wait(Cond &&cond) 69 | { 70 | std::unique_lock holder{to_main_mutex}; 71 | to_main_cond.wait(holder, std::forward(cond)); 72 | } 73 | 74 | void push(T &&t) 75 | { 76 | std::lock_guard holder{to_thread_mutex}; 77 | work_queue.push(std::move(t)); 78 | to_thread_cond.notify_one(); 79 | } 80 | 81 | private: 82 | std::thread thr; 83 | std::mutex to_thread_mutex; 84 | std::condition_variable to_thread_cond; 85 | std::mutex to_main_mutex; 86 | std::condition_variable to_main_cond; 87 | std::queue work_queue; 88 | Executor executor; 89 | 90 | #ifdef PARALLEL_RDP_SHADER_DIR 91 | Granite::Global::GlobalManagersHandle handles; 92 | #endif 93 | 94 | void main_loop() 95 | { 96 | #ifdef PARALLEL_RDP_SHADER_DIR 97 | Granite::Global::set_thread_context(*handles); 98 | handles.reset(); 99 | #endif 100 | 101 | for (;;) 102 | { 103 | T value; 104 | 105 | { 106 | std::unique_lock holder{to_thread_mutex}; 107 | to_thread_cond.wait(holder, [this]() { return !work_queue.empty(); }); 108 | value = std::move(work_queue.front()); 109 | work_queue.pop(); 110 | } 111 | 112 | if (executor.is_sentinel(value)) 113 | break; 114 | 115 | executor.perform_work(value); 116 | std::lock_guard holder{to_main_mutex}; 117 | executor.notify_work_locked(value); 118 | to_main_cond.notify_one(); 119 | } 120 | } 121 | }; 122 | } -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/small_types.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2020 Themaister 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | // Utility header to smooth over the difference between 24 | // 8/16-bit integer arithmetic vs. just 8/16-bit storage. 25 | 26 | #ifndef SMALL_INTEGERS_H_ 27 | #define SMALL_INTEGERS_H_ 28 | 29 | #extension GL_EXT_shader_16bit_storage : require 30 | #extension GL_EXT_shader_8bit_storage : require 31 | 32 | #if SMALL_TYPES 33 | #extension GL_EXT_shader_explicit_arithmetic_types_int8 : require 34 | #extension GL_EXT_shader_explicit_arithmetic_types_int16 : require 35 | 36 | #define mem_u8 uint8_t 37 | #define mem_u16 uint16_t 38 | #define mem_u8x2 u8vec2 39 | #define mem_u16x2 u16vec2 40 | #define mem_u8x3 u8vec3 41 | #define mem_u16x3 u16vec3 42 | #define mem_u8x4 u8vec4 43 | #define mem_u16x4 u16vec4 44 | 45 | #define mem_i8 int8_t 46 | #define mem_i16 int16_t 47 | #define mem_i8x2 i8vec2 48 | #define mem_i16x2 i16vec2 49 | #define mem_i8x3 i8vec3 50 | #define mem_i16x3 i16vec3 51 | #define mem_i8x4 i8vec4 52 | #define mem_i16x4 i16vec4 53 | 54 | #define u8 uint8_t 55 | #define u16 uint16_t 56 | #define u8x2 u8vec2 57 | #define u16x2 u16vec2 58 | #define u8x3 u8vec3 59 | #define u16x3 u16vec3 60 | #define u8x4 u8vec4 61 | #define u16x4 u16vec4 62 | 63 | #define i8 int8_t 64 | #define i16 int16_t 65 | #define i8x2 i8vec2 66 | #define i16x2 i16vec2 67 | #define i8x3 i8vec3 68 | #define i16x3 i16vec3 69 | #define i8x4 i8vec4 70 | #define i16x4 i16vec4 71 | 72 | #define U8_C(x) uint8_t(x) 73 | #define I8_C(x) int8_t(x) 74 | #define U16_C(x) uint16_t(x) 75 | #define I16_C(x) int16_t(x) 76 | 77 | #else 78 | 79 | #define mem_u8 uint8_t 80 | #define mem_u16 uint16_t 81 | #define mem_u8x2 u8vec2 82 | #define mem_u16x2 u16vec2 83 | #define mem_u8x3 u8vec3 84 | #define mem_u16x3 u16vec3 85 | #define mem_u8x4 u8vec4 86 | #define mem_u16x4 u16vec4 87 | 88 | #define mem_i8 int8_t 89 | #define mem_i16 int16_t 90 | #define mem_i8x2 i8vec2 91 | #define mem_i16x2 i16vec2 92 | #define mem_i8x3 i8vec3 93 | #define mem_i16x3 i16vec3 94 | #define mem_i8x4 i8vec4 95 | #define mem_i16x4 i16vec4 96 | 97 | #define u8 int 98 | #define u16 int 99 | #define u8x2 ivec2 100 | #define u16x2 ivec2 101 | #define u8x3 ivec3 102 | #define u16x3 ivec3 103 | #define u8x4 ivec4 104 | #define u16x4 ivec4 105 | 106 | #define i8 int 107 | #define i16 int 108 | #define i8x2 ivec2 109 | #define i16x2 ivec2 110 | #define i8x3 ivec3 111 | #define i16x3 ivec3 112 | #define i8x4 ivec4 113 | #define i16x4 ivec4 114 | 115 | #define U8_C(x) int(x) 116 | #define I8_C(x) int(x) 117 | #define U16_C(x) int(x) 118 | #define I16_C(x) int(x) 119 | 120 | #endif 121 | #endif -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/extract_vram.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | /* Copyright (c) 2020 Themaister 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files (the 6 | * "Software"), to deal in the Software without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #include "small_types.h" 24 | layout(local_size_x = 16, local_size_y = 8) in; 25 | 26 | // Copies VRAM into a texture which is then consumed by VI scanout. 27 | 28 | layout(set = 0, binding = 0, rgba8ui) uniform writeonly uimage2D uAAInput; 29 | layout(set = 0, binding = 1, std430) readonly buffer RDRAM16 30 | { 31 | mem_u16 elems[]; 32 | } vram16; 33 | 34 | layout(set = 0, binding = 1, std430) readonly buffer RDRAM32 35 | { 36 | uint elems[]; 37 | } vram32; 38 | 39 | layout(set = 0, binding = 2, std430) readonly buffer HiddenRDRAM 40 | { 41 | mem_u8 elems[]; 42 | } hidden_vram; 43 | 44 | layout(push_constant, std430) uniform Registers 45 | { 46 | int fb_offset; 47 | int fb_width; 48 | ivec2 offset; 49 | ivec2 resolution; 50 | } registers; 51 | 52 | layout(constant_id = 0) const int RDRAM_SIZE = 0; 53 | const int RDRAM_MASK_8 = RDRAM_SIZE - 1; 54 | const int RDRAM_MASK_16 = RDRAM_MASK_8 >> 1; 55 | const int RDRAM_MASK_32 = RDRAM_MASK_16 >> 1; 56 | layout(constant_id = 2) const int SCALING_LOG2 = 0; 57 | const int SCALING_FACTOR = 1 << SCALING_LOG2; 58 | 59 | #include "vi_status.h" 60 | 61 | uvec4 fetch_color(ivec2 coord) 62 | { 63 | ivec2 slice2d = coord & (SCALING_FACTOR - 1); 64 | coord >>= SCALING_LOG2; 65 | int slice = slice2d.y * SCALING_FACTOR + slice2d.x; 66 | 67 | uvec4 color; 68 | if (FMT_RGBA8888) 69 | { 70 | int linear_coord = coord.y * registers.fb_width + coord.x + registers.fb_offset; 71 | linear_coord &= RDRAM_MASK_32; 72 | linear_coord += slice * (RDRAM_SIZE >> 2); 73 | uint word = uint(vram32.elems[linear_coord]); 74 | color = (uvec4(word) >> uvec4(24, 16, 8, 5)) & uvec4(0xff, 0xff, 0xff, 7); 75 | } 76 | else if (FMT_RGBA5551) 77 | { 78 | int linear_coord = coord.y * registers.fb_width + coord.x + registers.fb_offset; 79 | linear_coord &= RDRAM_MASK_16; 80 | linear_coord += slice * (RDRAM_SIZE >> 1); 81 | uint word = uint(vram16.elems[linear_coord ^ 1]); 82 | uint hidden_word = uint(hidden_vram.elems[linear_coord]); 83 | 84 | uint r = (word >> 8u) & 0xf8u; 85 | uint g = (word >> 3u) & 0xf8u; 86 | uint b = (word << 2u) & 0xf8u; 87 | uint a = ((word & 1u) << 2u) | hidden_word; 88 | color = uvec4(r, g, b, a); 89 | } 90 | else 91 | color = uvec4(0); 92 | 93 | if (!FETCH_AA) 94 | color.a = 7u; 95 | 96 | return color; 97 | } 98 | 99 | void main() 100 | { 101 | if (any(greaterThanEqual(gl_GlobalInvocationID.xy, registers.resolution))) 102 | return; 103 | 104 | ivec2 coord = ivec2(gl_GlobalInvocationID.xy) + registers.offset; 105 | uvec4 col = fetch_color(coord); 106 | imageStore(uAAInput, ivec2(gl_GlobalInvocationID.xy), col); 107 | } -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/update_upscaled_domain_post.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | /* Copyright (c) 2020 Themaister 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files (the 6 | * "Software"), to deal in the Software without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #include "small_types.h" 25 | #include "fb_formats.h" 26 | 27 | layout(local_size_x_id = 3) in; 28 | 29 | layout(constant_id = 0) const int RDRAM_SIZE = 8 * 1024 * 1024; 30 | const int RDRAM_MASK_8 = RDRAM_SIZE - 1; 31 | const int RDRAM_MASK_16 = RDRAM_MASK_8 >> 1; 32 | const int RDRAM_MASK_32 = RDRAM_MASK_8 >> 2; 33 | layout(constant_id = 1) const int FB_SIZE_LOG2 = 0; 34 | layout(constant_id = 2) const bool COLOR_DEPTH_ALIAS = false; 35 | layout(constant_id = 4) const int NUM_SAMPLES = 1; 36 | 37 | layout(push_constant) uniform Registers 38 | { 39 | uint num_pixels, fb_addr, fb_depth_addr; 40 | } registers; 41 | 42 | layout(set = 0, binding = 0) readonly buffer RDRAMSingleSampled8 43 | { 44 | uint8_t elems[]; 45 | } vram8; 46 | 47 | layout(set = 0, binding = 0) readonly buffer RDRAMSingleSampled16 48 | { 49 | uint16_t elems[]; 50 | } vram16; 51 | 52 | layout(set = 0, binding = 0) readonly buffer RDRAMSingleSampled32 53 | { 54 | uint elems[]; 55 | } vram32; 56 | 57 | layout(set = 0, binding = 2) buffer RDRAMUpscalingReference8 58 | { 59 | uint8_t elems[]; 60 | } vram_reference8; 61 | 62 | layout(set = 0, binding = 2) buffer RDRAMUpscalingReference16 63 | { 64 | uint16_t elems[]; 65 | } vram_reference16; 66 | 67 | layout(set = 0, binding = 2) buffer RDRAMUpscalingReference32 68 | { 69 | uint elems[]; 70 | } vram_reference32; 71 | 72 | void copy_rdram_8(uint index) 73 | { 74 | index &= RDRAM_MASK_8; 75 | uint real_word = uint(vram8.elems[index]); 76 | vram_reference8.elems[index] = uint8_t(real_word); 77 | } 78 | 79 | void copy_rdram_16(uint index) 80 | { 81 | index &= RDRAM_MASK_16; 82 | uint real_word = uint(vram16.elems[index]); 83 | vram_reference16.elems[index] = uint16_t(real_word); 84 | } 85 | 86 | void copy_rdram_32(uint index) 87 | { 88 | index &= RDRAM_MASK_32; 89 | uint real_word = vram32.elems[index]; 90 | vram_reference32.elems[index] = real_word; 91 | } 92 | 93 | void main() 94 | { 95 | uint index = gl_GlobalInvocationID.x; 96 | if (index >= registers.num_pixels) 97 | return; 98 | 99 | uint depth_index = index + registers.fb_depth_addr; 100 | uint color_index = index + registers.fb_addr; 101 | 102 | switch (FB_SIZE_LOG2) 103 | { 104 | case 0: 105 | copy_rdram_8(color_index); 106 | break; 107 | 108 | case 1: 109 | copy_rdram_16(color_index); 110 | break; 111 | 112 | case 2: 113 | copy_rdram_32(color_index); 114 | break; 115 | } 116 | 117 | if (!COLOR_DEPTH_ALIAS) 118 | copy_rdram_16(depth_index); 119 | } -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/renderdoc_capture.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "device.hpp" 24 | #include "renderdoc_app.h" 25 | #include 26 | 27 | #ifdef _WIN32 28 | #define WIN32_LEAN_AND_MEAN 29 | #include 30 | #else 31 | #include 32 | #endif 33 | 34 | namespace Vulkan 35 | { 36 | static std::mutex module_lock; 37 | #ifdef _WIN32 38 | static HMODULE renderdoc_module; 39 | #else 40 | static void *renderdoc_module; 41 | #endif 42 | 43 | static RENDERDOC_API_1_0_0 *renderdoc_api; 44 | 45 | bool Device::init_renderdoc_capture() 46 | { 47 | std::lock_guard holder{module_lock}; 48 | if (renderdoc_module) 49 | return true; 50 | 51 | #ifdef _WIN32 52 | renderdoc_module = GetModuleHandleA("renderdoc.dll"); 53 | #elif defined(ANDROID) 54 | renderdoc_module = dlopen("libVkLayer_GLES_RenderDoc.so", RTLD_NOW | RTLD_NOLOAD); 55 | #else 56 | renderdoc_module = dlopen("librenderdoc.so", RTLD_NOW | RTLD_NOLOAD); 57 | #endif 58 | 59 | if (!renderdoc_module) 60 | { 61 | LOGE("Failed to load RenderDoc, make sure RenderDoc started the application in capture mode.\n"); 62 | return false; 63 | } 64 | 65 | #ifdef _WIN32 66 | // Workaround GCC warning about FARPROC mismatch. 67 | auto *gpa = GetProcAddress(renderdoc_module, "RENDERDOC_GetAPI"); 68 | pRENDERDOC_GetAPI func; 69 | memcpy(&func, &gpa, sizeof(func)); 70 | 71 | if (!func) 72 | { 73 | LOGE("Failed to load RENDERDOC_GetAPI function.\n"); 74 | return false; 75 | } 76 | #else 77 | auto *func = reinterpret_cast(dlsym(renderdoc_module, "RENDERDOC_GetAPI")); 78 | if (!func) 79 | { 80 | LOGE("Failed to load RENDERDOC_GetAPI function.\n"); 81 | return false; 82 | } 83 | #endif 84 | 85 | if (!func(eRENDERDOC_API_Version_1_0_0, reinterpret_cast(&renderdoc_api))) 86 | { 87 | LOGE("Failed to obtain RenderDoc 1.0.0 API.\n"); 88 | return false; 89 | } 90 | else 91 | { 92 | int major, minor, patch; 93 | renderdoc_api->GetAPIVersion(&major, &minor, &patch); 94 | LOGI("Initialized RenderDoc API %d.%d.%d.\n", major, minor, patch); 95 | } 96 | 97 | return true; 98 | } 99 | 100 | void Device::begin_renderdoc_capture() 101 | { 102 | std::lock_guard holder{module_lock}; 103 | if (!renderdoc_api) 104 | { 105 | LOGE("RenderDoc API is not loaded, cannot trigger capture.\n"); 106 | return; 107 | } 108 | next_frame_context(); 109 | 110 | LOGI("Starting RenderDoc frame capture.\n"); 111 | renderdoc_api->StartFrameCapture(nullptr, nullptr); 112 | } 113 | 114 | void Device::end_renderdoc_capture() 115 | { 116 | std::lock_guard holder{module_lock}; 117 | if (!renderdoc_api) 118 | { 119 | LOGE("RenderDoc API is not loaded, cannot trigger capture.\n"); 120 | return; 121 | } 122 | next_frame_context(); 123 | renderdoc_api->EndFrameCapture(nullptr, nullptr); 124 | LOGI("Ended RenderDoc frame capture.\n"); 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /src/parallel-rdp/vulkan/semaphore.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2017-2020 Hans-Kristian Arntzen 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining 4 | * a copy of this software and associated documentation files (the 5 | * "Software"), to deal in the Software without restriction, including 6 | * without limitation the rights to use, copy, modify, merge, publish, 7 | * distribute, sublicense, and/or sell copies of the Software, and to 8 | * permit persons to whom the Software is furnished to do so, subject to 9 | * the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be 12 | * included in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "vulkan_common.hpp" 26 | #include "vulkan_headers.hpp" 27 | #include "cookie.hpp" 28 | #include "object_pool.hpp" 29 | 30 | namespace Vulkan 31 | { 32 | class Device; 33 | 34 | class SemaphoreHolder; 35 | struct SemaphoreHolderDeleter 36 | { 37 | void operator()(SemaphoreHolder *semaphore); 38 | }; 39 | 40 | class SemaphoreHolder : public Util::IntrusivePtrEnabled, 41 | public InternalSyncEnabled 42 | { 43 | public: 44 | friend struct SemaphoreHolderDeleter; 45 | 46 | ~SemaphoreHolder(); 47 | 48 | const VkSemaphore &get_semaphore() const 49 | { 50 | return semaphore; 51 | } 52 | 53 | bool is_signalled() const 54 | { 55 | return signalled; 56 | } 57 | 58 | uint64_t get_timeline_value() const 59 | { 60 | return timeline; 61 | } 62 | 63 | VkSemaphore consume() 64 | { 65 | auto ret = semaphore; 66 | VK_ASSERT(semaphore); 67 | VK_ASSERT(signalled); 68 | semaphore = VK_NULL_HANDLE; 69 | signalled = false; 70 | return ret; 71 | } 72 | 73 | VkSemaphore release_semaphore() 74 | { 75 | auto ret = semaphore; 76 | semaphore = VK_NULL_HANDLE; 77 | signalled = false; 78 | return ret; 79 | } 80 | 81 | bool can_recycle() const 82 | { 83 | return !should_destroy_on_consume; 84 | } 85 | 86 | void wait_external() 87 | { 88 | VK_ASSERT(semaphore); 89 | VK_ASSERT(signalled); 90 | signalled = false; 91 | } 92 | 93 | void signal_external() 94 | { 95 | VK_ASSERT(!signalled); 96 | VK_ASSERT(semaphore); 97 | signalled = true; 98 | } 99 | 100 | void destroy_on_consume() 101 | { 102 | should_destroy_on_consume = true; 103 | } 104 | 105 | void signal_pending_wait() 106 | { 107 | pending = true; 108 | } 109 | 110 | bool is_pending_wait() const 111 | { 112 | return pending; 113 | } 114 | 115 | SemaphoreHolder &operator=(SemaphoreHolder &&other) noexcept; 116 | 117 | private: 118 | friend class Util::ObjectPool; 119 | SemaphoreHolder(Device *device_, VkSemaphore semaphore_, bool signalled_) 120 | : device(device_) 121 | , semaphore(semaphore_) 122 | , timeline(0) 123 | , signalled(signalled_) 124 | { 125 | } 126 | 127 | SemaphoreHolder(Device *device_, uint64_t timeline_, VkSemaphore semaphore_) 128 | : device(device_), semaphore(semaphore_), timeline(timeline_) 129 | { 130 | VK_ASSERT(timeline > 0); 131 | } 132 | 133 | explicit SemaphoreHolder(Device *device_) 134 | : device(device_) 135 | { 136 | } 137 | 138 | void recycle_semaphore(); 139 | 140 | Device *device; 141 | VkSemaphore semaphore = VK_NULL_HANDLE; 142 | uint64_t timeline = 0; 143 | bool signalled = true; 144 | bool pending = false; 145 | bool should_destroy_on_consume = false; 146 | }; 147 | 148 | using Semaphore = Util::IntrusivePtr; 149 | } 150 | -------------------------------------------------------------------------------- /src/parallel-rdp/parallel-rdp/shaders/ubershader.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | /* Copyright (c) 2020 Themaister 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files (the 6 | * "Software"), to deal in the Software without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | // RIP to any GPU which attempts to execute this monstrosity :) 25 | 26 | #if SUBGROUP 27 | #extension GL_KHR_shader_subgroup_basic : require 28 | #extension GL_KHR_shader_subgroup_vote : require 29 | #extension GL_KHR_shader_subgroup_ballot : require 30 | #extension GL_KHR_shader_subgroup_arithmetic : require 31 | #endif 32 | #include "small_types.h" 33 | 34 | layout(local_size_x_id = 3, local_size_y_id = 4) in; 35 | 36 | #include "debug.h" 37 | #include "data_structures_buffers.h" 38 | 39 | #include "noise.h" 40 | #include "memory_interfacing.h" 41 | #include "shading.h" 42 | 43 | layout(push_constant, std430) uniform Registers 44 | { 45 | uint fb_addr_index; 46 | uint fb_depth_addr_index; 47 | uint fb_width; 48 | uint fb_height; 49 | uint group_mask; 50 | } registers; 51 | 52 | layout(constant_id = 5) const int MAX_PRIMITIVES = 256; 53 | layout(constant_id = 6) const int MAX_WIDTH = 1024; 54 | 55 | const int TILE_BINNING_STRIDE = MAX_PRIMITIVES / 32; 56 | const int MAX_TILES_X = MAX_WIDTH / int(gl_WorkGroupSize.x); 57 | 58 | void main() 59 | { 60 | int x = int(gl_GlobalInvocationID.x); 61 | int y = int(gl_GlobalInvocationID.y); 62 | ivec2 tile = ivec2(gl_WorkGroupID.xy); 63 | 64 | int linear_tile = tile.x + tile.y * MAX_TILES_X; 65 | int linear_tile_base = linear_tile * TILE_BINNING_STRIDE; 66 | 67 | uint coarse_binned = tile_binning_coarse.elems[linear_tile] & registers.group_mask; 68 | if (coarse_binned == 0u) 69 | return; 70 | 71 | init_tile(gl_GlobalInvocationID.xy, 72 | registers.fb_width, registers.fb_height, 73 | registers.fb_addr_index, registers.fb_depth_addr_index); 74 | 75 | while (coarse_binned != 0u) 76 | { 77 | int mask_index = findLSB(coarse_binned); 78 | coarse_binned &= ~uint(1 << mask_index); 79 | 80 | uint binned = tile_binning.elems[linear_tile_base + mask_index]; 81 | while (binned != 0u) 82 | { 83 | int i = findLSB(binned); 84 | binned &= ~uint(1 << i); 85 | uint primitive_index = uint(i + 32 * mask_index); 86 | 87 | ShadedData shaded; 88 | if (shade_pixel(x, y, primitive_index, shaded)) 89 | { 90 | if ((shaded.coverage_count & COVERAGE_FILL_BIT) != 0) 91 | fill_color(derived_setup.elems[primitive_index].fill_color); 92 | else if ((shaded.coverage_count & COVERAGE_COPY_BIT) != 0) 93 | copy_pipeline(shaded.z_dith, primitive_index); 94 | else 95 | depth_blend(x, y, primitive_index, shaded); 96 | } 97 | } 98 | } 99 | 100 | finish_tile(gl_GlobalInvocationID.xy, 101 | registers.fb_width, registers.fb_height, 102 | registers.fb_addr_index, registers.fb_depth_addr_index); 103 | } 104 | --------------------------------------------------------------------------------