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
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>
2013-04-06 09:30:56 +00:00
# include "shader_parse.h"
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>
2014-10-01 22:45:11 +00:00
# include "../../general.h"
2013-04-06 09:30:56 +00:00
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 :
return " ??? " ;
}
}
static enum gfx_wrap_type wrap_str_to_mode ( const char * wrap_mode )
{
if ( strcmp ( wrap_mode , " clamp_to_border " ) = = 0 )
return RARCH_WRAP_BORDER ;
else if ( strcmp ( wrap_mode , " clamp_to_edge " ) = = 0 )
return RARCH_WRAP_EDGE ;
else if ( strcmp ( wrap_mode , " repeat " ) = = 0 )
return RARCH_WRAP_REPEAT ;
else if ( strcmp ( wrap_mode , " mirrored_repeat " ) = = 0 )
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
}
2014-09-09 03:56:12 +00:00
/* CGP */
2014-06-17 14:41:06 +00:00
static bool shader_parse_pass ( config_file_t * conf , struct gfx_shader_pass * pass , unsigned i )
2013-04-06 09:30:56 +00:00
{
2014-09-09 03:56:12 +00:00
/* Source */
2013-04-06 09:30:56 +00:00
char shader_name [ 64 ] ;
2014-10-26 02:04:35 +00:00
snprintf ( shader_name , sizeof ( shader_name ) , " shader%u " , i ) ;
2014-05-25 15:16:33 +00:00
if ( ! config_get_path ( conf , shader_name , pass - > source . path , sizeof ( pass - > source . path ) ) )
2013-04-06 09:30:56 +00:00
{
RARCH_ERR ( " Couldn't parse shader source (%s). \n " , shader_name ) ;
return false ;
}
2014-09-09 03:56:12 +00:00
/* Smooth */
2013-04-06 09:30:56 +00:00
char filter_name_buf [ 64 ] ;
2014-10-26 02:04:35 +00:00
snprintf ( filter_name_buf , sizeof ( filter_name_buf ) , " filter_linear%u " , i ) ;
2013-04-06 09:30:56 +00:00
bool smooth = false ;
if ( config_get_bool ( conf , filter_name_buf , & smooth ) )
pass - > filter = smooth ? RARCH_FILTER_LINEAR : RARCH_FILTER_NEAREST ;
else
pass - > filter = RARCH_FILTER_UNSPEC ;
2014-09-09 03:56:12 +00:00
/* Wrapping mode */
2013-08-15 22:30:54 +00:00
char wrap_name_buf [ 64 ] ;
char wrap_mode [ 64 ] ;
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 */
2013-04-06 09:30:56 +00:00
char frame_count_mod [ 64 ] = { 0 } ;
char frame_count_mod_buf [ 64 ] ;
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 ) ) )
2013-04-06 09:30:56 +00:00
pass - > frame_count_mod = strtoul ( frame_count_mod , NULL , 0 ) ;
2014-09-09 03:56:12 +00:00
/* FBO types and mipmapping */
2014-05-11 11:13:38 +00:00
char srgb_output_buf [ 64 ] ;
2014-10-26 02:04:35 +00:00
snprintf ( srgb_output_buf , sizeof ( srgb_output_buf ) , " srgb_framebuffer%u " , i ) ;
2014-05-11 17:35:54 +00:00
config_get_bool ( conf , srgb_output_buf , & pass - > fbo . srgb_fbo ) ;
char fp_fbo_buf [ 64 ] ;
2014-10-26 02:04:35 +00:00
snprintf ( fp_fbo_buf , sizeof ( fp_fbo_buf ) , " float_framebuffer%u " , i ) ;
2014-05-11 17:35:54 +00:00
config_get_bool ( conf , fp_fbo_buf , & pass - > fbo . fp_fbo ) ;
2014-05-11 11:13:38 +00:00
char mipmap_buf [ 64 ] ;
2014-10-26 02:04:35 +00:00
snprintf ( mipmap_buf , sizeof ( mipmap_buf ) , " mipmap_input%u " , i ) ;
2014-05-11 11:13:38 +00:00
config_get_bool ( conf , mipmap_buf , & pass - > mipmap ) ;
2014-05-23 13:02:12 +00:00
char alias_buf [ 64 ] ;
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 */
2013-04-06 09:30:56 +00:00
struct gfx_fbo_scale * scale = & pass - > fbo ;
char scale_type [ 64 ] = { 0 } ;
char scale_type_x [ 64 ] = { 0 } ;
char scale_type_y [ 64 ] = { 0 } ;
char scale_name_buf [ 64 ] ;
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 ) ) ;
}
char attr_name_buf [ 64 ] ;
float fattr = 0.0f ;
int iattr = 0 ;
scale - > valid = true ;
scale - > type_x = RARCH_SCALE_INPUT ;
scale - > type_y = RARCH_SCALE_INPUT ;
scale - > scale_x = 1.0 ;
scale - > scale_y = 1.0 ;
if ( * scale_type_x )
{
if ( strcmp ( scale_type_x , " source " ) = = 0 )
scale - > type_x = RARCH_SCALE_INPUT ;
else if ( strcmp ( scale_type_x , " viewport " ) = = 0 )
scale - > type_x = RARCH_SCALE_VIEWPORT ;
else if ( strcmp ( scale_type_x , " absolute " ) = = 0 )
scale - > type_x = RARCH_SCALE_ABSOLUTE ;
else
{
RARCH_ERR ( " Invalid attribute. \n " ) ;
return false ;
}
}
if ( * scale_type_y )
{
if ( strcmp ( scale_type_y , " source " ) = = 0 )
scale - > type_y = RARCH_SCALE_INPUT ;
else if ( strcmp ( scale_type_y , " viewport " ) = = 0 )
scale - > type_y = RARCH_SCALE_VIEWPORT ;
else if ( strcmp ( scale_type_y , " absolute " ) = = 0 )
scale - > type_y = RARCH_SCALE_ABSOLUTE ;
else
{
RARCH_ERR ( " Invalid attribute. \n " ) ;
return false ;
}
}
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 ;
}
}
return true ;
}
2014-09-08 15:57:18 +00:00
static bool shader_parse_textures ( config_file_t * conf ,
struct gfx_shader * shader )
2013-04-06 09:30:56 +00:00
{
2013-10-22 13:08:17 +00:00
const char * id ;
char * save ;
2013-04-06 09:30:56 +00:00
char textures [ 1024 ] ;
2014-06-01 00:37:34 +00:00
2013-04-06 09:30:56 +00:00
if ( ! config_get_array ( conf , " textures " , textures , sizeof ( textures ) ) )
return true ;
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 ) )
{
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 ) ;
return false ;
}
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
char id_filter [ 64 ] ;
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
bool smooth = false ;
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
char id_wrap [ 64 ] ;
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
char wrap_mode [ 64 ] ;
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
char id_mipmap [ 64 ] ;
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
bool mipmap = false ;
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
}
return true ;
}
2014-09-08 15:57:18 +00:00
static struct gfx_shader_parameter * find_parameter (
struct gfx_shader_parameter * params , unsigned num_params , const char * id )
2014-05-22 20:02:43 +00:00
{
unsigned i ;
for ( i = 0 ; i < num_params ; i + + )
{
if ( ! strcmp ( params [ i ] . id , id ) )
return & params [ i ] ;
}
return NULL ;
}
2014-09-08 15:57:18 +00:00
bool gfx_shader_resolve_parameters ( config_file_t * conf ,
struct gfx_shader * shader )
2014-05-22 19:24:52 +00:00
{
2014-05-22 20:02:43 +00:00
unsigned i ;
2014-05-22 19:24:52 +00:00
shader - > num_parameters = 0 ;
2014-09-08 15:57:18 +00:00
struct gfx_shader_parameter * param = ( struct gfx_shader_parameter * )
& shader - > parameters [ shader - > num_parameters ] ;
2014-05-22 19:24:52 +00:00
2014-09-08 15:57:18 +00:00
/* Find all parameters in our shaders. */
2014-05-22 19:24:52 +00:00
for ( i = 0 ; i < shader - > passes ; i + + )
{
2014-10-14 16:26:28 +00:00
char line [ PATH_MAX ] ;
2014-05-26 16:49:06 +00:00
FILE * file = fopen ( shader - > pass [ i ] . source . path , " r " ) ;
2014-05-22 19:24:52 +00:00
if ( ! file )
continue ;
2014-09-08 15:57:18 +00:00
while ( shader - > num_parameters < ARRAY_SIZE ( shader - > parameters )
& & fgets ( line , sizeof ( line ) , file ) )
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
if ( ret > = 5 )
2014-05-22 19:24:52 +00:00
{
param - > id [ 63 ] = ' \0 ' ;
param - > desc [ 63 ] = ' \0 ' ;
2014-05-22 20:02:43 +00:00
if ( ret = = 5 )
param - > step = 0.1f * ( param - > maximum - param - > minimum ) ;
2014-05-22 19:24:52 +00:00
RARCH_LOG ( " Found #pragma parameter %s (%s) %f %f %f %f \n " ,
2014-09-08 15:57:18 +00:00
param - > desc , param - > id , param - > initial ,
param - > minimum , param - > maximum , param - > step ) ;
2014-05-22 20:02:43 +00:00
param - > current = param - > initial ;
2014-05-22 19:24:52 +00:00
shader - > num_parameters + + ;
param + + ;
}
}
fclose ( file ) ;
}
2014-09-08 15:57:18 +00:00
/* Read in parameters which override the defaults. */
2014-05-22 20:02:43 +00:00
if ( conf )
{
2014-10-14 16:26:28 +00:00
char parameters [ PATH_MAX ] ;
2014-05-24 12:13:04 +00:00
char * save = NULL ;
const char * id ;
2014-09-08 15:57:18 +00:00
if ( ! config_get_array ( conf , " parameters " ,
parameters , sizeof ( parameters ) ) )
2014-05-22 20:02:43 +00:00
return true ;
2014-09-08 15:57:18 +00:00
for ( id = strtok_r ( parameters , " ; " , & save ) ; id ;
id = strtok_r ( NULL , " ; " , & save ) )
2014-05-22 20:02:43 +00:00
{
2014-10-14 16:26:28 +00:00
param = ( struct gfx_shader_parameter * )
2014-09-08 15:57:18 +00:00
find_parameter ( shader - > parameters , shader - > num_parameters , id ) ;
2014-05-22 20:02:43 +00:00
if ( ! param )
{
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 , & param - > current ) )
RARCH_WARN ( " [CGP/GLSLP]: Parameter %s is not set in preset. \n " , id ) ;
}
}
2014-05-22 19:24:52 +00:00
return true ;
}
2014-09-08 15:57:18 +00:00
static bool shader_parse_imports ( config_file_t * conf ,
struct gfx_shader * shader )
2013-04-06 09:30:56 +00:00
{
char imports [ 1024 ] ;
2014-05-22 19:24:52 +00:00
char * save = NULL ;
2013-10-22 13:08:17 +00:00
const char * id ;
2013-04-06 09:30:56 +00:00
if ( ! config_get_array ( conf , " imports " , imports , sizeof ( imports ) ) )
return true ;
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 ) )
{
2014-09-08 15:57:18 +00:00
struct state_tracker_uniform_info * var =
( struct state_tracker_uniform_info * )
& shader - > variable [ shader - > variables ] ;
2013-04-06 09:30:56 +00:00
strlcpy ( var - > id , id , sizeof ( var - > id ) ) ;
char semantic_buf [ 64 ] ;
char wram_buf [ 64 ] ;
char input_slot_buf [ 64 ] ;
char mask_buf [ 64 ] ;
char equal_buf [ 64 ] ;
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
char semantic [ 64 ] ;
if ( ! config_get_array ( conf , semantic_buf , semantic , sizeof ( semantic ) ) )
{
RARCH_ERR ( " No semantic for import variable. \n " ) ;
return false ;
}
if ( strcmp ( semantic , " capture " ) = = 0 )
var - > type = RARCH_STATE_CAPTURE ;
else if ( strcmp ( semantic , " transition " ) = = 0 )
var - > type = RARCH_STATE_TRANSITION ;
else if ( strcmp ( semantic , " transition_count " ) = = 0 )
var - > type = RARCH_STATE_TRANSITION_COUNT ;
else if ( strcmp ( semantic , " capture_previous " ) = = 0 )
var - > type = RARCH_STATE_CAPTURE_PREV ;
else if ( strcmp ( semantic , " transition_previous " ) = = 0 )
var - > type = RARCH_STATE_TRANSITION_PREV ;
else if ( strcmp ( semantic , " python " ) = = 0 )
var - > type = RARCH_STATE_PYTHON ;
else
{
RARCH_ERR ( " Invalid semantic. \n " ) ;
return false ;
}
unsigned addr = 0 , mask = 0 , equal = 0 ;
if ( var - > type ! = RARCH_STATE_PYTHON )
{
unsigned input_slot = 0 ;
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 " ) ;
return false ;
}
}
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 " ) ;
return false ;
}
}
if ( config_get_hex ( conf , mask_buf , & mask ) )
var - > mask = mask ;
if ( config_get_hex ( conf , equal_buf , & equal ) )
var - > equal = equal ;
}
2014-09-08 15:57:18 +00:00
config_get_path ( conf , " import_script " ,
shader - > script_path , sizeof ( shader - > script_path ) ) ;
config_get_array ( conf , " import_script_class " ,
shader - > script_class , sizeof ( shader - > script_class ) ) ;
2013-04-06 09:30:56 +00:00
return true ;
}
2014-06-17 14:41:06 +00:00
bool gfx_shader_read_conf_cgp ( config_file_t * conf , struct gfx_shader * shader )
2013-04-06 09:30:56 +00:00
{
2013-10-22 13:08:17 +00:00
unsigned shaders , i ;
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-10-22 13:08:17 +00:00
shaders = 0 ;
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 ;
}
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
{
if ( ! shader_parse_pass ( conf , & shader - > pass [ i ] , i ) )
return false ;
}
if ( ! shader_parse_textures ( conf , shader ) )
return false ;
if ( ! shader_parse_imports ( conf , shader ) )
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 :
return " ? " ;
}
}
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
{
char key [ 64 ] ;
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
{
char key [ 64 ] ;
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 ) ;
}
static const char * import_semantic_to_string ( enum state_tracker_type type )
{
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 :
return " ? " ;
}
}
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
{
const char * id = info - > id ;
char semantic_buf [ 64 ] ;
char wram_buf [ 64 ] ;
char input_slot_buf [ 64 ] ;
char mask_buf [ 64 ] ;
char equal_buf [ 64 ] ;
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 ,
import_semantic_to_string ( 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 ;
}
}
2014-09-08 15:57:18 +00:00
void gfx_shader_write_conf_cgp ( config_file_t * conf ,
struct gfx_shader * shader )
2013-04-06 09:30:56 +00:00
{
2013-10-22 13:08:17 +00:00
unsigned i ;
2013-04-06 09:30:56 +00:00
config_set_int ( conf , " shaders " , shader - > passes ) ;
2013-10-22 13:08:17 +00:00
for ( i = 0 ; i < shader - > passes ; i + + )
2013-04-06 09:30:56 +00:00
{
const struct gfx_shader_pass * pass = & shader - > pass [ i ] ;
char key [ 64 ] ;
2014-10-26 02:04:35 +00:00
snprintf ( key , sizeof ( key ) , " shader%u " , i ) ;
2014-05-25 15:16:33 +00:00
config_set_string ( conf , key , pass - > source . path ) ;
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 )
{
char parameters [ 4096 ] = { 0 } ;
strlcpy ( parameters , shader - > parameters [ 0 ] . id , sizeof ( parameters ) ) ;
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. */
2014-05-24 12:13:04 +00:00
strlcat ( parameters , " ; " , sizeof ( parameters ) ) ;
strlcat ( parameters , shader - > parameters [ i ] . id , sizeof ( parameters ) ) ;
}
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 ) ;
2014-05-24 12:13:04 +00:00
}
2013-04-06 09:30:56 +00:00
if ( shader - > luts )
{
char textures [ 4096 ] = { 0 } ;
strlcpy ( textures , shader - > lut [ 0 ] . id , sizeof ( textures ) ) ;
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. */
2013-04-06 09:30:56 +00:00
strlcat ( textures , " ; " , sizeof ( textures ) ) ;
strlcat ( textures , shader - > lut [ i ] . id , sizeof ( textures ) ) ;
}
config_set_string ( conf , " textures " , textures ) ;
2013-10-22 13:08:17 +00:00
for ( i = 0 ; i < shader - > luts ; i + + )
2013-04-06 09:30:56 +00:00
{
char key [ 64 ] ;
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 )
{
char variables [ 4096 ] = { 0 } ;
strlcpy ( variables , shader - > variable [ 0 ] . id , sizeof ( variables ) ) ;
2013-10-22 13:08:17 +00:00
for ( i = 1 ; i < shader - > variables ; i + + )
2013-04-06 09:30:56 +00:00
{
strlcat ( variables , " ; " , sizeof ( variables ) ) ;
strlcat ( variables , shader - > variable [ i ] . id , sizeof ( variables ) ) ;
}
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 ] ) ;
}
}
2014-09-08 15:57:18 +00:00
enum rarch_shader_type gfx_shader_parse_type ( const char * path ,
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 ;
2013-04-06 23:38:11 +00:00
const char * ext = path_get_extension ( path ) ;
if ( strcmp ( ext , " cg " ) = = 0 | | strcmp ( ext , " cgp " ) = = 0 )
return RARCH_SHADER_CG ;
2014-05-25 21:40:14 +00:00
else if ( strcmp ( ext , " glslp " ) = = 0 | | strcmp ( ext , " glsl " ) = = 0 )
2013-04-06 23:38:11 +00:00
return RARCH_SHADER_GLSL ;
return fallback ;
}
2014-09-08 15:57:18 +00:00
void gfx_shader_resolve_relative ( struct gfx_shader * shader ,
const char * ref_path )
2013-04-15 21:45:11 +00:00
{
2013-10-22 13:08:17 +00:00
unsigned i ;
2013-04-15 21:45:11 +00:00
char tmp_path [ PATH_MAX ] ;
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 ;
2014-05-25 15:16:33 +00:00
strlcpy ( tmp_path , shader - > pass [ i ] . source . path , sizeof ( tmp_path ) ) ;
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
{
strlcpy ( tmp_path , shader - > lut [ i ] . path , sizeof ( tmp_path ) ) ;
fill_pathname_resolve_relative ( shader - > lut [ i ] . path ,
ref_path , tmp_path , sizeof ( shader - > lut [ i ] . path ) ) ;
}
if ( * shader - > script_path )
{
strlcpy ( tmp_path , shader - > script_path , sizeof ( tmp_path ) ) ;
fill_pathname_resolve_relative ( shader - > script_path ,
ref_path , tmp_path , sizeof ( shader - > script_path ) ) ;
}
}