2012-04-21 23:13:50 +02:00
|
|
|
/* RetroArch - A frontend for libretro.
|
2014-01-01 01:50:59 +01:00
|
|
|
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
2011-01-05 17:22:12 +01:00
|
|
|
*
|
2012-04-21 23:13:50 +02:00
|
|
|
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
2011-01-05 17:22:12 +01:00
|
|
|
* 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.
|
|
|
|
*
|
2012-04-21 23:13:50 +02:00
|
|
|
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
2011-01-05 17:22:12 +01:00
|
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
|
|
* PURPOSE. See the GNU General Public License for more details.
|
|
|
|
*
|
2012-04-21 23:31:57 +02:00
|
|
|
* You should have received a copy of the GNU General Public License along with RetroArch.
|
2011-01-05 17:22:12 +01:00
|
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2012-11-14 21:01:40 +01:00
|
|
|
#ifdef _MSC_VER
|
2012-11-15 09:40:31 +01:00
|
|
|
#pragma comment(lib, "cg")
|
|
|
|
#pragma comment(lib, "cggl")
|
2012-11-14 21:01:40 +01:00
|
|
|
#endif
|
|
|
|
|
2014-10-02 12:50:27 +02:00
|
|
|
#include <stdint.h>
|
2014-10-02 13:21:45 +02:00
|
|
|
#include "shader_context.h"
|
2014-10-02 13:32:42 +02:00
|
|
|
|
2011-01-05 17:22:12 +01:00
|
|
|
#include <Cg/cg.h>
|
2014-10-02 13:32:42 +02:00
|
|
|
|
|
|
|
#ifdef HAVE_OPENGL
|
|
|
|
#include "../gl_common.h"
|
2011-01-05 17:22:12 +01:00
|
|
|
#include <Cg/cgGL.h>
|
2014-10-02 15:17:21 +02:00
|
|
|
|
2014-10-02 13:32:42 +02:00
|
|
|
#endif
|
|
|
|
|
2011-03-06 19:56:35 +01:00
|
|
|
#include <string.h>
|
2014-10-21 07:58:58 +02:00
|
|
|
#include <compat/strl.h>
|
|
|
|
#include <compat/posix_string.h>
|
2014-10-22 03:35:04 +02:00
|
|
|
#include <file/config_file.h>
|
2014-10-02 00:45:11 +02:00
|
|
|
#include "../../dynamic.h"
|
2014-10-22 00:23:06 +02:00
|
|
|
#include <file/file_path.h>
|
2011-05-27 02:25:26 +02:00
|
|
|
|
2014-10-02 00:45:11 +02:00
|
|
|
#include "../state_tracker.h"
|
2011-01-05 17:22:12 +01:00
|
|
|
|
2014-09-08 17:57:18 +02:00
|
|
|
#if 0
|
|
|
|
#define RARCH_CG_DEBUG
|
|
|
|
#endif
|
2011-05-26 00:23:36 +02:00
|
|
|
|
2014-09-08 17:57:18 +02:00
|
|
|
/* Used when we call deactivate() since just unbinding
|
|
|
|
* the program didn't seem to work... */
|
2011-11-02 19:31:36 +01:00
|
|
|
static const char *stock_cg_program =
|
2013-07-06 10:40:24 +02:00
|
|
|
"struct input"
|
|
|
|
"{"
|
|
|
|
" float2 tex_coord;"
|
|
|
|
" float4 color;"
|
|
|
|
" float4 vertex_coord;"
|
|
|
|
" uniform float4x4 mvp_matrix;"
|
|
|
|
" uniform sampler2D texture;"
|
|
|
|
"};"
|
|
|
|
"struct vertex_data"
|
|
|
|
"{"
|
|
|
|
" float2 tex;"
|
|
|
|
" float4 color;"
|
|
|
|
"};"
|
2011-01-23 00:48:47 +01:00
|
|
|
"void main_vertex"
|
|
|
|
"("
|
|
|
|
" out float4 oPosition : POSITION,"
|
2013-07-06 10:40:24 +02:00
|
|
|
" input IN,"
|
|
|
|
" out vertex_data vert"
|
2011-01-23 00:48:47 +01:00
|
|
|
")"
|
|
|
|
"{"
|
2013-07-06 10:40:24 +02:00
|
|
|
" oPosition = mul(IN.mvp_matrix, IN.vertex_coord);"
|
|
|
|
" vert = vertex_data(IN.tex_coord, IN.color);"
|
2011-01-23 00:48:47 +01:00
|
|
|
"}"
|
|
|
|
""
|
2013-07-06 10:40:24 +02:00
|
|
|
"float4 main_fragment(input IN, vertex_data vert, uniform sampler2D s0 : TEXUNIT0) : COLOR"
|
2011-01-23 00:48:47 +01:00
|
|
|
"{"
|
2013-07-06 10:40:24 +02:00
|
|
|
" return vert.color * tex2D(s0, vert.tex);"
|
2011-01-23 00:48:47 +01:00
|
|
|
"}";
|
|
|
|
|
2012-04-21 23:25:32 +02:00
|
|
|
#ifdef RARCH_CG_DEBUG
|
2011-05-23 21:43:08 +02:00
|
|
|
static void cg_error_handler(CGcontext ctx, CGerror error, void *data)
|
|
|
|
{
|
|
|
|
(void)ctx;
|
|
|
|
(void)data;
|
|
|
|
|
2011-05-26 02:03:38 +02:00
|
|
|
switch (error)
|
|
|
|
{
|
|
|
|
case CG_INVALID_PARAM_HANDLE_ERROR:
|
2012-09-15 11:22:07 +02:00
|
|
|
RARCH_ERR("CG: Invalid param handle.\n");
|
2011-05-26 02:03:38 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case CG_INVALID_PARAMETER_ERROR:
|
2012-09-15 11:22:07 +02:00
|
|
|
RARCH_ERR("CG: Invalid parameter.\n");
|
2011-05-26 02:03:38 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2012-09-15 11:22:07 +02:00
|
|
|
RARCH_ERR("CG error: \"%s\"\n", cgGetErrorString(error));
|
2011-05-23 21:43:08 +02:00
|
|
|
}
|
|
|
|
#endif
|
2011-01-23 00:48:47 +01:00
|
|
|
|
2011-01-05 17:22:12 +01:00
|
|
|
static CGcontext cgCtx;
|
2011-05-23 21:04:25 +02:00
|
|
|
|
|
|
|
struct cg_fbo_params
|
|
|
|
{
|
|
|
|
CGparameter vid_size_f;
|
|
|
|
CGparameter tex_size_f;
|
|
|
|
CGparameter vid_size_v;
|
|
|
|
CGparameter tex_size_v;
|
|
|
|
CGparameter tex;
|
|
|
|
CGparameter coord;
|
|
|
|
};
|
|
|
|
|
2011-05-27 02:25:26 +02:00
|
|
|
#define MAX_VARIABLES 64
|
2013-07-06 22:10:09 +02:00
|
|
|
#define PREV_TEXTURES (MAX_TEXTURES - 1)
|
2011-05-23 21:04:25 +02:00
|
|
|
|
2011-03-06 19:56:35 +01:00
|
|
|
struct cg_program
|
|
|
|
{
|
|
|
|
CGprogram vprg;
|
|
|
|
CGprogram fprg;
|
2012-09-15 11:22:07 +02:00
|
|
|
|
|
|
|
CGparameter tex;
|
|
|
|
CGparameter lut_tex;
|
|
|
|
CGparameter color;
|
|
|
|
CGparameter vertex;
|
|
|
|
|
2011-03-06 19:56:35 +01:00
|
|
|
CGparameter vid_size_f;
|
|
|
|
CGparameter tex_size_f;
|
|
|
|
CGparameter out_size_f;
|
2011-05-11 13:24:59 +02:00
|
|
|
CGparameter frame_cnt_f;
|
2011-11-09 23:45:34 +01:00
|
|
|
CGparameter frame_dir_f;
|
2011-03-06 19:56:35 +01:00
|
|
|
CGparameter vid_size_v;
|
|
|
|
CGparameter tex_size_v;
|
|
|
|
CGparameter out_size_v;
|
2011-05-11 13:24:59 +02:00
|
|
|
CGparameter frame_cnt_v;
|
2011-11-09 23:45:34 +01:00
|
|
|
CGparameter frame_dir_v;
|
2011-03-06 19:56:35 +01:00
|
|
|
CGparameter mvp;
|
2011-05-23 21:04:25 +02:00
|
|
|
|
2013-04-20 15:46:50 +02:00
|
|
|
struct cg_fbo_params fbo[GFX_MAX_SHADERS];
|
2011-05-23 21:04:25 +02:00
|
|
|
struct cg_fbo_params orig;
|
2011-11-12 12:55:03 +01:00
|
|
|
struct cg_fbo_params prev[PREV_TEXTURES];
|
2011-03-06 19:56:35 +01:00
|
|
|
};
|
|
|
|
|
2013-04-20 15:46:50 +02:00
|
|
|
static struct cg_program prg[GFX_MAX_SHADERS];
|
2013-04-06 11:30:56 +02:00
|
|
|
static bool cg_active;
|
2011-03-06 19:56:35 +01:00
|
|
|
static CGprofile cgVProf, cgFProf;
|
2014-10-20 19:27:32 +02:00
|
|
|
static unsigned active_idx;
|
2013-04-06 11:30:56 +02:00
|
|
|
|
|
|
|
static struct gfx_shader *cg_shader;
|
2011-01-05 17:22:12 +01:00
|
|
|
|
2013-04-06 11:30:56 +02:00
|
|
|
static state_tracker_t *state_tracker;
|
2014-05-08 13:39:12 -04:00
|
|
|
static GLuint lut_textures[GFX_MAX_TEXTURES];
|
2011-05-22 18:48:43 +02:00
|
|
|
|
2013-04-20 15:46:50 +02:00
|
|
|
static CGparameter cg_attribs[PREV_TEXTURES + 1 + 4 + GFX_MAX_SHADERS];
|
2014-10-20 19:27:32 +02:00
|
|
|
static unsigned cg_attrib_idx;
|
2011-11-12 18:31:22 +01:00
|
|
|
|
2014-05-23 15:19:32 +02:00
|
|
|
static char cg_alias_define[GFX_MAX_SHADERS][128];
|
|
|
|
|
2011-11-12 18:31:22 +01:00
|
|
|
static void gl_cg_reset_attrib(void)
|
|
|
|
{
|
2013-10-22 21:26:33 +02:00
|
|
|
unsigned i;
|
2014-09-08 17:57:18 +02:00
|
|
|
/* Add sanity check that we did not overflow. */
|
2014-10-20 19:27:32 +02:00
|
|
|
rarch_assert(cg_attrib_idx <= ARRAY_SIZE(cg_attribs));
|
2014-05-28 19:30:03 +02:00
|
|
|
|
2014-10-20 19:27:32 +02:00
|
|
|
for (i = 0; i < cg_attrib_idx; i++)
|
2011-11-12 18:31:22 +01:00
|
|
|
cgGLDisableClientState(cg_attribs[i]);
|
2014-10-20 19:27:32 +02:00
|
|
|
cg_attrib_idx = 0;
|
2011-11-12 18:31:22 +01:00
|
|
|
}
|
|
|
|
|
2014-03-07 05:51:56 +01:00
|
|
|
static bool gl_cg_set_mvp(void *data, const math_matrix *mat)
|
2011-01-05 17:22:12 +01:00
|
|
|
{
|
2014-03-07 05:51:56 +01:00
|
|
|
(void)data;
|
2014-10-20 19:27:32 +02:00
|
|
|
if (cg_active && prg[active_idx].mvp)
|
2012-09-11 23:32:00 +02:00
|
|
|
{
|
2014-10-20 19:27:32 +02:00
|
|
|
cgGLSetMatrixParameterfc(prg[active_idx].mvp, mat->data);
|
2012-09-11 23:32:00 +02:00
|
|
|
return true;
|
|
|
|
}
|
2014-08-27 03:28:22 +02:00
|
|
|
|
2014-10-02 15:17:21 +02:00
|
|
|
#ifndef NO_GL_FF_MATRIX
|
|
|
|
gl_ff_matrix(mat);
|
|
|
|
#endif
|
2014-08-27 03:28:22 +02:00
|
|
|
return false;
|
2012-09-11 23:32:00 +02:00
|
|
|
}
|
|
|
|
|
2012-09-15 11:22:07 +02:00
|
|
|
#define SET_COORD(name, coords_name, len) do { \
|
2014-10-20 19:27:32 +02:00
|
|
|
if (prg[active_idx].name) \
|
2012-09-15 11:22:07 +02:00
|
|
|
{ \
|
2014-10-20 19:27:32 +02:00
|
|
|
cgGLSetParameterPointer(prg[active_idx].name, len, GL_FLOAT, 0, coords->coords_name); \
|
|
|
|
cgGLEnableClientState(prg[active_idx].name); \
|
|
|
|
cg_attribs[cg_attrib_idx++] = prg[active_idx].name; \
|
2012-09-15 11:22:07 +02:00
|
|
|
} \
|
|
|
|
} while(0)
|
|
|
|
|
2014-10-02 11:11:34 +02:00
|
|
|
static bool gl_cg_set_coords(const void *data)
|
2012-09-11 23:32:00 +02:00
|
|
|
{
|
2014-10-02 11:11:34 +02:00
|
|
|
const struct gl_coords *coords = (const struct gl_coords*)data;
|
|
|
|
if (!cg_active || !coords)
|
2014-10-02 15:17:21 +02:00
|
|
|
goto fallback;
|
2012-09-15 11:22:07 +02:00
|
|
|
|
|
|
|
SET_COORD(vertex, vertex, 2);
|
|
|
|
SET_COORD(tex, tex_coord, 2);
|
|
|
|
SET_COORD(lut_tex, lut_tex_coord, 2);
|
|
|
|
SET_COORD(color, color, 4);
|
|
|
|
|
|
|
|
return true;
|
2014-10-02 15:17:21 +02:00
|
|
|
fallback:
|
|
|
|
#ifndef NO_GL_FF_VERTEX
|
|
|
|
gl_ff_vertex(coords);
|
|
|
|
#endif
|
|
|
|
return false;
|
2011-01-05 17:22:12 +01:00
|
|
|
}
|
|
|
|
|
2011-05-23 21:43:08 +02:00
|
|
|
#define set_param_2f(param, x, y) \
|
|
|
|
if (param) cgGLSetParameter2f(param, x, y)
|
|
|
|
#define set_param_1f(param, x) \
|
|
|
|
if (param) cgGLSetParameter1f(param, x)
|
|
|
|
|
2014-03-07 05:51:56 +01:00
|
|
|
static void gl_cg_set_params(void *data, unsigned width, unsigned height,
|
2011-01-05 17:22:12 +01:00
|
|
|
unsigned tex_width, unsigned tex_height,
|
2011-05-11 13:24:59 +02:00
|
|
|
unsigned out_width, unsigned out_height,
|
2011-05-23 17:41:52 +02:00
|
|
|
unsigned frame_count,
|
2014-10-02 11:11:34 +02:00
|
|
|
const void *_info,
|
|
|
|
const void *_prev_info,
|
|
|
|
const void *_fbo_info,
|
2011-05-23 19:57:52 +02:00
|
|
|
unsigned fbo_info_cnt)
|
2011-01-05 17:22:12 +01:00
|
|
|
{
|
2014-10-02 11:11:34 +02:00
|
|
|
const struct gl_tex_info *info = (const struct gl_tex_info*)_info;
|
|
|
|
const struct gl_tex_info *prev_info = (const struct gl_tex_info*)_prev_info;
|
|
|
|
const struct gl_tex_info *fbo_info = (const struct gl_tex_info*)_fbo_info;
|
2013-10-22 21:26:33 +02:00
|
|
|
unsigned i;
|
2014-10-02 11:11:34 +02:00
|
|
|
|
|
|
|
(void)data;
|
2014-10-20 19:27:32 +02:00
|
|
|
if (!cg_active || (active_idx == 0) ||
|
|
|
|
(active_idx == GL_SHADER_STOCK_BLEND))
|
2011-11-12 18:31:22 +01:00
|
|
|
return;
|
|
|
|
|
2014-09-08 17:57:18 +02:00
|
|
|
/* Set frame. */
|
2014-10-20 19:27:32 +02:00
|
|
|
set_param_2f(prg[active_idx].vid_size_f, width, height);
|
|
|
|
set_param_2f(prg[active_idx].tex_size_f, tex_width, tex_height);
|
|
|
|
set_param_2f(prg[active_idx].out_size_f, out_width, out_height);
|
|
|
|
set_param_1f(prg[active_idx].frame_dir_f,
|
2014-09-08 17:57:18 +02:00
|
|
|
g_extern.frame_is_reverse ? -1.0 : 1.0);
|
2011-11-12 18:31:22 +01:00
|
|
|
|
2014-10-20 19:27:32 +02:00
|
|
|
set_param_2f(prg[active_idx].vid_size_v, width, height);
|
|
|
|
set_param_2f(prg[active_idx].tex_size_v, tex_width, tex_height);
|
|
|
|
set_param_2f(prg[active_idx].out_size_v, out_width, out_height);
|
|
|
|
set_param_1f(prg[active_idx].frame_dir_v,
|
2014-09-08 17:57:18 +02:00
|
|
|
g_extern.frame_is_reverse ? -1.0 : 1.0);
|
2011-11-12 18:31:22 +01:00
|
|
|
|
2014-10-20 19:27:32 +02:00
|
|
|
if (prg[active_idx].frame_cnt_f || prg[active_idx].frame_cnt_v)
|
2013-03-25 14:47:33 +01:00
|
|
|
{
|
2014-10-20 19:27:32 +02:00
|
|
|
unsigned modulo = cg_shader->pass[active_idx - 1].frame_count_mod;
|
2013-04-06 11:30:56 +02:00
|
|
|
if (modulo)
|
|
|
|
frame_count %= modulo;
|
2013-03-25 14:47:33 +01:00
|
|
|
|
2014-10-20 19:27:32 +02:00
|
|
|
set_param_1f(prg[active_idx].frame_cnt_f, (float)frame_count);
|
|
|
|
set_param_1f(prg[active_idx].frame_cnt_v, (float)frame_count);
|
2013-03-25 14:47:33 +01:00
|
|
|
}
|
|
|
|
|
2014-09-08 17:57:18 +02:00
|
|
|
/* Set orig texture. */
|
2014-10-20 19:27:32 +02:00
|
|
|
CGparameter param = prg[active_idx].orig.tex;
|
2011-11-12 18:31:22 +01:00
|
|
|
if (param)
|
|
|
|
{
|
|
|
|
cgGLSetTextureParameter(param, info->tex);
|
|
|
|
cgGLEnableTextureParameter(param);
|
|
|
|
}
|
|
|
|
|
2014-10-20 19:27:32 +02:00
|
|
|
set_param_2f(prg[active_idx].orig.vid_size_v,
|
2014-09-08 17:57:18 +02:00
|
|
|
info->input_size[0], info->input_size[1]);
|
2014-10-20 19:27:32 +02:00
|
|
|
set_param_2f(prg[active_idx].orig.vid_size_f,
|
2014-09-08 17:57:18 +02:00
|
|
|
info->input_size[0], info->input_size[1]);
|
2014-10-20 19:27:32 +02:00
|
|
|
set_param_2f(prg[active_idx].orig.tex_size_v,
|
2014-09-08 17:57:18 +02:00
|
|
|
info->tex_size[0], info->tex_size[1]);
|
2014-10-20 19:27:32 +02:00
|
|
|
set_param_2f(prg[active_idx].orig.tex_size_f,
|
2014-09-08 17:57:18 +02:00
|
|
|
info->tex_size[0], info->tex_size[1]);
|
2014-10-20 19:27:32 +02:00
|
|
|
if (prg[active_idx].orig.coord)
|
2011-11-12 18:31:22 +01:00
|
|
|
{
|
2014-10-20 19:27:32 +02:00
|
|
|
cgGLSetParameterPointer(prg[active_idx].orig.coord, 2,
|
2014-09-08 17:57:18 +02:00
|
|
|
GL_FLOAT, 0, info->coord);
|
2014-10-20 19:27:32 +02:00
|
|
|
cgGLEnableClientState(prg[active_idx].orig.coord);
|
|
|
|
cg_attribs[cg_attrib_idx++] = prg[active_idx].orig.coord;
|
2011-11-12 18:31:22 +01:00
|
|
|
}
|
|
|
|
|
2014-09-08 17:57:18 +02:00
|
|
|
/* Set prev textures. */
|
2013-10-22 21:26:33 +02:00
|
|
|
for (i = 0; i < PREV_TEXTURES; i++)
|
2011-01-05 17:22:12 +01:00
|
|
|
{
|
2014-10-20 19:27:32 +02:00
|
|
|
param = prg[active_idx].prev[i].tex;
|
2011-05-26 02:03:38 +02:00
|
|
|
if (param)
|
|
|
|
{
|
2011-11-12 18:31:22 +01:00
|
|
|
cgGLSetTextureParameter(param, prev_info[i].tex);
|
2011-05-26 02:03:38 +02:00
|
|
|
cgGLEnableTextureParameter(param);
|
|
|
|
}
|
|
|
|
|
2014-10-20 19:27:32 +02:00
|
|
|
set_param_2f(prg[active_idx].prev[i].vid_size_v,
|
2014-09-08 17:57:18 +02:00
|
|
|
prev_info[i].input_size[0], prev_info[i].input_size[1]);
|
2014-10-20 19:27:32 +02:00
|
|
|
set_param_2f(prg[active_idx].prev[i].vid_size_f,
|
2014-09-08 17:57:18 +02:00
|
|
|
prev_info[i].input_size[0], prev_info[i].input_size[1]);
|
2014-10-20 19:27:32 +02:00
|
|
|
set_param_2f(prg[active_idx].prev[i].tex_size_v,
|
2014-09-08 17:57:18 +02:00
|
|
|
prev_info[i].tex_size[0], prev_info[i].tex_size[1]);
|
2014-10-20 19:27:32 +02:00
|
|
|
set_param_2f(prg[active_idx].prev[i].tex_size_f,
|
2014-09-08 17:57:18 +02:00
|
|
|
prev_info[i].tex_size[0], prev_info[i].tex_size[1]);
|
2011-11-12 18:31:22 +01:00
|
|
|
|
2014-10-20 19:27:32 +02:00
|
|
|
if (prg[active_idx].prev[i].coord)
|
2011-05-26 02:03:38 +02:00
|
|
|
{
|
2014-10-20 19:27:32 +02:00
|
|
|
cgGLSetParameterPointer(prg[active_idx].prev[i].coord,
|
2014-09-08 17:57:18 +02:00
|
|
|
2, GL_FLOAT, 0, prev_info[i].coord);
|
2014-10-20 19:27:32 +02:00
|
|
|
cgGLEnableClientState(prg[active_idx].prev[i].coord);
|
|
|
|
cg_attribs[cg_attrib_idx++] = prg[active_idx].prev[i].coord;
|
2011-05-26 02:03:38 +02:00
|
|
|
}
|
2011-11-12 18:31:22 +01:00
|
|
|
}
|
2011-05-26 02:03:38 +02:00
|
|
|
|
2014-09-08 17:57:18 +02:00
|
|
|
/* Set lookup textures. */
|
2013-10-22 21:26:33 +02:00
|
|
|
for (i = 0; i < cg_shader->luts; i++)
|
2011-11-12 18:31:22 +01:00
|
|
|
{
|
2014-09-08 17:57:18 +02:00
|
|
|
CGparameter fparam = cgGetNamedParameter(
|
2014-10-20 19:27:32 +02:00
|
|
|
prg[active_idx].fprg, cg_shader->lut[i].id);
|
2014-09-08 17:57:18 +02:00
|
|
|
|
2013-04-16 14:27:24 +02:00
|
|
|
if (fparam)
|
2011-07-03 15:39:35 +02:00
|
|
|
{
|
2013-04-16 14:27:24 +02:00
|
|
|
cgGLSetTextureParameter(fparam, lut_textures[i]);
|
|
|
|
cgGLEnableTextureParameter(fparam);
|
|
|
|
}
|
|
|
|
|
2014-09-08 17:57:18 +02:00
|
|
|
CGparameter vparam = cgGetNamedParameter(
|
2014-10-20 19:27:32 +02:00
|
|
|
prg[active_idx].vprg, cg_shader->lut[i].id);
|
2013-04-16 14:27:24 +02:00
|
|
|
if (vparam)
|
|
|
|
{
|
|
|
|
cgGLSetTextureParameter(vparam, lut_textures[i]);
|
|
|
|
cgGLEnableTextureParameter(vparam);
|
2011-07-03 15:39:35 +02:00
|
|
|
}
|
2011-11-12 18:31:22 +01:00
|
|
|
}
|
2011-07-03 15:39:35 +02:00
|
|
|
|
2014-09-08 17:57:18 +02:00
|
|
|
/* Set FBO textures. */
|
2014-10-20 19:27:32 +02:00
|
|
|
if (active_idx)
|
2011-11-12 18:31:22 +01:00
|
|
|
{
|
2013-10-22 21:26:33 +02:00
|
|
|
for (i = 0; i < fbo_info_cnt; i++)
|
2011-05-22 18:48:43 +02:00
|
|
|
{
|
2014-10-20 19:27:32 +02:00
|
|
|
if (prg[active_idx].fbo[i].tex)
|
2011-05-23 21:43:08 +02:00
|
|
|
{
|
2014-09-08 17:57:18 +02:00
|
|
|
cgGLSetTextureParameter(
|
2014-10-20 19:27:32 +02:00
|
|
|
prg[active_idx].fbo[i].tex, fbo_info[i].tex);
|
|
|
|
cgGLEnableTextureParameter(prg[active_idx].fbo[i].tex);
|
2011-05-23 21:43:08 +02:00
|
|
|
}
|
2011-05-23 21:04:25 +02:00
|
|
|
|
2014-10-20 19:27:32 +02:00
|
|
|
set_param_2f(prg[active_idx].fbo[i].vid_size_v,
|
2014-09-08 17:57:18 +02:00
|
|
|
fbo_info[i].input_size[0], fbo_info[i].input_size[1]);
|
2014-10-20 19:27:32 +02:00
|
|
|
set_param_2f(prg[active_idx].fbo[i].vid_size_f,
|
2014-09-08 17:57:18 +02:00
|
|
|
fbo_info[i].input_size[0], fbo_info[i].input_size[1]);
|
2011-05-23 21:04:25 +02:00
|
|
|
|
2014-10-20 19:27:32 +02:00
|
|
|
set_param_2f(prg[active_idx].fbo[i].tex_size_v,
|
2014-09-08 17:57:18 +02:00
|
|
|
fbo_info[i].tex_size[0], fbo_info[i].tex_size[1]);
|
2014-10-20 19:27:32 +02:00
|
|
|
set_param_2f(prg[active_idx].fbo[i].tex_size_f,
|
2014-09-08 17:57:18 +02:00
|
|
|
fbo_info[i].tex_size[0], fbo_info[i].tex_size[1]);
|
2011-05-23 21:04:25 +02:00
|
|
|
|
2014-10-20 19:27:32 +02:00
|
|
|
if (prg[active_idx].fbo[i].coord)
|
2011-11-12 18:31:22 +01:00
|
|
|
{
|
2014-10-20 19:27:32 +02:00
|
|
|
cgGLSetParameterPointer(prg[active_idx].fbo[i].coord,
|
2014-09-08 17:57:18 +02:00
|
|
|
2, GL_FLOAT, 0, fbo_info[i].coord);
|
2014-10-20 19:27:32 +02:00
|
|
|
cgGLEnableClientState(prg[active_idx].fbo[i].coord);
|
|
|
|
cg_attribs[cg_attrib_idx++] = prg[active_idx].fbo[i].coord;
|
2011-05-23 21:04:25 +02:00
|
|
|
}
|
|
|
|
}
|
2011-11-12 18:31:22 +01:00
|
|
|
}
|
2011-05-27 02:25:26 +02:00
|
|
|
|
2014-09-08 17:57:18 +02:00
|
|
|
/* #pragma parameters. */
|
2014-05-23 12:09:57 +02:00
|
|
|
for (i = 0; i < cg_shader->num_parameters; i++)
|
|
|
|
{
|
2014-09-08 17:57:18 +02:00
|
|
|
CGparameter param_v = cgGetNamedParameter(
|
2014-10-20 19:27:32 +02:00
|
|
|
prg[active_idx].vprg, cg_shader->parameters[i].id);
|
2014-09-08 17:57:18 +02:00
|
|
|
CGparameter param_f = cgGetNamedParameter(
|
2014-10-20 19:27:32 +02:00
|
|
|
prg[active_idx].fprg, cg_shader->parameters[i].id);
|
2014-05-23 12:09:57 +02:00
|
|
|
set_param_1f(param_v, cg_shader->parameters[i].current);
|
|
|
|
set_param_1f(param_f, cg_shader->parameters[i].current);
|
|
|
|
}
|
|
|
|
|
2014-09-08 17:57:18 +02:00
|
|
|
/* Set state parameters. */
|
2012-04-07 12:17:40 +02:00
|
|
|
if (state_tracker)
|
2011-11-12 18:31:22 +01:00
|
|
|
{
|
2014-09-08 17:57:18 +02:00
|
|
|
/* Only query uniforms in first pass. */
|
2014-10-21 02:21:13 +02:00
|
|
|
static struct state_tracker_uniform tracker_info[MAX_VARIABLES];
|
2011-11-12 18:31:22 +01:00
|
|
|
static unsigned cnt = 0;
|
2011-06-08 17:59:29 +02:00
|
|
|
|
2014-10-20 19:27:32 +02:00
|
|
|
if (active_idx == 1)
|
2014-10-21 02:21:13 +02:00
|
|
|
cnt = state_get_uniform(state_tracker, tracker_info,
|
2014-09-08 17:57:18 +02:00
|
|
|
MAX_VARIABLES, frame_count);
|
2011-06-08 17:59:29 +02:00
|
|
|
|
2013-10-22 21:26:33 +02:00
|
|
|
for (i = 0; i < cnt; i++)
|
2011-11-12 18:31:22 +01:00
|
|
|
{
|
2014-09-08 17:57:18 +02:00
|
|
|
CGparameter param_v = cgGetNamedParameter(
|
2014-10-21 02:21:13 +02:00
|
|
|
prg[active_idx].vprg, tracker_info[i].id);
|
2014-09-08 17:57:18 +02:00
|
|
|
CGparameter param_f = cgGetNamedParameter(
|
2014-10-21 02:21:13 +02:00
|
|
|
prg[active_idx].fprg, tracker_info[i].id);
|
|
|
|
set_param_1f(param_v, tracker_info[i].value);
|
|
|
|
set_param_1f(param_f, tracker_info[i].value);
|
2011-05-27 02:25:26 +02:00
|
|
|
}
|
2011-01-05 17:22:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-20 16:22:58 +01:00
|
|
|
static void gl_cg_deinit_progs(void)
|
2011-01-05 17:22:12 +01:00
|
|
|
{
|
2013-10-22 21:26:33 +02:00
|
|
|
unsigned i;
|
2012-09-15 11:22:07 +02:00
|
|
|
RARCH_LOG("CG: Destroying programs.\n");
|
2012-02-20 16:22:58 +01:00
|
|
|
cgGLUnbindProgram(cgFProf);
|
|
|
|
cgGLUnbindProgram(cgVProf);
|
|
|
|
|
2014-09-08 17:57:18 +02:00
|
|
|
/* Programs may alias [0]. */
|
2013-10-22 21:26:33 +02:00
|
|
|
for (i = 1; i < GFX_MAX_SHADERS; i++)
|
2012-02-20 16:22:58 +01:00
|
|
|
{
|
2012-09-15 11:22:07 +02:00
|
|
|
if (prg[i].fprg && prg[i].fprg != prg[0].fprg)
|
2012-02-20 16:22:58 +01:00
|
|
|
cgDestroyProgram(prg[i].fprg);
|
2012-09-15 11:22:07 +02:00
|
|
|
if (prg[i].vprg && prg[i].vprg != prg[0].vprg)
|
2012-02-20 16:22:58 +01:00
|
|
|
cgDestroyProgram(prg[i].vprg);
|
|
|
|
}
|
2011-06-11 22:02:05 +02:00
|
|
|
|
2012-02-20 16:22:58 +01:00
|
|
|
if (prg[0].fprg)
|
|
|
|
cgDestroyProgram(prg[0].fprg);
|
|
|
|
if (prg[0].vprg)
|
|
|
|
cgDestroyProgram(prg[0].vprg);
|
|
|
|
|
|
|
|
memset(prg, 0, sizeof(prg));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void gl_cg_deinit_state(void)
|
|
|
|
{
|
2011-11-12 18:31:22 +01:00
|
|
|
gl_cg_reset_attrib();
|
2013-04-01 15:34:02 +02:00
|
|
|
cg_active = false;
|
2012-02-20 16:22:58 +01:00
|
|
|
|
|
|
|
gl_cg_deinit_progs();
|
|
|
|
|
2013-04-06 11:30:56 +02:00
|
|
|
if (cg_shader && cg_shader->luts)
|
|
|
|
{
|
|
|
|
glDeleteTextures(cg_shader->luts, lut_textures);
|
|
|
|
memset(lut_textures, 0, sizeof(lut_textures));
|
|
|
|
}
|
2011-05-27 02:25:26 +02:00
|
|
|
|
2012-04-07 12:17:40 +02:00
|
|
|
if (state_tracker)
|
2011-05-27 02:25:26 +02:00
|
|
|
{
|
2012-04-07 12:17:40 +02:00
|
|
|
state_tracker_free(state_tracker);
|
|
|
|
state_tracker = NULL;
|
2011-05-27 02:25:26 +02:00
|
|
|
}
|
2013-04-06 11:30:56 +02:00
|
|
|
|
|
|
|
free(cg_shader);
|
|
|
|
cg_shader = NULL;
|
2012-02-20 16:22:58 +01:00
|
|
|
}
|
2011-06-11 22:02:05 +02:00
|
|
|
|
2014-09-08 17:57:18 +02:00
|
|
|
/* Final deinit. */
|
2012-02-20 16:22:58 +01:00
|
|
|
static void gl_cg_deinit_context_state(void)
|
|
|
|
{
|
|
|
|
if (cgCtx)
|
|
|
|
{
|
2012-09-15 11:22:07 +02:00
|
|
|
RARCH_LOG("CG: Destroying context.\n");
|
2012-02-20 16:22:58 +01:00
|
|
|
cgDestroyContext(cgCtx);
|
|
|
|
cgCtx = NULL;
|
|
|
|
}
|
2011-01-05 17:22:12 +01:00
|
|
|
}
|
|
|
|
|
2014-09-08 17:57:18 +02:00
|
|
|
/* Full deinit. */
|
2013-04-12 21:25:16 +02:00
|
|
|
static void gl_cg_deinit(void)
|
2012-02-20 16:22:58 +01:00
|
|
|
{
|
|
|
|
gl_cg_deinit_state();
|
|
|
|
gl_cg_deinit_context_state();
|
|
|
|
}
|
|
|
|
|
2011-11-10 00:46:39 +01:00
|
|
|
#define SET_LISTING(type) \
|
|
|
|
{ \
|
|
|
|
const char *list = cgGetLastListing(cgCtx); \
|
|
|
|
if (list) \
|
|
|
|
listing_##type = strdup(list); \
|
|
|
|
}
|
|
|
|
|
2014-10-20 19:27:32 +02:00
|
|
|
static bool load_program(unsigned idx,
|
2014-09-08 17:57:18 +02:00
|
|
|
const char *prog, bool path_is_file)
|
2011-01-05 17:22:12 +01:00
|
|
|
{
|
2012-01-25 21:56:21 +01:00
|
|
|
bool ret = true;
|
2012-01-25 22:55:34 +01:00
|
|
|
char *listing_f = NULL;
|
|
|
|
char *listing_v = NULL;
|
2011-07-04 13:33:09 +02:00
|
|
|
|
2014-05-23 15:19:32 +02:00
|
|
|
unsigned i, argc = 1;
|
2014-05-23 15:24:58 +02:00
|
|
|
const char *argv[2 + GFX_MAX_SHADERS] = {
|
2014-05-23 12:09:57 +02:00
|
|
|
"-DPARAMETER_UNIFORM",
|
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
2014-05-23 15:19:32 +02:00
|
|
|
for (i = 0; i < GFX_MAX_SHADERS; i++)
|
|
|
|
{
|
|
|
|
if (*(cg_alias_define[i]))
|
|
|
|
argv[argc++] = cg_alias_define[i];
|
|
|
|
}
|
|
|
|
|
2012-01-25 22:55:34 +01:00
|
|
|
if (path_is_file)
|
2011-01-05 17:22:12 +01:00
|
|
|
{
|
2014-10-20 19:27:32 +02:00
|
|
|
prg[idx].fprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE,
|
2014-09-08 17:57:18 +02:00
|
|
|
prog, cgFProf, "main_fragment", argv);
|
2012-01-25 22:55:34 +01:00
|
|
|
SET_LISTING(f);
|
2014-10-20 19:27:32 +02:00
|
|
|
prg[idx].vprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE,
|
2014-09-08 17:57:18 +02:00
|
|
|
prog, cgVProf, "main_vertex", argv);
|
2012-01-25 22:55:34 +01:00
|
|
|
SET_LISTING(v);
|
2011-03-06 19:56:35 +01:00
|
|
|
}
|
|
|
|
else
|
2011-05-22 17:02:09 +02:00
|
|
|
{
|
2014-10-20 19:27:32 +02:00
|
|
|
prg[idx].fprg = cgCreateProgram(cgCtx, CG_SOURCE,
|
2014-09-08 17:57:18 +02:00
|
|
|
prog, cgFProf, "main_fragment", argv);
|
2012-01-25 22:55:34 +01:00
|
|
|
SET_LISTING(f);
|
2014-10-20 19:27:32 +02:00
|
|
|
prg[idx].vprg = cgCreateProgram(cgCtx, CG_SOURCE,
|
2014-09-08 17:57:18 +02:00
|
|
|
prog, cgVProf, "main_vertex", argv);
|
2012-01-25 22:55:34 +01:00
|
|
|
SET_LISTING(v);
|
2011-05-22 17:02:09 +02:00
|
|
|
}
|
2011-03-06 19:56:35 +01:00
|
|
|
|
2014-10-20 19:27:32 +02:00
|
|
|
if (!prg[idx].fprg || !prg[idx].vprg)
|
2011-03-06 19:56:35 +01:00
|
|
|
{
|
2012-04-21 23:25:32 +02:00
|
|
|
RARCH_ERR("CG error: %s\n", cgGetErrorString(cgGetError()));
|
2012-01-25 22:55:34 +01:00
|
|
|
if (listing_f)
|
2012-04-21 23:25:32 +02:00
|
|
|
RARCH_ERR("Fragment:\n%s\n", listing_f);
|
2012-01-25 22:55:34 +01:00
|
|
|
else if (listing_v)
|
2012-04-21 23:25:32 +02:00
|
|
|
RARCH_ERR("Vertex:\n%s\n", listing_v);
|
2011-03-06 19:56:35 +01:00
|
|
|
|
2012-01-25 22:55:34 +01:00
|
|
|
ret = false;
|
|
|
|
goto end;
|
2011-01-05 17:22:12 +01:00
|
|
|
}
|
2011-03-06 19:56:35 +01:00
|
|
|
|
2014-10-20 19:27:32 +02:00
|
|
|
cgGLLoadProgram(prg[idx].fprg);
|
|
|
|
cgGLLoadProgram(prg[idx].vprg);
|
2012-01-25 22:55:34 +01:00
|
|
|
|
2012-01-25 21:56:21 +01:00
|
|
|
end:
|
2012-01-25 22:55:34 +01:00
|
|
|
free(listing_f);
|
|
|
|
free(listing_v);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2012-09-15 11:22:07 +02:00
|
|
|
static void set_program_base_attrib(unsigned i);
|
|
|
|
|
2012-01-25 22:55:34 +01:00
|
|
|
static bool load_stock(void)
|
|
|
|
{
|
|
|
|
if (!load_program(0, stock_cg_program, false))
|
2011-11-10 00:46:39 +01:00
|
|
|
{
|
2012-04-21 23:25:32 +02:00
|
|
|
RARCH_ERR("Failed to compile passthrough shader, is something wrong with your environment?\n");
|
2012-01-25 22:55:34 +01:00
|
|
|
return false;
|
2011-11-10 00:46:39 +01:00
|
|
|
}
|
|
|
|
|
2012-09-15 11:22:07 +02:00
|
|
|
set_program_base_attrib(0);
|
|
|
|
|
2012-01-25 22:55:34 +01:00
|
|
|
return true;
|
2012-01-25 21:56:21 +01:00
|
|
|
}
|
2011-07-04 13:33:09 +02:00
|
|
|
|
2012-01-25 22:55:34 +01:00
|
|
|
static bool load_plain(const char *path)
|
2012-01-25 21:56:21 +01:00
|
|
|
{
|
2012-01-25 22:55:34 +01:00
|
|
|
if (!load_stock())
|
|
|
|
return false;
|
2012-01-25 21:56:21 +01:00
|
|
|
|
2013-04-06 11:30:56 +02:00
|
|
|
cg_shader = (struct gfx_shader*)calloc(1, sizeof(*cg_shader));
|
|
|
|
if (!cg_shader)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
cg_shader->passes = 1;
|
|
|
|
|
2013-01-08 03:46:18 +01:00
|
|
|
if (path)
|
2011-07-04 13:33:09 +02:00
|
|
|
{
|
2013-01-08 03:46:18 +01:00
|
|
|
RARCH_LOG("Loading Cg file: %s\n", path);
|
2014-09-08 17:57:18 +02:00
|
|
|
strlcpy(cg_shader->pass[0].source.path, path,
|
|
|
|
sizeof(cg_shader->pass[0].source.path));
|
2013-01-08 03:46:18 +01:00
|
|
|
if (!load_program(1, path, true))
|
2012-01-25 22:55:34 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-01-08 03:46:18 +01:00
|
|
|
RARCH_LOG("Loading stock Cg file.\n");
|
2013-04-06 05:46:09 +02:00
|
|
|
prg[1] = prg[0];
|
2011-07-04 13:33:09 +02:00
|
|
|
}
|
2012-01-25 21:56:21 +01:00
|
|
|
|
2014-05-22 21:24:52 +02:00
|
|
|
gfx_shader_resolve_parameters(NULL, cg_shader);
|
2012-01-25 22:55:34 +01:00
|
|
|
return true;
|
|
|
|
}
|
2012-01-25 21:56:21 +01:00
|
|
|
|
2013-04-15 23:45:11 +02:00
|
|
|
static bool load_imports(void)
|
2011-05-27 02:25:26 +02:00
|
|
|
{
|
2013-10-22 21:26:33 +02:00
|
|
|
unsigned i;
|
2013-04-16 22:30:28 +02:00
|
|
|
if (!cg_shader->variables)
|
|
|
|
return true;
|
|
|
|
|
2012-04-07 12:17:40 +02:00
|
|
|
struct state_tracker_info tracker_info = {0};
|
2011-12-24 13:46:12 +01:00
|
|
|
|
2013-10-22 21:26:33 +02:00
|
|
|
for (i = 0; i < cg_shader->variables; i++)
|
2011-05-27 02:25:26 +02:00
|
|
|
{
|
2011-10-26 19:51:10 +02:00
|
|
|
unsigned memtype;
|
2013-04-06 11:30:56 +02:00
|
|
|
switch (cg_shader->variable[i].ram_type)
|
2011-05-27 02:25:26 +02:00
|
|
|
{
|
2012-04-21 23:25:32 +02:00
|
|
|
case RARCH_STATE_WRAM:
|
2012-04-07 12:17:40 +02:00
|
|
|
memtype = RETRO_MEMORY_SYSTEM_RAM;
|
2011-05-28 15:06:46 +02:00
|
|
|
break;
|
2011-06-11 20:02:17 +02:00
|
|
|
|
2011-05-27 02:25:26 +02:00
|
|
|
default:
|
2011-10-26 19:51:10 +02:00
|
|
|
memtype = -1u;
|
2011-05-27 02:25:26 +02:00
|
|
|
}
|
|
|
|
|
2014-09-08 17:57:18 +02:00
|
|
|
if ((memtype != -1u) &&
|
|
|
|
(cg_shader->variable[i].addr >= pretro_get_memory_size(memtype)))
|
2011-05-28 15:06:46 +02:00
|
|
|
{
|
2012-04-21 23:25:32 +02:00
|
|
|
RARCH_ERR("Address out of bounds.\n");
|
2013-04-06 11:30:56 +02:00
|
|
|
return false;
|
2011-05-28 15:06:46 +02:00
|
|
|
}
|
2011-05-27 02:25:26 +02:00
|
|
|
}
|
|
|
|
|
2014-09-08 17:57:18 +02:00
|
|
|
tracker_info.wram = (uint8_t*)
|
|
|
|
pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM);
|
2013-04-06 11:30:56 +02:00
|
|
|
tracker_info.info = cg_shader->variable;
|
|
|
|
tracker_info.info_elem = cg_shader->variables;
|
2011-05-27 02:25:26 +02:00
|
|
|
|
2011-06-06 20:18:31 +02:00
|
|
|
#ifdef HAVE_PYTHON
|
2013-04-06 11:30:56 +02:00
|
|
|
if (*cg_shader->script_path)
|
2011-06-06 20:18:31 +02:00
|
|
|
{
|
2013-04-15 23:45:11 +02:00
|
|
|
tracker_info.script = cg_shader->script_path;
|
2013-04-06 11:30:56 +02:00
|
|
|
tracker_info.script_is_file = true;
|
2011-06-06 20:18:31 +02:00
|
|
|
}
|
2011-06-07 15:33:29 +02:00
|
|
|
|
2014-09-08 17:57:18 +02:00
|
|
|
tracker_info.script_class =
|
|
|
|
*cg_shader->script_class ? cg_shader->script_class : NULL;
|
2011-06-06 20:18:31 +02:00
|
|
|
#endif
|
|
|
|
|
2012-04-07 12:17:40 +02:00
|
|
|
state_tracker = state_tracker_init(&tracker_info);
|
|
|
|
if (!state_tracker)
|
2012-04-21 23:25:32 +02:00
|
|
|
RARCH_WARN("Failed to initialize state tracker.\n");
|
2011-05-27 02:25:26 +02:00
|
|
|
|
2013-04-06 11:30:56 +02:00
|
|
|
return true;
|
2011-05-27 02:25:26 +02:00
|
|
|
}
|
2011-05-22 18:48:43 +02:00
|
|
|
|
2013-04-15 23:45:11 +02:00
|
|
|
static bool load_shader(unsigned i)
|
2012-01-25 22:55:34 +01:00
|
|
|
{
|
2013-04-15 23:45:11 +02:00
|
|
|
RARCH_LOG("Loading Cg shader: \"%s\".\n",
|
2014-05-25 17:16:33 +02:00
|
|
|
cg_shader->pass[i].source.path);
|
2012-01-25 22:55:34 +01:00
|
|
|
|
2014-05-25 17:16:33 +02:00
|
|
|
if (!load_program(i + 1, cg_shader->pass[i].source.path, true))
|
2012-01-25 22:55:34 +01:00
|
|
|
return false;
|
|
|
|
|
2013-03-25 14:47:33 +01:00
|
|
|
return true;
|
2012-01-25 22:55:34 +01:00
|
|
|
}
|
2011-05-26 23:55:27 +02:00
|
|
|
|
2011-05-22 17:02:09 +02:00
|
|
|
static bool load_preset(const char *path)
|
|
|
|
{
|
2013-10-22 21:26:33 +02:00
|
|
|
unsigned i;
|
2012-01-25 22:55:34 +01:00
|
|
|
if (!load_stock())
|
2011-05-22 17:02:09 +02:00
|
|
|
return false;
|
|
|
|
|
2012-04-21 23:25:32 +02:00
|
|
|
RARCH_LOG("Loading Cg meta-shader: %s\n", path);
|
2011-05-22 17:02:09 +02:00
|
|
|
config_file_t *conf = config_file_new(path);
|
|
|
|
if (!conf)
|
|
|
|
{
|
2012-04-21 23:25:32 +02:00
|
|
|
RARCH_ERR("Failed to load preset.\n");
|
2013-04-06 11:30:56 +02:00
|
|
|
return false;
|
2011-05-22 17:02:09 +02:00
|
|
|
}
|
|
|
|
|
2013-04-06 11:30:56 +02:00
|
|
|
if (!cg_shader)
|
|
|
|
cg_shader = (struct gfx_shader*)calloc(1, sizeof(*cg_shader));
|
|
|
|
if (!cg_shader)
|
|
|
|
return false;
|
2011-05-22 17:02:09 +02:00
|
|
|
|
2013-04-06 11:30:56 +02:00
|
|
|
if (!gfx_shader_read_conf_cgp(conf, cg_shader))
|
2013-04-06 04:37:17 +02:00
|
|
|
{
|
2013-04-06 11:30:56 +02:00
|
|
|
RARCH_ERR("Failed to parse CGP file.\n");
|
|
|
|
config_file_free(conf);
|
|
|
|
return false;
|
2013-04-06 04:37:17 +02:00
|
|
|
}
|
2013-04-01 15:34:02 +02:00
|
|
|
|
2013-04-15 23:45:11 +02:00
|
|
|
gfx_shader_resolve_relative(cg_shader, path);
|
2014-05-22 21:24:52 +02:00
|
|
|
gfx_shader_resolve_parameters(conf, cg_shader);
|
|
|
|
config_file_free(conf);
|
2013-04-06 11:30:56 +02:00
|
|
|
|
2013-04-20 15:46:50 +02:00
|
|
|
if (cg_shader->passes > GFX_MAX_SHADERS - 3)
|
2011-05-22 18:48:43 +02:00
|
|
|
{
|
2014-09-08 17:57:18 +02:00
|
|
|
RARCH_WARN("Too many shaders ... Capping shader amount to %d.\n",
|
|
|
|
GFX_MAX_SHADERS - 3);
|
2013-04-20 15:46:50 +02:00
|
|
|
cg_shader->passes = GFX_MAX_SHADERS - 3;
|
2011-05-22 18:48:43 +02:00
|
|
|
}
|
2014-05-23 15:19:32 +02:00
|
|
|
|
|
|
|
for (i = 0; i < cg_shader->passes; i++)
|
|
|
|
if (*cg_shader->pass[i].alias)
|
2014-09-08 17:57:18 +02:00
|
|
|
snprintf(cg_alias_define[i], sizeof(cg_alias_define[i]),
|
|
|
|
"-D%s_ALIAS", cg_shader->pass[i].alias);
|
2014-05-23 15:19:32 +02:00
|
|
|
|
2013-10-22 21:26:33 +02:00
|
|
|
for (i = 0; i < cg_shader->passes; i++)
|
2011-05-22 17:02:09 +02:00
|
|
|
{
|
2013-04-15 23:45:11 +02:00
|
|
|
if (!load_shader(i))
|
2011-05-22 17:02:09 +02:00
|
|
|
{
|
2012-04-21 23:25:32 +02:00
|
|
|
RARCH_ERR("Failed to load shaders ...\n");
|
2013-04-06 11:30:56 +02:00
|
|
|
return false;
|
2011-05-22 17:02:09 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-08 13:39:12 -04:00
|
|
|
if (!gl_load_luts(cg_shader, lut_textures))
|
2011-05-22 18:48:43 +02:00
|
|
|
{
|
2012-04-21 23:25:32 +02:00
|
|
|
RARCH_ERR("Failed to load lookup textures ...\n");
|
2013-04-06 11:30:56 +02:00
|
|
|
return false;
|
2011-05-22 18:48:43 +02:00
|
|
|
}
|
2011-05-22 17:02:09 +02:00
|
|
|
|
2013-04-15 23:45:11 +02:00
|
|
|
if (!load_imports())
|
2011-05-27 02:25:26 +02:00
|
|
|
{
|
2012-04-21 23:25:32 +02:00
|
|
|
RARCH_ERR("Failed to load imports ...\n");
|
2013-04-06 11:30:56 +02:00
|
|
|
return false;
|
2011-05-27 02:25:26 +02:00
|
|
|
}
|
|
|
|
|
2013-04-06 11:30:56 +02:00
|
|
|
return true;
|
2011-05-22 17:02:09 +02:00
|
|
|
}
|
|
|
|
|
2012-09-15 11:22:07 +02:00
|
|
|
static void set_program_base_attrib(unsigned i)
|
|
|
|
{
|
|
|
|
CGparameter param = cgGetFirstParameter(prg[i].vprg, CG_PROGRAM);
|
|
|
|
for (; param; param = cgGetNextParameter(param))
|
|
|
|
{
|
2014-09-08 17:57:18 +02:00
|
|
|
if (cgGetParameterDirection(param) != CG_IN
|
|
|
|
|| cgGetParameterVariability(param) != CG_VARYING)
|
2012-09-15 11:22:07 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
const char *semantic = cgGetParameterSemantic(param);
|
|
|
|
if (!semantic)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
RARCH_LOG("CG: Found semantic \"%s\" in prog #%u.\n", semantic, i);
|
|
|
|
|
|
|
|
if (strcmp(semantic, "TEXCOORD") == 0 || strcmp(semantic, "TEXCOORD0") == 0)
|
|
|
|
prg[i].tex = param;
|
|
|
|
else if (strcmp(semantic, "COLOR") == 0 || strcmp(semantic, "COLOR0") == 0)
|
|
|
|
prg[i].color = param;
|
|
|
|
else if (strcmp(semantic, "POSITION") == 0)
|
|
|
|
prg[i].vertex = param;
|
|
|
|
else if (strcmp(semantic, "TEXCOORD1") == 0)
|
|
|
|
prg[i].lut_tex = param;
|
|
|
|
}
|
2013-07-06 10:40:24 +02:00
|
|
|
|
|
|
|
if (!prg[i].tex)
|
|
|
|
prg[i].tex = cgGetNamedParameter(prg[i].vprg, "IN.tex_coord");
|
|
|
|
if (!prg[i].color)
|
|
|
|
prg[i].color = cgGetNamedParameter(prg[i].vprg, "IN.color");
|
|
|
|
if (!prg[i].vertex)
|
|
|
|
prg[i].vertex = cgGetNamedParameter(prg[i].vprg, "IN.vertex_coord");
|
|
|
|
if (!prg[i].lut_tex)
|
|
|
|
prg[i].lut_tex = cgGetNamedParameter(prg[i].vprg, "IN.lut_tex_coord");
|
|
|
|
}
|
|
|
|
|
2014-10-14 18:26:28 +02:00
|
|
|
static void set_pass_attrib(struct cg_program *program, struct cg_fbo_params *fbo,
|
2013-07-06 10:40:24 +02:00
|
|
|
const char *attr)
|
|
|
|
{
|
|
|
|
char attr_buf[64];
|
|
|
|
|
|
|
|
snprintf(attr_buf, sizeof(attr_buf), "%s.texture", attr);
|
|
|
|
if (!fbo->tex)
|
2014-10-14 18:26:28 +02:00
|
|
|
fbo->tex = cgGetNamedParameter(program->fprg, attr_buf);
|
2013-07-06 10:40:24 +02:00
|
|
|
|
|
|
|
snprintf(attr_buf, sizeof(attr_buf), "%s.video_size", attr);
|
|
|
|
if (!fbo->vid_size_v)
|
2014-10-14 18:26:28 +02:00
|
|
|
fbo->vid_size_v = cgGetNamedParameter(program->vprg, attr_buf);
|
2013-07-06 10:40:24 +02:00
|
|
|
if (!fbo->vid_size_f)
|
2014-10-14 18:26:28 +02:00
|
|
|
fbo->vid_size_f = cgGetNamedParameter(program->fprg, attr_buf);
|
2013-07-06 10:40:24 +02:00
|
|
|
|
|
|
|
snprintf(attr_buf, sizeof(attr_buf), "%s.texture_size", attr);
|
|
|
|
if (!fbo->tex_size_v)
|
2014-10-14 18:26:28 +02:00
|
|
|
fbo->tex_size_v = cgGetNamedParameter(program->vprg, attr_buf);
|
2013-07-06 10:40:24 +02:00
|
|
|
if (!fbo->tex_size_f)
|
2014-10-14 18:26:28 +02:00
|
|
|
fbo->tex_size_f = cgGetNamedParameter(program->fprg, attr_buf);
|
2013-07-06 10:40:24 +02:00
|
|
|
|
|
|
|
snprintf(attr_buf, sizeof(attr_buf), "%s.tex_coord", attr);
|
|
|
|
if (!fbo->coord)
|
2014-10-14 18:26:28 +02:00
|
|
|
fbo->coord = cgGetNamedParameter(program->vprg, attr_buf);
|
2012-09-15 11:22:07 +02:00
|
|
|
}
|
|
|
|
|
2012-01-25 21:56:21 +01:00
|
|
|
static void set_program_attributes(unsigned i)
|
|
|
|
{
|
2013-10-22 21:26:33 +02:00
|
|
|
unsigned j;
|
2012-01-25 21:56:21 +01:00
|
|
|
cgGLBindProgram(prg[i].fprg);
|
|
|
|
cgGLBindProgram(prg[i].vprg);
|
|
|
|
|
2012-09-15 11:22:07 +02:00
|
|
|
set_program_base_attrib(i);
|
|
|
|
|
2012-01-25 21:56:21 +01:00
|
|
|
prg[i].vid_size_f = cgGetNamedParameter(prg[i].fprg, "IN.video_size");
|
|
|
|
prg[i].tex_size_f = cgGetNamedParameter(prg[i].fprg, "IN.texture_size");
|
|
|
|
prg[i].out_size_f = cgGetNamedParameter(prg[i].fprg, "IN.output_size");
|
|
|
|
prg[i].frame_cnt_f = cgGetNamedParameter(prg[i].fprg, "IN.frame_count");
|
|
|
|
prg[i].frame_dir_f = cgGetNamedParameter(prg[i].fprg, "IN.frame_direction");
|
|
|
|
prg[i].vid_size_v = cgGetNamedParameter(prg[i].vprg, "IN.video_size");
|
|
|
|
prg[i].tex_size_v = cgGetNamedParameter(prg[i].vprg, "IN.texture_size");
|
|
|
|
prg[i].out_size_v = cgGetNamedParameter(prg[i].vprg, "IN.output_size");
|
|
|
|
prg[i].frame_cnt_v = cgGetNamedParameter(prg[i].vprg, "IN.frame_count");
|
|
|
|
prg[i].frame_dir_v = cgGetNamedParameter(prg[i].vprg, "IN.frame_direction");
|
2013-07-06 10:40:24 +02:00
|
|
|
|
2012-01-25 21:56:21 +01:00
|
|
|
prg[i].mvp = cgGetNamedParameter(prg[i].vprg, "modelViewProj");
|
2013-07-06 10:40:24 +02:00
|
|
|
if (!prg[i].mvp)
|
|
|
|
prg[i].mvp = cgGetNamedParameter(prg[i].vprg, "IN.mvp_matrix");
|
2012-01-25 21:56:21 +01:00
|
|
|
|
|
|
|
prg[i].orig.tex = cgGetNamedParameter(prg[i].fprg, "ORIG.texture");
|
|
|
|
prg[i].orig.vid_size_v = cgGetNamedParameter(prg[i].vprg, "ORIG.video_size");
|
|
|
|
prg[i].orig.vid_size_f = cgGetNamedParameter(prg[i].fprg, "ORIG.video_size");
|
|
|
|
prg[i].orig.tex_size_v = cgGetNamedParameter(prg[i].vprg, "ORIG.texture_size");
|
|
|
|
prg[i].orig.tex_size_f = cgGetNamedParameter(prg[i].fprg, "ORIG.texture_size");
|
|
|
|
prg[i].orig.coord = cgGetNamedParameter(prg[i].vprg, "ORIG.tex_coord");
|
|
|
|
|
2013-07-06 10:40:24 +02:00
|
|
|
if (i > 1)
|
|
|
|
{
|
|
|
|
char pass_str[64];
|
|
|
|
snprintf(pass_str, sizeof(pass_str), "PASSPREV%u", i);
|
|
|
|
set_pass_attrib(&prg[i], &prg[i].orig, pass_str);
|
|
|
|
}
|
|
|
|
|
2013-10-22 21:26:33 +02:00
|
|
|
for (j = 0; j < PREV_TEXTURES; j++)
|
2012-01-25 21:56:21 +01:00
|
|
|
{
|
|
|
|
char attr_buf_tex[64];
|
|
|
|
char attr_buf_vid_size[64];
|
|
|
|
char attr_buf_tex_size[64];
|
|
|
|
char attr_buf_coord[64];
|
|
|
|
static const char *prev_names[PREV_TEXTURES] = {
|
|
|
|
"PREV",
|
|
|
|
"PREV1",
|
|
|
|
"PREV2",
|
|
|
|
"PREV3",
|
|
|
|
"PREV4",
|
|
|
|
"PREV5",
|
|
|
|
"PREV6",
|
|
|
|
};
|
|
|
|
|
2014-09-08 17:57:18 +02:00
|
|
|
snprintf(attr_buf_tex, sizeof(attr_buf_tex),
|
|
|
|
"%s.texture", prev_names[j]);
|
|
|
|
snprintf(attr_buf_vid_size, sizeof(attr_buf_vid_size),
|
|
|
|
"%s.video_size", prev_names[j]);
|
|
|
|
snprintf(attr_buf_tex_size, sizeof(attr_buf_tex_size),
|
|
|
|
"%s.texture_size", prev_names[j]);
|
|
|
|
snprintf(attr_buf_coord, sizeof(attr_buf_coord),
|
|
|
|
"%s.tex_coord", prev_names[j]);
|
2012-01-25 21:56:21 +01:00
|
|
|
|
|
|
|
prg[i].prev[j].tex = cgGetNamedParameter(prg[i].fprg, attr_buf_tex);
|
|
|
|
|
2014-09-08 17:57:18 +02:00
|
|
|
prg[i].prev[j].vid_size_v =
|
|
|
|
cgGetNamedParameter(prg[i].vprg, attr_buf_vid_size);
|
|
|
|
prg[i].prev[j].vid_size_f =
|
|
|
|
cgGetNamedParameter(prg[i].fprg, attr_buf_vid_size);
|
2012-01-25 21:56:21 +01:00
|
|
|
|
2014-09-08 17:57:18 +02:00
|
|
|
prg[i].prev[j].tex_size_v =
|
|
|
|
cgGetNamedParameter(prg[i].vprg, attr_buf_tex_size);
|
|
|
|
prg[i].prev[j].tex_size_f =
|
|
|
|
cgGetNamedParameter(prg[i].fprg, attr_buf_tex_size);
|
2012-01-25 21:56:21 +01:00
|
|
|
|
|
|
|
prg[i].prev[j].coord = cgGetNamedParameter(prg[i].vprg, attr_buf_coord);
|
|
|
|
}
|
|
|
|
|
2014-05-23 15:02:12 +02:00
|
|
|
for (j = 0; j + 1 < i; j++)
|
2012-01-25 21:56:21 +01:00
|
|
|
{
|
2013-07-06 10:40:24 +02:00
|
|
|
char pass_str[64];
|
|
|
|
snprintf(pass_str, sizeof(pass_str), "PASS%u", j + 1);
|
|
|
|
set_pass_attrib(&prg[i], &prg[i].fbo[j], pass_str);
|
2014-05-16 16:17:02 +02:00
|
|
|
snprintf(pass_str, sizeof(pass_str), "PASSPREV%u", i - (j + 1));
|
2013-07-06 10:40:24 +02:00
|
|
|
set_pass_attrib(&prg[i], &prg[i].fbo[j], pass_str);
|
2014-05-23 15:02:12 +02:00
|
|
|
|
|
|
|
if (*cg_shader->pass[j].alias)
|
|
|
|
set_pass_attrib(&prg[i], &prg[i].fbo[j], cg_shader->pass[j].alias);
|
2012-01-25 21:56:21 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-07 05:31:24 +01:00
|
|
|
static bool gl_cg_init(void *data, const char *path)
|
2011-05-22 17:02:09 +02:00
|
|
|
{
|
2013-10-22 21:26:33 +02:00
|
|
|
unsigned i;
|
2014-03-07 05:31:24 +01:00
|
|
|
(void)data;
|
2012-09-27 17:45:49 +02:00
|
|
|
#ifdef HAVE_CG_RUNTIME_COMPILER
|
2011-12-03 01:26:56 +01:00
|
|
|
cgRTCgcInit();
|
|
|
|
#endif
|
2012-01-25 21:56:21 +01:00
|
|
|
|
2012-02-20 16:22:58 +01:00
|
|
|
if (!cgCtx)
|
|
|
|
cgCtx = cgCreateContext();
|
|
|
|
|
2011-05-22 17:02:09 +02:00
|
|
|
if (cgCtx == NULL)
|
|
|
|
{
|
2012-04-21 23:25:32 +02:00
|
|
|
RARCH_ERR("Failed to create Cg context\n");
|
2011-05-22 17:02:09 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-04-21 23:25:32 +02:00
|
|
|
#ifdef RARCH_CG_DEBUG
|
2011-05-23 21:43:08 +02:00
|
|
|
cgGLSetDebugMode(CG_TRUE);
|
|
|
|
cgSetErrorHandler(cg_error_handler, NULL);
|
|
|
|
#endif
|
|
|
|
|
2011-05-22 17:02:09 +02:00
|
|
|
cgFProf = cgGLGetLatestProfile(CG_GL_FRAGMENT);
|
|
|
|
cgVProf = cgGLGetLatestProfile(CG_GL_VERTEX);
|
|
|
|
if (cgFProf == CG_PROFILE_UNKNOWN || cgVProf == CG_PROFILE_UNKNOWN)
|
|
|
|
{
|
2012-04-21 23:25:32 +02:00
|
|
|
RARCH_ERR("Invalid profile type\n");
|
2013-06-05 10:42:39 +02:00
|
|
|
goto error;
|
2011-05-22 17:02:09 +02:00
|
|
|
}
|
2014-02-25 22:01:46 +01:00
|
|
|
#ifndef HAVE_GCMGL
|
2012-11-18 23:51:38 +01:00
|
|
|
RARCH_LOG("[Cg]: Vertex profile: %s\n", cgGetProfileString(cgVProf));
|
|
|
|
RARCH_LOG("[Cg]: Fragment profile: %s\n", cgGetProfileString(cgFProf));
|
2013-03-29 18:58:29 +01:00
|
|
|
#endif
|
2011-05-22 17:02:09 +02:00
|
|
|
cgGLSetOptimalOptions(cgFProf);
|
|
|
|
cgGLSetOptimalOptions(cgVProf);
|
2011-05-22 17:36:18 +02:00
|
|
|
cgGLEnableProfile(cgFProf);
|
|
|
|
cgGLEnableProfile(cgVProf);
|
2011-05-22 17:02:09 +02:00
|
|
|
|
2014-05-23 15:19:32 +02:00
|
|
|
memset(cg_alias_define, 0, sizeof(cg_alias_define));
|
|
|
|
|
2013-04-10 22:38:45 +02:00
|
|
|
if (path && strcmp(path_get_extension(path), "cgp") == 0)
|
2011-05-22 17:02:09 +02:00
|
|
|
{
|
|
|
|
if (!load_preset(path))
|
2013-06-05 10:42:39 +02:00
|
|
|
goto error;
|
2011-05-22 17:02:09 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!load_plain(path))
|
2013-06-05 10:42:39 +02:00
|
|
|
goto error;
|
2011-05-22 17:02:09 +02:00
|
|
|
}
|
|
|
|
|
2013-07-06 10:40:24 +02:00
|
|
|
prg[0].mvp = cgGetNamedParameter(prg[0].vprg, "IN.mvp_matrix");
|
2013-10-22 21:26:33 +02:00
|
|
|
for (i = 1; i <= cg_shader->passes; i++)
|
2012-01-25 21:56:21 +01:00
|
|
|
set_program_attributes(i);
|
2011-05-23 21:04:25 +02:00
|
|
|
|
2014-09-08 17:57:18 +02:00
|
|
|
/* If we aren't using last pass non-FBO shader,
|
|
|
|
* this shader will be assumed to be "fixed-function".
|
|
|
|
*
|
|
|
|
* Just use prg[0] for that pass, which will be
|
|
|
|
* pass-through. */
|
2013-04-10 20:55:48 +02:00
|
|
|
prg[cg_shader->passes + 1] = prg[0];
|
|
|
|
|
2014-09-08 17:57:18 +02:00
|
|
|
/* No need to apply Android hack in Cg. */
|
2013-04-20 15:46:50 +02:00
|
|
|
prg[GL_SHADER_STOCK_BLEND] = prg[0];
|
|
|
|
|
2011-03-06 19:56:35 +01:00
|
|
|
cgGLBindProgram(prg[1].fprg);
|
|
|
|
cgGLBindProgram(prg[1].vprg);
|
|
|
|
|
|
|
|
cg_active = true;
|
|
|
|
return true;
|
2013-06-05 10:42:39 +02:00
|
|
|
|
|
|
|
error:
|
|
|
|
gl_cg_deinit();
|
|
|
|
return false;
|
2011-01-23 00:48:47 +01:00
|
|
|
}
|
|
|
|
|
2014-10-20 19:27:32 +02:00
|
|
|
static void gl_cg_use(void *data, unsigned idx)
|
2011-01-23 00:48:47 +01:00
|
|
|
{
|
2014-03-07 05:51:56 +01:00
|
|
|
(void)data;
|
|
|
|
|
2014-10-20 19:27:32 +02:00
|
|
|
if (cg_active && prg[idx].vprg && prg[idx].fprg)
|
2011-01-23 00:48:47 +01:00
|
|
|
{
|
2011-11-12 18:31:22 +01:00
|
|
|
gl_cg_reset_attrib();
|
|
|
|
|
2014-10-20 19:27:32 +02:00
|
|
|
active_idx = idx;
|
|
|
|
cgGLBindProgram(prg[idx].vprg);
|
|
|
|
cgGLBindProgram(prg[idx].fprg);
|
2011-01-23 00:48:47 +01:00
|
|
|
}
|
|
|
|
}
|
2011-03-12 15:30:57 +01:00
|
|
|
|
2013-04-12 21:25:16 +02:00
|
|
|
static unsigned gl_cg_num(void)
|
2011-03-12 15:30:57 +01:00
|
|
|
{
|
|
|
|
if (cg_active)
|
2013-04-06 11:30:56 +02:00
|
|
|
return cg_shader->passes;
|
2014-08-27 03:28:22 +02:00
|
|
|
return 0;
|
2011-03-12 15:30:57 +01:00
|
|
|
}
|
2011-03-14 21:28:30 +01:00
|
|
|
|
2014-10-20 19:27:32 +02:00
|
|
|
static bool gl_cg_filter_type(unsigned idx, bool *smooth)
|
2011-03-14 21:28:30 +01:00
|
|
|
{
|
2014-10-20 19:27:32 +02:00
|
|
|
if (cg_active && idx &&
|
|
|
|
(cg_shader->pass[idx - 1].filter != RARCH_FILTER_UNSPEC)
|
2014-10-02 15:25:01 +02:00
|
|
|
)
|
2011-05-22 17:02:09 +02:00
|
|
|
{
|
2014-10-20 19:27:32 +02:00
|
|
|
*smooth = (cg_shader->pass[idx - 1].filter == RARCH_FILTER_LINEAR);
|
2011-05-22 17:02:09 +02:00
|
|
|
return true;
|
|
|
|
}
|
2014-08-27 03:28:22 +02:00
|
|
|
|
|
|
|
return false;
|
2011-03-14 21:28:30 +01:00
|
|
|
}
|
2011-03-14 22:09:35 +01:00
|
|
|
|
2014-10-20 19:27:32 +02:00
|
|
|
static enum gfx_wrap_type gl_cg_wrap_type(unsigned idx)
|
2013-08-16 00:30:54 +02:00
|
|
|
{
|
2014-10-20 19:27:32 +02:00
|
|
|
if (cg_active && idx)
|
|
|
|
return cg_shader->pass[idx - 1].wrap;
|
2014-08-27 03:28:22 +02:00
|
|
|
return RARCH_WRAP_BORDER;
|
2013-08-16 00:30:54 +02:00
|
|
|
}
|
|
|
|
|
2014-10-20 19:27:32 +02:00
|
|
|
static void gl_cg_shader_scale(unsigned idx, struct gfx_fbo_scale *scale)
|
2011-03-14 22:09:35 +01:00
|
|
|
{
|
2014-10-20 19:27:32 +02:00
|
|
|
if (cg_active && idx)
|
|
|
|
*scale = cg_shader->pass[idx - 1].fbo;
|
2011-05-22 17:02:09 +02:00
|
|
|
else
|
|
|
|
scale->valid = false;
|
2011-03-14 22:09:35 +01:00
|
|
|
}
|
2012-01-25 21:56:21 +01:00
|
|
|
|
2013-07-06 22:10:09 +02:00
|
|
|
static unsigned gl_cg_get_prev_textures(void)
|
|
|
|
{
|
2013-10-22 21:26:33 +02:00
|
|
|
unsigned i, j;
|
2013-07-06 22:10:09 +02:00
|
|
|
if (!cg_active)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
unsigned max_prev = 0;
|
2013-10-22 21:26:33 +02:00
|
|
|
for (i = 1; i <= cg_shader->passes; i++)
|
|
|
|
for (j = 0; j < PREV_TEXTURES; j++)
|
2013-07-06 22:10:09 +02:00
|
|
|
if (prg[i].prev[j].tex)
|
|
|
|
max_prev = max(j + 1, max_prev);
|
|
|
|
|
|
|
|
return max_prev;
|
|
|
|
}
|
|
|
|
|
2014-10-20 19:27:32 +02:00
|
|
|
static bool gl_cg_mipmap_input(unsigned idx)
|
2014-05-11 13:13:38 +02:00
|
|
|
{
|
2014-10-02 21:09:34 +02:00
|
|
|
#ifndef HAVE_GCMGL
|
2014-10-20 19:27:32 +02:00
|
|
|
if (cg_active && idx)
|
|
|
|
return cg_shader->pass[idx - 1].mipmap;
|
2014-10-02 21:09:34 +02:00
|
|
|
#endif
|
2014-08-27 03:28:22 +02:00
|
|
|
return false;
|
2014-05-11 13:13:38 +02:00
|
|
|
}
|
|
|
|
|
2014-05-23 12:23:08 +02:00
|
|
|
static struct gfx_shader *gl_cg_get_current_shader(void)
|
|
|
|
{
|
|
|
|
return cg_active ? cg_shader : NULL;
|
|
|
|
}
|
|
|
|
|
2014-10-02 11:11:34 +02:00
|
|
|
const shader_backend_t gl_cg_backend = {
|
2012-11-14 22:51:08 +01:00
|
|
|
gl_cg_init,
|
|
|
|
gl_cg_deinit,
|
|
|
|
gl_cg_set_params,
|
|
|
|
gl_cg_use,
|
|
|
|
gl_cg_num,
|
|
|
|
gl_cg_filter_type,
|
2013-08-16 00:30:54 +02:00
|
|
|
gl_cg_wrap_type,
|
2012-11-14 22:51:08 +01:00
|
|
|
gl_cg_shader_scale,
|
|
|
|
gl_cg_set_coords,
|
|
|
|
gl_cg_set_mvp,
|
2013-07-06 22:10:09 +02:00
|
|
|
gl_cg_get_prev_textures,
|
2014-05-11 13:13:38 +02:00
|
|
|
gl_cg_mipmap_input,
|
2014-05-23 12:23:08 +02:00
|
|
|
gl_cg_get_current_shader,
|
2013-01-08 03:46:18 +01:00
|
|
|
|
|
|
|
RARCH_SHADER_CG,
|
2014-10-02 15:19:21 +02:00
|
|
|
"gl_cg"
|
2012-11-14 22:51:08 +01:00
|
|
|
};
|
|
|
|
|