diff --git a/gfx/common/d3d10_defines.h b/gfx/common/d3d10_defines.h index 833a26e4e5a..c46796cc3f4 100644 --- a/gfx/common/d3d10_defines.h +++ b/gfx/common/d3d10_defines.h @@ -218,6 +218,9 @@ typedef struct uint32_t rotation; uint32_t total_subframes; uint32_t current_subframe; + float core_aspect; + float core_aspect_rot; + } pass[GFX_MAX_SHADERS]; struct video_shader* shader_preset; diff --git a/gfx/common/d3d11_defines.h b/gfx/common/d3d11_defines.h index 98035b21bc0..dccaf8efec3 100644 --- a/gfx/common/d3d11_defines.h +++ b/gfx/common/d3d11_defines.h @@ -294,6 +294,8 @@ typedef struct uint32_t rotation; uint32_t total_subframes; uint32_t current_subframe; + float core_aspect; + float core_aspect_rot; } pass[GFX_MAX_SHADERS]; struct video_shader* shader_preset; diff --git a/gfx/common/d3d12_defines.h b/gfx/common/d3d12_defines.h index df3a2ccf613..5803d9f61e6 100644 --- a/gfx/common/d3d12_defines.h +++ b/gfx/common/d3d12_defines.h @@ -331,6 +331,8 @@ typedef struct uint32_t rotation; uint32_t total_subframes; uint32_t current_subframe; + float core_aspect; + float core_aspect_rot; D3D12_GPU_DESCRIPTOR_HANDLE textures; D3D12_GPU_DESCRIPTOR_HANDLE samplers; } pass[GFX_MAX_SHADERS]; diff --git a/gfx/drivers/d3d10.c b/gfx/drivers/d3d10.c index 8e721c944d9..5eec2d8304e 100644 --- a/gfx/drivers/d3d10.c +++ b/gfx/drivers/d3d10.c @@ -1336,6 +1336,8 @@ static bool d3d10_gfx_set_shader(void* data, &d3d10->pass[i].frame_count, /* FrameCount */ &d3d10->pass[i].frame_direction, /* FrameDirection */ &d3d10->pass[i].rotation, /* Rotation */ + &d3d10->pass[i].core_aspect, /* OriginalAspect */ + &d3d10->pass[i].core_aspect_rot, /* OriginalAspectRotated */ &d3d10->pass[i].total_subframes, /* TotalSubFrames */ &d3d10->pass[i].current_subframe,/* CurrentSubFrame */ } @@ -2331,6 +2333,14 @@ static bool d3d10_gfx_frame( d3d10->pass[i].rotation = retroarch_get_rotation(); + d3d10->pass[i].core_aspect = video_driver_get_core_aspect(); + + /* OriginalAspectRotated: return 1/aspect for 90 and 270 rotated content */ + d3d10->pass[i].core_aspect_rot = video_driver_get_core_aspect(); + uint32_t rot = retroarch_get_rotation(); + if (rot == 1 || rot == 3) + d3d10->pass[i].core_aspect_rot = 1/d3d10->pass[i].core_aspect_rot; + /* Sub-frame info for multiframe shaders (per real content frame). Should always be 1 for non-use of subframes */ if (!(d3d10->flags & D3D10_ST_FLAG_FRAME_DUPE_LOCK)) diff --git a/gfx/drivers/d3d11.c b/gfx/drivers/d3d11.c index 7c335ebbef3..2b41e804779 100644 --- a/gfx/drivers/d3d11.c +++ b/gfx/drivers/d3d11.c @@ -1538,6 +1538,8 @@ static bool d3d11_gfx_set_shader(void* data, enum rarch_shader_type type, const &d3d11->pass[i].frame_count, /* FrameCount */ &d3d11->pass[i].frame_direction, /* FrameDirection */ &d3d11->pass[i].rotation, /* Rotation */ + &d3d11->pass[i].core_aspect, /* OriginalAspect */ + &d3d11->pass[i].core_aspect_rot, /* OriginalAspectRotated */ &d3d11->pass[i].total_subframes, /* TotalSubFrames */ &d3d11->pass[i].current_subframe,/* CurrentSubFrame */ } @@ -3094,6 +3096,14 @@ static bool d3d11_gfx_frame( d3d11->pass[i].rotation = retroarch_get_rotation(); + d3d11->pass[i].core_aspect = video_driver_get_core_aspect(); + + /* OriginalAspectRotated: return 1/aspect for 90 and 270 rotated content */ + d3d11->pass[i].core_aspect_rot = video_driver_get_core_aspect(); + uint32_t rot = retroarch_get_rotation(); + if (rot == 1 || rot == 3) + d3d11->pass[i].core_aspect_rot = 1/d3d11->pass[i].core_aspect_rot; + /* Sub-frame info for multiframe shaders (per real content frame). Should always be 1 for non-use of subframes */ if (!(d3d11->flags & D3D11_ST_FLAG_FRAME_DUPE_LOCK)) diff --git a/gfx/drivers/d3d12.c b/gfx/drivers/d3d12.c index fbad25c4cb5..9661b4a402c 100644 --- a/gfx/drivers/d3d12.c +++ b/gfx/drivers/d3d12.c @@ -1725,6 +1725,8 @@ static bool d3d12_gfx_set_shader(void* data, enum rarch_shader_type type, const &d3d12->pass[i].frame_count, /* FrameCount */ &d3d12->pass[i].frame_direction, /* FrameDirection */ &d3d12->pass[i].rotation, /* Rotation */ + &d3d12->pass[i].core_aspect, /* OriginalAspect */ + &d3d12->pass[i].core_aspect_rot, /* OriginalAspectRotated */ &d3d12->pass[i].total_subframes, /* TotalSubFrames */ &d3d12->pass[i].current_subframe,/* CurrentSubFrame */ } @@ -3595,6 +3597,14 @@ static bool d3d12_gfx_frame( d3d12->pass[i].rotation = retroarch_get_rotation(); + d3d12->pass[i].core_aspect = video_driver_get_core_aspect(); + + /* OriginalAspectRotated: return 1/aspect for 90 and 270 rotated content */ + d3d12->pass[i].core_aspect_rot = video_driver_get_core_aspect(); + uint32_t rot = retroarch_get_rotation(); + if (rot == 1 || rot == 3) + d3d12->pass[i].core_aspect_rot = 1/d3d12->pass[i].core_aspect_rot; + /* Sub-frame info for multiframe shaders (per real content frame). Should always be 1 for non-use of subframes */ if (!(d3d12->flags & D3D12_ST_FLAG_FRAME_DUPE_LOCK)) diff --git a/gfx/drivers/gl3.c b/gfx/drivers/gl3.c index 18684ef1b7e..f4321066feb 100644 --- a/gfx/drivers/gl3.c +++ b/gfx/drivers/gl3.c @@ -2744,6 +2744,15 @@ static bool gl3_frame(void *data, const void *frame, #endif 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()); + + /* OriginalAspectRotated: return 1/aspect for 90 and 270 rotated content */ + uint32_t rot = retroarch_get_rotation(); + float core_aspect_rot = video_driver_get_core_aspect(); + if (rot == 1 || rot == 3) + core_aspect_rot = 1/core_aspect_rot; + gl3_filter_chain_set_core_aspect_rot(gl->filter_chain, core_aspect_rot); + /* Sub-frame info for multiframe shaders (per real content frame). Should always be 1 for non-use of subframes*/ if (!(gl->flags & GL3_FLAG_FRAME_DUPE_LOCK)) diff --git a/gfx/drivers/gx2_gfx.c b/gfx/drivers/gx2_gfx.c index b144532b50e..93f18c282d4 100644 --- a/gfx/drivers/gx2_gfx.c +++ b/gfx/drivers/gx2_gfx.c @@ -1665,7 +1665,7 @@ 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) + uint64_t frame_count, int32_t frame_direction, uint32_t rotation, float core_aspect, float core_aspect_rot) { unsigned i; for (i = 0; i < uniformVarCount; i++) @@ -1723,6 +1723,18 @@ static void gx2_update_uniform_block(wiiu_video_t *wiiu, continue; } + if (string_is_equal(id, "OriginalAspect")) + { + *dst = core_aspect; + continue; + } + + if (string_is_equal(id, "OriginalAspectRotated")) + { + *dst = core_aspect_rot; + continue; + } + if (string_is_equal(id, "OriginalSize")) { ((GX2_vec4 *)dst)->x = wiiu->texture.surface.width; @@ -1940,6 +1952,13 @@ static bool gx2_frame(void *data, const void *frame, #endif uint32_t rotation = retroarch_get_rotation(); + float core_aspect = video_driver_get_core_aspect(); + + /* OriginalAspectRotated: return 1/aspect for 90 and 270 rotated content */ + float core_aspect_rot = core_aspect; + if (rotation == 1 || rotation == 3) + core_aspect_rot = 1/core_aspect; + for (i = 0; i < wiiu->shader_preset->passes; i++) { unsigned j; @@ -1950,7 +1969,7 @@ 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); + frame_count, frame_direction, rotation, core_aspect, core_aspect_rot); GX2SetVertexUniformBlock(wiiu->pass[i].gfd->vs->uniformBlocks[j].offset, wiiu->pass[i].gfd->vs->uniformBlocks[j].size, wiiu->pass[i].vs_ubos[j]); } @@ -1962,7 +1981,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); + frame_count, frame_direction, rotation, core_aspect, core_aspect_rot); 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 25846b5062c..b0ee1e15528 100644 --- a/gfx/drivers/metal.m +++ b/gfx/drivers/metal.m @@ -1206,6 +1206,8 @@ typedef struct MTLALIGN(16) uint32_t frame_count; int32_t frame_direction; uint32_t rotation; + float_t core_aspect; + float_t core_aspect_rot; pass_semantics_t semantics; MTLViewport viewport; __unsafe_unretained id _state; @@ -1579,6 +1581,15 @@ - (void)drawWithContext:(Context *)ctx _engine.pass[i].rotation = retroarch_get_rotation(); + _engine.pass[i].core_aspect = video_driver_get_core_aspect(); + + /* OriginalAspectRotated: return 1/aspect for 90 and 270 rotated content */ + int rot = retroarch_get_rotation(); + float core_aspect_rot = video_driver_get_core_aspect(); + if (rot == 1 || rot == 3) + core_aspect_rot = 1/core_aspect_rot; + _engine.pass[i].core_aspect_rot = core_aspect_rot; + for (j = 0; j < SLANG_CBUFFER_MAX; j++) { id buffer = _engine.pass[i].buffers[j]; @@ -1836,6 +1847,8 @@ - (BOOL)setShaderFromPath:(NSString *)path &_engine.pass[i].frame_count, /* FrameCount */ &_engine.pass[i].frame_direction, /* FrameDirection */ &_engine.pass[i].rotation, /* Rotation */ + &_engine.pass[i].core_aspect, /* OriginalAspect */ + &_engine.pass[i].core_aspect_rot, /* OriginalAspectRotated */ } }; /* clang-format on */ diff --git a/gfx/drivers/vulkan.c b/gfx/drivers/vulkan.c index 76d6d9f7210..77d6a94e927 100644 --- a/gfx/drivers/vulkan.c +++ b/gfx/drivers/vulkan.c @@ -4574,6 +4574,17 @@ static bool vulkan_frame(void *data, const void *frame, vulkan_filter_chain_set_rotation( (vulkan_filter_chain_t*)vk->filter_chain, retroarch_get_rotation()); + vulkan_filter_chain_set_core_aspect( + (vulkan_filter_chain_t*)vk->filter_chain, video_driver_get_core_aspect()); + + /* OriginalAspectRotated: return 1/aspect for 90 and 270 rotated content */ + uint32_t rot = retroarch_get_rotation(); + float core_aspect_rot = video_driver_get_core_aspect(); + if (rot == 1 || rot == 3) + core_aspect_rot = 1/core_aspect_rot; + vulkan_filter_chain_set_core_aspect_rot( + (vulkan_filter_chain_t*)vk->filter_chain, core_aspect_rot); + /* Render offscreen filter chain passes. */ { /* Set the source texture in the filter chain */ diff --git a/gfx/drivers_shader/glslang_util.c b/gfx/drivers_shader/glslang_util.c index 728b05dea9e..159dfcf37e3 100644 --- a/gfx/drivers_shader/glslang_util.c +++ b/gfx/drivers_shader/glslang_util.c @@ -177,17 +177,21 @@ bool glslang_read_shader_file(const char *path, goto error; } + /* Add defines about supported retroarch features */ + if (!string_list_append(output, "#define _HAS_ORIGINALASPECT_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); if (!string_list_append(output, tmp, attr)) goto error; - + /* Loop through lines of file */ for (i = root_file ? 1 : 0; i < lines.size; i++) { const char *line = lines.elems[i].data; - + /* Check for 'include' statements */ bool include_optional = !strncmp("#pragma include_optional ", line, STRLEN_CONST("#pragma include_optional ")); if ( !strncmp("#include ", line, STRLEN_CONST("#include ")) || include_optional ) diff --git a/gfx/drivers_shader/shader_gl3.cpp b/gfx/drivers_shader/shader_gl3.cpp index 2038b66fe21..7ebbed84214 100644 --- a/gfx/drivers_shader/shader_gl3.cpp +++ b/gfx/drivers_shader/shader_gl3.cpp @@ -757,6 +757,16 @@ class Pass rotation = rot; } + void set_core_aspect(float coreaspect) + { + core_aspect = coreaspect; + } + + void set_core_aspect_rot(float coreaspectrot) + { + core_aspect_rot = coreaspectrot; + } + void set_shader_subframes(uint32_t tot_subframes) { total_subframes = tot_subframes; @@ -855,6 +865,8 @@ class Pass slang_semantic semantic, uint32_t value); void build_semantic_int(uint8_t *data, slang_semantic semantic, int32_t value); + void build_semantic_float(uint8_t *data, + slang_semantic semantic, float value); void build_semantic_parameter(uint8_t *data, unsigned index, float value); void build_semantic_texture_vec4(uint8_t *data, slang_texture_semantic semantic, @@ -872,6 +884,8 @@ class Pass unsigned frame_count_period = 0; int32_t frame_direction = 1; uint32_t rotation = 0; + float core_aspect = 0; + float core_aspect_rot = 0; unsigned pass_number = 0; uint32_t total_subframes = 1; uint32_t current_subframe = 1; @@ -1080,6 +1094,8 @@ bool Pass::init_pipeline() reflect_parameter("FrameCount", reflection.semantics[SLANG_SEMANTIC_FRAME_COUNT]); reflect_parameter("FrameDirection", reflection.semantics[SLANG_SEMANTIC_FRAME_DIRECTION]); 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]); reflect_parameter("TotalSubFrames", reflection.semantics[SLANG_SEMANTIC_TOTAL_SUBFRAMES]); reflect_parameter("CurrentSubFrame", reflection.semantics[SLANG_SEMANTIC_CURRENT_SUBFRAME]); @@ -1319,6 +1335,38 @@ void Pass::build_semantic_int(uint8_t *data, slang_semantic semantic, } } +void Pass::build_semantic_float(uint8_t *data, slang_semantic semantic, + float value) +{ + auto &refl = reflection.semantics[semantic]; + + if (data && refl.uniform) + { + if (refl.location.ubo_vertex >= 0 || refl.location.ubo_fragment >= 0) + { + if (refl.location.ubo_vertex >= 0) + glUniform1f(refl.location.ubo_vertex, value); + if (refl.location.ubo_fragment >= 0) + glUniform1f(refl.location.ubo_fragment, value); + } + else + *reinterpret_cast(data + reflection.semantics[semantic].ubo_offset) = value; + } + + if (refl.push_constant) + { + if (refl.location.push_vertex >= 0 || refl.location.push_fragment >= 0) + { + if (refl.location.push_vertex >= 0) + glUniform1f(refl.location.push_vertex, value); + if (refl.location.push_fragment >= 0) + glUniform1f(refl.location.push_fragment, value); + } + else + *reinterpret_cast(push_constant_buffer.data() + refl.push_constant_offset) = value; + } +} + void Pass::build_semantic_texture(uint8_t *buffer, slang_texture_semantic semantic, const Texture &texture) { @@ -1515,6 +1563,12 @@ void Pass::build_semantics(uint8_t *buffer, build_semantic_uint(buffer, SLANG_SEMANTIC_ROTATION, rotation); + build_semantic_float(buffer, SLANG_SEMANTIC_CORE_ASPECT, + core_aspect); + + build_semantic_float(buffer, SLANG_SEMANTIC_CORE_ASPECT_ROT, + core_aspect_rot); + build_semantic_uint(buffer, SLANG_SEMANTIC_TOTAL_SUBFRAMES, total_subframes); build_semantic_uint(buffer, SLANG_SEMANTIC_CURRENT_SUBFRAME, @@ -1764,6 +1818,8 @@ struct gl3_filter_chain void set_frame_count_period(unsigned pass, unsigned period); void set_frame_direction(int32_t direction); void set_rotation(uint32_t rot); + void set_core_aspect(float coreaspect); + void set_core_aspect_rot(float coreaspectrot); void set_shader_subframes(uint32_t tot_subframes); void set_current_shader_subframe(uint32_t cur_subframe); #ifdef GL3_ROLLING_SCANLINE_SIMULATION @@ -2259,6 +2315,21 @@ void gl3_filter_chain::set_rotation(uint32_t rot) passes[i]->set_rotation(rot); } +void gl3_filter_chain::set_core_aspect(float coreaspect) +{ + unsigned i; + for (i = 0; i < passes.size(); i++) + passes[i]->set_core_aspect(coreaspect); +} + +void gl3_filter_chain::set_core_aspect_rot(float coreaspectrot) +{ + unsigned i; + for (i = 0; i < passes.size(); i++) + passes[i]->set_core_aspect_rot(coreaspectrot); +} + + void gl3_filter_chain::set_shader_subframes(uint32_t tot_subframes) { unsigned i; @@ -2702,6 +2773,20 @@ void gl3_filter_chain_set_rotation( chain->set_rotation(rot); } +void gl3_filter_chain_set_core_aspect( + gl3_filter_chain_t *chain, + float coreaspect) +{ + chain->set_core_aspect(coreaspect); +} + +void gl3_filter_chain_set_core_aspect_rot( + gl3_filter_chain_t *chain, + float coreaspectrot) +{ + chain->set_core_aspect_rot(coreaspectrot); +} + void gl3_filter_chain_set_shader_subframes( gl3_filter_chain_t *chain, uint32_t tot_subframes) diff --git a/gfx/drivers_shader/shader_gl3.h b/gfx/drivers_shader/shader_gl3.h index 0e364bda050..f3b181b5bef 100644 --- a/gfx/drivers_shader/shader_gl3.h +++ b/gfx/drivers_shader/shader_gl3.h @@ -56,7 +56,7 @@ struct gl3_filter_chain_pass_info float scale_x; float scale_y; - /* Ignored for the last pass, swapchain info + /* Ignored for the last pass, swapchain info * will be used instead. */ GLenum rt_format; /* For the last pass, make sure VIEWPORT scale @@ -119,6 +119,14 @@ void gl3_filter_chain_set_rotation( gl3_filter_chain_t *chain, uint32_t rotation); +void gl3_filter_chain_set_core_aspect( + gl3_filter_chain_t *chain, + float coreaspect); + +void gl3_filter_chain_set_core_aspect_rot( + gl3_filter_chain_t *chain, + float coreaspectrot); + void gl3_filter_chain_set_shader_subframes( gl3_filter_chain_t *chain, uint32_t tot_subframes); @@ -131,7 +139,7 @@ void gl3_filter_chain_set_current_shader_subframe( void gl3_filter_chain_set_simulate_scanline( gl3_filter_chain_t *chain, bool simulate_scanline); -#endif // GL3_ROLLING_SCANLINE_SIMULATION +#endif // GL3_ROLLING_SCANLINE_SIMULATION void gl3_filter_chain_set_pass_name( gl3_filter_chain_t *chain, diff --git a/gfx/drivers_shader/shader_gl_cg.c b/gfx/drivers_shader/shader_gl_cg.c index 57c54360bf7..e5ce6a33c00 100644 --- a/gfx/drivers_shader/shader_gl_cg.c +++ b/gfx/drivers_shader/shader_gl_cg.c @@ -87,12 +87,16 @@ struct shader_program_cg CGparameter frame_cnt_f; CGparameter frame_dir_f; CGparameter rotation_f; + CGparameter originalaspect_f; + CGparameter originalaspectrotated_f; CGparameter vid_size_v; CGparameter tex_size_v; CGparameter out_size_v; CGparameter frame_cnt_v; CGparameter frame_dir_v; CGparameter rotation_v; + CGparameter originalaspect_v; + CGparameter originalaspectrotated_v; CGparameter mvp; struct cg_fbo_params fbo[GFX_MAX_SHADERS]; @@ -310,7 +314,9 @@ static void gl_cg_set_texture_info( static void gl_cg_set_params(void *dat, void *shader_data) { - unsigned i; + unsigned int i; + int rot; + float originalaspectrotated; video_shader_ctx_params_t *params = (video_shader_ctx_params_t*)dat; unsigned width = params->width; @@ -361,11 +367,22 @@ static void gl_cg_set_params(void *dat, void *shader_data) cg_gl_set_param_1f(cg->prg[cg->active_idx].rotation_f, (float)retroarch_get_rotation()); cg_gl_set_param_1f(cg->prg[cg->active_idx].rotation_v, (float)retroarch_get_rotation()); + cg_gl_set_param_1f(cg->prg[cg->active_idx].originalaspect_f, (float)video_driver_get_core_aspect()); + cg_gl_set_param_1f(cg->prg[cg->active_idx].originalaspect_v, (float)video_driver_get_core_aspect()); + + /* OriginalAspectRotated: return 1/aspect for 90 and 270 rotated content */ + rot = retroarch_get_rotation(); + originalaspectrotated = video_driver_get_core_aspect(); + if (rot == 1 || rot == 3) + originalaspectrotated = 1/originalaspectrotated; + cg_gl_set_param_1f(cg->prg[cg->active_idx].originalaspectrotated_f, (float)originalaspectrotated); + cg_gl_set_param_1f(cg->prg[cg->active_idx].originalaspectrotated_v, (float)originalaspectrotated); + set_param_2f(cg->prg[cg->active_idx].vid_size_v, width, height); set_param_2f(cg->prg[cg->active_idx].tex_size_v, tex_width, tex_height); set_param_2f(cg->prg[cg->active_idx].out_size_v, out_width, out_height); - if ( cg->prg[cg->active_idx].frame_cnt_f || + if ( cg->prg[cg->active_idx].frame_cnt_f || cg->prg[cg->active_idx].frame_cnt_v) { unsigned modulo = cg->shader->pass[cg->active_idx - 1].frame_count_mod; @@ -797,12 +814,16 @@ static void gl_cg_set_program_attributes(void *data, unsigned i) cg->prg[i].frame_cnt_f = cgGetNamedParameter(cg->prg[i].fprg, "IN.frame_count"); cg->prg[i].frame_dir_f = cgGetNamedParameter(cg->prg[i].fprg, "IN.frame_direction"); cg->prg[i].rotation_f = cgGetNamedParameter(cg->prg[i].fprg, "IN.rotation"); + cg->prg[i].originalaspect_f = cgGetNamedParameter(cg->prg[i].fprg, "IN.originalaspect"); + cg->prg[i].originalaspectrotated_f = cgGetNamedParameter(cg->prg[i].fprg, "IN.originalaspectrotated"); cg->prg[i].vid_size_v = cgGetNamedParameter (cg->prg[i].vprg, "IN.video_size"); cg->prg[i].tex_size_v = cgGetNamedParameter (cg->prg[i].vprg, "IN.texture_size"); cg->prg[i].out_size_v = cgGetNamedParameter (cg->prg[i].vprg, "IN.output_size"); cg->prg[i].frame_cnt_v = cgGetNamedParameter(cg->prg[i].vprg, "IN.frame_count"); cg->prg[i].frame_dir_v = cgGetNamedParameter(cg->prg[i].vprg, "IN.frame_direction"); cg->prg[i].rotation_v = cgGetNamedParameter(cg->prg[i].vprg, "IN.rotation"); + cg->prg[i].originalaspect_v = cgGetNamedParameter(cg->prg[i].fprg, "IN.originalaspect"); + cg->prg[i].originalaspectrotated_v = cgGetNamedParameter(cg->prg[i].fprg, "IN.originalaspectrotated"); cg->prg[i].mvp = cgGetNamedParameter(cg->prg[i].vprg, "modelViewProj"); if (!cg->prg[i].mvp) diff --git a/gfx/drivers_shader/shader_glsl.c b/gfx/drivers_shader/shader_glsl.c index 4bc75602262..b35770036b7 100644 --- a/gfx/drivers_shader/shader_glsl.c +++ b/gfx/drivers_shader/shader_glsl.c @@ -101,6 +101,9 @@ struct shader_uniforms /* Use int for maximal compatibility despite other drivers using uint. */ int rotation; + float core_aspect; + float core_aspect_rot; + int lut_texture[GFX_MAX_TEXTURES]; unsigned frame_count_mod; @@ -287,7 +290,7 @@ static const XXH64_hash_t gl_glsl_hash_shader( { XXH64_update(state, source[n], strlen(source[n])); } - + XXH64_hash_t const hash = XXH64_digest(state); XXH64_freeState(state); @@ -417,10 +420,10 @@ static bool gl_glsl_compile_shader(glsl_shader_data_t *glsl, source[2] = glsl->alias_define; source[3] = program; -#if defined(ORBIS) +#if defined(ORBIS) { char save_path[250]; - XXH64_hash_t const hash = + XXH64_hash_t const hash = gl_glsl_hash_shader(source, ARRAY_SIZE(source)); snprintf(save_path, sizeof(save_path), "/data/retroarch/temp/%lx.sb", hash); @@ -468,7 +471,7 @@ static bool gl_glsl_compile_program( struct shader_program_info *program_info) { glsl_shader_data_t *glsl = (glsl_shader_data_t*)data; - struct shader_program_glsl_data *program = + struct shader_program_glsl_data *program = (struct shader_program_glsl_data*)program_data; GLuint prog = glCreateProgram(); @@ -486,7 +489,8 @@ static bool gl_glsl_compile_program( if (!gl_glsl_compile_shader( glsl, program->vprg, - "#define VERTEX\n#define PARAMETER_UNIFORM\n", program_info->vertex)) + "#define VERTEX\n#define PARAMETER_UNIFORM\n#define _HAS_ORIGINALASPECT_UNIFORMS\n", + program_info->vertex)) { RARCH_ERR("Failed to compile vertex shader #%u\n", idx); goto error; @@ -500,7 +504,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 FRAGMENT\n#define PARAMETER_UNIFORM\n#define _HAS_ORIGINALASPECT_UNIFORMS\n", program_info->fragment)) { RARCH_ERR("Failed to compile fragment shader #%u\n", idx); @@ -750,6 +754,8 @@ static void gl_glsl_find_uniforms(glsl_shader_data_t *glsl, 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"); for (i = 0; i < glsl->shader->luts; i++) uni->lut_texture[i] = glGetUniformLocation(prog, glsl->shader->lut[i].id); @@ -1112,7 +1118,7 @@ static void *gl_glsl_init(void *data, const char *path) goto error; } #else - if ( glsl_core + if ( glsl_core && (!(glsl->shader->flags & SHDR_FLAG_MODERN))) { RARCH_ERR("[GL]: GL core context is used, but shader is not core compatible. Cannot use it.\n"); @@ -1358,6 +1364,18 @@ static void gl_glsl_set_params(void *dat, void *shader_data) if (uni->rotation >= 0) glUniform1i(uni->rotation, retroarch_get_rotation()); + if (uni->core_aspect >= 0) + glUniform1f(uni->core_aspect, video_driver_get_core_aspect()); + + if (uni->core_aspect_rot >= 0) { + /* OriginalAspectRotated: return 1/aspect for 90 and 270 rotated content */ + float core_aspect_rot = video_driver_get_core_aspect(); + uint32_t rot = retroarch_get_rotation(); + if (rot == 1 || rot == 3) + core_aspect_rot = 1/core_aspect_rot; + glUniform1f(uni->core_aspect_rot, core_aspect_rot); + } + /* Set lookup textures. */ for (i = 0; i < glsl->shader->luts; i++) { @@ -1545,7 +1563,7 @@ static bool gl_glsl_set_mvp(void *shader_data, const void *mat_data) int loc; glsl_shader_data_t *glsl = (glsl_shader_data_t*)shader_data; - if ( !glsl + if ( !glsl || (!(glsl->shader->flags & SHDR_FLAG_MODERN))) return false; @@ -1589,7 +1607,7 @@ static bool gl_glsl_set_coords(void *shader_data, const struct shader_uniforms *uni = glsl ? &glsl->uniforms[glsl->active_idx] : NULL; - if ( !glsl + if ( !glsl || (!(glsl->shader->flags & SHDR_FLAG_MODERN)) || !coords) { diff --git a/gfx/drivers_shader/shader_vulkan.cpp b/gfx/drivers_shader/shader_vulkan.cpp index 310b78effad..4b068c9bdaf 100644 --- a/gfx/drivers_shader/shader_vulkan.cpp +++ b/gfx/drivers_shader/shader_vulkan.cpp @@ -254,6 +254,8 @@ class Pass #endif /* VULKAN_ROLLING_SCANLINE_SIMULATION */ void set_frame_direction(int32_t dir) { frame_direction = dir; } 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; } void set_name(const char *name) { pass_name = name; } const std::string &get_name() const { return pass_name; } glslang_filter_chain_filter get_source_filter() const { @@ -328,6 +330,7 @@ class Pass unsigned width, unsigned height); void build_semantic_uint(uint8_t *data, slang_semantic semantic, uint32_t value); void build_semantic_int(uint8_t *data, slang_semantic semantic, int32_t value); + void build_semantic_float(uint8_t *data,slang_semantic semantic, float value); void build_semantic_parameter(uint8_t *data, unsigned index, float value); void build_semantic_texture_vec4(uint8_t *data, slang_texture_semantic semantic, @@ -343,6 +346,8 @@ class Pass uint64_t frame_count = 0; int32_t frame_direction = 1; uint32_t rotation = 0; + float core_aspect = 0; + float core_aspect_rot = 0; unsigned frame_count_period = 0; unsigned pass_number = 0; uint32_t total_subframes = 1; @@ -411,6 +416,8 @@ struct vulkan_filter_chain #endif /* VULKAN_ROLLING_SCANLINE_SIMULATION */ void set_frame_direction(int32_t direction); void set_rotation(uint32_t rot); + void set_core_aspect(float coreaspect); + void set_core_aspect_rot(float coreaspect); void set_pass_name(unsigned pass, const char *name); void add_static_texture(std::unique_ptr texture); @@ -1441,6 +1448,21 @@ void vulkan_filter_chain::set_rotation(uint32_t rot) passes[i]->set_rotation(rot); } + +void vulkan_filter_chain::set_core_aspect(float coreaspect) +{ + unsigned i; + for (i = 0; i < passes.size(); i++) + passes[i]->set_core_aspect(coreaspect); +} + +void vulkan_filter_chain::set_core_aspect_rot(float coreaspectrot) +{ + unsigned i; + for (i = 0; i < passes.size(); i++) + passes[i]->set_core_aspect_rot(coreaspectrot); +} + void vulkan_filter_chain::set_pass_name(unsigned pass, const char *name) { passes[pass]->set_name(name); @@ -2279,6 +2301,19 @@ void Pass::build_semantic_int(uint8_t *data, slang_semantic semantic, *reinterpret_cast(push.buffer.data() + (refl.push_constant_offset >> 2)) = value; } +void Pass::build_semantic_float(uint8_t *data, slang_semantic semantic, + float value) +{ + auto &refl = reflection.semantics[semantic]; + + if (data && refl.uniform) + *reinterpret_cast(data + reflection.semantics[semantic].ubo_offset) = value; + + if (refl.push_constant) + *reinterpret_cast(push.buffer.data() + (refl.push_constant_offset >> 2)) = value; +} + + void Pass::build_semantic_texture(VkDescriptorSet set, uint8_t *buffer, slang_texture_semantic semantic, const Texture &texture) { @@ -2344,6 +2379,12 @@ void Pass::build_semantics(VkDescriptorSet set, uint8_t *buffer, build_semantic_uint(buffer, SLANG_SEMANTIC_ROTATION, rotation); + build_semantic_float(buffer, SLANG_SEMANTIC_CORE_ASPECT, + core_aspect); + + build_semantic_float(buffer, SLANG_SEMANTIC_CORE_ASPECT_ROT, + core_aspect_rot); + /* Standard inputs */ build_semantic_texture(set, buffer, SLANG_TEXTURE_SEMANTIC_ORIGINAL, original); build_semantic_texture(set, buffer, SLANG_TEXTURE_SEMANTIC_SOURCE, source); @@ -3188,6 +3229,20 @@ void vulkan_filter_chain_set_rotation( chain->set_rotation(rot); } +void vulkan_filter_chain_set_core_aspect( + vulkan_filter_chain_t *chain, + float coreaspect) +{ + chain->set_core_aspect(coreaspect); +} + +void vulkan_filter_chain_set_core_aspect_rot( + vulkan_filter_chain_t *chain, + float coreaspectrot) +{ + chain->set_core_aspect_rot(coreaspectrot); +} + void vulkan_filter_chain_set_pass_name( vulkan_filter_chain_t *chain, unsigned pass, diff --git a/gfx/drivers_shader/shader_vulkan.h b/gfx/drivers_shader/shader_vulkan.h index 04725e3df53..378d184434f 100644 --- a/gfx/drivers_shader/shader_vulkan.h +++ b/gfx/drivers_shader/shader_vulkan.h @@ -51,7 +51,7 @@ struct vulkan_filter_chain_pass_info float scale_x; float scale_y; - /* Ignored for the last pass, swapchain info + /* Ignored for the last pass, swapchain info * will be used instead. */ VkFormat rt_format; /* For the last pass, make sure VIEWPORT scale @@ -102,7 +102,7 @@ void vulkan_filter_chain_set_shader(vulkan_filter_chain_t *chain, VkFormat vulkan_filter_chain_get_pass_rt_format( vulkan_filter_chain_t *chain, - unsigned pass); + unsigned pass); bool vulkan_filter_chain_update_swapchain_info(vulkan_filter_chain_t *chain, const struct vulkan_filter_chain_swapchain_info *info); @@ -139,6 +139,12 @@ void vulkan_filter_chain_set_frame_direction(vulkan_filter_chain_t *chain, void vulkan_filter_chain_set_rotation(vulkan_filter_chain_t *chain, uint32_t rot); +void vulkan_filter_chain_set_core_aspect(vulkan_filter_chain_t *chain, + float coreaspect); + +void vulkan_filter_chain_set_core_aspect_rot(vulkan_filter_chain_t *chain, + float coreaspectrot); + void vulkan_filter_chain_build_offscreen_passes(vulkan_filter_chain_t *chain, VkCommandBuffer cmd, const VkViewport *vp); void vulkan_filter_chain_build_viewport_pass(vulkan_filter_chain_t *chain, diff --git a/gfx/drivers_shader/slang_process.cpp b/gfx/drivers_shader/slang_process.cpp index 9318cd90031..28173c25069 100644 --- a/gfx/drivers_shader/slang_process.cpp +++ b/gfx/drivers_shader/slang_process.cpp @@ -157,6 +157,8 @@ static bool slang_process_reflection( "FrameCount", "FrameDirection", "Rotation", + "OriginalAspect", + "OriginalAspectRotated", "TotalSubFrames", "CurrentSubFrame", }; diff --git a/gfx/drivers_shader/slang_reflection.cpp b/gfx/drivers_shader/slang_reflection.cpp index b762830ad05..d0e793380eb 100644 --- a/gfx/drivers_shader/slang_reflection.cpp +++ b/gfx/drivers_shader/slang_reflection.cpp @@ -51,6 +51,8 @@ static const char *semantic_uniform_names[] = { "FrameCount", "FrameDirection", "Rotation", + "OriginalAspect", + "OriginalAspectRotated", "TotalSubFrames", "CurrentSubFrame", }; @@ -270,6 +272,14 @@ static bool validate_type_for_semantic(const spirv_cross::SPIRType &type, slang_ return type.basetype == spirv_cross::SPIRType::UInt && type.vecsize == 1 && type.columns == 1; + case SLANG_SEMANTIC_CORE_ASPECT: + return type.basetype == spirv_cross::SPIRType::Float + && type.vecsize == 1 + && type.columns == 1; + case SLANG_SEMANTIC_CORE_ASPECT_ROT: + return type.basetype == spirv_cross::SPIRType::Float + && type.vecsize == 1 + && type.columns == 1; /* float */ case SLANG_SEMANTIC_FLOAT_PARAMETER: return type.basetype == spirv_cross::SPIRType::Float diff --git a/gfx/drivers_shader/slang_reflection.h b/gfx/drivers_shader/slang_reflection.h index e3a455017d4..a38abadeb2e 100644 --- a/gfx/drivers_shader/slang_reflection.h +++ b/gfx/drivers_shader/slang_reflection.h @@ -72,14 +72,18 @@ enum slang_semantic SLANG_SEMANTIC_FRAME_DIRECTION = 4, /* uint, rotation */ SLANG_SEMANTIC_ROTATION = 5, + /* float, rotation */ + SLANG_SEMANTIC_CORE_ASPECT = 6, + SLANG_SEMANTIC_CORE_ASPECT_ROT = 7, + /* uint, sub frames per content frame */ - SLANG_SEMANTIC_TOTAL_SUBFRAMES = 6, + SLANG_SEMANTIC_TOTAL_SUBFRAMES = 8, /* uint, current sub frame */ - SLANG_SEMANTIC_CURRENT_SUBFRAME = 7, + SLANG_SEMANTIC_CURRENT_SUBFRAME = 9, SLANG_NUM_BASE_SEMANTICS, /* float, user defined parameter, arrayed */ - SLANG_SEMANTIC_FLOAT_PARAMETER = 8, + SLANG_SEMANTIC_FLOAT_PARAMETER = 10, SLANG_NUM_SEMANTICS, SLANG_INVALID_SEMANTIC = -1 diff --git a/tools/cg2glsl.py b/tools/cg2glsl.py index f2ff0258575..283ed061416 100755 --- a/tools/cg2glsl.py +++ b/tools/cg2glsl.py @@ -50,6 +50,8 @@ def replace_global_in(source): ('IN.frame_count', 'FrameCount'), ('IN.frame_direction', 'FrameDirection'), ('IN.rotation', 'Rotation'), + ('IN.core_aspect', 'OriginalAspect'), + ('IN.core_aspect_rot', 'OriginalAspectRotated'), ] for line in source.splitlines(): @@ -109,6 +111,8 @@ def no_uniform(elem): '_frame_count', '_frame_direction', '_rotation', + '_core_aspect', + '_core_aspect_rot', '_mvp_matrix', '_vertex_coord', 'sampler2D'