RetroArch/gfx/drivers_shader/shader_hlsl.c

608 lines
18 KiB
C
Raw Normal View History

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
2017-01-22 13:40:32 +01:00
* Copyright (C) 2011-2017 - Daniel De Matteis
*
2012-04-21 23:13:50 +02: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.
*
2012-04-21 23:13:50 +02:00
* 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.
*
2012-04-21 23:31:57 +02:00
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
2017-09-05 03:21:58 +02:00
#include <retro_math.h>
#include <compat/strl.h>
2015-12-26 07:59:15 +01:00
#include <string/stdstring.h>
2017-09-05 03:21:58 +02:00
#include <file/file_path.h>
#include <d3dx9shader.h>
#include "../../defines/d3d_defines.h"
2018-01-25 12:35:46 +01:00
#include "../common/d3d_common.h"
2015-12-26 07:59:15 +01:00
2016-09-06 23:59:43 +02:00
#ifdef HAVE_CONFIG_H
#include "../../config.h"
#endif
#include "../video_shader_parse.h"
2017-01-19 20:31:33 +01:00
#include "../drivers/d3d.h"
#include "../../managers/state_manager.h"
2017-09-05 03:21:58 +02:00
#include "../../verbosity.h"
2016-04-17 00:16:32 +02:00
#include "../drivers/d3d_shaders/opaque.hlsl.d3d9.h"
2017-09-05 03:21:58 +02:00
#include "shader_hlsl.h"
2013-04-12 15:14:14 +02:00
2017-12-31 06:09:39 +01:00
#ifdef __cplusplus
#ifndef ID3DXConstantTable_SetDefaults
#define ID3DXConstantTable_SetDefaults(p,a) (p)->SetDefaults(a);
#endif
2017-12-30 12:36:00 +01:00
#ifndef ID3DXConstantTable_SetFloatArray
2017-12-31 06:09:39 +01:00
#define ID3DXConstantTable_SetFloatArray(p,a,b,c,d) (p)->SetFloatArray(a,b,c,d)
#endif
2018-01-06 21:30:50 +01:00
#ifndef ID3DXConstantTable_GetConstantByName
#define ID3DXConstantTable_GetConstantByName(p,a,b) ((p)->GetConstantByName(a, b))
2017-12-31 06:09:39 +01:00
#endif
2018-01-01 15:11:06 +01:00
#ifndef ID3DXConstantTable_SetMatrix
#define ID3DXConstantTable_SetMatrix(p,a,b,c) ((p)->SetMatrix(a,b,c))
#endif
2017-12-31 06:09:39 +01:00
#else
#ifndef ID3DXConstantTable_SetDefaults
#define ID3DXConstantTable_SetDefaults(p,a) (p)->lpVtbl->SetDefaults(p,a)
#endif
2017-12-30 12:36:00 +01:00
#ifndef ID3DXConstantTable_SetFloatArray
2017-12-31 06:09:39 +01:00
#define ID3DXConstantTable_SetFloatArray(p,a,b,c,d) (p)->lpVtbl->SetFloatArray(p,a,b,c,d)
#endif
2018-01-06 21:30:50 +01:00
#ifndef ID3DXConstantTable_GetConstantByName
#define ID3DXConstantTable_GetConstantByName(p,a,b) ((p)->lpVtbl->GetConstantByName(p, a, b))
2017-12-31 06:09:39 +01:00
#endif
2018-01-01 15:11:06 +01:00
#ifndef ID3DXConstantTable_SetMatrix
#define ID3DXConstantTable_SetMatrix(p,a,b,c) ((p)->lpVtbl->SetMatrix(p,a,b,c))
#endif
2017-12-31 06:09:39 +01:00
#endif
#define set_param_2f(param, xy, constanttable) if (param) { ID3DXConstantTable_SetFloatArray(constanttable, d3dr, param, xy, 2); }
#define get_constant_by_name(a, b, constanttable) ID3DXConstantTable_GetConstantByName(constanttable, a, b)
2018-01-07 20:55:00 +01:00
struct shader_program_hlsl_data
{
2018-01-25 15:35:07 +01:00
LPDIRECT3DVERTEXSHADER9 vprg;
LPDIRECT3DPIXELSHADER9 fprg;
2018-01-07 20:55:00 +01:00
D3DXHANDLE vid_size_f;
D3DXHANDLE tex_size_f;
D3DXHANDLE out_size_f;
D3DXHANDLE frame_cnt_f;
D3DXHANDLE frame_dir_f;
D3DXHANDLE vid_size_v;
D3DXHANDLE tex_size_v;
D3DXHANDLE out_size_v;
D3DXHANDLE frame_cnt_v;
D3DXHANDLE frame_dir_v;
D3DXHANDLE mvp;
LPD3DXCONSTANTTABLE v_ctable;
LPD3DXCONSTANTTABLE f_ctable;
D3DXMATRIX mvp_val;
};
typedef struct hlsl_shader_data hlsl_shader_data_t;
2015-12-05 07:33:21 +01:00
struct hlsl_shader_data
{
2016-04-14 03:41:53 +02:00
d3d_video_t *d3d;
struct shader_program_hlsl_data prg[RARCH_HLSL_MAX_SHADERS];
unsigned active_idx;
2015-01-19 21:24:08 +01:00
struct video_shader *cg_shader;
2015-12-05 07:33:21 +01:00
};
2018-01-06 20:48:17 +01:00
void hlsl_set_proj_matrix(void *data, void *matrix_data)
{
2015-12-05 07:33:21 +01:00
hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)data;
2018-01-06 20:48:17 +01:00
const D3DMATRIX *matrix = (const D3DMATRIX*)matrix_data;
if (hlsl && matrix)
hlsl->prg[hlsl->active_idx].mvp_val = *matrix;
}
2016-04-16 19:44:44 +02:00
static void hlsl_set_uniform_parameter(
2016-04-16 19:29:45 +02:00
void *data,
struct uniform_info *param,
void *uniform_data)
{
2016-04-16 19:29:45 +02:00
hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)data;
(void)hlsl;
if (!param || !param->enabled)
return;
switch (param->type)
{
case UNIFORM_1F:
2016-04-16 19:29:45 +02:00
/* Unimplemented */
break;
case UNIFORM_2F:
2016-04-16 19:29:45 +02:00
/* Unimplemented */
break;
case UNIFORM_3F:
2016-04-16 19:29:45 +02:00
/* Unimplemented */
break;
case UNIFORM_4F:
2016-04-16 19:29:45 +02:00
/* Unimplemented */
break;
case UNIFORM_1FV:
2016-04-16 19:29:45 +02:00
/* Unimplemented */
break;
case UNIFORM_2FV:
2016-04-16 19:29:45 +02:00
/* Unimplemented */
break;
case UNIFORM_3FV:
2016-04-16 19:29:45 +02:00
/* Unimplemented */
break;
case UNIFORM_4FV:
2016-04-16 19:29:45 +02:00
/* Unimplemented */
break;
case UNIFORM_1I:
/* Unimplemented - Cg limitation */
break;
}
}
2015-12-05 07:33:21 +01:00
static void hlsl_set_params(void *data, void *shader_data,
unsigned width, unsigned height,
2012-04-15 20:02:51 +02:00
unsigned tex_width, unsigned tex_height,
2012-04-16 04:21:49 +02:00
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)
{
2017-12-30 12:00:26 +01:00
float ori_size[2], tex_size[2], out_size[2];
float frame_cnt = frame_counter;
2017-01-19 21:20:05 +01:00
d3d_video_t *d3d = (d3d_video_t*)data;
2018-01-25 01:45:03 +01:00
LPDIRECT3DDEVICE9 d3dr = (LPDIRECT3DDEVICE9)d3d->dev;
2017-01-19 21:20:05 +01:00
const struct video_tex_info *info = (const struct video_tex_info*)_info;
2016-05-10 02:39:09 +02:00
const struct video_tex_info *prev_info = (const struct video_tex_info*)_prev_info;
2017-01-19 21:20:05 +01:00
const struct video_tex_info *fbo_info = (const struct video_tex_info*)_fbo_info;
hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)shader_data;
if (!hlsl)
return;
2017-12-30 12:00:26 +01:00
ori_size[0] = (float)width;
ori_size[1] = (float)height;
tex_size[0] = (float)tex_width;
tex_size[1] = (float)tex_height;
out_size[0] = (float)out_width;
out_size[1] = (float)out_height;
2012-04-18 02:57:46 +02:00
ID3DXConstantTable_SetDefaults(
2018-01-07 20:55:00 +01:00
hlsl->prg[hlsl->active_idx].f_ctable, d3dr);
ID3DXConstantTable_SetDefaults(
2018-01-07 20:55:00 +01:00
hlsl->prg[hlsl->active_idx].v_ctable, d3dr);
2012-04-15 20:02:51 +02:00
set_param_2f(hlsl->prg[hlsl->active_idx].vid_size_f, ori_size, hlsl->prg[hlsl->active_idx].f_ctable);
set_param_2f(hlsl->prg[hlsl->active_idx].tex_size_f, tex_size, hlsl->prg[hlsl->active_idx].f_ctable);
set_param_2f(hlsl->prg[hlsl->active_idx].out_size_f, out_size, hlsl->prg[hlsl->active_idx].f_ctable);
2018-01-29 11:44:38 +01:00
if (hlsl->prg[hlsl->active_idx].frame_cnt_f)
d3dx_constant_table_set_float(hlsl->prg[hlsl->active_idx].f_ctable, d3dr,
hlsl->prg[hlsl->active_idx].frame_cnt_f, frame_cnt);
if (hlsl->prg[hlsl->active_idx].frame_dir_f)
d3dx_constant_table_set_float(hlsl->prg[hlsl->active_idx].f_ctable, d3dr, hlsl->prg[hlsl->active_idx].frame_dir_f, state_manager_frame_is_reversed() ? -1.0 : 1.0);
2012-04-15 20:02:51 +02:00
set_param_2f(hlsl->prg[hlsl->active_idx].vid_size_v, ori_size, hlsl->prg[hlsl->active_idx].v_ctable);
set_param_2f(hlsl->prg[hlsl->active_idx].tex_size_v, tex_size, hlsl->prg[hlsl->active_idx].v_ctable);
set_param_2f(hlsl->prg[hlsl->active_idx].out_size_v, out_size, hlsl->prg[hlsl->active_idx].v_ctable);
2018-01-29 11:44:38 +01:00
if (hlsl->prg[hlsl->active_idx].frame_cnt_v)
d3dx_constant_table_set_float(hlsl->prg[hlsl->active_idx].v_ctable, d3dr,
hlsl->prg[hlsl->active_idx].frame_cnt_v, frame_cnt);
if (hlsl->prg[hlsl->active_idx].frame_dir_v)
d3dx_constant_table_set_float(hlsl->prg[hlsl->active_idx].v_ctable, d3dr, hlsl->prg[hlsl->active_idx].frame_dir_v, state_manager_frame_is_reversed() ? -1.0 : 1.0);
2013-04-12 20:06:08 +02:00
/* TODO - set lookup textures/FBO textures/state parameters/etc */
}
2016-04-14 03:20:19 +02:00
static bool hlsl_compile_program(
void *data,
unsigned idx,
2016-04-16 04:56:15 +02:00
void *program_data,
2016-04-14 03:38:45 +02:00
struct shader_program_info *program_info)
{
2017-01-19 21:20:05 +01:00
hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)data;
d3d_video_t *d3d = (d3d_video_t*)hlsl->d3d;
struct shader_program_hlsl_data *program = (struct shader_program_hlsl_data*)program_data;
2018-01-25 01:45:03 +01:00
LPDIRECT3DDEVICE9 d3dr = (LPDIRECT3DDEVICE9)d3d->dev;
2017-01-19 21:20:05 +01:00
ID3DXBuffer *listing_f = NULL;
ID3DXBuffer *listing_v = NULL;
ID3DXBuffer *code_f = NULL;
ID3DXBuffer *code_v = NULL;
if (!program)
program = &hlsl->prg[idx];
2016-04-14 03:38:45 +02:00
if (program_info->is_file)
{
2018-01-07 11:52:32 +01:00
if (!d3dx_compile_shader_from_file(program_info->combined, NULL, NULL,
2018-01-07 20:55:00 +01:00
"main_fragment", "ps_3_0", 0, &code_f, &listing_f, &program->f_ctable))
2018-01-07 11:52:32 +01:00
goto error;
if (!d3dx_compile_shader_from_file(program_info->combined, NULL, NULL,
2018-01-07 20:55:00 +01:00
"main_vertex", "vs_3_0", 0, &code_v, &listing_v, &program->v_ctable))
2018-01-07 11:52:32 +01:00
goto error;
}
else
{
2012-04-14 22:19:39 +02:00
/* TODO - crashes currently - to do with 'end of line' of stock shader */
2018-01-07 20:47:35 +01:00
if (!d3dx_compile_shader(program_info->combined,
strlen(program_info->combined), NULL, NULL,
"main_fragment", "ps_3_0", 0, &code_f, &listing_f,
&program->f_ctable ))
2018-01-07 11:52:32 +01:00
goto error;
2018-01-07 20:47:35 +01:00
if (!d3dx_compile_shader(program_info->combined,
strlen(program_info->combined), NULL, NULL,
"main_vertex", "vs_3_0", 0, &code_v, &listing_v,
&program->v_ctable ))
2018-01-07 11:52:32 +01:00
goto error;
}
2018-01-29 11:44:38 +01:00
d3d_create_pixel_shader(d3dr, (const DWORD*)d3dx_get_buffer_ptr(code_f), (void**)&program->fprg);
d3d_create_vertex_shader(d3dr, (const DWORD*)d3dx_get_buffer_ptr(code_v), (void**)&program->vprg);
2018-01-06 21:30:50 +01:00
d3dxbuffer_release((void*)code_f);
d3dxbuffer_release((void*)code_v);
2018-01-07 21:34:39 +01:00
return true;
2018-01-07 11:52:32 +01:00
error:
RARCH_ERR("Cg/HLSL error:\n");
if(listing_f)
2018-01-29 11:44:38 +01:00
RARCH_ERR("Fragment:\n%s\n", (char*)d3dx_get_buffer_ptr(listing_f));
2018-01-07 11:52:32 +01:00
if(listing_v)
2018-01-29 11:44:38 +01:00
RARCH_ERR("Vertex:\n%s\n", (char*)d3dx_get_buffer_ptr(listing_v));
2018-01-07 11:52:32 +01:00
d3dxbuffer_release((void*)listing_f);
d3dxbuffer_release((void*)listing_v);
2018-01-07 21:34:39 +01:00
return false;
}
static bool hlsl_load_stock(hlsl_shader_data_t *hlsl, void *data)
{
2016-04-14 03:38:45 +02:00
struct shader_program_info program_info;
2018-01-07 21:34:39 +01:00
program_info.combined = stock_hlsl_program;
program_info.is_file = false;
2016-04-14 03:38:45 +02:00
2018-01-07 21:34:39 +01:00
hlsl->d3d = (d3d_video_t*)data;
2016-04-14 03:41:53 +02:00
if (!hlsl_compile_program(hlsl, 0, &hlsl->prg[0], &program_info))
{
2012-04-21 23:25:32 +02:00
RARCH_ERR("Failed to compile passthrough shader, is something wrong with your environment?\n");
return false;
}
return true;
}
static void hlsl_set_program_attributes(hlsl_shader_data_t *hlsl, unsigned i)
{
if (!hlsl)
return;
2017-12-31 06:09:39 +01:00
hlsl->prg[i].vid_size_f = get_constant_by_name(NULL, "$IN.video_size", hlsl->prg[i].f_ctable);
hlsl->prg[i].tex_size_f = get_constant_by_name(NULL, "$IN.texture_size", hlsl->prg[i].f_ctable);
hlsl->prg[i].out_size_f = get_constant_by_name(NULL, "$IN.output_size", hlsl->prg[i].f_ctable);
hlsl->prg[i].frame_cnt_f = get_constant_by_name(NULL, "$IN.frame_count", hlsl->prg[i].f_ctable);
hlsl->prg[i].frame_dir_f = get_constant_by_name(NULL, "$IN.frame_direction", hlsl->prg[i].f_ctable);
hlsl->prg[i].vid_size_v = get_constant_by_name(NULL, "$IN.video_size", hlsl->prg[i].v_ctable);
hlsl->prg[i].tex_size_v = get_constant_by_name(NULL, "$IN.texture_size", hlsl->prg[i].v_ctable);
hlsl->prg[i].out_size_v = get_constant_by_name(NULL, "$IN.output_size", hlsl->prg[i].v_ctable);
hlsl->prg[i].frame_cnt_v = get_constant_by_name(NULL, "$IN.frame_count", hlsl->prg[i].v_ctable);
hlsl->prg[i].frame_dir_v = get_constant_by_name(NULL, "$IN.frame_direction", hlsl->prg[i].v_ctable);
hlsl->prg[i].mvp = get_constant_by_name(NULL, "$modelViewProj", hlsl->prg[i].v_ctable);
2018-01-06 20:48:17 +01:00
d3d_matrix_identity(&hlsl->prg[i].mvp_val);
}
static bool hlsl_load_shader(hlsl_shader_data_t *hlsl,
2018-01-07 20:55:00 +01:00
void *data, const char *cgp_path, unsigned i)
{
2016-04-14 03:38:45 +02:00
struct shader_program_info program_info;
2016-12-17 14:40:06 +01:00
char path_buf[PATH_MAX_LENGTH];
path_buf[0] = '\0';
2015-06-13 02:10:06 +02:00
2016-04-14 03:38:45 +02:00
program_info.combined = path_buf;
program_info.is_file = true;
2013-04-12 20:06:08 +02:00
fill_pathname_resolve_relative(path_buf, cgp_path,
2018-01-07 20:55:00 +01:00
hlsl->cg_shader->pass[i].source.path, sizeof(path_buf));
2013-04-12 20:06:08 +02:00
RARCH_LOG("Loading Cg/HLSL shader: \"%s\".\n", path_buf);
2016-04-14 03:41:53 +02:00
hlsl->d3d = (d3d_video_t*)data;
2017-01-19 21:05:04 +01:00
if (!hlsl_compile_program(hlsl, i + 1, &hlsl->prg[i + 1], &program_info))
2013-04-12 20:06:08 +02:00
return false;
2013-04-12 20:06:08 +02:00
return true;
}
static bool hlsl_load_plain(hlsl_shader_data_t *hlsl, void *data, const char *path)
{
if (!hlsl_load_stock(hlsl, data))
2013-04-12 20:06:08 +02:00
return false;
2015-01-19 21:24:08 +01:00
hlsl->cg_shader = (struct video_shader*)calloc(1, sizeof(*hlsl->cg_shader));
if (!hlsl->cg_shader)
return false;
hlsl->cg_shader->passes = 1;
2015-12-26 07:59:15 +01:00
if (!string_is_empty(path))
2013-01-22 14:00:34 +01:00
{
2016-04-14 03:38:45 +02:00
struct shader_program_info program_info;
program_info.combined = path;
program_info.is_file = true;
2013-04-12 20:06:08 +02:00
RARCH_LOG("Loading Cg/HLSL file: %s\n", path);
2016-04-14 03:38:45 +02:00
strlcpy(hlsl->cg_shader->pass[0].source.path,
2018-01-07 20:55:00 +01:00
path, sizeof(hlsl->cg_shader->pass[0].source.path));
2016-04-14 03:41:53 +02:00
hlsl->d3d = (d3d_video_t*)data;
2017-01-19 21:05:04 +01:00
if (!hlsl_compile_program(hlsl, 1, &hlsl->prg[1], &program_info))
2013-04-12 20:06:08 +02:00
return false;
}
else
{
RARCH_LOG("Loading stock Cg/HLSL file.\n");
hlsl->prg[1] = hlsl->prg[0];
2013-01-22 14:00:34 +01:00
}
return true;
}
static void hlsl_deinit_progs(hlsl_shader_data_t *hlsl)
{
unsigned i;
for (i = 1; i < RARCH_HLSL_MAX_SHADERS; i++)
{
if (hlsl->prg[i].fprg && hlsl->prg[i].fprg != hlsl->prg[0].fprg)
2018-01-07 12:00:09 +01:00
d3d_free_pixel_shader(hlsl->d3d->dev, hlsl->prg[i].fprg);
if (hlsl->prg[i].vprg && hlsl->prg[i].vprg != hlsl->prg[0].vprg)
2018-01-07 12:00:09 +01:00
d3d_free_vertex_shader(hlsl->d3d->dev, hlsl->prg[i].vprg);
2016-04-14 03:16:24 +02:00
2018-01-07 20:55:00 +01:00
hlsl->prg[i].fprg = NULL;
hlsl->prg[i].vprg = NULL;
}
2012-05-06 23:40:29 +02:00
if (hlsl->prg[0].fprg)
2018-01-07 12:00:09 +01:00
d3d_free_pixel_shader(hlsl->d3d->dev, hlsl->prg[0].fprg);
if (hlsl->prg[0].vprg)
2018-01-07 12:00:09 +01:00
d3d_free_vertex_shader(hlsl->d3d->dev, hlsl->prg[0].vprg);
2016-04-14 03:16:24 +02:00
hlsl->prg[0].fprg = NULL;
hlsl->prg[0].vprg = NULL;
}
static void hlsl_deinit_state(hlsl_shader_data_t *hlsl)
{
hlsl_deinit_progs(hlsl);
memset(hlsl->prg, 0, sizeof(hlsl->prg));
if (hlsl->cg_shader)
free(hlsl->cg_shader);
hlsl->cg_shader = NULL;
}
static bool hlsl_load_preset(hlsl_shader_data_t *hlsl, void *data, const char *path)
{
2016-04-14 03:11:13 +02:00
unsigned i;
2016-04-14 03:09:15 +02:00
config_file_t *conf = NULL;
if (!hlsl_load_stock(hlsl, data))
2013-04-12 20:06:08 +02:00
return false;
RARCH_LOG("Loading Cg meta-shader: %s\n", path);
2016-04-14 03:09:15 +02:00
conf = config_file_new(path);
2013-04-12 20:06:08 +02:00
if (!conf)
2016-04-14 03:09:15 +02:00
goto error;
2013-04-12 20:06:08 +02:00
if (!hlsl->cg_shader)
2015-01-19 21:24:08 +01:00
hlsl->cg_shader = (struct video_shader*)calloc(1, sizeof(*hlsl->cg_shader));
if (!hlsl->cg_shader)
2016-04-14 03:09:15 +02:00
goto error;
2013-04-12 20:06:08 +02:00
if (!video_shader_read_conf_cgp(conf, hlsl->cg_shader))
2013-04-12 20:06:08 +02:00
{
RARCH_ERR("Failed to parse CGP file.\n");
2016-04-14 03:09:15 +02:00
goto error;
2013-04-12 20:06:08 +02:00
}
config_file_free(conf);
if (hlsl->cg_shader->passes > RARCH_HLSL_MAX_SHADERS - 3)
2013-04-12 20:06:08 +02:00
{
RARCH_WARN("Too many shaders ... Capping shader amount to %d.\n", RARCH_HLSL_MAX_SHADERS - 3);
hlsl->cg_shader->passes = RARCH_HLSL_MAX_SHADERS - 3;
2013-04-12 20:06:08 +02:00
}
2016-04-14 03:11:13 +02:00
for (i = 0; i < hlsl->cg_shader->passes; i++)
2013-04-12 20:06:08 +02:00
{
if (!hlsl_load_shader(hlsl, data, path, i))
2016-04-14 03:11:13 +02:00
goto error;
2013-04-12 20:06:08 +02:00
}
/* TODO - textures / imports */
return true;
2016-04-14 03:09:15 +02:00
error:
RARCH_ERR("Failed to load preset.\n");
if (conf)
config_file_free(conf);
conf = NULL;
return false;
}
2015-12-05 07:33:21 +01:00
static void *hlsl_init(void *data, const char *path)
{
unsigned i;
d3d_video_t *d3d = (d3d_video_t*)data;
2015-12-05 07:33:21 +01:00
hlsl_shader_data_t *hlsl_data = (hlsl_shader_data_t*)
calloc(1, sizeof(hlsl_shader_data_t));
if (!hlsl_data)
2018-01-07 20:55:00 +01:00
return NULL;
if (path && (string_is_equal(path_get_extension(path), ".cgp")))
{
if (!hlsl_load_preset(hlsl_data, d3d, path))
goto error;
}
else
{
if (!hlsl_load_plain(hlsl_data, d3d, path))
goto error;
}
2013-04-12 20:06:08 +02:00
for(i = 1; i <= hlsl_data->cg_shader->passes; i++)
hlsl_set_program_attributes(hlsl_data, i);
d3d_set_vertex_shader(d3d->dev, 1, hlsl_data->prg[1].vprg);
2018-01-06 22:49:17 +01:00
d3d_set_pixel_shader(d3d->dev, hlsl_data->prg[1].fprg);
2015-12-05 07:33:21 +01:00
return hlsl_data;
error:
if (hlsl_data)
2018-01-07 20:55:00 +01:00
free(hlsl_data);
2015-12-05 07:33:21 +01:00
return NULL;
}
2015-12-05 07:33:21 +01:00
static void hlsl_deinit(void *data)
2013-04-12 20:06:08 +02:00
{
2015-12-05 07:33:21 +01:00
hlsl_shader_data_t *hlsl_data = (hlsl_shader_data_t*)data;
hlsl_deinit_state(hlsl_data);
if (hlsl_data)
free(hlsl_data);
2013-04-12 20:06:08 +02:00
}
static void hlsl_use(void *data, void *shader_data, unsigned idx, bool set_active)
{
2018-01-25 01:45:03 +01:00
d3d_video_t *d3d = (d3d_video_t*)data;
2015-12-05 07:33:21 +01:00
hlsl_shader_data_t *hlsl_data = (hlsl_shader_data_t*)shader_data;
2018-01-25 01:45:03 +01:00
LPDIRECT3DDEVICE9 d3dr = (LPDIRECT3DDEVICE9)d3d->dev;
if (hlsl_data && hlsl_data->prg[idx].vprg && hlsl_data->prg[idx].fprg)
2012-05-06 21:57:01 +02:00
{
if (set_active)
hlsl_data->active_idx = idx;
d3d_set_vertex_shader(d3dr, idx, hlsl_data->prg[idx].vprg);
2018-01-06 22:49:17 +01:00
d3d_set_pixel_shader(d3dr, hlsl_data->prg[idx].fprg);
2012-05-06 21:57:01 +02:00
}
}
2015-12-05 07:33:21 +01:00
static unsigned hlsl_num(void *data)
{
2015-12-05 07:33:21 +01:00
hlsl_shader_data_t *hlsl_data = (hlsl_shader_data_t*)data;
if (hlsl_data)
return hlsl_data->cg_shader->passes;
2014-08-27 03:28:22 +02:00
return 0;
2013-04-12 20:06:08 +02:00
}
2015-12-05 07:33:21 +01:00
static bool hlsl_filter_type(void *data, unsigned idx, bool *smooth)
2013-04-12 20:06:08 +02:00
{
2015-12-05 07:33:21 +01:00
hlsl_shader_data_t *hlsl_data = (hlsl_shader_data_t*)data;
if (hlsl_data && idx
&& (hlsl_data->cg_shader->pass[idx - 1].filter != RARCH_FILTER_UNSPEC))
2013-04-12 20:06:08 +02:00
{
2018-01-29 11:44:38 +01:00
*smooth = RARCH_FILTER_LINEAR;
hlsl_data->cg_shader->pass[idx - 1].filter = RARCH_FILTER_LINEAR;
2013-04-12 20:06:08 +02:00
return true;
}
2014-08-27 03:28:22 +02:00
return false;
}
2013-04-12 20:06:08 +02:00
2015-12-05 07:33:21 +01:00
static void hlsl_shader_scale(void *data, unsigned idx, struct gfx_fbo_scale *scale)
2013-04-12 20:06:08 +02:00
{
2015-12-05 07:33:21 +01:00
hlsl_shader_data_t *hlsl_data = (hlsl_shader_data_t*)data;
if (hlsl_data && idx)
*scale = hlsl_data->cg_shader->pass[idx - 1].fbo;
2013-04-12 20:06:08 +02:00
else
scale->valid = false;
}
2017-11-15 14:09:41 +01:00
static bool hlsl_set_mvp(void *data, void *shader_data, const void *mat_data)
{
2017-10-03 05:18:32 +02:00
d3d_video_t *d3d = (d3d_video_t*)data;
2018-01-25 01:45:03 +01:00
LPDIRECT3DDEVICE9 d3dr = (LPDIRECT3DDEVICE9)d3d->dev;
2017-10-03 05:18:32 +02:00
hlsl_shader_data_t *hlsl_data = (hlsl_shader_data_t*)shader_data;
2017-11-15 14:09:41 +01:00
const math_matrix_4x4 *mat = (const math_matrix_4x4*)mat_data;
if(hlsl_data && hlsl_data->prg[hlsl_data->active_idx].mvp)
{
2018-01-01 15:11:06 +01:00
ID3DXConstantTable_SetMatrix(hlsl_data->prg[hlsl_data->active_idx].v_ctable, d3dr,
2018-01-07 20:55:00 +01:00
hlsl_data->prg[hlsl_data->active_idx].mvp,
&hlsl_data->prg[hlsl_data->active_idx].mvp_val);
return true;
}
2014-08-27 03:28:22 +02:00
return false;
}
2015-12-05 07:33:21 +01:00
static bool hlsl_mipmap_input(void *data, unsigned idx)
2014-05-11 13:13:38 +02:00
{
2014-10-20 19:27:32 +02:00
(void)idx;
2014-05-11 13:13:38 +02:00
return false;
}
2015-12-05 07:33:21 +01:00
static bool hlsl_get_feedback_pass(void *data, unsigned *idx)
{
(void)idx;
return false;
}
2015-12-05 07:33:21 +01:00
static struct video_shader *hlsl_get_current_shader(void *data)
{
return NULL;
}
const shader_backend_t hlsl_backend = {
hlsl_init,
hlsl_deinit,
hlsl_set_params,
2016-04-16 19:44:44 +02:00
hlsl_set_uniform_parameter,
2017-01-19 20:56:07 +01:00
NULL, /* compile_program */
hlsl_use,
hlsl_num,
hlsl_filter_type,
2013-09-15 18:49:18 +02:00
NULL, /* hlsl_wrap_type */
hlsl_shader_scale,
2013-09-15 18:49:18 +02:00
NULL, /* hlsl_set_coords */
hlsl_set_mvp,
2013-09-15 18:49:18 +02:00
NULL, /* hlsl_get_prev_textures */
hlsl_get_feedback_pass,
2014-05-11 13:13:38 +02:00
hlsl_mipmap_input,
hlsl_get_current_shader,
RARCH_SHADER_HLSL,
"hlsl"
2018-01-06 21:30:50 +01:00
};