2013-04-06 09:30:56 +00:00
/* RetroArch - A frontend for libretro.
2014-01-01 00:50:59 +00:00
* Copyright ( C ) 2010 - 2014 - Hans - Kristian Arntzen
2017-01-22 12:40:32 +00:00
* Copyright ( C ) 2011 - 2017 - Daniel De Matteis
2013-04-06 09:30:56 +00:00
*
* RetroArch is free software : you can redistribute it and / or modify it under the terms
* of the GNU General Public License as published by the Free Software Found -
* ation , either version 3 of the License , or ( at your option ) any later version .
*
* RetroArch is distributed in the hope that it will be useful , but WITHOUT ANY WARRANTY ;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE . See the GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License along with RetroArch .
* If not , see < http : //www.gnu.org/licenses/>.
*/
2014-06-17 18:42:38 +00:00
# include <stdlib.h>
# include <string.h>
2015-10-31 19:53:08 +00:00
2014-10-21 05:58:58 +00:00
# include <compat/posix_string.h>
# include <compat/msvc.h>
# include <compat/strl.h>
2014-10-21 22:23:06 +00:00
# include <file/file_path.h>
2015-06-14 17:02:53 +00:00
# include <rhash.h>
2016-01-20 03:07:24 +00:00
# include <string/stdstring.h>
2016-06-02 22:11:41 +00:00
# include <streams/file_stream.h>
2015-06-14 17:02:53 +00:00
2016-06-20 20:17:03 +00:00
# include "../msg_hash.h"
2015-11-23 11:03:38 +00:00
# include "../verbosity.h"
2015-06-14 17:02:53 +00:00
# include "video_shader_parse.h"
2013-04-06 09:30:56 +00:00
2016-12-20 14:50:50 +00:00
# ifdef HAVE_SLANG
# include "drivers_shader/slang_preprocess.h"
# endif
2015-12-26 10:27:52 +00:00
# define WRAP_MODE_CLAMP_TO_BORDER 0x3676ed11U
# define WRAP_MODE_CLAMP_TO_EDGE 0x9427a608U
# define WRAP_MODE_REPEAT 0x192dec66U
# define WRAP_MODE_MIRRORED_REPEAT 0x117ac9a9U
# define SCALE_TYPE_SOURCE 0x1c3aff76U
# define SCALE_TYPE_VIEWPORT 0xe8f01225U
# define SCALE_TYPE_ABSOLUTE 0x8cc74f64U
# define SEMANTIC_CAPTURE 0xb2f5d639U
# define SEMANTIC_CAPTURE_PREVIOUS 0x64d6d495U
# define SEMANTIC_TRANSITION 0x96486f70U
# define SEMANTIC_TRANSITION_PREVIOUS 0x536abbacU
# define SEMANTIC_TRANSITION_COUNT 0x3ef2af78U
# define SEMANTIC_PYTHON 0x15efc547U
2015-01-11 18:59:59 +00:00
/**
* wrap_mode_to_str :
* @ type : Wrap type .
*
* Translates wrap mode to human - readable string identifier .
*
* Returns : human - readable string identifier of wrap mode .
* */
2013-08-15 22:30:54 +00:00
static const char * wrap_mode_to_str ( enum gfx_wrap_type type )
{
switch ( type )
{
case RARCH_WRAP_BORDER :
return " clamp_to_border " ;
case RARCH_WRAP_EDGE :
return " clamp_to_edge " ;
case RARCH_WRAP_REPEAT :
return " repeat " ;
case RARCH_WRAP_MIRRORED_REPEAT :
return " mirrored_repeat " ;
default :
2015-10-11 07:31:04 +00:00
break ;
2013-08-15 22:30:54 +00:00
}
2015-10-11 07:31:04 +00:00
return " ??? " ;
2013-08-15 22:30:54 +00:00
}
2015-01-11 18:59:59 +00:00
/**
* wrap_str_to_mode :
* @ type : Wrap type in human - readable string format .
*
* Translates wrap mode from human - readable string to enum mode value .
*
* Returns : enum mode value of wrap type .
* */
2013-08-15 22:30:54 +00:00
static enum gfx_wrap_type wrap_str_to_mode ( const char * wrap_mode )
{
2015-06-14 17:02:53 +00:00
uint32_t wrap_mode_hash = djb2_calculate ( wrap_mode ) ;
switch ( wrap_mode_hash )
{
case WRAP_MODE_CLAMP_TO_BORDER :
return RARCH_WRAP_BORDER ;
case WRAP_MODE_CLAMP_TO_EDGE :
return RARCH_WRAP_EDGE ;
case WRAP_MODE_REPEAT :
return RARCH_WRAP_REPEAT ;
case WRAP_MODE_MIRRORED_REPEAT :
return RARCH_WRAP_MIRRORED_REPEAT ;
}
2014-09-05 19:06:41 +00:00
RARCH_WARN ( " Invalid wrapping type %s. Valid ones are: clamp_to_border (default), clamp_to_edge, repeat and mirrored_repeat. Falling back to default. \n " ,
wrap_mode ) ;
return RARCH_WRAP_DEFAULT ;
2013-08-15 22:30:54 +00:00
}
2015-01-11 18:59:59 +00:00
/**
2015-01-19 20:09:39 +00:00
* video_shader_parse_pass :
2015-01-11 18:59:59 +00:00
* @ conf : Preset file to read from .
* @ pass : Shader passes handle .
* @ i : Index of shader pass .
*
* Parses shader pass from preset file .
*
* Returns : true ( 1 ) if successful , otherwise false ( 0 ) .
* */
2016-02-06 20:51:37 +00:00
static bool video_shader_parse_pass ( config_file_t * conf ,
struct video_shader_pass * pass , unsigned i )
2013-04-06 09:30:56 +00:00
{
2016-10-21 04:10:58 +00:00
char shader_name [ 64 ] ;
char filter_name_buf [ 64 ] ;
char wrap_name_buf [ 64 ] ;
char wrap_mode [ 64 ] ;
char frame_count_mod_buf [ 64 ] ;
char srgb_output_buf [ 64 ] ;
2016-12-19 18:17:23 +00:00
char fp_fbo_buf [ 64 ] ;
char mipmap_buf [ 64 ] ;
char alias_buf [ 64 ] ;
char scale_name_buf [ 64 ] ;
char attr_name_buf [ 64 ] ;
char scale_type [ 64 ] ;
char scale_type_x [ 64 ] ;
char scale_type_y [ 64 ] ;
char frame_count_mod [ 64 ] ;
2017-09-09 20:54:55 +00:00
size_t path_size = PATH_MAX_LENGTH * sizeof ( char ) ;
char * tmp_str = ( char * ) malloc ( PATH_MAX_LENGTH * sizeof ( char ) ) ;
char * tmp_path = ( char * ) malloc ( PATH_MAX_LENGTH * sizeof ( char ) ) ;
2015-06-12 23:18:13 +00:00
struct gfx_fbo_scale * scale = NULL ;
2016-05-24 20:48:15 +00:00
bool tmp_bool = false ;
2015-06-12 23:18:13 +00:00
float fattr = 0.0f ;
int iattr = 0 ;
2015-01-10 01:44:04 +00:00
2016-12-19 18:17:23 +00:00
fp_fbo_buf [ 0 ] = mipmap_buf [ 0 ] = alias_buf [ 0 ] =
scale_name_buf [ 0 ] = attr_name_buf [ 0 ] = scale_type [ 0 ] =
scale_type_x [ 0 ] = scale_type_y [ 0 ] = frame_count_mod [ 0 ] =
tmp_str [ 0 ] = shader_name [ 0 ] = filter_name_buf [ 0 ] =
wrap_name_buf [ 0 ] = wrap_mode [ 0 ] = frame_count_mod_buf [ 0 ] = ' \0 ' ;
2016-10-21 04:10:58 +00:00
srgb_output_buf [ 0 ] = ' \0 ' ;
2014-09-09 03:56:12 +00:00
/* Source */
2014-10-26 02:04:35 +00:00
snprintf ( shader_name , sizeof ( shader_name ) , " shader%u " , i ) ;
2017-09-09 20:54:55 +00:00
if ( ! config_get_path ( conf , shader_name , tmp_str , path_size ) )
2013-04-06 09:30:56 +00:00
{
RARCH_ERR ( " Couldn't parse shader source (%s). \n " , shader_name ) ;
2017-09-09 20:54:55 +00:00
goto error ;
2013-04-06 09:30:56 +00:00
}
2016-06-25 05:17:48 +00:00
2017-09-09 20:54:55 +00:00
strlcpy ( tmp_path , tmp_str , path_size ) ;
path_resolve_realpath ( tmp_path , path_size ) ;
2016-12-04 07:09:19 +00:00
2016-12-04 17:38:46 +00:00
if ( ! path_file_exists ( tmp_path ) )
2016-12-04 07:09:19 +00:00
strlcpy ( pass - > source . path , tmp_str , sizeof ( pass - > source . path ) ) ;
else
strlcpy ( pass - > source . path , tmp_path , sizeof ( pass - > source . path ) ) ;
2014-09-09 03:56:12 +00:00
/* Smooth */
2014-10-26 02:04:35 +00:00
snprintf ( filter_name_buf , sizeof ( filter_name_buf ) , " filter_linear%u " , i ) ;
2016-05-24 20:48:15 +00:00
if ( config_get_bool ( conf , filter_name_buf , & tmp_bool ) )
{
bool smooth = tmp_bool ;
2013-04-06 09:30:56 +00:00
pass - > filter = smooth ? RARCH_FILTER_LINEAR : RARCH_FILTER_NEAREST ;
2016-05-24 20:48:15 +00:00
}
2013-04-06 09:30:56 +00:00
else
pass - > filter = RARCH_FILTER_UNSPEC ;
2014-09-09 03:56:12 +00:00
/* Wrapping mode */
2014-10-26 02:04:35 +00:00
snprintf ( wrap_name_buf , sizeof ( wrap_name_buf ) , " wrap_mode%u " , i ) ;
2013-08-15 22:30:54 +00:00
if ( config_get_array ( conf , wrap_name_buf , wrap_mode , sizeof ( wrap_mode ) ) )
pass - > wrap = wrap_str_to_mode ( wrap_mode ) ;
2014-09-09 03:56:12 +00:00
/* Frame count mod */
2014-10-26 02:04:35 +00:00
snprintf ( frame_count_mod_buf , sizeof ( frame_count_mod_buf ) , " frame_count_mod%u " , i ) ;
2014-09-08 15:57:18 +00:00
if ( config_get_array ( conf , frame_count_mod_buf ,
frame_count_mod , sizeof ( frame_count_mod ) ) )
2017-02-26 09:33:03 +00:00
pass - > frame_count_mod = ( unsigned ) strtoul ( frame_count_mod , NULL , 0 ) ;
2013-04-06 09:30:56 +00:00
2014-09-09 03:56:12 +00:00
/* FBO types and mipmapping */
2014-10-26 02:04:35 +00:00
snprintf ( srgb_output_buf , sizeof ( srgb_output_buf ) , " srgb_framebuffer%u " , i ) ;
2016-05-24 20:48:15 +00:00
if ( config_get_bool ( conf , srgb_output_buf , & tmp_bool ) )
pass - > fbo . srgb_fbo = tmp_bool ;
2014-05-11 17:35:54 +00:00
2014-10-26 02:04:35 +00:00
snprintf ( fp_fbo_buf , sizeof ( fp_fbo_buf ) , " float_framebuffer%u " , i ) ;
2016-05-24 20:48:15 +00:00
if ( config_get_bool ( conf , fp_fbo_buf , & tmp_bool ) )
pass - > fbo . fp_fbo = tmp_bool ;
2014-05-11 11:13:38 +00:00
2014-10-26 02:04:35 +00:00
snprintf ( mipmap_buf , sizeof ( mipmap_buf ) , " mipmap_input%u " , i ) ;
2016-05-24 20:48:15 +00:00
if ( config_get_bool ( conf , mipmap_buf , & tmp_bool ) )
pass - > mipmap = tmp_bool ;
2014-05-11 11:13:38 +00:00
2014-10-26 02:04:35 +00:00
snprintf ( alias_buf , sizeof ( alias_buf ) , " alias%u " , i ) ;
2014-05-23 13:02:12 +00:00
if ( ! config_get_array ( conf , alias_buf , pass - > alias , sizeof ( pass - > alias ) ) )
* pass - > alias = ' \0 ' ;
2014-09-09 03:56:12 +00:00
/* Scale */
2015-01-10 01:44:04 +00:00
scale = & pass - > fbo ;
2014-10-26 02:04:35 +00:00
snprintf ( scale_name_buf , sizeof ( scale_name_buf ) , " scale_type%u " , i ) ;
2013-04-06 09:30:56 +00:00
config_get_array ( conf , scale_name_buf , scale_type , sizeof ( scale_type ) ) ;
2014-10-26 02:04:35 +00:00
snprintf ( scale_name_buf , sizeof ( scale_name_buf ) , " scale_type_x%u " , i ) ;
2013-04-06 09:30:56 +00:00
config_get_array ( conf , scale_name_buf , scale_type_x , sizeof ( scale_type_x ) ) ;
2014-10-26 02:04:35 +00:00
snprintf ( scale_name_buf , sizeof ( scale_name_buf ) , " scale_type_y%u " , i ) ;
2013-04-06 09:30:56 +00:00
config_get_array ( conf , scale_name_buf , scale_type_y , sizeof ( scale_type_y ) ) ;
if ( ! * scale_type & & ! * scale_type_x & & ! * scale_type_y )
return true ;
if ( * scale_type )
{
strlcpy ( scale_type_x , scale_type , sizeof ( scale_type_x ) ) ;
strlcpy ( scale_type_y , scale_type , sizeof ( scale_type_y ) ) ;
}
2015-06-14 17:02:53 +00:00
scale - > valid = true ;
scale - > type_x = RARCH_SCALE_INPUT ;
scale - > type_y = RARCH_SCALE_INPUT ;
2013-04-06 09:30:56 +00:00
scale - > scale_x = 1.0 ;
scale - > scale_y = 1.0 ;
if ( * scale_type_x )
{
2015-06-14 17:02:53 +00:00
uint32_t scale_type_x_hash = djb2_calculate ( scale_type_x ) ;
switch ( scale_type_x_hash )
2013-04-06 09:30:56 +00:00
{
2015-06-14 17:02:53 +00:00
case SCALE_TYPE_SOURCE :
scale - > type_x = RARCH_SCALE_INPUT ;
break ;
case SCALE_TYPE_VIEWPORT :
scale - > type_x = RARCH_SCALE_VIEWPORT ;
break ;
case SCALE_TYPE_ABSOLUTE :
scale - > type_x = RARCH_SCALE_ABSOLUTE ;
break ;
default :
RARCH_ERR ( " Invalid attribute. \n " ) ;
2017-09-09 20:54:55 +00:00
goto error ;
2013-04-06 09:30:56 +00:00
}
}
if ( * scale_type_y )
{
2015-06-14 17:02:53 +00:00
uint32_t scale_type_y_hash = djb2_calculate ( scale_type_y ) ;
switch ( scale_type_y_hash )
2013-04-06 09:30:56 +00:00
{
2015-06-14 17:02:53 +00:00
case SCALE_TYPE_SOURCE :
scale - > type_y = RARCH_SCALE_INPUT ;
break ;
case SCALE_TYPE_VIEWPORT :
scale - > type_y = RARCH_SCALE_VIEWPORT ;
break ;
case SCALE_TYPE_ABSOLUTE :
scale - > type_y = RARCH_SCALE_ABSOLUTE ;
break ;
default :
RARCH_ERR ( " Invalid attribute. \n " ) ;
2017-09-09 20:54:55 +00:00
goto error ;
2013-04-06 09:30:56 +00:00
}
}
2014-10-26 02:04:35 +00:00
snprintf ( attr_name_buf , sizeof ( attr_name_buf ) , " scale%u " , i ) ;
2013-04-06 09:30:56 +00:00
if ( scale - > type_x = = RARCH_SCALE_ABSOLUTE )
{
if ( config_get_int ( conf , attr_name_buf , & iattr ) )
scale - > abs_x = iattr ;
else
{
2014-10-26 02:04:35 +00:00
snprintf ( attr_name_buf , sizeof ( attr_name_buf ) , " scale_x%u " , i ) ;
2013-04-06 09:30:56 +00:00
if ( config_get_int ( conf , attr_name_buf , & iattr ) )
scale - > abs_x = iattr ;
}
}
else
{
if ( config_get_float ( conf , attr_name_buf , & fattr ) )
scale - > scale_x = fattr ;
else
{
2014-10-26 02:04:35 +00:00
snprintf ( attr_name_buf , sizeof ( attr_name_buf ) , " scale_x%u " , i ) ;
2013-04-06 09:30:56 +00:00
if ( config_get_float ( conf , attr_name_buf , & fattr ) )
scale - > scale_x = fattr ;
}
}
2014-10-26 02:04:35 +00:00
snprintf ( attr_name_buf , sizeof ( attr_name_buf ) , " scale%u " , i ) ;
2013-04-06 09:30:56 +00:00
if ( scale - > type_y = = RARCH_SCALE_ABSOLUTE )
{
if ( config_get_int ( conf , attr_name_buf , & iattr ) )
scale - > abs_y = iattr ;
else
{
2014-10-26 02:04:35 +00:00
snprintf ( attr_name_buf , sizeof ( attr_name_buf ) , " scale_y%u " , i ) ;
2013-04-06 09:30:56 +00:00
if ( config_get_int ( conf , attr_name_buf , & iattr ) )
scale - > abs_y = iattr ;
}
}
else
{
if ( config_get_float ( conf , attr_name_buf , & fattr ) )
scale - > scale_y = fattr ;
else
{
2014-10-26 02:04:35 +00:00
snprintf ( attr_name_buf , sizeof ( attr_name_buf ) , " scale_y%u " , i ) ;
2013-04-06 09:30:56 +00:00
if ( config_get_float ( conf , attr_name_buf , & fattr ) )
scale - > scale_y = fattr ;
}
}
2017-09-09 20:54:55 +00:00
free ( tmp_str ) ;
free ( tmp_path ) ;
2013-04-06 09:30:56 +00:00
return true ;
2017-09-09 20:54:55 +00:00
error :
free ( tmp_str ) ;
free ( tmp_path ) ;
return false ;
2013-04-06 09:30:56 +00:00
}
2015-01-11 18:59:59 +00:00
/**
2015-01-19 20:09:39 +00:00
* video_shader_parse_textures :
2015-01-11 18:59:59 +00:00
* @ conf : Preset file to read from .
* @ shader : Shader pass handle .
*
* Parses shader textures .
*
* Returns : true ( 1 ) if successful , otherwise false ( 0 ) .
* */
2015-01-19 20:09:39 +00:00
static bool video_shader_parse_textures ( config_file_t * conf ,
2015-01-19 20:24:08 +00:00
struct video_shader * shader )
2013-04-06 09:30:56 +00:00
{
2017-09-09 20:54:55 +00:00
size_t path_size = PATH_MAX_LENGTH * sizeof ( char ) ;
2015-06-12 23:18:13 +00:00
const char * id = NULL ;
char * save = NULL ;
2017-09-09 20:54:55 +00:00
char * textures = ( char * ) malloc ( 1024 * sizeof ( char ) ) ;
char * tmp_path = ( char * ) malloc ( PATH_MAX_LENGTH * sizeof ( char ) ) ;
2016-10-21 04:10:58 +00:00
textures [ 0 ] = ' \0 ' ;
2014-06-01 00:37:34 +00:00
2017-09-09 20:54:55 +00:00
if ( ! config_get_array ( conf , " textures " , textures , 1024 * sizeof ( char ) ) )
{
free ( textures ) ;
free ( tmp_path ) ;
2013-04-06 09:30:56 +00:00
return true ;
2017-09-09 20:54:55 +00:00
}
2013-04-06 09:30:56 +00:00
2013-10-22 13:08:17 +00:00
for ( id = strtok_r ( textures , " ; " , & save ) ;
2013-04-06 09:30:56 +00:00
id & & shader - > luts < GFX_MAX_TEXTURES ;
shader - > luts + + , id = strtok_r ( NULL , " ; " , & save ) )
{
2016-10-21 04:10:58 +00:00
char id_filter [ 64 ] ;
char id_wrap [ 64 ] ;
char wrap_mode [ 64 ] ;
char id_mipmap [ 64 ] ;
2015-06-12 23:18:13 +00:00
bool mipmap = false ;
bool smooth = false ;
2015-01-10 01:44:04 +00:00
2016-10-21 04:10:58 +00:00
id_filter [ 0 ] = id_wrap [ 0 ] = wrap_mode [ 0 ] = id_mipmap [ 0 ] = ' \0 ' ;
2014-09-08 15:57:18 +00:00
if ( ! config_get_array ( conf , id , shader - > lut [ shader - > luts ] . path ,
sizeof ( shader - > lut [ shader - > luts ] . path ) ) )
2013-04-06 09:30:56 +00:00
{
RARCH_ERR ( " Cannot find path to texture \" %s \" ... \n " , id ) ;
2017-09-09 20:54:55 +00:00
goto error ;
2013-04-06 09:30:56 +00:00
}
2017-09-09 20:54:55 +00:00
strlcpy ( tmp_path , shader - > lut [ shader - > luts ] . path ,
path_size ) ;
path_resolve_realpath ( tmp_path , path_size ) ;
2016-12-04 17:38:46 +00:00
if ( path_file_exists ( tmp_path ) )
2016-12-04 07:09:19 +00:00
{
strlcpy ( shader - > lut [ shader - > luts ] . path ,
tmp_path , sizeof ( shader - > lut [ shader - > luts ] . path ) ) ;
}
2014-09-08 15:57:18 +00:00
strlcpy ( shader - > lut [ shader - > luts ] . id , id ,
sizeof ( shader - > lut [ shader - > luts ] . id ) ) ;
2013-04-06 09:30:56 +00:00
2014-10-26 02:04:35 +00:00
snprintf ( id_filter , sizeof ( id_filter ) , " %s_linear " , id ) ;
2013-04-06 09:30:56 +00:00
if ( config_get_bool ( conf , id_filter , & smooth ) )
2014-09-08 15:57:18 +00:00
shader - > lut [ shader - > luts ] . filter = smooth ?
RARCH_FILTER_LINEAR : RARCH_FILTER_NEAREST ;
2013-04-06 09:30:56 +00:00
else
shader - > lut [ shader - > luts ] . filter = RARCH_FILTER_UNSPEC ;
2013-08-15 22:30:54 +00:00
2014-10-26 02:04:35 +00:00
snprintf ( id_wrap , sizeof ( id_wrap ) , " %s_wrap_mode " , id ) ;
2013-08-15 22:30:54 +00:00
if ( config_get_array ( conf , id_wrap , wrap_mode , sizeof ( wrap_mode ) ) )
shader - > lut [ shader - > luts ] . wrap = wrap_str_to_mode ( wrap_mode ) ;
2014-05-08 17:39:12 +00:00
2014-10-26 02:04:35 +00:00
snprintf ( id_mipmap , sizeof ( id_mipmap ) , " %s_mipmap " , id ) ;
2014-05-08 17:39:12 +00:00
if ( config_get_bool ( conf , id_mipmap , & mipmap ) )
shader - > lut [ shader - > luts ] . mipmap = mipmap ;
else
shader - > lut [ shader - > luts ] . mipmap = false ;
2013-04-06 09:30:56 +00:00
}
2017-09-09 20:54:55 +00:00
free ( textures ) ;
free ( tmp_path ) ;
2013-04-06 09:30:56 +00:00
return true ;
2017-09-09 20:54:55 +00:00
error :
free ( textures ) ;
free ( tmp_path ) ;
return false ;
2013-04-06 09:30:56 +00:00
}
2015-01-11 18:59:59 +00:00
/**
2015-01-19 20:09:39 +00:00
* video_shader_parse_find_parameter :
2015-01-11 18:59:59 +00:00
* @ params : Shader parameter handle .
* @ num_params : Number of shader params in @ params .
* @ id : Identifier to search for .
*
* Finds a shader parameter with identifier @ id in @ params . .
*
* Returns : handle to shader parameter if successful , otherwise NULL .
* */
2015-01-19 20:24:08 +00:00
static struct video_shader_parameter * video_shader_parse_find_parameter (
2016-02-06 20:51:37 +00:00
struct video_shader_parameter * params ,
unsigned num_params , const char * id )
2014-05-22 20:02:43 +00:00
{
unsigned i ;
2015-01-10 01:44:04 +00:00
2014-05-22 20:02:43 +00:00
for ( i = 0 ; i < num_params ; i + + )
{
2016-01-20 03:07:24 +00:00
if ( string_is_equal ( params [ i ] . id , id ) )
2014-05-22 20:02:43 +00:00
return & params [ i ] ;
}
2015-01-11 18:59:59 +00:00
2014-05-22 20:02:43 +00:00
return NULL ;
}
2016-08-01 15:51:44 +00:00
/**
* video_shader_set_current_parameters :
* @ conf : Preset file to read from .
* @ shader : Shader passes handle .
*
* Reads the current value for all parameters from config file .
*
* Returns : true ( 1 ) if successful , otherwise false ( 0 ) .
* */
bool video_shader_resolve_current_parameters ( config_file_t * conf ,
struct video_shader * shader )
{
2017-09-09 20:54:55 +00:00
size_t param_size = 4096 * sizeof ( char ) ;
char * parameters = ( char * ) malloc ( 4096 * sizeof ( char ) ) ;
2016-08-01 15:51:44 +00:00
const char * id = NULL ;
char * save = NULL ;
2006-01-17 05:11:55 +00:00
if ( ! conf )
2017-09-09 20:54:55 +00:00
{
free ( parameters ) ;
2006-01-17 05:11:55 +00:00
return false ;
2017-09-09 20:54:55 +00:00
}
2006-01-17 05:11:55 +00:00
2016-10-21 04:10:58 +00:00
parameters [ 0 ] = ' \0 ' ;
2006-01-17 05:11:55 +00:00
/* Read in parameters which override the defaults. */
2016-08-01 15:51:44 +00:00
if ( ! config_get_array ( conf , " parameters " ,
2017-09-09 20:54:55 +00:00
parameters , param_size ) )
{
free ( parameters ) ;
2016-08-01 15:51:44 +00:00
return true ;
2017-09-09 20:54:55 +00:00
}
2016-08-01 15:51:44 +00:00
for ( id = strtok_r ( parameters , " ; " , & save ) ; id ;
id = strtok_r ( NULL , " ; " , & save ) )
{
2017-09-09 20:54:55 +00:00
struct video_shader_parameter * parameter =
( struct video_shader_parameter * )
video_shader_parse_find_parameter (
shader - > parameters , shader - > num_parameters , id ) ;
2016-08-01 15:51:44 +00:00
if ( ! parameter )
{
RARCH_WARN ( " [CGP/GLSLP]: Parameter %s is set in the preset, but no shader uses this parameter, ignoring. \n " , id ) ;
continue ;
}
if ( ! config_get_float ( conf , id , & parameter - > current ) )
RARCH_WARN ( " [CGP/GLSLP]: Parameter %s is not set in preset. \n " , id ) ;
}
2017-09-09 20:54:55 +00:00
free ( parameters ) ;
2016-08-01 16:57:00 +00:00
return true ;
2016-08-01 15:51:44 +00:00
}
2015-01-11 18:59:59 +00:00
/**
2015-01-19 20:09:39 +00:00
* video_shader_resolve_parameters :
2015-01-11 18:59:59 +00:00
* @ conf : Preset file to read from .
* @ shader : Shader passes handle .
*
* Resolves all shader parameters belonging to shaders .
*
* Returns : true ( 1 ) if successful , otherwise false ( 0 ) .
* */
2015-01-19 20:09:39 +00:00
bool video_shader_resolve_parameters ( config_file_t * conf ,
2015-01-19 20:24:08 +00:00
struct video_shader * shader )
2014-05-22 19:24:52 +00:00
{
2014-05-22 20:02:43 +00:00
unsigned i ;
2016-08-01 13:43:34 +00:00
struct video_shader_parameter * param = & shader - > parameters [ 0 ] ;
2014-05-22 19:24:52 +00:00
shader - > num_parameters = 0 ;
2014-09-08 15:57:18 +00:00
/* Find all parameters in our shaders. */
2015-01-11 18:59:59 +00:00
2014-05-22 19:24:52 +00:00
for ( i = 0 ; i < shader - > passes ; i + + )
{
2017-05-28 15:46:01 +00:00
RFILE * file = NULL ;
2017-09-09 20:54:55 +00:00
size_t line_size = 4096 * sizeof ( char ) ;
char * line = ( char * ) malloc ( 4096 * sizeof ( char ) ) ;
2017-05-28 15:46:01 +00:00
const char * path = shader - > pass [ i ] . source . path ;
2017-09-09 20:54:55 +00:00
2016-12-20 14:50:50 +00:00
# ifdef HAVE_SLANG
/* First try to use the more robust slang implementation to support #includes. */
/* FIXME: The check for slang can be removed if it's sufficiently tested for
* GLSL / Cg as well , it should be the same implementation . */
2017-05-28 15:46:01 +00:00
if ( ! string_is_empty ( path ) & & ( string_is_equal_fast ( path_get_extension ( path ) , " slang " , 5 ) ) & &
2016-12-20 14:50:50 +00:00
slang_preprocess_parse_parameters ( shader - > pass [ i ] . source . path , shader ) )
2017-09-09 20:54:55 +00:00
{
free ( line ) ;
2016-12-20 14:50:50 +00:00
continue ;
2017-09-09 20:54:55 +00:00
}
2016-12-20 14:50:50 +00:00
/* If that doesn't work, fallback to the old path.
* Ideally , we ' d get rid of this path sooner or later . */
# endif
2017-05-28 15:46:42 +00:00
file = filestream_open ( path , RFILE_MODE_READ_TEXT , - 1 ) ;
2015-01-10 01:44:04 +00:00
2014-05-22 19:24:52 +00:00
if ( ! file )
2017-09-09 20:54:55 +00:00
{
free ( line ) ;
2014-05-22 19:24:52 +00:00
continue ;
2017-09-09 20:54:55 +00:00
}
2014-05-22 19:24:52 +00:00
2016-10-21 04:10:58 +00:00
line [ 0 ] = ' \0 ' ;
2014-09-08 15:57:18 +00:00
while ( shader - > num_parameters < ARRAY_SIZE ( shader - > parameters )
2017-09-09 20:54:55 +00:00
& & filestream_gets ( file , line , line_size ) )
2014-05-22 19:24:52 +00:00
{
2014-09-08 15:57:18 +00:00
int ret = sscanf ( line ,
" #pragma parameter %63s \" %63[^ \" ] \" %f %f %f %f " ,
param - > id , param - > desc , & param - > initial ,
& param - > minimum , & param - > maximum , & param - > step ) ;
2014-05-22 20:02:43 +00:00
2015-01-11 18:59:59 +00:00
if ( ret < 5 )
continue ;
2015-10-11 07:31:04 +00:00
param - > id [ 63 ] = ' \0 ' ;
2015-01-11 18:59:59 +00:00
param - > desc [ 63 ] = ' \0 ' ;
2014-05-22 20:02:43 +00:00
2015-01-11 18:59:59 +00:00
if ( ret = = 5 )
param - > step = 0.1f * ( param - > maximum - param - > minimum ) ;
2014-05-22 20:02:43 +00:00
2015-01-11 18:59:59 +00:00
RARCH_LOG ( " Found #pragma parameter %s (%s) %f %f %f %f \n " ,
param - > desc , param - > id , param - > initial ,
param - > minimum , param - > maximum , param - > step ) ;
param - > current = param - > initial ;
2014-05-22 19:24:52 +00:00
2015-01-11 18:59:59 +00:00
shader - > num_parameters + + ;
param + + ;
2014-05-22 19:24:52 +00:00
}
2017-09-09 20:54:55 +00:00
free ( line ) ;
2016-06-02 22:11:41 +00:00
filestream_close ( file ) ;
2014-05-22 19:24:52 +00:00
}
2016-08-01 15:51:44 +00:00
if ( conf & & ! video_shader_resolve_current_parameters ( conf , shader ) )
return false ;
2014-05-22 19:24:52 +00:00
return true ;
}
2015-01-11 19:17:45 +00:00
/**
2015-01-19 20:09:39 +00:00
* video_shader_parse_imports :
2015-01-11 19:17:45 +00:00
* @ conf : Preset file to read from .
* @ shader : Shader passes handle .
*
* Resolves import parameters belonging to shaders .
*
* Returns : true ( 1 ) if successful , otherwise false ( 0 ) .
* */
2015-01-19 20:09:39 +00:00
static bool video_shader_parse_imports ( config_file_t * conf ,
2015-01-19 20:24:08 +00:00
struct video_shader * shader )
2013-04-06 09:30:56 +00:00
{
2017-09-09 20:54:55 +00:00
size_t path_size = PATH_MAX_LENGTH * sizeof ( char ) ;
char * imports = ( char * ) malloc ( 1024 * sizeof ( char ) ) ;
char * tmp_str = ( char * ) malloc ( PATH_MAX_LENGTH * sizeof ( char ) ) ;
2015-06-12 23:18:13 +00:00
const char * id = NULL ;
char * save = NULL ;
2016-10-21 04:10:58 +00:00
imports [ 0 ] = tmp_str [ 0 ] = ' \0 ' ;
2015-01-10 01:44:04 +00:00
2017-09-09 20:54:55 +00:00
if ( ! config_get_array ( conf , " imports " , imports ,
1024 * sizeof ( char ) ) )
{
free ( imports ) ;
free ( tmp_str ) ;
2013-04-06 09:30:56 +00:00
return true ;
2017-09-09 20:54:55 +00:00
}
2013-04-06 09:30:56 +00:00
2013-10-22 13:08:17 +00:00
for ( id = strtok_r ( imports , " ; " , & save ) ;
2013-04-06 09:30:56 +00:00
id & & shader - > variables < GFX_MAX_VARIABLES ;
shader - > variables + + , id = strtok_r ( NULL , " ; " , & save ) )
{
2015-06-14 17:02:53 +00:00
uint32_t semantic_hash ;
2016-10-21 04:10:58 +00:00
char semantic_buf [ 64 ] ;
char wram_buf [ 64 ] ;
char input_slot_buf [ 64 ] ;
char mask_buf [ 64 ] ;
char equal_buf [ 64 ] ;
char semantic [ 64 ] ;
2015-06-12 23:18:13 +00:00
unsigned addr = 0 ;
unsigned mask = 0 ;
unsigned equal = 0 ;
2014-09-08 15:57:18 +00:00
struct state_tracker_uniform_info * var =
& shader - > variable [ shader - > variables ] ;
2013-04-06 09:30:56 +00:00
2016-10-21 04:10:58 +00:00
semantic_buf [ 0 ] = wram_buf [ 0 ] = input_slot_buf [ 0 ] =
mask_buf [ 0 ] = equal_buf [ 0 ] = semantic [ 0 ] = ' \0 ' ;
2013-04-06 09:30:56 +00:00
strlcpy ( var - > id , id , sizeof ( var - > id ) ) ;
2014-10-26 02:04:35 +00:00
snprintf ( semantic_buf , sizeof ( semantic_buf ) , " %s_semantic " , id ) ;
snprintf ( wram_buf , sizeof ( wram_buf ) , " %s_wram " , id ) ;
snprintf ( input_slot_buf , sizeof ( input_slot_buf ) , " %s_input_slot " , id ) ;
snprintf ( mask_buf , sizeof ( mask_buf ) , " %s_mask " , id ) ;
snprintf ( equal_buf , sizeof ( equal_buf ) , " %s_equal " , id ) ;
2013-04-06 09:30:56 +00:00
if ( ! config_get_array ( conf , semantic_buf , semantic , sizeof ( semantic ) ) )
{
RARCH_ERR ( " No semantic for import variable. \n " ) ;
2017-09-09 20:54:55 +00:00
goto error ;
2013-04-06 09:30:56 +00:00
}
2015-06-14 17:02:53 +00:00
semantic_hash = djb2_calculate ( semantic ) ;
switch ( semantic_hash )
2013-04-06 09:30:56 +00:00
{
2015-06-14 17:02:53 +00:00
case SEMANTIC_CAPTURE :
var - > type = RARCH_STATE_CAPTURE ;
break ;
case SEMANTIC_TRANSITION :
var - > type = RARCH_STATE_TRANSITION ;
break ;
case SEMANTIC_TRANSITION_COUNT :
var - > type = RARCH_STATE_TRANSITION_COUNT ;
break ;
case SEMANTIC_CAPTURE_PREVIOUS :
var - > type = RARCH_STATE_CAPTURE_PREV ;
break ;
case SEMANTIC_TRANSITION_PREVIOUS :
var - > type = RARCH_STATE_TRANSITION_PREV ;
break ;
case SEMANTIC_PYTHON :
var - > type = RARCH_STATE_PYTHON ;
break ;
default :
RARCH_ERR ( " Invalid semantic. \n " ) ;
2017-09-09 20:54:55 +00:00
goto error ;
2013-04-06 09:30:56 +00:00
}
2015-06-14 17:02:53 +00:00
2013-04-06 09:30:56 +00:00
if ( var - > type ! = RARCH_STATE_PYTHON )
{
unsigned input_slot = 0 ;
2015-01-11 19:17:45 +00:00
2013-04-06 09:30:56 +00:00
if ( config_get_uint ( conf , input_slot_buf , & input_slot ) )
{
switch ( input_slot )
{
case 1 :
var - > ram_type = RARCH_STATE_INPUT_SLOT1 ;
break ;
case 2 :
var - > ram_type = RARCH_STATE_INPUT_SLOT2 ;
break ;
default :
RARCH_ERR ( " Invalid input slot for import. \n " ) ;
2017-09-09 20:54:55 +00:00
goto error ;
2013-04-06 09:30:56 +00:00
}
}
else if ( config_get_hex ( conf , wram_buf , & addr ) )
{
var - > ram_type = RARCH_STATE_WRAM ;
var - > addr = addr ;
}
else
{
RARCH_ERR ( " No address assigned to semantic. \n " ) ;
2017-09-09 20:54:55 +00:00
goto error ;
2013-04-06 09:30:56 +00:00
}
}
if ( config_get_hex ( conf , mask_buf , & mask ) )
var - > mask = mask ;
if ( config_get_hex ( conf , equal_buf , & equal ) )
var - > equal = equal ;
}
2017-09-09 20:54:55 +00:00
if ( config_get_path ( conf , " import_script " , tmp_str , path_size ) )
2016-06-25 05:17:48 +00:00
strlcpy ( shader - > script_path , tmp_str , sizeof ( shader - > script_path ) ) ;
2014-09-08 15:57:18 +00:00
config_get_array ( conf , " import_script_class " ,
shader - > script_class , sizeof ( shader - > script_class ) ) ;
2013-04-06 09:30:56 +00:00
2017-09-09 20:54:55 +00:00
free ( imports ) ;
free ( tmp_str ) ;
2013-04-06 09:30:56 +00:00
return true ;
2017-09-09 20:54:55 +00:00
error :
free ( imports ) ;
free ( tmp_str ) ;
return false ;
2013-04-06 09:30:56 +00:00
}
2015-01-11 19:17:45 +00:00
/**
2015-01-19 20:09:39 +00:00
* video_shader_read_conf_cgp :
2015-01-11 19:17:45 +00:00
* @ conf : Preset file to read from .
* @ shader : Shader passes handle .
*
* Loads preset file and all associated state ( passes ,
* textures , imports , etc ) .
*
* Returns : true ( 1 ) if successful , otherwise false ( 0 ) .
* */
2017-09-08 14:43:34 +00:00
bool video_shader_read_conf_cgp ( config_file_t * conf ,
struct video_shader * shader )
2013-04-06 09:30:56 +00:00
{
2017-09-08 14:43:34 +00:00
unsigned i ;
unsigned shaders = 0 ;
2015-01-10 01:44:04 +00:00
2013-04-06 09:30:56 +00:00
memset ( shader , 0 , sizeof ( * shader ) ) ;
2013-04-07 10:41:05 +00:00
shader - > type = RARCH_SHADER_CG ;
2013-04-06 09:30:56 +00:00
if ( ! config_get_uint ( conf , " shaders " , & shaders ) )
{
RARCH_ERR ( " Cannot find \" shaders \" param. \n " ) ;
return false ;
}
if ( ! shaders )
{
RARCH_ERR ( " Need to define at least 1 shader. \n " ) ;
return false ;
}
2015-08-30 16:37:41 +00:00
if ( ! config_get_int ( conf , " feedback_pass " , & shader - > feedback_pass ) )
shader - > feedback_pass = - 1 ;
2016-03-01 23:07:31 +00:00
shader - > passes = MIN ( shaders , GFX_MAX_SHADERS ) ;
2013-10-22 13:08:17 +00:00
for ( i = 0 ; i < shader - > passes ; i + + )
2013-04-06 09:30:56 +00:00
{
2015-01-19 20:09:39 +00:00
if ( ! video_shader_parse_pass ( conf , & shader - > pass [ i ] , i ) )
2013-04-06 09:30:56 +00:00
return false ;
}
2015-01-19 20:09:39 +00:00
if ( ! video_shader_parse_textures ( conf , shader ) )
2013-04-06 09:30:56 +00:00
return false ;
2015-01-19 20:09:39 +00:00
if ( ! video_shader_parse_imports ( conf , shader ) )
2013-04-06 09:30:56 +00:00
return false ;
return true ;
}
2014-09-08 15:57:18 +00:00
/* CGP store */
2013-04-06 09:30:56 +00:00
static const char * scale_type_to_str ( enum gfx_scale_type type )
{
switch ( type )
{
case RARCH_SCALE_INPUT :
return " source " ;
case RARCH_SCALE_VIEWPORT :
return " viewport " ;
case RARCH_SCALE_ABSOLUTE :
return " absolute " ;
default :
2015-10-11 07:31:04 +00:00
break ;
2013-04-06 09:30:56 +00:00
}
2015-10-11 07:31:04 +00:00
return " ? " ;
2013-04-06 09:30:56 +00:00
}
static void shader_write_scale_dim ( config_file_t * conf , const char * dim ,
2014-10-20 23:09:24 +00:00
enum gfx_scale_type type , float scale , unsigned absolute , unsigned i )
2013-04-06 09:30:56 +00:00
{
2016-10-21 04:10:58 +00:00
char key [ 64 ] ;
key [ 0 ] = ' \0 ' ;
2015-01-10 01:44:04 +00:00
2014-10-26 02:04:35 +00:00
snprintf ( key , sizeof ( key ) , " scale_type_%s%u " , dim , i ) ;
2013-04-06 09:30:56 +00:00
config_set_string ( conf , key , scale_type_to_str ( type ) ) ;
2014-10-26 02:04:35 +00:00
snprintf ( key , sizeof ( key ) , " scale_%s%u " , dim , i ) ;
2013-04-06 09:30:56 +00:00
if ( type = = RARCH_SCALE_ABSOLUTE )
2014-10-20 23:09:24 +00:00
config_set_int ( conf , key , absolute ) ;
2013-04-06 09:30:56 +00:00
else
config_set_float ( conf , key , scale ) ;
}
2014-09-08 15:57:18 +00:00
static void shader_write_fbo ( config_file_t * conf ,
const struct gfx_fbo_scale * fbo , unsigned i )
2013-04-06 09:30:56 +00:00
{
2016-10-21 04:10:58 +00:00
char key [ 64 ] ;
key [ 0 ] = ' \0 ' ;
2015-01-10 01:44:04 +00:00
2014-10-26 02:04:35 +00:00
snprintf ( key , sizeof ( key ) , " float_framebuffer%u " , i ) ;
2013-04-06 09:30:56 +00:00
config_set_bool ( conf , key , fbo - > fp_fbo ) ;
2014-10-26 02:04:35 +00:00
snprintf ( key , sizeof ( key ) , " srgb_framebuffer%u " , i ) ;
2014-05-11 17:35:54 +00:00
config_set_bool ( conf , key , fbo - > srgb_fbo ) ;
2013-04-06 09:30:56 +00:00
if ( ! fbo - > valid )
return ;
shader_write_scale_dim ( conf , " x " , fbo - > type_x , fbo - > scale_x , fbo - > abs_x , i ) ;
shader_write_scale_dim ( conf , " y " , fbo - > type_y , fbo - > scale_y , fbo - > abs_y , i ) ;
}
2015-01-11 19:17:45 +00:00
/**
* import_semantic_to_string :
* @ type : Import semantic type from state tracker .
*
* Translates import semantic to human - readable string identifier .
*
* Returns : human - readable string identifier of import semantic .
* */
static const char * import_semantic_to_str ( enum state_tracker_type type )
2013-04-06 09:30:56 +00:00
{
switch ( type )
{
case RARCH_STATE_CAPTURE :
return " capture " ;
case RARCH_STATE_TRANSITION :
return " transition " ;
case RARCH_STATE_TRANSITION_COUNT :
return " transition_count " ;
case RARCH_STATE_CAPTURE_PREV :
return " capture_previous " ;
case RARCH_STATE_TRANSITION_PREV :
return " transition_previous " ;
case RARCH_STATE_PYTHON :
return " python " ;
default :
2015-10-11 07:31:04 +00:00
break ;
2013-04-06 09:30:56 +00:00
}
2015-10-11 07:31:04 +00:00
return " ? " ;
2013-04-06 09:30:56 +00:00
}
2015-01-11 19:17:45 +00:00
/**
* shader_write_variable :
* @ conf : Preset file to read from .
* @ info : State tracker uniform info handle .
*
* Writes variable to shader preset file .
* */
2014-09-08 15:57:18 +00:00
static void shader_write_variable ( config_file_t * conf ,
const struct state_tracker_uniform_info * info )
2013-04-06 09:30:56 +00:00
{
2016-10-21 04:10:58 +00:00
char semantic_buf [ 64 ] ;
char wram_buf [ 64 ] ;
char input_slot_buf [ 64 ] ;
char mask_buf [ 64 ] ;
char equal_buf [ 64 ] ;
2015-06-12 23:18:13 +00:00
const char * id = info - > id ;
2013-04-06 09:30:56 +00:00
2016-10-21 04:10:58 +00:00
semantic_buf [ 0 ] = wram_buf [ 0 ] = input_slot_buf [ 0 ] =
mask_buf [ 0 ] = equal_buf [ 0 ] = ' \0 ' ;
2014-10-26 02:04:35 +00:00
snprintf ( semantic_buf , sizeof ( semantic_buf ) , " %s_semantic " , id ) ;
snprintf ( wram_buf , sizeof ( wram_buf ) , " %s_wram " , id ) ;
snprintf ( input_slot_buf , sizeof ( input_slot_buf ) , " %s_input_slot " , id ) ;
snprintf ( mask_buf , sizeof ( mask_buf ) , " %s_mask " , id ) ;
snprintf ( equal_buf , sizeof ( equal_buf ) , " %s_equal " , id ) ;
2013-04-06 09:30:56 +00:00
2014-09-08 15:57:18 +00:00
config_set_string ( conf , semantic_buf ,
2015-01-11 19:17:45 +00:00
import_semantic_to_str ( info - > type ) ) ;
2013-04-06 09:30:56 +00:00
config_set_hex ( conf , mask_buf , info - > mask ) ;
config_set_hex ( conf , equal_buf , info - > equal ) ;
switch ( info - > ram_type )
{
case RARCH_STATE_INPUT_SLOT1 :
config_set_int ( conf , input_slot_buf , 1 ) ;
break ;
case RARCH_STATE_INPUT_SLOT2 :
config_set_int ( conf , input_slot_buf , 2 ) ;
break ;
case RARCH_STATE_WRAM :
config_set_hex ( conf , wram_buf , info - > addr ) ;
break ;
2014-09-21 02:07:52 +00:00
case RARCH_STATE_NONE :
2013-04-06 09:30:56 +00:00
break ;
}
}
2015-01-11 19:17:45 +00:00
/**
2015-01-19 20:09:39 +00:00
* video_shader_write_conf_cgp :
2015-01-11 19:17:45 +00:00
* @ conf : Preset file to read from .
* @ shader : Shader passes handle .
*
* Saves preset and all associated state ( passes ,
* textures , imports , etc ) to disk .
* */
2015-01-19 20:09:39 +00:00
void video_shader_write_conf_cgp ( config_file_t * conf ,
2015-01-19 20:24:08 +00:00
struct video_shader * shader )
2013-04-06 09:30:56 +00:00
{
2013-10-22 13:08:17 +00:00
unsigned i ;
2015-01-10 01:44:04 +00:00
2013-04-06 09:30:56 +00:00
config_set_int ( conf , " shaders " , shader - > passes ) ;
2015-08-30 16:37:41 +00:00
if ( shader - > feedback_pass > = 0 )
config_set_int ( conf , " feedback_pass " , shader - > feedback_pass ) ;
2015-01-10 01:44:04 +00:00
2013-10-22 13:08:17 +00:00
for ( i = 0 ; i < shader - > passes ; i + + )
2013-04-06 09:30:56 +00:00
{
2016-10-21 04:10:58 +00:00
char key [ 64 ] ;
2017-09-09 20:54:55 +00:00
size_t tmp_size = PATH_MAX_LENGTH * sizeof ( char ) ;
char * tmp = ( char * ) malloc ( PATH_MAX_LENGTH * sizeof ( char ) ) ;
2015-01-19 20:24:08 +00:00
const struct video_shader_pass * pass = & shader - > pass [ i ] ;
2013-04-06 09:30:56 +00:00
2016-10-21 04:10:58 +00:00
key [ 0 ] = ' \0 ' ;
2014-10-26 02:04:35 +00:00
snprintf ( key , sizeof ( key ) , " shader%u " , i ) ;
2017-09-09 20:54:55 +00:00
strlcpy ( tmp , pass - > source . path , tmp_size ) ;
2016-12-04 06:12:57 +00:00
if ( ! path_is_absolute ( tmp ) )
2017-09-09 20:54:55 +00:00
path_resolve_realpath ( tmp , tmp_size ) ;
2016-12-04 06:12:57 +00:00
config_set_string ( conf , key , tmp ) ;
2013-04-06 09:30:56 +00:00
2017-09-09 20:54:55 +00:00
free ( tmp ) ;
2013-04-06 09:30:56 +00:00
if ( pass - > filter ! = RARCH_FILTER_UNSPEC )
{
2014-10-26 02:04:35 +00:00
snprintf ( key , sizeof ( key ) , " filter_linear%u " , i ) ;
2013-04-06 09:30:56 +00:00
config_set_bool ( conf , key , pass - > filter = = RARCH_FILTER_LINEAR ) ;
}
2014-10-26 02:04:35 +00:00
snprintf ( key , sizeof ( key ) , " wrap_mode%u " , i ) ;
2013-08-15 22:30:54 +00:00
config_set_string ( conf , key , wrap_mode_to_str ( pass - > wrap ) ) ;
2013-04-06 09:30:56 +00:00
if ( pass - > frame_count_mod )
{
2014-10-26 02:04:35 +00:00
snprintf ( key , sizeof ( key ) , " frame_count_mod%u " , i ) ;
2013-04-06 09:30:56 +00:00
config_set_int ( conf , key , pass - > frame_count_mod ) ;
}
2014-10-26 02:04:35 +00:00
snprintf ( key , sizeof ( key ) , " mipmap_input%u " , i ) ;
2014-05-11 11:13:38 +00:00
config_set_bool ( conf , key , pass - > mipmap ) ;
2014-10-26 02:04:35 +00:00
snprintf ( key , sizeof ( key ) , " alias%u " , i ) ;
2014-05-23 13:02:12 +00:00
config_set_string ( conf , key , pass - > alias ) ;
2013-04-06 09:30:56 +00:00
shader_write_fbo ( conf , & pass - > fbo , i ) ;
}
2014-05-24 12:13:04 +00:00
if ( shader - > num_parameters )
{
2017-09-09 20:54:55 +00:00
size_t param_size = 4096 * sizeof ( char ) ;
char * parameters = ( char * ) malloc ( 4096 * sizeof ( char ) ) ;
2016-10-21 04:10:58 +00:00
parameters [ 0 ] = ' \0 ' ;
2015-01-10 01:44:04 +00:00
2017-09-09 20:54:55 +00:00
strlcpy ( parameters , shader - > parameters [ 0 ] . id , param_size ) ;
2015-01-10 01:44:04 +00:00
2014-05-24 12:13:04 +00:00
for ( i = 1 ; i < shader - > num_parameters ; i + + )
{
2014-09-08 15:57:18 +00:00
/* O(n^2), but number of parameters is very limited. */
2017-09-09 20:54:55 +00:00
strlcat ( parameters , " ; " , param_size ) ;
strlcat ( parameters , shader - > parameters [ i ] . id , param_size ) ;
2014-05-24 12:13:04 +00:00
}
config_set_string ( conf , " parameters " , parameters ) ;
for ( i = 0 ; i < shader - > num_parameters ; i + + )
2014-09-08 15:57:18 +00:00
config_set_float ( conf , shader - > parameters [ i ] . id ,
shader - > parameters [ i ] . current ) ;
2017-09-09 20:54:55 +00:00
free ( parameters ) ;
2014-05-24 12:13:04 +00:00
}
2013-04-06 09:30:56 +00:00
if ( shader - > luts )
{
2017-09-09 20:54:55 +00:00
size_t tex_size = 4096 * sizeof ( char ) ;
char * textures = ( char * ) malloc ( 4096 * sizeof ( char ) ) ;
2016-10-21 04:10:58 +00:00
textures [ 0 ] = ' \0 ' ;
2015-01-10 01:44:04 +00:00
2017-09-09 20:54:55 +00:00
strlcpy ( textures , shader - > lut [ 0 ] . id , tex_size ) ;
2013-10-22 13:08:17 +00:00
for ( i = 1 ; i < shader - > luts ; i + + )
2013-04-06 09:30:56 +00:00
{
2014-09-08 15:57:18 +00:00
/* O(n^2), but number of textures is very limited. */
2017-09-09 20:54:55 +00:00
strlcat ( textures , " ; " , tex_size ) ;
strlcat ( textures , shader - > lut [ i ] . id , tex_size ) ;
2013-04-06 09:30:56 +00:00
}
config_set_string ( conf , " textures " , textures ) ;
2017-09-09 20:54:55 +00:00
free ( textures ) ;
2013-10-22 13:08:17 +00:00
for ( i = 0 ; i < shader - > luts ; i + + )
2013-04-06 09:30:56 +00:00
{
2016-10-21 04:10:58 +00:00
char key [ 64 ] ;
key [ 0 ] = ' \0 ' ;
2013-04-06 09:30:56 +00:00
2013-04-16 20:22:26 +00:00
config_set_string ( conf , shader - > lut [ i ] . id , shader - > lut [ i ] . path ) ;
2013-04-06 09:30:56 +00:00
if ( shader - > lut [ i ] . filter ! = RARCH_FILTER_UNSPEC )
{
2014-10-26 02:04:35 +00:00
snprintf ( key , sizeof ( key ) , " %s_linear " , shader - > lut [ i ] . id ) ;
2014-09-08 15:57:18 +00:00
config_set_bool ( conf , key ,
shader - > lut [ i ] . filter = = RARCH_FILTER_LINEAR ) ;
2013-04-06 09:30:56 +00:00
}
2013-08-15 22:30:54 +00:00
2014-10-26 02:04:35 +00:00
snprintf ( key , sizeof ( key ) , " %s_wrap_mode " , shader - > lut [ i ] . id ) ;
2013-08-15 22:30:54 +00:00
config_set_string ( conf , key , wrap_mode_to_str ( shader - > lut [ i ] . wrap ) ) ;
2014-05-08 17:39:12 +00:00
2014-10-26 02:04:35 +00:00
snprintf ( key , sizeof ( key ) , " %s_mipmap " , shader - > lut [ i ] . id ) ;
2014-05-08 17:39:12 +00:00
config_set_bool ( conf , key , shader - > lut [ i ] . mipmap ) ;
2013-04-06 09:30:56 +00:00
}
}
if ( * shader - > script_path )
config_set_string ( conf , " import_script " , shader - > script_path ) ;
if ( * shader - > script_class )
config_set_string ( conf , " import_script_class " , shader - > script_class ) ;
if ( shader - > variables )
{
2017-09-09 20:54:55 +00:00
size_t var_tmp = 4096 * sizeof ( char ) ;
char * variables = ( char * ) malloc ( 4096 * sizeof ( char ) ) ;
2016-10-21 04:10:58 +00:00
variables [ 0 ] = ' \0 ' ;
2015-01-10 01:44:04 +00:00
2017-09-09 20:54:55 +00:00
strlcpy ( variables , shader - > variable [ 0 ] . id , var_tmp ) ;
2015-01-10 01:44:04 +00:00
2013-10-22 13:08:17 +00:00
for ( i = 1 ; i < shader - > variables ; i + + )
2013-04-06 09:30:56 +00:00
{
2017-09-09 20:54:55 +00:00
strlcat ( variables , " ; " , var_tmp ) ;
strlcat ( variables , shader - > variable [ i ] . id , var_tmp ) ;
2013-04-06 09:30:56 +00:00
}
config_set_string ( conf , " imports " , variables ) ;
2013-10-22 13:08:17 +00:00
for ( i = 0 ; i < shader - > variables ; i + + )
2013-04-06 09:30:56 +00:00
shader_write_variable ( conf , & shader - > variable [ i ] ) ;
2017-09-09 20:54:55 +00:00
free ( variables ) ;
2013-04-06 09:30:56 +00:00
}
}
2015-01-11 19:10:01 +00:00
/**
2015-01-19 20:09:39 +00:00
* video_shader_parse_type :
2015-01-11 19:10:01 +00:00
* @ path : Shader path .
* @ fallback : Fallback shader type in case no
* type could be found .
*
* Parses type of shader .
*
* Returns : value of shader type on success , otherwise will return
* user - supplied @ fallback value .
* */
2015-01-19 20:09:39 +00:00
enum rarch_shader_type video_shader_parse_type ( const char * path ,
2014-09-08 15:57:18 +00:00
enum rarch_shader_type fallback )
2013-04-06 23:38:11 +00:00
{
2013-04-07 11:08:09 +00:00
if ( ! path )
return fallback ;
2017-09-08 14:43:34 +00:00
switch ( msg_hash_to_file_type (
msg_hash_calculate ( path_get_extension ( path ) ) ) )
2016-06-20 20:17:03 +00:00
{
case FILE_TYPE_SHADER_CG :
case FILE_TYPE_SHADER_PRESET_CGP :
return RARCH_SHADER_CG ;
case FILE_TYPE_SHADER_GLSL :
case FILE_TYPE_SHADER_PRESET_GLSLP :
return RARCH_SHADER_GLSL ;
case FILE_TYPE_SHADER_SLANG :
case FILE_TYPE_SHADER_PRESET_SLANGP :
return RARCH_SHADER_SLANG ;
default :
break ;
}
2013-04-06 23:38:11 +00:00
return fallback ;
}
2015-01-11 19:10:01 +00:00
/**
2015-01-19 20:09:39 +00:00
* video_shader_resolve_relative :
2015-01-11 19:10:01 +00:00
* @ shader : Shader pass handle .
* @ ref_path : Relative shader path .
*
* Resolves relative shader path ( @ ref_path ) into absolute
* shader paths .
* */
2015-01-19 20:24:08 +00:00
void video_shader_resolve_relative ( struct video_shader * shader ,
2014-09-08 15:57:18 +00:00
const char * ref_path )
2013-04-15 21:45:11 +00:00
{
2013-10-22 13:08:17 +00:00
unsigned i ;
2017-09-09 20:54:55 +00:00
size_t tmp_path_size = 4096 * sizeof ( char ) ;
char * tmp_path = ( char * ) malloc ( 4096 * sizeof ( char ) ) ;
2016-10-21 04:10:58 +00:00
tmp_path [ 0 ] = ' \0 ' ;
2014-06-01 00:37:34 +00:00
2013-10-22 13:08:17 +00:00
for ( i = 0 ; i < shader - > passes ; i + + )
2013-04-15 21:45:11 +00:00
{
2014-05-25 15:16:33 +00:00
if ( ! * shader - > pass [ i ] . source . path )
2013-04-15 21:45:11 +00:00
continue ;
2017-09-09 20:54:55 +00:00
strlcpy ( tmp_path , shader - > pass [ i ] . source . path , tmp_path_size ) ;
2014-05-25 15:16:33 +00:00
fill_pathname_resolve_relative ( shader - > pass [ i ] . source . path ,
ref_path , tmp_path , sizeof ( shader - > pass [ i ] . source . path ) ) ;
2013-04-15 21:45:11 +00:00
}
2013-10-22 13:08:17 +00:00
for ( i = 0 ; i < shader - > luts ; i + + )
2013-04-15 21:45:11 +00:00
{
2017-09-09 20:54:55 +00:00
strlcpy ( tmp_path , shader - > lut [ i ] . path , tmp_path_size ) ;
2013-04-15 21:45:11 +00:00
fill_pathname_resolve_relative ( shader - > lut [ i ] . path ,
ref_path , tmp_path , sizeof ( shader - > lut [ i ] . path ) ) ;
}
if ( * shader - > script_path )
{
2017-09-09 20:54:55 +00:00
strlcpy ( tmp_path , shader - > script_path , tmp_path_size ) ;
2013-04-15 21:45:11 +00:00
fill_pathname_resolve_relative ( shader - > script_path ,
ref_path , tmp_path , sizeof ( shader - > script_path ) ) ;
}
2017-09-09 20:54:55 +00:00
free ( tmp_path ) ;
2013-04-15 21:45:11 +00:00
}