mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-25 15:15:40 +00:00
Add subset of headers from libretro-common
This commit is contained in:
parent
f5fd37c4c4
commit
5dedd8707b
|
@ -15,6 +15,7 @@ endif()
|
|||
if(NOT ANDROID)
|
||||
option(BUILD_SDL_FRONTEND "Build the SDL frontend" ON)
|
||||
option(BUILD_QT_FRONTEND "Build the Qt frontend" ON)
|
||||
option(BUILD_LIBRETRO_CORE "Build a libretro core" OFF)
|
||||
option(ENABLE_DISCORD_PRESENCE "Build with Discord Rich Presence support" ON)
|
||||
option(USE_SDL2 "Link with SDL2 for controller support" ON)
|
||||
endif()
|
||||
|
@ -28,6 +29,35 @@ if(LINUX OR ANDROID)
|
|||
option(USE_EGL "Support EGL OpenGL context creation" ON)
|
||||
endif()
|
||||
|
||||
# When we're building for libretro, everything else is invalid because of PIC.
|
||||
if(BUILD_LIBRETRO_CORE)
|
||||
if(BUILD_SDL_FRONTEND)
|
||||
message(WARNING "Building libretro core, disabling SDL frontend")
|
||||
set(BUILD_SDL_FRONTEND OFF)
|
||||
endif()
|
||||
if(BUILD_QT_FRONTEND)
|
||||
message(WARNING "Building libretro core, disabling Qt frontend")
|
||||
set(BUILD_QT_FRONTEND OFF)
|
||||
endif()
|
||||
if(ENABLE_DISCORD_PRESENCE)
|
||||
message("Building libretro core, disabling Discord Presence support")
|
||||
set(ENABLE_DISCORD_PRESENCE OFF)
|
||||
endif()
|
||||
if(USE_SDL2)
|
||||
message("Building libretro core, disabling SDL2 support")
|
||||
set(USE_SDL2 OFF)
|
||||
endif()
|
||||
if(USE_X11)
|
||||
set(USE_X11 OFF)
|
||||
endif()
|
||||
if(USE_EGL)
|
||||
set(USE_EGL OFF)
|
||||
endif()
|
||||
|
||||
# Force PIC when compiling a libretro core.
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
endif()
|
||||
|
||||
|
||||
# Common include/library directories on Windows.
|
||||
if(WIN32)
|
||||
|
|
|
@ -22,6 +22,10 @@ if(BUILD_SDL_FRONTEND)
|
|||
add_subdirectory(nativefiledialog)
|
||||
endif()
|
||||
|
||||
if(BUILD_LIBRETRO_CORE)
|
||||
add_subdirectory(libretro-common)
|
||||
endif()
|
||||
|
||||
if(${CPU_ARCH} STREQUAL "aarch64")
|
||||
add_subdirectory(vixl)
|
||||
endif()
|
||||
|
|
2
dep/libretro-common/CMakeLists.txt
Normal file
2
dep/libretro-common/CMakeLists.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
add_library(libretro-common INTERFACE)
|
||||
target_include_directories(libretro-common INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include/")
|
2880
dep/libretro-common/include/libretro.h
Normal file
2880
dep/libretro-common/include/libretro.h
Normal file
File diff suppressed because it is too large
Load diff
59
dep/libretro-common/include/libretro_d3d.h
Normal file
59
dep/libretro-common/include/libretro_d3d.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this libretro API header (libretro_d3d.h)
|
||||
* ---------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the
|
||||
* "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef LIBRETRO_DIRECT3D_H__
|
||||
#define LIBRETRO_DIRECT3D_H__
|
||||
|
||||
#include "libretro.h"
|
||||
|
||||
#ifdef HAVE_D3D11
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
#define RETRO_HW_RENDER_INTERFACE_D3D11_VERSION 1
|
||||
|
||||
struct retro_hw_render_interface_d3d11
|
||||
{
|
||||
/* Must be set to RETRO_HW_RENDER_INTERFACE_D3D11. */
|
||||
enum retro_hw_render_interface_type interface_type;
|
||||
/* Must be set to RETRO_HW_RENDER_INTERFACE_D3D11_VERSION. */
|
||||
unsigned interface_version;
|
||||
|
||||
/* Opaque handle to the d3d11 backend in the frontend
|
||||
* which must be passed along to all function pointers
|
||||
* in this interface.
|
||||
*/
|
||||
void* handle;
|
||||
ID3D11Device *device;
|
||||
ID3D11DeviceContext *context;
|
||||
D3D_FEATURE_LEVEL featureLevel;
|
||||
pD3DCompile D3DCompile;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* LIBRETRO_DIRECT3D_H__ */
|
397
dep/libretro-common/include/libretro_vulkan.h
Normal file
397
dep/libretro-common/include/libretro_vulkan.h
Normal file
|
@ -0,0 +1,397 @@
|
|||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this libretro API header (libretro_vulkan.h)
|
||||
* ---------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef LIBRETRO_VULKAN_H__
|
||||
#define LIBRETRO_VULKAN_H__
|
||||
|
||||
#include <libretro.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#define RETRO_HW_RENDER_INTERFACE_VULKAN_VERSION 5
|
||||
#define RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN_VERSION 1
|
||||
|
||||
struct retro_vulkan_image
|
||||
{
|
||||
VkImageView image_view;
|
||||
VkImageLayout image_layout;
|
||||
VkImageViewCreateInfo create_info;
|
||||
};
|
||||
|
||||
typedef void (*retro_vulkan_set_image_t)(void *handle,
|
||||
const struct retro_vulkan_image *image,
|
||||
uint32_t num_semaphores,
|
||||
const VkSemaphore *semaphores,
|
||||
uint32_t src_queue_family);
|
||||
|
||||
typedef uint32_t (*retro_vulkan_get_sync_index_t)(void *handle);
|
||||
typedef uint32_t (*retro_vulkan_get_sync_index_mask_t)(void *handle);
|
||||
typedef void (*retro_vulkan_set_command_buffers_t)(void *handle,
|
||||
uint32_t num_cmd,
|
||||
const VkCommandBuffer *cmd);
|
||||
typedef void (*retro_vulkan_wait_sync_index_t)(void *handle);
|
||||
typedef void (*retro_vulkan_lock_queue_t)(void *handle);
|
||||
typedef void (*retro_vulkan_unlock_queue_t)(void *handle);
|
||||
typedef void (*retro_vulkan_set_signal_semaphore_t)(void *handle, VkSemaphore semaphore);
|
||||
|
||||
typedef const VkApplicationInfo *(*retro_vulkan_get_application_info_t)(void);
|
||||
|
||||
struct retro_vulkan_context
|
||||
{
|
||||
VkPhysicalDevice gpu;
|
||||
VkDevice device;
|
||||
VkQueue queue;
|
||||
uint32_t queue_family_index;
|
||||
VkQueue presentation_queue;
|
||||
uint32_t presentation_queue_family_index;
|
||||
};
|
||||
|
||||
typedef bool (*retro_vulkan_create_device_t)(
|
||||
struct retro_vulkan_context *context,
|
||||
VkInstance instance,
|
||||
VkPhysicalDevice gpu,
|
||||
VkSurfaceKHR surface,
|
||||
PFN_vkGetInstanceProcAddr get_instance_proc_addr,
|
||||
const char **required_device_extensions,
|
||||
unsigned num_required_device_extensions,
|
||||
const char **required_device_layers,
|
||||
unsigned num_required_device_layers,
|
||||
const VkPhysicalDeviceFeatures *required_features);
|
||||
|
||||
typedef void (*retro_vulkan_destroy_device_t)(void);
|
||||
|
||||
/* Note on thread safety:
|
||||
* The Vulkan API is heavily designed around multi-threading, and
|
||||
* the libretro interface for it should also be threading friendly.
|
||||
* A core should be able to build command buffers and submit
|
||||
* command buffers to the GPU from any thread.
|
||||
*/
|
||||
|
||||
struct retro_hw_render_context_negotiation_interface_vulkan
|
||||
{
|
||||
/* Must be set to RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN. */
|
||||
enum retro_hw_render_context_negotiation_interface_type interface_type;
|
||||
/* Must be set to RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN_VERSION. */
|
||||
unsigned interface_version;
|
||||
|
||||
/* If non-NULL, returns a VkApplicationInfo struct that the frontend can use instead of
|
||||
* its "default" application info.
|
||||
*/
|
||||
retro_vulkan_get_application_info_t get_application_info;
|
||||
|
||||
/* If non-NULL, the libretro core will choose one or more physical devices,
|
||||
* create one or more logical devices and create one or more queues.
|
||||
* The core must prepare a designated PhysicalDevice, Device, Queue and queue family index
|
||||
* which the frontend will use for its internal operation.
|
||||
*
|
||||
* If gpu is not VK_NULL_HANDLE, the physical device provided to the frontend must be this PhysicalDevice.
|
||||
* The core is still free to use other physical devices.
|
||||
*
|
||||
* The frontend will request certain extensions and layers for a device which is created.
|
||||
* The core must ensure that the queue and queue_family_index support GRAPHICS and COMPUTE.
|
||||
*
|
||||
* If surface is not VK_NULL_HANDLE, the core must consider presentation when creating the queues.
|
||||
* If presentation to "surface" is supported on the queue, presentation_queue must be equal to queue.
|
||||
* If not, a second queue must be provided in presentation_queue and presentation_queue_index.
|
||||
* If surface is not VK_NULL_HANDLE, the instance from frontend will have been created with supported for
|
||||
* VK_KHR_surface extension.
|
||||
*
|
||||
* The core is free to set its own queue priorities.
|
||||
* Device provided to frontend is owned by the frontend, but any additional device resources must be freed by core
|
||||
* in destroy_device callback.
|
||||
*
|
||||
* If this function returns true, a PhysicalDevice, Device and Queues are initialized.
|
||||
* If false, none of the above have been initialized and the frontend will attempt
|
||||
* to fallback to "default" device creation, as if this function was never called.
|
||||
*/
|
||||
retro_vulkan_create_device_t create_device;
|
||||
|
||||
/* If non-NULL, this callback is called similar to context_destroy for HW_RENDER_INTERFACE.
|
||||
* However, it will be called even if context_reset was not called.
|
||||
* This can happen if the context never succeeds in being created.
|
||||
* destroy_device will always be called before the VkInstance
|
||||
* of the frontend is destroyed if create_device was called successfully so that the core has a chance of
|
||||
* tearing down its own device resources.
|
||||
*
|
||||
* Only auxillary resources should be freed here, i.e. resources which are not part of retro_vulkan_context.
|
||||
*/
|
||||
retro_vulkan_destroy_device_t destroy_device;
|
||||
};
|
||||
|
||||
struct retro_hw_render_interface_vulkan
|
||||
{
|
||||
/* Must be set to RETRO_HW_RENDER_INTERFACE_VULKAN. */
|
||||
enum retro_hw_render_interface_type interface_type;
|
||||
/* Must be set to RETRO_HW_RENDER_INTERFACE_VULKAN_VERSION. */
|
||||
unsigned interface_version;
|
||||
|
||||
/* Opaque handle to the Vulkan backend in the frontend
|
||||
* which must be passed along to all function pointers
|
||||
* in this interface.
|
||||
*
|
||||
* The rationale for including a handle here (which libretro v1
|
||||
* doesn't currently do in general) is:
|
||||
*
|
||||
* - Vulkan cores should be able to be freely threaded without lots of fuzz.
|
||||
* This would break frontends which currently rely on TLS
|
||||
* to deal with multiple cores loaded at the same time.
|
||||
* - Fixing this in general is TODO for an eventual libretro v2.
|
||||
*/
|
||||
void *handle;
|
||||
|
||||
/* The Vulkan instance the context is using. */
|
||||
VkInstance instance;
|
||||
/* The physical device used. */
|
||||
VkPhysicalDevice gpu;
|
||||
/* The logical device used. */
|
||||
VkDevice device;
|
||||
|
||||
/* Allows a core to fetch all its needed symbols without having to link
|
||||
* against the loader itself. */
|
||||
PFN_vkGetDeviceProcAddr get_device_proc_addr;
|
||||
PFN_vkGetInstanceProcAddr get_instance_proc_addr;
|
||||
|
||||
/* The queue the core must use to submit data.
|
||||
* This queue and index must remain constant throughout the lifetime
|
||||
* of the context.
|
||||
*
|
||||
* This queue will be the queue that supports graphics and compute
|
||||
* if the device supports compute.
|
||||
*/
|
||||
VkQueue queue;
|
||||
unsigned queue_index;
|
||||
|
||||
/* Before calling retro_video_refresh_t with RETRO_HW_FRAME_BUFFER_VALID,
|
||||
* set which image to use for this frame.
|
||||
*
|
||||
* If num_semaphores is non-zero, the frontend will wait for the
|
||||
* semaphores provided to be signaled before using the results further
|
||||
* in the pipeline.
|
||||
*
|
||||
* Semaphores provided by a single call to set_image will only be
|
||||
* waited for once (waiting for a semaphore resets it).
|
||||
* E.g. set_image, video_refresh, and then another
|
||||
* video_refresh without set_image,
|
||||
* but same image will only wait for semaphores once.
|
||||
*
|
||||
* For this reason, ownership transfer will only occur if semaphores
|
||||
* are waited on for a particular frame in the frontend.
|
||||
*
|
||||
* Using semaphores is optional for synchronization purposes,
|
||||
* but if not using
|
||||
* semaphores, an image memory barrier in vkCmdPipelineBarrier
|
||||
* should be used in the graphics_queue.
|
||||
* Example:
|
||||
*
|
||||
* vkCmdPipelineBarrier(cmd,
|
||||
* srcStageMask = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
|
||||
* dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
* image_memory_barrier = {
|
||||
* srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
* dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
|
||||
* });
|
||||
*
|
||||
* The use of pipeline barriers instead of semaphores is encouraged
|
||||
* as it is simpler and more fine-grained. A layout transition
|
||||
* must generally happen anyways which requires a
|
||||
* pipeline barrier.
|
||||
*
|
||||
* The image passed to set_image must have imageUsage flags set to at least
|
||||
* VK_IMAGE_USAGE_TRANSFER_SRC_BIT and VK_IMAGE_USAGE_SAMPLED_BIT.
|
||||
* The core will naturally want to use flags such as
|
||||
* VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT and/or
|
||||
* VK_IMAGE_USAGE_TRANSFER_DST_BIT depending
|
||||
* on how the final image is created.
|
||||
*
|
||||
* The image must also have been created with MUTABLE_FORMAT bit set if
|
||||
* 8-bit formats are used, so that the frontend can reinterpret sRGB
|
||||
* formats as it sees fit.
|
||||
*
|
||||
* Images passed to set_image should be created with TILING_OPTIMAL.
|
||||
* The image layout should be transitioned to either
|
||||
* VK_IMAGE_LAYOUT_GENERIC or VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL.
|
||||
* The actual image layout used must be set in image_layout.
|
||||
*
|
||||
* The image must be a 2D texture which may or not be layered
|
||||
* and/or mipmapped.
|
||||
*
|
||||
* The image must be suitable for linear sampling.
|
||||
* While the image_view is typically the only field used,
|
||||
* the frontend may want to reinterpret the texture as sRGB vs.
|
||||
* non-sRGB for example so the VkImageViewCreateInfo used to
|
||||
* create the image view must also be passed in.
|
||||
*
|
||||
* The data in the pointer to the image struct will not be copied
|
||||
* as the pNext field in create_info cannot be reliably deep-copied.
|
||||
* The image pointer passed to set_image must be valid until
|
||||
* retro_video_refresh_t has returned.
|
||||
*
|
||||
* If frame duping is used when passing NULL to retro_video_refresh_t,
|
||||
* the frontend is free to either use the latest image passed to
|
||||
* set_image or reuse the older pointer passed to set_image the
|
||||
* frame RETRO_HW_FRAME_BUFFER_VALID was last used.
|
||||
*
|
||||
* Essentially, the lifetime of the pointer passed to
|
||||
* retro_video_refresh_t should be extended if frame duping is used
|
||||
* so that the frontend can reuse the older pointer.
|
||||
*
|
||||
* The image itself however, must not be touched by the core until
|
||||
* wait_sync_index has been completed later. The frontend may perform
|
||||
* layout transitions on the image, so even read-only access is not defined.
|
||||
* The exception to read-only rule is if GENERAL layout is used for the image.
|
||||
* In this case, the frontend is not allowed to perform any layout transitions,
|
||||
* so concurrent reads from core and frontend are allowed.
|
||||
*
|
||||
* If frame duping is used, or if set_command_buffers is used,
|
||||
* the frontend will not wait for any semaphores.
|
||||
*
|
||||
* The src_queue_family is used to specify which queue family
|
||||
* the image is currently owned by. If using multiple queue families
|
||||
* (e.g. async compute), the frontend will need to acquire ownership of the
|
||||
* image before rendering with it and release the image afterwards.
|
||||
*
|
||||
* If src_queue_family is equal to the queue family (queue_index),
|
||||
* no ownership transfer will occur.
|
||||
* Similarly, if src_queue_family is VK_QUEUE_FAMILY_IGNORED,
|
||||
* no ownership transfer will occur.
|
||||
*
|
||||
* The frontend will always release ownership back to src_queue_family.
|
||||
* Waiting for frontend to complete with wait_sync_index() ensures that
|
||||
* the frontend has released ownership back to the application.
|
||||
* Note that in Vulkan, transfering ownership is a two-part process.
|
||||
*
|
||||
* Example frame:
|
||||
* - core releases ownership from src_queue_index to queue_index with VkImageMemoryBarrier.
|
||||
* - core calls set_image with src_queue_index.
|
||||
* - Frontend will acquire the image with src_queue_index -> queue_index as well, completing the ownership transfer.
|
||||
* - Frontend renders the frame.
|
||||
* - Frontend releases ownership with queue_index -> src_queue_index.
|
||||
* - Next time image is used, core must acquire ownership from queue_index ...
|
||||
*
|
||||
* Since the frontend releases ownership, we cannot necessarily dupe the frame because
|
||||
* the core needs to make the roundtrip of ownership transfer.
|
||||
*/
|
||||
retro_vulkan_set_image_t set_image;
|
||||
|
||||
/* Get the current sync index for this frame which is obtained in
|
||||
* frontend by calling e.g. vkAcquireNextImageKHR before calling
|
||||
* retro_run().
|
||||
*
|
||||
* This index will correspond to which swapchain buffer is currently
|
||||
* the active one.
|
||||
*
|
||||
* Knowing this index is very useful for maintaining safe asynchronous CPU
|
||||
* and GPU operation without stalling.
|
||||
*
|
||||
* The common pattern for synchronization is to receive fences when
|
||||
* submitting command buffers to Vulkan (vkQueueSubmit) and add this fence
|
||||
* to a list of fences for frame number get_sync_index().
|
||||
*
|
||||
* Next time we receive the same get_sync_index(), we can wait for the
|
||||
* fences from before, which will usually return immediately as the
|
||||
* frontend will generally also avoid letting the GPU run ahead too much.
|
||||
*
|
||||
* After the fence has signaled, we know that the GPU has completed all
|
||||
* GPU work related to work submitted in the frame we last saw get_sync_index().
|
||||
*
|
||||
* This means we can safely reuse or free resources allocated in this frame.
|
||||
*
|
||||
* In theory, even if we wait for the fences correctly, it is not technically
|
||||
* safe to write to the image we earlier passed to the frontend since we're
|
||||
* not waiting for the frontend GPU jobs to complete.
|
||||
*
|
||||
* The frontend will guarantee that the appropriate pipeline barrier
|
||||
* in graphics_queue has been used such that
|
||||
* VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT cannot
|
||||
* start until the frontend is done with the image.
|
||||
*/
|
||||
retro_vulkan_get_sync_index_t get_sync_index;
|
||||
|
||||
/* Returns a bitmask of how many swapchain images we currently have
|
||||
* in the frontend.
|
||||
*
|
||||
* If bit #N is set in the return value, get_sync_index can return N.
|
||||
* Knowing this value is useful for preallocating per-frame management
|
||||
* structures ahead of time.
|
||||
*
|
||||
* While this value will typically remain constant throughout the
|
||||
* applications lifecycle, it may for example change if the frontend
|
||||
* suddently changes fullscreen state and/or latency.
|
||||
*
|
||||
* If this value ever changes, it is safe to assume that the device
|
||||
* is completely idle and all synchronization objects can be deleted
|
||||
* right away as desired.
|
||||
*/
|
||||
retro_vulkan_get_sync_index_mask_t get_sync_index_mask;
|
||||
|
||||
/* Instead of submitting the command buffer to the queue first, the core
|
||||
* can pass along its command buffer to the frontend, and the frontend
|
||||
* will submit the command buffer together with the frontends command buffers.
|
||||
*
|
||||
* This has the advantage that the overhead of vkQueueSubmit can be
|
||||
* amortized into a single call. For this mode, semaphores in set_image
|
||||
* will be ignored, so vkCmdPipelineBarrier must be used to synchronize
|
||||
* the core and frontend.
|
||||
*
|
||||
* The command buffers in set_command_buffers are only executed once,
|
||||
* even if frame duping is used.
|
||||
*
|
||||
* If frame duping is used, set_image should be used for the frames
|
||||
* which should be duped instead.
|
||||
*
|
||||
* Command buffers passed to the frontend with set_command_buffers
|
||||
* must not actually be submitted to the GPU until retro_video_refresh_t
|
||||
* is called.
|
||||
*
|
||||
* The frontend must submit the command buffer before submitting any
|
||||
* other command buffers provided by set_command_buffers. */
|
||||
retro_vulkan_set_command_buffers_t set_command_buffers;
|
||||
|
||||
/* Waits on CPU for device activity for the current sync index to complete.
|
||||
* This is useful since the core will not have a relevant fence to sync with
|
||||
* when the frontend is submitting the command buffers. */
|
||||
retro_vulkan_wait_sync_index_t wait_sync_index;
|
||||
|
||||
/* If the core submits command buffers itself to any of the queues provided
|
||||
* in this interface, the core must lock and unlock the frontend from
|
||||
* racing on the VkQueue.
|
||||
*
|
||||
* Queue submission can happen on any thread.
|
||||
* Even if queue submission happens on the same thread as retro_run(),
|
||||
* the lock/unlock functions must still be called.
|
||||
*
|
||||
* NOTE: Queue submissions are heavy-weight. */
|
||||
retro_vulkan_lock_queue_t lock_queue;
|
||||
retro_vulkan_unlock_queue_t unlock_queue;
|
||||
|
||||
/* Sets a semaphore which is signaled when the image in set_image can safely be reused.
|
||||
* The semaphore is consumed next call to retro_video_refresh_t.
|
||||
* The semaphore will be signalled even for duped frames.
|
||||
* The semaphore will be signalled only once, so set_signal_semaphore should be called every frame.
|
||||
* The semaphore may be VK_NULL_HANDLE, which disables semaphore signalling for next call to retro_video_refresh_t.
|
||||
*
|
||||
* This is mostly useful to support use cases where you're rendering to a single image that
|
||||
* is recycled in a ping-pong fashion with the frontend to save memory (but potentially less throughput).
|
||||
*/
|
||||
retro_vulkan_set_signal_semaphore_t set_signal_semaphore;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue