/* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - Daniel De Matteis * * 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 . */ #ifndef VIDEO_SHADER_DRIVER_H__ #define VIDEO_SHADER_DRIVER_H__ #include #include #include #include "video_coord_array.h" #ifdef HAVE_CONFIG_H #include "../config.h" #endif #if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) #ifndef HAVE_SHADER_MANAGER #define HAVE_SHADER_MANAGER #endif #include "video_shader_parse.h" #define VIDEO_SHADER_STOCK_BLEND (GFX_MAX_SHADERS - 1) #define VIDEO_SHADER_MENU (GFX_MAX_SHADERS - 2) #define VIDEO_SHADER_MENU_2 (GFX_MAX_SHADERS - 3) #define VIDEO_SHADER_MENU_3 (GFX_MAX_SHADERS - 4) #define VIDEO_SHADER_MENU_4 (GFX_MAX_SHADERS - 5) #define VIDEO_SHADER_MENU_5 (GFX_MAX_SHADERS - 6) #endif #if defined(_XBOX360) #define DEFAULT_SHADER_TYPE RARCH_SHADER_HLSL #elif defined(__PSL1GHT__) || defined(HAVE_OPENGLES2) || defined(HAVE_GLSL) #define DEFAULT_SHADER_TYPE RARCH_SHADER_GLSL #elif defined(__CELLOS_LV2__) || defined(HAVE_CG) #define DEFAULT_SHADER_TYPE RARCH_SHADER_CG #else #define DEFAULT_SHADER_TYPE RARCH_SHADER_NONE #endif #include "video_context_driver.h" RETRO_BEGIN_DECLS enum shader_uniform_type { UNIFORM_1F = 0, UNIFORM_2F, UNIFORM_3F, UNIFORM_4F, UNIFORM_1FV, UNIFORM_2FV, UNIFORM_3FV, UNIFORM_4FV, UNIFORM_1I }; enum shader_program_type { SHADER_PROGRAM_VERTEX = 0, SHADER_PROGRAM_FRAGMENT, SHADER_PROGRAM_COMBINED }; struct shader_program_info { void *data; const char *vertex; const char *fragment; const char *combined; unsigned idx; bool is_file; }; struct uniform_info { unsigned type; /* shader uniform type */ bool enabled; int32_t location; int32_t count; struct { enum shader_program_type type; const char *ident; uint32_t idx; bool add_prefix; bool enable; } lookup; struct { struct { intptr_t v0; intptr_t v1; intptr_t v2; intptr_t v3; } integer; intptr_t *integerv; struct { uintptr_t v0; uintptr_t v1; uintptr_t v2; uintptr_t v3; } unsigned_integer; uintptr_t *unsigned_integerv; struct { float v0; float v1; float v2; float v3; } f; float *floatv; } result; }; typedef struct shader_backend { void *(*init)(void *data, const char *path); void (*deinit)(void *data); /* Set shader parameters. */ void (*set_params)(void *data, void *shader_data, unsigned width, unsigned height, unsigned tex_width, unsigned tex_height, unsigned out_width, unsigned out_height, unsigned frame_counter, const void *info, const void *prev_info, const void *feedback_info, const void *fbo_info, unsigned fbo_info_cnt); void (*set_uniform_parameter)(void *data, struct uniform_info *param, void *uniform_data); /* Compile a shader program. */ bool (*compile_program)(void *data, unsigned idx, void *program_data, struct shader_program_info *program_info); /* Use a shader program specified by variable 'index'. */ void (*use)(void *data, void *shader_data, unsigned index, bool set_active); /* Returns the number of currently loaded shaders. */ unsigned (*num_shaders)(void *data); bool (*filter_type)(void *data, unsigned index, bool *smooth); enum gfx_wrap_type (*wrap_type)(void *data, unsigned index); void (*shader_scale)(void *data, unsigned index, struct gfx_fbo_scale *scale); bool (*set_coords)(void *handle_data, void *shader_data, const struct video_coords *coords); bool (*set_mvp)(void *data, void *shader_data, const math_matrix_4x4 *mat); unsigned (*get_prev_textures)(void *data); bool (*get_feedback_pass)(void *data, unsigned *pass); bool (*mipmap_input)(void *data, unsigned index); struct video_shader *(*get_current_shader)(void *data); enum rarch_shader_type type; /* Human readable string. */ const char *ident; } shader_backend_t; typedef struct video_shader_ctx_init { enum rarch_shader_type shader_type; const shader_backend_t *shader; struct { bool core_context_enabled; } gl; void *data; const char *path; } video_shader_ctx_init_t; typedef struct video_shader_ctx_params { void *data; unsigned width; unsigned height; unsigned tex_width; unsigned tex_height; unsigned out_width; unsigned out_height; unsigned frame_counter; const void *info; const void *prev_info; const void *feedback_info; const void *fbo_info; unsigned fbo_info_cnt; } video_shader_ctx_params_t; typedef struct video_shader_ctx_coords { void *handle_data; const void *data; } video_shader_ctx_coords_t; typedef struct video_shader_ctx_scale { unsigned idx; struct gfx_fbo_scale *scale; } video_shader_ctx_scale_t; typedef struct video_shader_ctx_info { bool set_active; unsigned num; unsigned idx; void *data; } video_shader_ctx_info_t; typedef struct video_shader_ctx_mvp { void *data; const math_matrix_4x4 *matrix; } video_shader_ctx_mvp_t; typedef struct video_shader_ctx_filter { unsigned index; bool *smooth; } video_shader_ctx_filter_t; typedef struct video_shader_ctx_wrap { unsigned idx; enum gfx_wrap_type type; } video_shader_ctx_wrap_t; typedef struct video_shader_ctx { struct video_shader *data; } video_shader_ctx_t; typedef struct video_shader_ctx_ident { const char *ident; } video_shader_ctx_ident_t; typedef struct video_shader_ctx_texture { unsigned id; } video_shader_ctx_texture_t; bool video_shader_driver_get_prev_textures(video_shader_ctx_texture_t *texture); bool video_shader_driver_get_ident(video_shader_ctx_ident_t *ident); bool video_shader_driver_get_current_shader(video_shader_ctx_t *shader); bool video_shader_driver_direct_get_current_shader(video_shader_ctx_t *shader); bool video_shader_driver_deinit(void); #define video_shader_driver_set_parameter(param) \ if (current_shader && current_shader->set_uniform_parameter) \ current_shader->set_uniform_parameter(shader_data, ¶m, NULL) #define video_shader_driver_set_parameters(params) \ if (current_shader && current_shader->set_params) \ current_shader->set_params(params.data, shader_data, params.width, params.height, params.tex_width, params.tex_height, params.out_width, params.out_height, params.frame_counter, params.info, params.prev_info, params.feedback_info, params.fbo_info, params.fbo_info_cnt) bool video_shader_driver_init_first(void); bool video_shader_driver_init(video_shader_ctx_init_t *init); bool video_shader_driver_get_feedback_pass(unsigned *data); bool video_shader_driver_mipmap_input(unsigned *index); #define video_shader_driver_set_coords(coords) \ if (current_shader && current_shader->set_coords) \ current_shader->set_coords(coords.handle_data, shader_data, (const struct video_coords*)coords.data) bool video_shader_driver_scale(video_shader_ctx_scale_t *scaler); bool video_shader_driver_info(video_shader_ctx_info_t *shader_info); #define video_shader_driver_set_mvp(mvp) \ if (mvp.matrix && current_shader && current_shader->set_mvp) \ current_shader->set_mvp(mvp.data, shader_data, mvp.matrix) \ bool video_shader_driver_filter_type(video_shader_ctx_filter_t *filter); bool video_shader_driver_compile_program(struct shader_program_info *program_info); #define video_shader_driver_use(shader_info) \ if (current_shader) \ current_shader->use(shader_info.data, shader_data, shader_info.idx, shader_info.set_active) bool video_shader_driver_wrap_type(video_shader_ctx_wrap_t *wrap); extern const shader_backend_t *current_shader; extern void *shader_data; extern const shader_backend_t gl_glsl_backend; extern const shader_backend_t hlsl_backend; extern const shader_backend_t gl_cg_backend; extern const shader_backend_t shader_null_backend; RETRO_END_DECLS #endif