diff --git a/gfx/common/d3d10_common.h b/gfx/common/d3d10_common.h index 9ba5923b28..5411b22861 100644 --- a/gfx/common/d3d10_common.h +++ b/gfx/common/d3d10_common.h @@ -212,6 +212,7 @@ typedef struct pass_semantics_t semantics; uint32_t frame_count; int32_t frame_direction; + uint32_t rotation; } pass[GFX_MAX_SHADERS]; struct video_shader* shader_preset; diff --git a/gfx/common/d3d11_common.h b/gfx/common/d3d11_common.h index 29684a6a65..5c9d41be45 100644 --- a/gfx/common/d3d11_common.h +++ b/gfx/common/d3d11_common.h @@ -290,6 +290,7 @@ typedef struct pass_semantics_t semantics; uint32_t frame_count; int32_t frame_direction; + uint32_t rotation; } pass[GFX_MAX_SHADERS]; struct video_shader* shader_preset; diff --git a/gfx/common/d3d12_common.h b/gfx/common/d3d12_common.h index 84e34f82a0..8cb03070bb 100644 --- a/gfx/common/d3d12_common.h +++ b/gfx/common/d3d12_common.h @@ -302,6 +302,7 @@ typedef struct pass_semantics_t semantics; uint32_t frame_count; int32_t frame_direction; + uint32_t rotation; 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 c76b0dd25d..a82bc1d55c 100644 --- a/gfx/drivers/d3d10.c +++ b/gfx/drivers/d3d10.c @@ -456,6 +456,7 @@ static bool d3d10_gfx_set_shader(void* data, enum rarch_shader_type type, const &d3d10->frame.output_size, /* FinalViewportSize */ &d3d10->pass[i].frame_count, /* FrameCount */ &d3d10->pass[i].frame_direction, /* FrameDirection */ + &d3d10->pass[i].rotation, /* Rotation */ } }; /* clang-format on */ @@ -1429,6 +1430,8 @@ static bool d3d10_gfx_frame( d3d10->pass[i].frame_direction = 1; #endif + d3d10->pass[i].rotation = retroarch_get_rotation(); + for (j = 0; j < SLANG_CBUFFER_MAX; j++) { D3D10Buffer buffer = d3d10->pass[i].buffers[j]; diff --git a/gfx/drivers/d3d11.c b/gfx/drivers/d3d11.c index 6d4c97a906..74a56d6bb8 100644 --- a/gfx/drivers/d3d11.c +++ b/gfx/drivers/d3d11.c @@ -629,6 +629,7 @@ 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].rotation, /* Rotation */ } }; /* clang-format on */ @@ -2156,6 +2157,8 @@ static bool d3d11_gfx_frame( d3d11->pass[i].frame_direction = 1; #endif + d3d11->pass[i].rotation = retroarch_get_rotation(); + for (j = 0; j < SLANG_CBUFFER_MAX; j++) { D3D11Buffer buffer = d3d11->pass[i].buffers[j]; diff --git a/gfx/drivers/d3d12.c b/gfx/drivers/d3d12.c index 78fcd56375..06ae24cb21 100644 --- a/gfx/drivers/d3d12.c +++ b/gfx/drivers/d3d12.c @@ -688,6 +688,7 @@ 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].rotation, /* Rotation */ } }; /* clang-format on */ @@ -2430,6 +2431,8 @@ static bool d3d12_gfx_frame( #endif d3d12->pass[i].frame_direction = 1; + d3d12->pass[i].rotation = retroarch_get_rotation(); + for (j = 0; j < SLANG_CBUFFER_MAX; j++) { cbuffer_sem_t* buffer_sem = &d3d12->pass[i].semantics.cbuffers[j]; diff --git a/gfx/drivers/gl3.c b/gfx/drivers/gl3.c index a37b8be5e5..33507276c4 100644 --- a/gfx/drivers/gl3.c +++ b/gfx/drivers/gl3.c @@ -1785,6 +1785,7 @@ 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_rotation(gl->filter_chain, retroarch_get_rotation()); gl3_filter_chain_set_input_texture(gl->filter_chain, &texture); gl3_filter_chain_build_offscreen_passes(gl->filter_chain, &gl->filter_chain_vp); diff --git a/gfx/drivers/gx2_gfx.c b/gfx/drivers/gx2_gfx.c index f4a530555a..3a97bcc352 100644 --- a/gfx/drivers/gx2_gfx.c +++ b/gfx/drivers/gx2_gfx.c @@ -927,7 +927,7 @@ static bool wiiu_init_frame_textures(wiiu_video_t *wiiu, unsigned width, unsigne static void wiiu_gfx_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) + uint64_t frame_count, int32_t frame_direction, uint32_t rotation) { unsigned i; for (i = 0; i < uniformVarCount; i++) @@ -978,6 +978,13 @@ static void wiiu_gfx_update_uniform_block(wiiu_video_t *wiiu, continue; } + if (string_is_equal(id, "Rotation")) + { + *dst = rotation; + *(u32 *)dst = __builtin_bswap32(*(u32 *)dst); + continue; + } + if (string_is_equal(id, "OriginalSize")) { ((GX2_vec4 *)dst)->x = wiiu->texture.surface.width; @@ -1193,6 +1200,7 @@ static bool wiiu_gfx_frame(void *data, const void *frame, #else int32_t frame_direction = 1; #endif + uint32_t rotation = retroarch_get_rotation(); for (i = 0; i < wiiu->shader_preset->passes; i++) { @@ -1204,7 +1212,7 @@ static bool wiiu_gfx_frame(void *data, const void *frame, wiiu_gfx_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); + frame_count, frame_direction, rotation); GX2SetVertexUniformBlock(wiiu->pass[i].gfd->vs->uniformBlocks[j].offset, wiiu->pass[i].gfd->vs->uniformBlocks[j].size, wiiu->pass[i].vs_ubos[j]); } @@ -1216,7 +1224,7 @@ static bool wiiu_gfx_frame(void *data, const void *frame, wiiu_gfx_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); + frame_count, frame_direction, rotation); 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 d63c7fff5c..5589e716e1 100644 --- a/gfx/drivers/metal.m +++ b/gfx/drivers/metal.m @@ -577,6 +577,7 @@ typedef struct MTLALIGN(16) texture_t feedback; uint32_t frame_count; int32_t frame_direction; + uint32_t rotation; pass_semantics_t semantics; MTLViewport viewport; __unsafe_unretained id _state; @@ -948,6 +949,8 @@ typedef struct MTLALIGN(16) _engine.pass[i].frame_direction = 1; #endif + _engine.pass[i].rotation = retroarch_get_rotation(); + for (j = 0; j < SLANG_CBUFFER_MAX; j++) { id buffer = _engine.pass[i].buffers[j]; @@ -1204,6 +1207,7 @@ typedef struct MTLALIGN(16) &_engine.frame.output_size, /* FinalViewportSize */ &_engine.pass[i].frame_count, /* FrameCount */ &_engine.pass[i].frame_direction, /* FrameDirection */ + &_engine.pass[i].rotation, /* Rotation */ } }; /* clang-format on */ diff --git a/gfx/drivers/vulkan.c b/gfx/drivers/vulkan.c index f226443fe5..d04a24172c 100644 --- a/gfx/drivers/vulkan.c +++ b/gfx/drivers/vulkan.c @@ -2391,6 +2391,8 @@ static bool vulkan_frame(void *data, const void *frame, (vulkan_filter_chain_t*)vk->filter_chain, 1); #endif + vulkan_filter_chain_set_rotation( + (vulkan_filter_chain_t*)vk->filter_chain, retroarch_get_rotation()); /* Render offscreen filter chain passes. */ { diff --git a/gfx/drivers_shader/shader_gl3.cpp b/gfx/drivers_shader/shader_gl3.cpp index 6178e5b37b..2675483cc3 100644 --- a/gfx/drivers_shader/shader_gl3.cpp +++ b/gfx/drivers_shader/shader_gl3.cpp @@ -920,6 +920,11 @@ public: frame_direction = direction; } + void set_rotation(uint32_t rot) + { + rotation = rot; + } + void set_name(const char *name) { pass_name = name; @@ -1017,6 +1022,7 @@ private: uint64_t frame_count = 0; unsigned frame_count_period = 0; int32_t frame_direction = 1; + uint32_t rotation = 0; unsigned pass_number = 0; size_t ubo_offset = 0; @@ -1214,6 +1220,7 @@ 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("Rotation", reflection.semantics[SLANG_SEMANTIC_ROTATION]); reflect_parameter("OriginalSize", reflection.semantic_textures[SLANG_TEXTURE_SEMANTIC_ORIGINAL][0]); reflect_parameter("SourceSize", reflection.semantic_textures[SLANG_TEXTURE_SEMANTIC_SOURCE][0]); @@ -1644,6 +1651,9 @@ void Pass::build_semantics(uint8_t *buffer, build_semantic_int(buffer, SLANG_SEMANTIC_FRAME_DIRECTION, frame_direction); + build_semantic_uint(buffer, SLANG_SEMANTIC_ROTATION, + rotation); + /* Standard inputs */ build_semantic_texture(buffer, SLANG_TEXTURE_SEMANTIC_ORIGINAL, original); build_semantic_texture(buffer, SLANG_TEXTURE_SEMANTIC_SOURCE, source); @@ -1838,6 +1848,7 @@ public: 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_rotation(uint32_t rot); void set_pass_name(unsigned pass, const char *name); void add_static_texture(std::unique_ptr texture); @@ -2320,6 +2331,13 @@ void gl3_filter_chain::set_frame_direction(int32_t direction) passes[i]->set_frame_direction(direction); } +void gl3_filter_chain::set_rotation(uint32_t rot) +{ + unsigned i; + for (i = 0; i < passes.size(); i++) + passes[i]->set_rotation(rot); +} + void gl3_filter_chain::set_pass_name(unsigned pass, const char *name) { passes[pass]->set_name(name); @@ -2733,6 +2751,13 @@ void gl3_filter_chain_set_frame_direction( chain->set_frame_direction(direction); } +void gl3_filter_chain_set_rotation( + gl3_filter_chain_t *chain, + uint32_t rot) +{ + chain->set_rotation(rot); +} + void gl3_filter_chain_set_frame_count_period( gl3_filter_chain_t *chain, unsigned pass, diff --git a/gfx/drivers_shader/shader_gl3.h b/gfx/drivers_shader/shader_gl3.h index 011058d6b6..87fed30247 100644 --- a/gfx/drivers_shader/shader_gl3.h +++ b/gfx/drivers_shader/shader_gl3.h @@ -113,6 +113,10 @@ void gl3_filter_chain_set_frame_direction( gl3_filter_chain_t *chain, int32_t direction); +void gl3_filter_chain_set_rotation( + gl3_filter_chain_t *chain, + uint32_t rotation); + void gl3_filter_chain_set_pass_name( gl3_filter_chain_t *chain, unsigned pass, diff --git a/gfx/drivers_shader/shader_gl_cg.c b/gfx/drivers_shader/shader_gl_cg.c index 18386a9e5c..4ffb998500 100644 --- a/gfx/drivers_shader/shader_gl_cg.c +++ b/gfx/drivers_shader/shader_gl_cg.c @@ -86,11 +86,13 @@ struct shader_program_cg CGparameter out_size_f; CGparameter frame_cnt_f; CGparameter frame_dir_f; + CGparameter rotation_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 mvp; struct cg_fbo_params fbo[GFX_MAX_SHADERS]; @@ -353,6 +355,8 @@ static void gl_cg_set_params(void *dat, void *shader_data) 1.0); } #endif + 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()); 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); @@ -790,11 +794,13 @@ static void gl_cg_set_program_attributes(void *data, unsigned i) cg->prg[i].out_size_f = cgGetNamedParameter (cg->prg[i].fprg, "IN.output_size"); 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].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].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 d16244156c..0e30aa441f 100644 --- a/gfx/drivers_shader/shader_glsl.c +++ b/gfx/drivers_shader/shader_glsl.c @@ -97,6 +97,7 @@ struct shader_uniforms int frame_count; int frame_direction; + unsigned rotation; int lut_texture[GFX_MAX_TEXTURES]; unsigned frame_count_mod; @@ -731,6 +732,7 @@ 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"); for (i = 0; i < glsl->shader->luts; i++) uni->lut_texture[i] = glGetUniformLocation(prog, glsl->shader->lut[i].id); @@ -1328,6 +1330,9 @@ static void gl_glsl_set_params(void *dat, void *shader_data) glUniform1i(uni->frame_direction, 1); } + if (uni->rotation >= 0) + glUniform1i(uni->rotation, retroarch_get_rotation()); + /* Set lookup textures. */ for (i = 0; i < glsl->shader->luts; i++) { diff --git a/gfx/drivers_shader/shader_vulkan.cpp b/gfx/drivers_shader/shader_vulkan.cpp index e2fadfc2a7..31d2e1e07c 100644 --- a/gfx/drivers_shader/shader_vulkan.cpp +++ b/gfx/drivers_shader/shader_vulkan.cpp @@ -532,6 +532,7 @@ class Pass void set_frame_count(uint64_t count) { frame_count = count; } void set_frame_count_period(unsigned p) { frame_count_period = p; } void set_frame_direction(int32_t dir) { frame_direction = dir; } + void set_rotation(uint32_t rot) { rotation = rot; } 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 { @@ -617,6 +618,7 @@ class Pass uint64_t frame_count = 0; int32_t frame_direction = 1; + uint32_t rotation = 0; unsigned frame_count_period = 0; unsigned pass_number = 0; @@ -677,6 +679,7 @@ struct vulkan_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_rotation(uint32_t rot); void set_pass_name(unsigned pass, const char *name); void add_static_texture(std::unique_ptr texture); @@ -1651,6 +1654,13 @@ void vulkan_filter_chain::set_frame_direction(int32_t direction) passes[i]->set_frame_direction(direction); } +void vulkan_filter_chain::set_rotation(uint32_t rot) +{ + unsigned i; + for (i = 0; i < passes.size(); i++) + passes[i]->set_rotation(rot); +} + void vulkan_filter_chain::set_pass_name(unsigned pass, const char *name) { passes[pass]->set_name(name); @@ -2483,6 +2493,9 @@ void Pass::build_semantics(VkDescriptorSet set, uint8_t *buffer, build_semantic_int(buffer, SLANG_SEMANTIC_FRAME_DIRECTION, frame_direction); + build_semantic_uint(buffer, SLANG_SEMANTIC_ROTATION, + rotation); + /* Standard inputs */ build_semantic_texture(set, buffer, SLANG_TEXTURE_SEMANTIC_ORIGINAL, original); build_semantic_texture(set, buffer, SLANG_TEXTURE_SEMANTIC_SOURCE, source); @@ -3246,6 +3259,13 @@ void vulkan_filter_chain_set_frame_direction( chain->set_frame_direction(direction); } +void vulkan_filter_chain_set_rotation( + vulkan_filter_chain_t *chain, + uint32_t rot) +{ + chain->set_rotation(rot); +} + 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 1b449d0393..d227f6037a 100644 --- a/gfx/drivers_shader/shader_vulkan.h +++ b/gfx/drivers_shader/shader_vulkan.h @@ -123,6 +123,9 @@ void vulkan_filter_chain_set_frame_count_period(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_rotation(vulkan_filter_chain_t *chain, + uint32_t rot); + 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 c491d87122..1d4a4da59a 100644 --- a/gfx/drivers_shader/slang_process.cpp +++ b/gfx/drivers_shader/slang_process.cpp @@ -160,6 +160,7 @@ static bool slang_process_reflection( "FinalViewportSize", "FrameCount", "FrameDirection", + "Rotation", }; int size = sizeof(names) / sizeof(*names); if (semantic < size) diff --git a/gfx/drivers_shader/slang_reflection.cpp b/gfx/drivers_shader/slang_reflection.cpp index 70ce526ebc..e26f867487 100644 --- a/gfx/drivers_shader/slang_reflection.cpp +++ b/gfx/drivers_shader/slang_reflection.cpp @@ -52,6 +52,7 @@ static const char *semantic_uniform_names[] = { "FinalViewportSize", "FrameCount", "FrameDirection", + "Rotation", }; static slang_texture_semantic slang_name_to_texture_semantic( @@ -245,6 +246,9 @@ static bool validate_type_for_semantic(const SPIRType &type, slang_semantic sem) /* int */ case SLANG_SEMANTIC_FRAME_DIRECTION: return type.basetype == SPIRType::Int && type.vecsize == 1 && type.columns == 1; + /* uint */ + case SLANG_SEMANTIC_ROTATION: + return type.basetype == SPIRType::UInt && type.vecsize == 1 && type.columns == 1; /* float */ case SLANG_SEMANTIC_FLOAT_PARAMETER: return type.basetype == SPIRType::Float && type.vecsize == 1 && type.columns == 1; diff --git a/gfx/drivers_shader/slang_reflection.h b/gfx/drivers_shader/slang_reflection.h index a814da743f..40991e6d15 100644 --- a/gfx/drivers_shader/slang_reflection.h +++ b/gfx/drivers_shader/slang_reflection.h @@ -70,10 +70,12 @@ enum slang_semantic SLANG_SEMANTIC_FRAME_COUNT = 3, /* int, frame direction */ SLANG_SEMANTIC_FRAME_DIRECTION = 4, + /* uint, rotation */ + SLANG_SEMANTIC_ROTATION = 5, SLANG_NUM_BASE_SEMANTICS, /* float, user defined parameter, arrayed */ - SLANG_SEMANTIC_FLOAT_PARAMETER = 5, + SLANG_SEMANTIC_FLOAT_PARAMETER = 6, SLANG_NUM_SEMANTICS, SLANG_INVALID_SEMANTIC = -1 diff --git a/tools/cg2glsl.py b/tools/cg2glsl.py index c22315a064..f2ff025857 100755 --- a/tools/cg2glsl.py +++ b/tools/cg2glsl.py @@ -49,6 +49,7 @@ def replace_global_in(source): ('IN.output_size', 'OutputSize'), ('IN.frame_count', 'FrameCount'), ('IN.frame_direction', 'FrameDirection'), + ('IN.rotation', 'Rotation'), ] for line in source.splitlines(): @@ -107,6 +108,7 @@ def no_uniform(elem): '_output_dummy_size', '_frame_count', '_frame_direction', + '_rotation', '_mvp_matrix', '_vertex_coord', 'sampler2D'