Commit b04ff5d8 authored by Adrien Plazas's avatar Adrien Plazas

Start implementing HW rendering APIs

parent acc17641
Pipeline #21144 failed with stages
in 1 minute and 29 seconds
......@@ -435,18 +435,6 @@ struct retro_frame_time_callback
The hardware rendering system is unimplemented.
```
#define RETRO_ENVIRONMENT_SET_HW_RENDER 14
/* struct retro_hw_render_callback * --
* Sets an interface to let a libretro core render with
* hardware acceleration.
* Should be called in retro_load_game().
* If successful, libretro cores will be able to render to a
* frontend-provided framebuffer.
* The size of this framebuffer will be at least as large as
* max_width/max_height provided in get_av_info().
* If HW rendering is used, pass only RETRO_HW_FRAME_BUFFER_VALID or
* NULL to retro_video_refresh_t.
*/
#define RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE (41 | RETRO_ENVIRONMENT_EXPERIMENTAL)
/* const struct retro_hw_render_interface ** --
* Returns an API specific rendering interface for accessing API specific data.
......@@ -509,141 +497,6 @@ struct retro_hw_render_context_negotiation_interface
enum retro_hw_render_context_negotiation_interface_type interface_type;
unsigned interface_version;
};
/* Pass this to retro_video_refresh_t if rendering to hardware.
* Passing NULL to retro_video_refresh_t is still a frame dupe as normal.
* */
#define RETRO_HW_FRAME_BUFFER_VALID ((void*)-1)
/* Invalidates the current HW context.
* Any GL state is lost, and must not be deinitialized explicitly.
* If explicit deinitialization is desired by the libretro core,
* it should implement context_destroy callback.
* If called, all GPU resources must be reinitialized.
* Usually called when frontend reinits video driver.
* Also called first time video driver is initialized,
* allowing libretro core to initialize resources.
*/
typedef void (RETRO_CALLCONV *retro_hw_context_reset_t)(void);
/* Gets current framebuffer which is to be rendered to.
* Could change every frame potentially.
*/
typedef uintptr_t (RETRO_CALLCONV *retro_hw_get_current_framebuffer_t)(void);
/* Get a symbol from HW context. */
typedef retro_proc_address_t (RETRO_CALLCONV *retro_hw_get_proc_address_t)(const char *sym);
enum retro_hw_context_type
{
RETRO_HW_CONTEXT_NONE = 0,
/* OpenGL 2.x. Driver can choose to use latest compatibility context. */
RETRO_HW_CONTEXT_OPENGL = 1,
/* OpenGL ES 2.0. */
RETRO_HW_CONTEXT_OPENGLES2 = 2,
/* Modern desktop core GL context. Use version_major/
* version_minor fields to set GL version. */
RETRO_HW_CONTEXT_OPENGL_CORE = 3,
/* OpenGL ES 3.0 */
RETRO_HW_CONTEXT_OPENGLES3 = 4,
/* OpenGL ES 3.1+. Set version_major/version_minor. For GLES2 and GLES3,
* use the corresponding enums directly. */
RETRO_HW_CONTEXT_OPENGLES_VERSION = 5,
/* Vulkan, see RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE. */
RETRO_HW_CONTEXT_VULKAN = 6,
/* Direct3D, set version_major to select the type of interface
* returned by RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE */
RETRO_HW_CONTEXT_DIRECT3D = 7,
RETRO_HW_CONTEXT_DUMMY = INT_MAX
};
struct retro_hw_render_callback
{
/* Which API to use. Set by libretro core. */
enum retro_hw_context_type context_type;
/* Called when a context has been created or when it has been reset.
* An OpenGL context is only valid after context_reset() has been called.
*
* When context_reset is called, OpenGL resources in the libretro
* implementation are guaranteed to be invalid.
*
* It is possible that context_reset is called multiple times during an
* application lifecycle.
* If context_reset is called without any notification (context_destroy),
* the OpenGL context was lost and resources should just be recreated
* without any attempt to "free" old resources.
*/
retro_hw_context_reset_t context_reset;
/* Set by frontend.
* TODO: This is rather obsolete. The frontend should not
* be providing preallocated framebuffers. */
retro_hw_get_current_framebuffer_t get_current_framebuffer;
/* Set by frontend.
* Can return all relevant functions, including glClear on Windows. */
retro_hw_get_proc_address_t get_proc_address;
/* Set if render buffers should have depth component attached.
* TODO: Obsolete. */
bool depth;
/* Set if stencil buffers should be attached.
* TODO: Obsolete. */
bool stencil;
/* If depth and stencil are true, a packed 24/8 buffer will be added.
* Only attaching stencil is invalid and will be ignored. */
/* Use conventional bottom-left origin convention. If false,
* standard libretro top-left origin semantics are used.
* TODO: Move to GL specific interface. */
bool bottom_left_origin;
/* Major version number for core GL context or GLES 3.1+. */
unsigned version_major;
/* Minor version number for core GL context or GLES 3.1+. */
unsigned version_minor;
/* If this is true, the frontend will go very far to avoid
* resetting context in scenarios like toggling fullscreen, etc.
* TODO: Obsolete? Maybe frontend should just always assume this ...
*/
bool cache_context;
/* The reset callback might still be called in extreme situations
* such as if the context is lost beyond recovery.
*
* For optimal stability, set this to false, and allow context to be
* reset at any time.
*/
/* A callback to be called before the context is destroyed in a
* controlled way by the frontend. */
retro_hw_context_reset_t context_destroy;
/* OpenGL resources can be deinitialized cleanly at this step.
* context_destroy can be set to NULL, in which resources will
* just be destroyed without any notification.
*
* Even when context_destroy is non-NULL, it is possible that
* context_reset is called without any destroy notification.
* This happens if context is lost by external factors (such as
* notified by GL_ARB_robustness).
*
* In this case, the context is assumed to be already dead,
* and the libretro implementation must not try to free any OpenGL
* resources in the subsequent context_reset.
*/
/* Creates a debug context. */
bool debug_context;
};
```
## Input Descriptors
......@@ -1152,8 +1005,6 @@ The proc address system is unimplemented.
* **MUST** be called from within retro_set_environment().
*/
typedef void (RETRO_CALLCONV *retro_proc_address_t)(void);
/* libretro API extension functions:
* (None here so far).
*
......
......@@ -12,7 +12,7 @@
"sources": [
{
"type": "git",
"url": "https://github.com/libretro/libretro-samples.git"
"path": "/home/kekun/Projects/libretro-samples"
},
{
"type": "file",
......
......@@ -61,7 +61,7 @@
{
"type" : "script",
"commands" : [
"retro-demo /app/lib/libretro/test_libretro.so"
"retro-demo /app/lib/libretro/testgl_libretro.so"
],
"dest-filename" : "retro-demo-samples-test"
},
......
......@@ -9,6 +9,7 @@
#include "retro-core.h"
#include "retro-disk-control-callback.h"
#include "retro-hardware-render-callback.h"
#include "retro-input.h"
#include "retro-input-descriptor.h"
#include "retro-module.h"
......@@ -44,6 +45,7 @@ struct _RetroCore
RetroPixelFormat pixel_format;
RetroRotation rotation;
gdouble sample_rate;
RetroHardwareRenderCallback hardware_render_callback;
RetroKeyboardCallback keyboard_callback;
RetroController *default_controllers[RETRO_CONTROLLER_TYPE_COUNT];
......@@ -68,6 +70,8 @@ void retro_core_set_system_av_info (RetroCore *self,
RetroSystemAvInfo *system_av_info);
void retro_core_set_geometry (RetroCore *self,
RetroGameGeometry *geometry);
void retro_core_set_hardware_render_callback (RetroCore *self,
RetroHardwareRenderCallback *hardware_render_callback);
void retro_core_poll_controllers (RetroCore *self);
gint16 retro_core_get_controller_input_state (RetroCore *self,
uint port,
......
......@@ -636,6 +636,13 @@ retro_core_set_geometry (RetroCore *self,
(float) geometry->base_height;
}
void
retro_core_set_hardware_render_callback (RetroCore *self,
RetroHardwareRenderCallback *hardware_render_callback)
{
self->hardware_render_callback = *hardware_render_callback;
}
/**
* retro_core_get_name:
* @self: a #RetroCore
......@@ -1529,6 +1536,12 @@ retro_core_run (RetroCore *self)
run = retro_module_get_run (self->module);
static gboolean hardware_context;
if (!hardware_context) {
hardware_context = TRUE;
self->hardware_render_callback.context_reset ();
}
if (self->runahead == 0) {
self->run_remaining = 0;
retro_core_push_cb_data (self);
......
This diff is collapsed.
// This file is part of retro-gtk. License: GPL-3.0+.
#ifndef RETRO_HARDWARE_RENDER_CALLBACK_H
#define RETRO_HARDWARE_RENDER_CALLBACK_H
#if !defined(__RETRO_GTK_INSIDE__) && !defined(RETRO_GTK_COMPILATION)
# error "Only <retro-gtk.h> can be included directly."
#endif
#include <glib.h>
#include <stdbool.h>
#include <stdint.h>
#include "retro-proc-address.h"
typedef enum _RetroHardwareContextType RetroHardwareContextType;
typedef struct _RetroHardwareRenderCallback RetroHardwareRenderCallback;
enum _RetroHardwareContextType
{
RETRO_HW_CONTEXT_NONE = 0,
/* OpenGL 2.x. Driver can choose to use latest compatibility context. */
RETRO_HW_CONTEXT_OPENGL = 1,
/* OpenGL ES 2.0. */
RETRO_HW_CONTEXT_OPENGLES2 = 2,
/* Modern desktop core GL context. Use version_major/
* version_minor fields to set GL version. */
RETRO_HW_CONTEXT_OPENGL_CORE = 3,
/* OpenGL ES 3.0 */
RETRO_HW_CONTEXT_OPENGLES3 = 4,
/* OpenGL ES 3.1+. Set version_major/version_minor. For GLES2 and GLES3,
* use the corresponding enums directly. */
RETRO_HW_CONTEXT_OPENGLES_VERSION = 5,
/* Vulkan, see RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE. */
RETRO_HW_CONTEXT_VULKAN = 6,
/* Direct3D, set version_major to select the type of interface
* returned by RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE */
RETRO_HW_CONTEXT_DIRECT3D = 7,
RETRO_HW_CONTEXT_DUMMY = G_MAXINT,
};
/* Invalidates the current HW context.
* Any GL state is lost, and must not be deinitialized explicitly.
* If explicit deinitialization is desired by the libretro core,
* it should implement context_destroy callback.
* If called, all GPU resources must be reinitialized.
* Usually called when frontend reinits video driver.
* Also called first time video driver is initialized,
* allowing libretro core to initialize resources.
*/
typedef void (*RetroHardwareContextReset) (void);
/* Gets current framebuffer which is to be rendered to.
* Could change every frame potentially.
*/
typedef uintptr_t (*RetroHardwareGetCurrentFramebuffer) (void);
/* Get a symbol from HW context. */
typedef RetroProcAddress (*RetroHardwareGetProcAddress) (const gchar *symbol);
struct _RetroHardwareRenderCallback
{
/* Which API to use. Set by libretro core. */
RetroHardwareContextType context_type;
/* Called when a context has been created or when it has been reset.
* An OpenGL context is only valid after context_reset() has been called.
*
* When context_reset is called, OpenGL resources in the libretro
* implementation are guaranteed to be invalid.
*
* It is possible that context_reset is called multiple times during an
* application lifecycle.
* If context_reset is called without any notification (context_destroy),
* the OpenGL context was lost and resources should just be recreated
* without any attempt to "free" old resources.
*/
RetroHardwareContextReset context_reset;
RetroHardwareGetCurrentFramebuffer get_current_framebuffer;
RetroHardwareGetProcAddress get_proc_address;
/* Set if render buffers should have depth component attached.
* TODO: Obsolete. */
bool depth;
/* Set if stencil buffers should be attached.
* TODO: Obsolete. */
bool stencil;
/* If depth and stencil are true, a packed 24/8 buffer will be added.
* Only attaching stencil is invalid and will be ignored. */
/* Use conventional bottom-left origin convention. If false,
* standard libretro top-left origin semantics are used.
* TODO: Move to GL specific interface. */
bool bottom_left_origin;
/* Major version number for core GL context or GLES 3.1+. */
guint version_major;
/* Minor version number for core GL context or GLES 3.1+. */
guint version_minor;
/* If this is true, the frontend will go very far to avoid
* resetting context in scenarios like toggling fullscreen, etc.
* TODO: Obsolete? Maybe frontend should just always assume this ...
*/
bool cache_context;
/* The reset callback might still be called in extreme situations
* such as if the context is lost beyond recovery.
*
* For optimal stability, set this to false, and allow context to be
* reset at any time.
*/
/* A callback to be called before the context is destroyed in a
* controlled way by the frontend. */
RetroHardwareContextReset context_destroy;
/* OpenGL resources can be deinitialized cleanly at this step.
* context_destroy can be set to NULL, in which resources will
* just be destroyed without any notification.
*
* Even when context_destroy is non-NULL, it is possible that
* context_reset is called without any destroy notification.
* This happens if context is lost by external factors (such as
* notified by GL_ARB_robustness).
*
* In this case, the context is assumed to be already dead,
* and the libretro implementation must not try to free any OpenGL
* resources in the subsequent context_reset.
*/
/* Creates a debug context. */
bool debug_context;
};
#endif /* RETRO_HARDWARE_RENDER_CALLBACK_H */
// This file is part of retro-gtk. License: GPL-3.0+.
#ifndef RETRO_PROC_ADDRESS_H
#define RETRO_PROC_ADDRESS_H
#if !defined(__RETRO_GTK_INSIDE__) && !defined(RETRO_GTK_COMPILATION)
# error "Only <retro-gtk.h> can be included directly."
#endif
typedef void (*RetroProcAddress) (void);
#endif /* RETRO_PROC_ADDRESS_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment