From 2a56a827e8a97a3838a9d455f1dca442c0ffbb07 Mon Sep 17 00:00:00 2001 From: Antonio Orefice Date: Wed, 13 Nov 2024 04:50:59 +0100 Subject: [PATCH] Add Frametime Uniforms (#17155) * Initial implementation of CoreAspect uniform * float -> float_t * Possibly fix wii_u building * vulkan: use float instead of float_t; * slangp: Advertise support of CoreAspect uniform by defining _RARCH_HAS_COREASPECT_UNIFORM early in the shader source, just after "#extension GL_GOOGLE_cpp_style_line_directive : require" * CoreAspect + glsl fix: use glUniform1f() * Add CoreAspectRot uniform. It reports CoreAspect value or 1/CoreAspect when the content is rotated by 90 or 270 deg. * Fixed stupid typo * Just use _HAS_COREASPECT_UNIFORMS to check for CoreAspect uniforms support (was _RARCH_HAS_COREASPECT_UNIFORMS) * Rename CoreAspect, CoreAspectRot, _HAS_COREASPECT_UNIFORMS to OriginalAspect, OriginlAspectRot, _HAS_ORIGINALASPECT_UNIFORMS * GLCore: void Pass::build_semantic_float needs glUniform1f. ...how on earth did it worked for UBO !? * d3d10,11,12, wrong function called by overlook. * Add test shader, will remove that before PR * Fix metal rotated aspect reporting * remove test shader * Fix C89 Build * Use OriginalAspectRotated instead of OriginalAspectRot * Add CoreFPS and FrameTimeDelta Uniforms. _HAS_ORIGINALASPECT_UNIFORMS is (#)defined and can be used to query for them. * add test shader * remote test shader * Wrong paste. * gx2: use float * wrong indentation * resolved merge conflict * fix indentation * Fix comment/Formatting * Change uniform name from CoreFPS to OriginalFPS * underliyng references: core_fps -> original_fps --- gfx/common/d3d10_defines.h | 2 + gfx/common/d3d11_defines.h | 2 + gfx/common/d3d12_defines.h | 2 + gfx/drivers/d3d10.c | 6 +++ gfx/drivers/d3d11.c | 5 +++ gfx/drivers/d3d12.c | 8 +++- gfx/drivers/gl2.c | 26 ++++++------- gfx/drivers/gl3.c | 4 ++ gfx/drivers/gx2_gfx.c | 26 +++++++++++-- gfx/drivers/metal.m | 10 ++++- gfx/drivers/vulkan.c | 6 +++ gfx/drivers_shader/glslang_util.c | 3 ++ gfx/drivers_shader/shader_gl3.cpp | 50 +++++++++++++++++++++++++ gfx/drivers_shader/shader_gl3.h | 8 ++++ gfx/drivers_shader/shader_glsl.c | 50 +++++++++++++++---------- gfx/drivers_shader/shader_vulkan.cpp | 40 ++++++++++++++++++++ gfx/drivers_shader/shader_vulkan.h | 6 +++ gfx/drivers_shader/slang_process.cpp | 2 + gfx/drivers_shader/slang_reflection.cpp | 12 ++++++ gfx/drivers_shader/slang_reflection.h | 20 ++++++---- gfx/video_driver.c | 23 ++++++++++++ gfx/video_driver.h | 4 ++ 22 files changed, 270 insertions(+), 45 deletions(-) diff --git a/gfx/common/d3d10_defines.h b/gfx/common/d3d10_defines.h index c46796cc3f4..37743447670 100644 --- a/gfx/common/d3d10_defines.h +++ b/gfx/common/d3d10_defines.h @@ -215,6 +215,8 @@ typedef struct pass_semantics_t semantics; uint32_t frame_count; int32_t frame_direction; + uint32_t frame_time_delta; + float original_fps; uint32_t rotation; uint32_t total_subframes; uint32_t current_subframe; diff --git a/gfx/common/d3d11_defines.h b/gfx/common/d3d11_defines.h index dccaf8efec3..22f12537cc2 100644 --- a/gfx/common/d3d11_defines.h +++ b/gfx/common/d3d11_defines.h @@ -291,6 +291,8 @@ typedef struct pass_semantics_t semantics; uint32_t frame_count; int32_t frame_direction; + uint32_t frame_time_delta; + float original_fps; uint32_t rotation; uint32_t total_subframes; uint32_t current_subframe; diff --git a/gfx/common/d3d12_defines.h b/gfx/common/d3d12_defines.h index 5803d9f61e6..a9e0c0f9f59 100644 --- a/gfx/common/d3d12_defines.h +++ b/gfx/common/d3d12_defines.h @@ -328,6 +328,8 @@ typedef struct pass_semantics_t semantics; uint32_t frame_count; int32_t frame_direction; + uint32_t frame_time_delta; + float original_fps; uint32_t rotation; uint32_t total_subframes; uint32_t current_subframe; diff --git a/gfx/drivers/d3d10.c b/gfx/drivers/d3d10.c index 5eec2d8304e..36417ea100a 100644 --- a/gfx/drivers/d3d10.c +++ b/gfx/drivers/d3d10.c @@ -1335,6 +1335,8 @@ static bool d3d10_gfx_set_shader(void* data, &d3d10->frame.output_size, /* FinalViewportSize */ &d3d10->pass[i].frame_count, /* FrameCount */ &d3d10->pass[i].frame_direction, /* FrameDirection */ + &d3d10->pass[i].frame_time_delta,/* FrameTimeDelta */ + &d3d10->pass[i].original_fps, /* OriginalFPS */ &d3d10->pass[i].rotation, /* Rotation */ &d3d10->pass[i].core_aspect, /* OriginalAspect */ &d3d10->pass[i].core_aspect_rot, /* OriginalAspectRotated */ @@ -2331,6 +2333,10 @@ static bool d3d10_gfx_frame( d3d10->pass[i].frame_direction = 1; #endif + d3d10->pass[i].frame_time_delta = video_driver_get_frame_time_delta_usec(); + + d3d10->pass[i].original_fps = video_driver_get_original_fps(); + d3d10->pass[i].rotation = retroarch_get_rotation(); d3d10->pass[i].core_aspect = video_driver_get_core_aspect(); diff --git a/gfx/drivers/d3d11.c b/gfx/drivers/d3d11.c index 2b41e804779..b08a7a2c143 100644 --- a/gfx/drivers/d3d11.c +++ b/gfx/drivers/d3d11.c @@ -1537,6 +1537,8 @@ static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const &d3d11->frame.output_size, /* FinalViewportSize */ &d3d11->pass[i].frame_count, /* FrameCount */ &d3d11->pass[i].frame_direction, /* FrameDirection */ + &d3d11->pass[i].frame_time_delta,/* FrameTimeDelta */ + &d3d11->pass[i].original_fps, /* OriginalFPS */ &d3d11->pass[i].rotation, /* Rotation */ &d3d11->pass[i].core_aspect, /* OriginalAspect */ &d3d11->pass[i].core_aspect_rot, /* OriginalAspectRotated */ @@ -3093,6 +3095,9 @@ static bool d3d11_gfx_frame( #else d3d11->pass[i].frame_direction = 1; #endif + d3d11->pass[i].frame_time_delta = video_driver_get_frame_time_delta_usec(); + + d3d11->pass[i].original_fps = video_driver_get_original_fps(); d3d11->pass[i].rotation = retroarch_get_rotation(); diff --git a/gfx/drivers/d3d12.c b/gfx/drivers/d3d12.c index 9661b4a402c..77bfd78d143 100644 --- a/gfx/drivers/d3d12.c +++ b/gfx/drivers/d3d12.c @@ -1724,6 +1724,8 @@ static bool d3d12_gfx_set_shader(void* data, enum rarch_shader_type type, const &d3d12->frame.output_size, /* FinalViewportSize */ &d3d12->pass[i].frame_count, /* FrameCount */ &d3d12->pass[i].frame_direction, /* FrameDirection */ + &d3d12->pass[i].frame_time_delta,/* FrameTimeDelta */ + &d3d12->pass[i].original_fps, /* OriginalFPS */ &d3d12->pass[i].rotation, /* Rotation */ &d3d12->pass[i].core_aspect, /* OriginalAspect */ &d3d12->pass[i].core_aspect_rot, /* OriginalAspectRotated */ @@ -3593,7 +3595,11 @@ static bool d3d12_gfx_frame( d3d12->pass[i].frame_direction = -1; else #endif - d3d12->pass[i].frame_direction = 1; + d3d12->pass[i].frame_direction = 1; + + d3d12->pass[i].frame_time_delta = video_driver_get_frame_time_delta_usec(); + + d3d12->pass[i].original_fps = video_driver_get_original_fps(); d3d12->pass[i].rotation = retroarch_get_rotation(); diff --git a/gfx/drivers/gl2.c b/gfx/drivers/gl2.c index 003a1f715a2..1e5e77d9655 100644 --- a/gfx/drivers/gl2.c +++ b/gfx/drivers/gl2.c @@ -3559,19 +3559,19 @@ static bool gl2_frame(void *data, const void *frame, glClear(GL_COLOR_BUFFER_BIT); - params.data = gl; - params.width = frame_width; - params.height = frame_height; - params.tex_width = gl->tex_w; - params.tex_height = gl->tex_h; - params.out_width = gl->vp.width; - params.out_height = gl->vp.height; - params.frame_counter = (unsigned int)frame_count; - params.info = &gl->tex_info; - params.prev_info = gl->prev_info; - params.feedback_info = &feedback_info; - params.fbo_info = NULL; - params.fbo_info_cnt = 0; + params.data = gl; + params.width = frame_width; + params.height = frame_height; + params.tex_width = gl->tex_w; + params.tex_height = gl->tex_h; + params.out_width = gl->vp.width; + params.out_height = gl->vp.height; + params.frame_counter = (unsigned int)frame_count; + params.info = &gl->tex_info; + params.prev_info = gl->prev_info; + params.feedback_info = &feedback_info; + params.fbo_info = NULL; + params.fbo_info_cnt = 0; gl->shader->set_params(¶ms, gl->shader_data); diff --git a/gfx/drivers/gl3.c b/gfx/drivers/gl3.c index f4321066feb..fed78c229ad 100644 --- a/gfx/drivers/gl3.c +++ b/gfx/drivers/gl3.c @@ -2742,6 +2742,10 @@ static bool gl3_frame(void *data, const void *frame, #else gl3_filter_chain_set_frame_direction(gl->filter_chain, 1); #endif + gl3_filter_chain_set_frame_time_delta(gl->filter_chain, video_driver_get_frame_time_delta_usec()); + + gl3_filter_chain_set_original_fps(gl->filter_chain, video_driver_get_original_fps()); + gl3_filter_chain_set_rotation(gl->filter_chain, retroarch_get_rotation()); gl3_filter_chain_set_core_aspect(gl->filter_chain, video_driver_get_core_aspect()); diff --git a/gfx/drivers/gx2_gfx.c b/gfx/drivers/gx2_gfx.c index 93f18c282d4..281c517f03e 100644 --- a/gfx/drivers/gx2_gfx.c +++ b/gfx/drivers/gx2_gfx.c @@ -1665,7 +1665,8 @@ static bool wiiu_init_frame_textures(wiiu_video_t *wiiu, unsigned width, unsigne static void gx2_update_uniform_block(wiiu_video_t *wiiu, int pass, float *ubo, int id, int size, int uniformVarCount, GX2UniformVar *uniformVars, - uint64_t frame_count, int32_t frame_direction, uint32_t rotation, float core_aspect, float core_aspect_rot) + uint64_t frame_count, int32_t frame_direction, uint32_t rotation, float core_aspect, + float core_aspect_rot, uint32_t frame_time_delta, uint32_t original_fps) { unsigned i; for (i = 0; i < uniformVarCount; i++) @@ -1716,6 +1717,19 @@ static void gx2_update_uniform_block(wiiu_video_t *wiiu, continue; } + if (string_is_equal(id, "FrameTimeDelta")) + { + *dst = frame_time_delta; + *(u32 *)dst = __builtin_bswap32(*(u32 *)dst); + continue; + } + + if (string_is_equal(id, "OriginalFPS")) + { + *dst = original_fps; + continue; + } + if (string_is_equal(id, "Rotation")) { *dst = rotation; @@ -1950,6 +1964,11 @@ static bool gx2_frame(void *data, const void *frame, #else int32_t frame_direction = 1; #endif + + uint32_t frame_time_delta = video_driver_get_frame_time_delta_usec(); + + float original_fps = video_driver_get_original_fps(); + uint32_t rotation = retroarch_get_rotation(); float core_aspect = video_driver_get_core_aspect(); @@ -1969,7 +1988,8 @@ static bool gx2_frame(void *data, const void *frame, gx2_update_uniform_block(wiiu, i, wiiu->pass[i].vs_ubos[j], j, wiiu->pass[i].gfd->vs->uniformBlocks[j].size, wiiu->pass[i].gfd->vs->uniformVarCount, wiiu->pass[i].gfd->vs->uniformVars, - frame_count, frame_direction, rotation, core_aspect, core_aspect_rot); + frame_count, frame_direction, rotation, core_aspect, core_aspect_rot,frame_time_delta, original_fps); + GX2SetVertexUniformBlock(wiiu->pass[i].gfd->vs->uniformBlocks[j].offset, wiiu->pass[i].gfd->vs->uniformBlocks[j].size, wiiu->pass[i].vs_ubos[j]); } @@ -1981,7 +2001,7 @@ static bool gx2_frame(void *data, const void *frame, gx2_update_uniform_block(wiiu, i, wiiu->pass[i].ps_ubos[j], j, wiiu->pass[i].gfd->ps->uniformBlocks[j].size, wiiu->pass[i].gfd->ps->uniformVarCount, wiiu->pass[i].gfd->ps->uniformVars, - frame_count, frame_direction, rotation, core_aspect, core_aspect_rot); + frame_count, frame_direction, rotation, core_aspect, core_aspect_rot,frame_time_delta, original_fps); GX2SetPixelUniformBlock(wiiu->pass[i].gfd->ps->uniformBlocks[j].offset, wiiu->pass[i].gfd->ps->uniformBlocks[j].size, wiiu->pass[i].ps_ubos[j]); } diff --git a/gfx/drivers/metal.m b/gfx/drivers/metal.m index b0ee1e15528..36ac1449f46 100644 --- a/gfx/drivers/metal.m +++ b/gfx/drivers/metal.m @@ -1205,6 +1205,8 @@ typedef struct MTLALIGN(16) texture_t feedback; uint32_t frame_count; int32_t frame_direction; + int32_t frame_time_delta; + float original_fps; uint32_t rotation; float_t core_aspect; float_t core_aspect_rot; @@ -1576,9 +1578,13 @@ - (void)drawWithContext:(Context *)ctx _engine.pass[i].frame_direction = -1; else #else - _engine.pass[i].frame_direction = 1; + _engine.pass[i].frame_direction = 1; #endif + _engine.pass[i].frame_time_delta = video_driver_get_frame_time_delta_usec(); + + _engine.pass[i].original_fps = video_driver_get_original_fps(); + _engine.pass[i].rotation = retroarch_get_rotation(); _engine.pass[i].core_aspect = video_driver_get_core_aspect(); @@ -1846,6 +1852,8 @@ - (BOOL)setShaderFromPath:(NSString *)path &_engine.frame.output_size, /* FinalViewportSize */ &_engine.pass[i].frame_count, /* FrameCount */ &_engine.pass[i].frame_direction, /* FrameDirection */ + &_engine.pass[i].frame_time_delta,/* FrameTimeDelta */ + &_engine.pass[i].original_fps, /* OriginalFPS */ &_engine.pass[i].rotation, /* Rotation */ &_engine.pass[i].core_aspect, /* OriginalAspect */ &_engine.pass[i].core_aspect_rot, /* OriginalAspectRotated */ diff --git a/gfx/drivers/vulkan.c b/gfx/drivers/vulkan.c index 77d6a94e927..3f377dd4612 100644 --- a/gfx/drivers/vulkan.c +++ b/gfx/drivers/vulkan.c @@ -4571,6 +4571,12 @@ static bool vulkan_frame(void *data, const void *frame, (vulkan_filter_chain_t*)vk->filter_chain, 1); #endif + vulkan_filter_chain_set_frame_time_delta( + (vulkan_filter_chain_t*)vk->filter_chain, video_driver_get_frame_time_delta_usec()); + + vulkan_filter_chain_set_original_fps( + (vulkan_filter_chain_t*)vk->filter_chain, video_driver_get_original_fps()); + vulkan_filter_chain_set_rotation( (vulkan_filter_chain_t*)vk->filter_chain, retroarch_get_rotation()); diff --git a/gfx/drivers_shader/glslang_util.c b/gfx/drivers_shader/glslang_util.c index 159dfcf37e3..c4ee42c2321 100644 --- a/gfx/drivers_shader/glslang_util.c +++ b/gfx/drivers_shader/glslang_util.c @@ -181,6 +181,9 @@ bool glslang_read_shader_file(const char *path, if (!string_list_append(output, "#define _HAS_ORIGINALASPECT_UNIFORMS", attr)) goto error; + if (!string_list_append(output, "#define _HAS_FRAMETIME_UNIFORMS", attr)) + goto error; + /* At least VIM treats the first line as line #1, * so offset everything by one. */ snprintf(tmp, sizeof(tmp), "#line %u \"%s\"", root_file ? 2 : 1, basename); diff --git a/gfx/drivers_shader/shader_gl3.cpp b/gfx/drivers_shader/shader_gl3.cpp index 7ebbed84214..d07029fc17f 100644 --- a/gfx/drivers_shader/shader_gl3.cpp +++ b/gfx/drivers_shader/shader_gl3.cpp @@ -752,6 +752,16 @@ class Pass frame_direction = direction; } + void set_frame_time_delta(uint32_t time_delta) + { + frame_time_delta = time_delta; + } + + void set_original_fps(float fps) + { + original_fps = fps; + } + void set_rotation(uint32_t rot) { rotation = rot; @@ -883,6 +893,8 @@ class Pass uint64_t frame_count = 0; unsigned frame_count_period = 0; int32_t frame_direction = 1; + uint32_t frame_time_delta = 0; + float original_fps = 0; uint32_t rotation = 0; float core_aspect = 0; float core_aspect_rot = 0; @@ -1093,6 +1105,8 @@ bool Pass::init_pipeline() reflect_parameter("FinalViewportSize", reflection.semantics[SLANG_SEMANTIC_FINAL_VIEWPORT]); reflect_parameter("FrameCount", reflection.semantics[SLANG_SEMANTIC_FRAME_COUNT]); reflect_parameter("FrameDirection", reflection.semantics[SLANG_SEMANTIC_FRAME_DIRECTION]); + reflect_parameter("FrameTimeDelta", reflection.semantics[SLANG_SEMANTIC_FRAME_TIME_DELTA]); + reflect_parameter("OriginalFPS", reflection.semantics[SLANG_SEMANTIC_ORIGINAL_FPS]); reflect_parameter("Rotation", reflection.semantics[SLANG_SEMANTIC_ROTATION]); reflect_parameter("OriginalAspect", reflection.semantics[SLANG_SEMANTIC_CORE_ASPECT]); reflect_parameter("OriginalAspectRotated", reflection.semantics[SLANG_SEMANTIC_CORE_ASPECT_ROT]); @@ -1560,6 +1574,12 @@ void Pass::build_semantics(uint8_t *buffer, build_semantic_int(buffer, SLANG_SEMANTIC_FRAME_DIRECTION, frame_direction); + build_semantic_uint(buffer, SLANG_SEMANTIC_FRAME_TIME_DELTA, + frame_time_delta); + + build_semantic_float(buffer, SLANG_SEMANTIC_ORIGINAL_FPS, + original_fps); + build_semantic_uint(buffer, SLANG_SEMANTIC_ROTATION, rotation); @@ -1817,6 +1837,8 @@ struct gl3_filter_chain void set_frame_count(uint64_t count); void set_frame_count_period(unsigned pass, unsigned period); void set_frame_direction(int32_t direction); + void set_frame_time_delta(uint32_t rot); + void set_original_fps(float fps); void set_rotation(uint32_t rot); void set_core_aspect(float coreaspect); void set_core_aspect_rot(float coreaspectrot); @@ -2308,6 +2330,20 @@ void gl3_filter_chain::set_frame_direction(int32_t direction) passes[i]->set_frame_direction(direction); } +void gl3_filter_chain::set_frame_time_delta(uint32_t time_delta) +{ + unsigned i; + for (i = 0; i < passes.size(); i++) + passes[i]->set_frame_time_delta(time_delta); +} + +void gl3_filter_chain::set_original_fps(float fps) +{ + unsigned i; + for (i = 0; i < passes.size(); i++) + passes[i]->set_original_fps(fps); +} + void gl3_filter_chain::set_rotation(uint32_t rot) { unsigned i; @@ -2766,6 +2802,20 @@ void gl3_filter_chain_set_frame_direction( chain->set_frame_direction(direction); } +void gl3_filter_chain_set_frame_time_delta( + gl3_filter_chain_t *chain, + uint32_t time_delta) +{ + chain->set_frame_time_delta(time_delta); +} + +void gl3_filter_chain_set_original_fps( + gl3_filter_chain_t *chain, + float fps) +{ + chain->set_original_fps(fps); +} + void gl3_filter_chain_set_rotation( gl3_filter_chain_t *chain, uint32_t rot) diff --git a/gfx/drivers_shader/shader_gl3.h b/gfx/drivers_shader/shader_gl3.h index f3b181b5bef..950e5fe753d 100644 --- a/gfx/drivers_shader/shader_gl3.h +++ b/gfx/drivers_shader/shader_gl3.h @@ -115,6 +115,14 @@ void gl3_filter_chain_set_frame_direction( gl3_filter_chain_t *chain, int32_t direction); +void gl3_filter_chain_set_frame_time_delta( + gl3_filter_chain_t *chain, + uint32_t time_delta); + +void gl3_filter_chain_set_original_fps( + gl3_filter_chain_t *chain, + float fps); + void gl3_filter_chain_set_rotation( gl3_filter_chain_t *chain, uint32_t rotation); diff --git a/gfx/drivers_shader/shader_glsl.c b/gfx/drivers_shader/shader_glsl.c index b35770036b7..8b682416696 100644 --- a/gfx/drivers_shader/shader_glsl.c +++ b/gfx/drivers_shader/shader_glsl.c @@ -98,6 +98,8 @@ struct shader_uniforms int frame_count; int frame_direction; + int frame_time_delta; + float original_fps; /* Use int for maximal compatibility despite other drivers using uint. */ int rotation; @@ -489,7 +491,7 @@ static bool gl_glsl_compile_program( if (!gl_glsl_compile_shader( glsl, program->vprg, - "#define VERTEX\n#define PARAMETER_UNIFORM\n#define _HAS_ORIGINALASPECT_UNIFORMS\n", + "#define VERTEX\n#define PARAMETER_UNIFORM\n#define _HAS_ORIGINALASPECT_UNIFORMS\n#define _HAS_FRAMETIME_UNIFORMS\n", program_info->vertex)) { RARCH_ERR("Failed to compile vertex shader #%u\n", idx); @@ -504,7 +506,7 @@ static bool gl_glsl_compile_program( RARCH_LOG("[GLSL]: Found GLSL fragment shader.\n"); program->fprg = glCreateShader(GL_FRAGMENT_SHADER); if (!gl_glsl_compile_shader(glsl, program->fprg, - "#define FRAGMENT\n#define PARAMETER_UNIFORM\n#define _HAS_ORIGINALASPECT_UNIFORMS\n", + "#define FRAGMENT\n#define PARAMETER_UNIFORM\n#define _HAS_ORIGINALASPECT_UNIFORMS\n#define _HAS_FRAMETIME_UNIFORMS\n", program_info->fragment)) { RARCH_ERR("Failed to compile fragment shader #%u\n", idx); @@ -738,24 +740,28 @@ static void gl_glsl_find_uniforms(glsl_shader_data_t *glsl, glUseProgram(prog); #if defined(VITA) - uni->time = gl_glsl_get_uniform(glsl, prog, "Time"); + uni->time = gl_glsl_get_uniform(glsl, prog, "Time"); #endif - uni->mvp = gl_glsl_get_uniform(glsl, prog, "MVPMatrix"); - uni->tex_coord = gl_glsl_get_attrib(glsl, prog, "TexCoord"); - uni->vertex_coord = gl_glsl_get_attrib(glsl, prog, "VertexCoord"); - uni->color = gl_glsl_get_attrib(glsl, prog, "Color"); - uni->lut_tex_coord = gl_glsl_get_attrib(glsl, prog, "LUTTexCoord"); - - uni->input_size = gl_glsl_get_uniform(glsl, prog, "InputSize"); - uni->output_size = gl_glsl_get_uniform(glsl, prog, "OutputSize"); - uni->texture_size = gl_glsl_get_uniform(glsl, prog, "TextureSize"); - uni->final_vp_size = gl_glsl_get_uniform(glsl, prog, "FinalViewportSize"); - - uni->frame_count = gl_glsl_get_uniform(glsl, prog, "FrameCount"); - uni->frame_direction = gl_glsl_get_uniform(glsl, prog, "FrameDirection"); - uni->rotation = gl_glsl_get_uniform(glsl, prog, "Rotation"); - uni->core_aspect = gl_glsl_get_uniform(glsl, prog, "OriginalAspect"); - uni->core_aspect_rot = gl_glsl_get_uniform(glsl, prog, "OriginalAspectRotated"); + + uni->mvp = gl_glsl_get_uniform(glsl, prog, "MVPMatrix"); + uni->tex_coord = gl_glsl_get_attrib(glsl, prog, "TexCoord"); + uni->vertex_coord = gl_glsl_get_attrib(glsl, prog, "VertexCoord"); + uni->color = gl_glsl_get_attrib(glsl, prog, "Color"); + uni->lut_tex_coord = gl_glsl_get_attrib(glsl, prog, "LUTTexCoord"); + + uni->input_size = gl_glsl_get_uniform(glsl, prog, "InputSize"); + uni->output_size = gl_glsl_get_uniform(glsl, prog, "OutputSize"); + uni->texture_size = gl_glsl_get_uniform(glsl, prog, "TextureSize"); + uni->final_vp_size = gl_glsl_get_uniform(glsl, prog, "FinalViewportSize"); + + uni->frame_count = gl_glsl_get_uniform(glsl, prog, "FrameCount"); + uni->frame_direction = gl_glsl_get_uniform(glsl, prog, "FrameDirection"); + uni->frame_time_delta = gl_glsl_get_uniform(glsl, prog, "FrameTimeDelta"); + uni->original_fps = gl_glsl_get_uniform(glsl, prog, "OriginalFPS"); + uni->rotation = gl_glsl_get_uniform(glsl, prog, "Rotation"); + uni->core_aspect = gl_glsl_get_uniform(glsl, prog, "OriginalAspect"); + uni->core_aspect_rot = gl_glsl_get_uniform(glsl, prog, "OriginalAspectRotAted"); + for (i = 0; i < glsl->shader->luts; i++) uni->lut_texture[i] = glGetUniformLocation(prog, glsl->shader->lut[i].id); @@ -1361,6 +1367,12 @@ static void gl_glsl_set_params(void *dat, void *shader_data) glUniform1i(uni->frame_direction, 1); } + if (uni->frame_time_delta >= 0) + glUniform1i(uni->frame_time_delta, video_driver_get_frame_time_delta_usec()); + + if (uni->original_fps >= 0) + glUniform1f(uni->original_fps, video_driver_get_original_fps()); + if (uni->rotation >= 0) glUniform1i(uni->rotation, retroarch_get_rotation()); diff --git a/gfx/drivers_shader/shader_vulkan.cpp b/gfx/drivers_shader/shader_vulkan.cpp index 4b068c9bdaf..dd19915ce9b 100644 --- a/gfx/drivers_shader/shader_vulkan.cpp +++ b/gfx/drivers_shader/shader_vulkan.cpp @@ -253,6 +253,8 @@ class Pass void set_simulate_scanline(bool simulate) { simulate_scanline = simulate; } #endif /* VULKAN_ROLLING_SCANLINE_SIMULATION */ void set_frame_direction(int32_t dir) { frame_direction = dir; } + void set_frame_time_delta(uint32_t time_delta) { frame_time_delta = time_delta; } + void set_original_fps(float fps) { original_fps = fps; } void set_rotation(uint32_t rot) { rotation = rot; } void set_core_aspect(float coreaspect) { core_aspect = coreaspect; } void set_core_aspect_rot(float coreaspectrot) { core_aspect_rot = coreaspectrot; } @@ -345,6 +347,8 @@ class Pass uint64_t frame_count = 0; int32_t frame_direction = 1; + uint32_t frame_time_delta = 0; + float original_fps = 0; uint32_t rotation = 0; float core_aspect = 0; float core_aspect_rot = 0; @@ -415,6 +419,8 @@ struct vulkan_filter_chain void set_simulate_scanline(bool simulate_scanline); #endif /* VULKAN_ROLLING_SCANLINE_SIMULATION */ void set_frame_direction(int32_t direction); + void set_frame_time_delta(uint32_t time_delta); + void set_original_fps(float fps); void set_rotation(uint32_t rot); void set_core_aspect(float coreaspect); void set_core_aspect_rot(float coreaspect); @@ -1441,6 +1447,20 @@ void vulkan_filter_chain::set_frame_direction(int32_t direction) passes[i]->set_frame_direction(direction); } +void vulkan_filter_chain::set_frame_time_delta(uint32_t time_delta) +{ + unsigned i; + for (i = 0; i < passes.size(); i++) + passes[i]->set_frame_time_delta(time_delta); +} + +void vulkan_filter_chain::set_original_fps(float fps) +{ + unsigned i; + for (i = 0; i < passes.size(); i++) + passes[i]->set_original_fps(fps); +} + void vulkan_filter_chain::set_rotation(uint32_t rot) { unsigned i; @@ -2376,6 +2396,12 @@ void Pass::build_semantics(VkDescriptorSet set, uint8_t *buffer, build_semantic_uint(buffer, SLANG_SEMANTIC_CURRENT_SUBFRAME, current_subframe); + build_semantic_uint(buffer, SLANG_SEMANTIC_FRAME_TIME_DELTA, + frame_time_delta); + + build_semantic_float(buffer, SLANG_SEMANTIC_ORIGINAL_FPS, + original_fps); + build_semantic_uint(buffer, SLANG_SEMANTIC_ROTATION, rotation); @@ -3222,6 +3248,20 @@ void vulkan_filter_chain_set_frame_direction( chain->set_frame_direction(direction); } +void vulkan_filter_chain_set_frame_time_delta( + vulkan_filter_chain_t *chain, + uint32_t time_delta) +{ + chain->set_frame_time_delta(time_delta); +} + +void vulkan_filter_chain_set_original_fps( + vulkan_filter_chain_t *chain, + float fps) +{ + chain->set_original_fps(fps); +} + void vulkan_filter_chain_set_rotation( vulkan_filter_chain_t *chain, uint32_t rot) diff --git a/gfx/drivers_shader/shader_vulkan.h b/gfx/drivers_shader/shader_vulkan.h index 378d184434f..875a93aa3ae 100644 --- a/gfx/drivers_shader/shader_vulkan.h +++ b/gfx/drivers_shader/shader_vulkan.h @@ -136,6 +136,12 @@ void vulkan_filter_chain_set_simulate_scanline(vulkan_filter_chain_t *chain, void vulkan_filter_chain_set_frame_direction(vulkan_filter_chain_t *chain, int32_t direction); +void vulkan_filter_chain_set_frame_time_delta(vulkan_filter_chain_t *chain, + uint32_t time_delta); + +void vulkan_filter_chain_set_original_fps(vulkan_filter_chain_t *chain, + float fps); + void vulkan_filter_chain_set_rotation(vulkan_filter_chain_t *chain, uint32_t rot); diff --git a/gfx/drivers_shader/slang_process.cpp b/gfx/drivers_shader/slang_process.cpp index 28173c25069..6463c6cf01a 100644 --- a/gfx/drivers_shader/slang_process.cpp +++ b/gfx/drivers_shader/slang_process.cpp @@ -156,6 +156,8 @@ static bool slang_process_reflection( "FinalViewportSize", "FrameCount", "FrameDirection", + "FrameTimeDelta", + "OriginalFPS", "Rotation", "OriginalAspect", "OriginalAspectRotated", diff --git a/gfx/drivers_shader/slang_reflection.cpp b/gfx/drivers_shader/slang_reflection.cpp index d0e793380eb..e16879d3d09 100644 --- a/gfx/drivers_shader/slang_reflection.cpp +++ b/gfx/drivers_shader/slang_reflection.cpp @@ -50,6 +50,8 @@ static const char *semantic_uniform_names[] = { "FinalViewportSize", "FrameCount", "FrameDirection", + "FrameTimeDelta", + "OriginalFPS", "Rotation", "OriginalAspect", "OriginalAspectRotated", @@ -268,6 +270,16 @@ static bool validate_type_for_semantic(const spirv_cross::SPIRType &type, slang_ && type.vecsize == 1 && type.columns == 1; /* uint */ + case SLANG_SEMANTIC_FRAME_TIME_DELTA: + return type.basetype == spirv_cross::SPIRType::UInt + && type.vecsize == 1 + && type.columns == 1; + /* uint */ + case SLANG_SEMANTIC_ORIGINAL_FPS: + return type.basetype == spirv_cross::SPIRType::Float + && type.vecsize == 1 + && type.columns == 1; + /* uint */ case SLANG_SEMANTIC_ROTATION: return type.basetype == spirv_cross::SPIRType::UInt && type.vecsize == 1 diff --git a/gfx/drivers_shader/slang_reflection.h b/gfx/drivers_shader/slang_reflection.h index a38abadeb2e..be9d7465d79 100644 --- a/gfx/drivers_shader/slang_reflection.h +++ b/gfx/drivers_shader/slang_reflection.h @@ -70,20 +70,24 @@ enum slang_semantic SLANG_SEMANTIC_FRAME_COUNT = 3, /* int, frame direction */ SLANG_SEMANTIC_FRAME_DIRECTION = 4, + /* uint, FrameTimeDelta */ + SLANG_SEMANTIC_FRAME_TIME_DELTA = 5, + /* uint, OriginalFPS */ + SLANG_SEMANTIC_ORIGINAL_FPS = 6, /* uint, rotation */ - SLANG_SEMANTIC_ROTATION = 5, - /* float, rotation */ - SLANG_SEMANTIC_CORE_ASPECT = 6, - SLANG_SEMANTIC_CORE_ASPECT_ROT = 7, - + SLANG_SEMANTIC_ROTATION = 7, + /* float, OriginalAspect */ + SLANG_SEMANTIC_CORE_ASPECT = 8, + /* float, OriginalAspectRotated */ + SLANG_SEMANTIC_CORE_ASPECT_ROT = 9, /* uint, sub frames per content frame */ - SLANG_SEMANTIC_TOTAL_SUBFRAMES = 8, + SLANG_SEMANTIC_TOTAL_SUBFRAMES = 10, /* uint, current sub frame */ - SLANG_SEMANTIC_CURRENT_SUBFRAME = 9, + SLANG_SEMANTIC_CURRENT_SUBFRAME = 11, SLANG_NUM_BASE_SEMANTICS, /* float, user defined parameter, arrayed */ - SLANG_SEMANTIC_FLOAT_PARAMETER = 10, + SLANG_SEMANTIC_FLOAT_PARAMETER = 12, SLANG_NUM_SEMANTICS, SLANG_INVALID_SEMANTIC = -1 diff --git a/gfx/video_driver.c b/gfx/video_driver.c index 6cdd6d699e7..31595ffb20a 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -1895,6 +1895,29 @@ void video_driver_unset_stub_frame(void) video_st->frame_bak = NULL; } + + +/* Get time diff between frames in usec*/ +uint32_t video_driver_get_frame_time_delta_usec(void) +{ + static retro_time_t last_time; + retro_time_t now_time; + retro_time_t delta_time; + now_time = cpu_features_get_time_usec(); + delta_time = now_time - last_time; + last_time = now_time; + return delta_time; +} + +/* Get Original fps (core fps) */ +float video_driver_get_original_fps(void) +{ + video_driver_state_t *video_st = &video_driver_st; + struct retro_system_av_info *av_info = &video_st->av_info; + float original_fps = (float)video_st->av_info.timing.fps; + return original_fps; +} + /* Get aspect ratio (DAR) requested by the core */ float video_driver_get_core_aspect(void) { diff --git a/gfx/video_driver.h b/gfx/video_driver.h index 2e87a17f2e4..c5d7274ca4f 100644 --- a/gfx/video_driver.h +++ b/gfx/video_driver.h @@ -915,6 +915,10 @@ void video_driver_unset_stub_frame(void); float video_driver_get_core_aspect(void); +uint32_t video_driver_get_frame_time_delta_usec(void); + +float video_driver_get_original_fps(void); + void video_driver_set_viewport_core(void); void video_driver_set_rgba(void);