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
|
2016-01-10 04:41:52 +01:00
|
|
|
* Copyright (C) 2011-2016 - Daniel De Matteis
|
2012-04-14 20:33:56 +02:00
|
|
|
*
|
2012-04-21 23:13:50 +02:00
|
|
|
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
2012-04-14 20:33:56 +02: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;
|
2012-04-14 20:33:56 +02: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.
|
2012-04-14 20:33:56 +02:00
|
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2015-12-26 07:59:15 +01:00
|
|
|
#include <string/stdstring.h>
|
|
|
|
|
2012-04-14 20:33:56 +02:00
|
|
|
#include "shader_hlsl.h"
|
2015-09-16 11:14:43 +02:00
|
|
|
|
2015-01-12 23:42:50 +01:00
|
|
|
#include "../video_shader_parse.h"
|
2015-01-07 22:23:45 +01:00
|
|
|
#include "../d3d/d3d.h"
|
2015-09-16 11:14:43 +02:00
|
|
|
#include "../../rewind.h"
|
2012-04-14 20:33:56 +02:00
|
|
|
|
2013-04-12 15:14:14 +02:00
|
|
|
static const char *stock_hlsl_program =
|
2013-04-12 18:20:08 +02:00
|
|
|
"void main_vertex\n"
|
|
|
|
"(\n"
|
|
|
|
" float4 position : POSITION,\n"
|
|
|
|
" float4 color : COLOR,\n"
|
|
|
|
"\n"
|
|
|
|
" uniform float4x4 modelViewProj,\n"
|
|
|
|
"\n"
|
|
|
|
" float4 texCoord : TEXCOORD0,\n"
|
|
|
|
" out float4 oPosition : POSITION,\n"
|
|
|
|
" out float4 oColor : COLOR,\n"
|
|
|
|
" out float2 otexCoord : TEXCOORD\n"
|
|
|
|
")\n"
|
|
|
|
"{\n"
|
|
|
|
" oPosition = mul(modelViewProj, position);\n"
|
|
|
|
" oColor = color;\n"
|
|
|
|
" otexCoord = texCoord;\n"
|
|
|
|
"}\n"
|
|
|
|
"\n"
|
|
|
|
"struct output\n"
|
|
|
|
"{\n"
|
|
|
|
" float4 color: COLOR;\n"
|
|
|
|
"};\n"
|
|
|
|
"\n"
|
|
|
|
"struct input\n"
|
|
|
|
"{\n"
|
|
|
|
" float2 video_size;\n"
|
|
|
|
" float2 texture_size;\n"
|
|
|
|
" float2 output_size;\n"
|
|
|
|
" float frame_count;\n"
|
|
|
|
" float frame_direction;\n"
|
|
|
|
" float frame_rotation;\n"
|
|
|
|
"};\n"
|
|
|
|
"\n"
|
|
|
|
"output main_fragment(float2 texCoord : TEXCOORD0,\n"
|
|
|
|
"uniform sampler2D decal : TEXUNIT0, uniform input IN)\n"
|
|
|
|
"{\n"
|
|
|
|
" output OUT;\n"
|
|
|
|
" OUT.color = tex2D(decal, texCoord);\n"
|
|
|
|
" return OUT;\n"
|
|
|
|
"}\n";
|
2013-04-12 15:14:14 +02:00
|
|
|
|
2016-04-16 07:39:41 +02:00
|
|
|
struct shader_program_hlsl_data
|
2012-04-14 20:33:56 +02:00
|
|
|
{
|
2014-01-01 00:58:21 +01:00
|
|
|
LPDIRECT3DVERTEXSHADER vprg;
|
|
|
|
LPDIRECT3DPIXELSHADER fprg;
|
2016-04-14 03:06:59 +02: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;
|
|
|
|
|
2012-04-14 22:44:46 +02:00
|
|
|
LPD3DXCONSTANTTABLE v_ctable;
|
|
|
|
LPD3DXCONSTANTTABLE f_ctable;
|
2012-04-17 05:23:54 +02:00
|
|
|
XMMATRIX mvp_val; /* TODO: Move to D3DXMATRIX here */
|
2012-04-14 20:33:56 +02:00
|
|
|
};
|
|
|
|
|
2015-12-05 07:33:21 +01:00
|
|
|
typedef struct hlsl_shader_data hlsl_shader_data_t;
|
|
|
|
|
|
|
|
struct hlsl_shader_data
|
2014-10-26 07:12:09 +01:00
|
|
|
{
|
2016-04-14 03:41:53 +02:00
|
|
|
d3d_video_t *d3d;
|
2016-04-16 07:39:41 +02:00
|
|
|
struct shader_program_hlsl_data prg[RARCH_HLSL_MAX_SHADERS];
|
2014-10-26 07:12:09 +01:00
|
|
|
unsigned active_idx;
|
2015-01-19 21:24:08 +01:00
|
|
|
struct video_shader *cg_shader;
|
2015-12-05 07:33:21 +01:00
|
|
|
};
|
2012-04-14 20:33:56 +02:00
|
|
|
|
2015-12-05 07:33:21 +01:00
|
|
|
void hlsl_set_proj_matrix(void *data, XMMATRIX rotation_value)
|
2012-04-14 20:33:56 +02:00
|
|
|
{
|
2015-12-05 07:33:21 +01:00
|
|
|
hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)data;
|
2015-11-30 02:28:35 +01:00
|
|
|
if (hlsl_data)
|
|
|
|
hlsl_data->prg[hlsl_data->active_idx].mvp_val = rotation_value;
|
2012-04-14 20:33:56 +02:00
|
|
|
}
|
|
|
|
|
2016-04-16 19:29:45 +02:00
|
|
|
static void hlsl_uniform_set_parameter(
|
|
|
|
void *data,
|
2016-04-16 19:41:48 +02:00
|
|
|
struct uniform_info *param,
|
2016-04-16 19:29:45 +02:00
|
|
|
void *_shader_info_data,
|
|
|
|
void *uniform_data)
|
2016-04-14 03:52:29 +02:00
|
|
|
{
|
2016-04-16 19:29:45 +02:00
|
|
|
hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)data;
|
|
|
|
struct shader_program_hlsl_data *shader_data = (struct shader_program_hlsl_data*)_shader_info_data;
|
|
|
|
|
|
|
|
(void)hlsl;
|
2016-04-14 03:52:29 +02:00
|
|
|
|
|
|
|
if (!param || !param->enabled)
|
|
|
|
return;
|
|
|
|
|
|
|
|
switch (param->type)
|
|
|
|
{
|
|
|
|
case UNIFORM_1F:
|
2016-04-16 19:29:45 +02:00
|
|
|
/* Unimplemented */
|
2016-04-14 03:52:29 +02:00
|
|
|
break;
|
|
|
|
case UNIFORM_2F:
|
2016-04-16 19:29:45 +02:00
|
|
|
/* Unimplemented */
|
2016-04-14 03:52:29 +02:00
|
|
|
break;
|
|
|
|
case UNIFORM_3F:
|
2016-04-16 19:29:45 +02:00
|
|
|
/* Unimplemented */
|
2016-04-14 03:52:29 +02:00
|
|
|
break;
|
|
|
|
case UNIFORM_4F:
|
2016-04-16 19:29:45 +02:00
|
|
|
/* Unimplemented */
|
2016-04-14 03:52:29 +02:00
|
|
|
break;
|
|
|
|
case UNIFORM_1FV:
|
2016-04-16 19:29:45 +02:00
|
|
|
/* Unimplemented */
|
2016-04-14 03:52:29 +02:00
|
|
|
break;
|
|
|
|
case UNIFORM_2FV:
|
2016-04-16 19:29:45 +02:00
|
|
|
/* Unimplemented */
|
2016-04-14 03:52:29 +02:00
|
|
|
break;
|
|
|
|
case UNIFORM_3FV:
|
2016-04-16 19:29:45 +02:00
|
|
|
/* Unimplemented */
|
2016-04-14 03:52:29 +02:00
|
|
|
break;
|
|
|
|
case UNIFORM_4FV:
|
2016-04-16 19:29:45 +02:00
|
|
|
/* Unimplemented */
|
2016-04-14 03:52:29 +02:00
|
|
|
break;
|
|
|
|
case UNIFORM_1I:
|
|
|
|
/* Unimplemented - Cg limitation */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-15 20:02:51 +02:00
|
|
|
#define set_param_2f(param, xy, constanttable) \
|
2012-04-16 18:11:20 +02:00
|
|
|
if (param) constanttable->SetFloatArray(d3d_device_ptr, param, xy, 2)
|
2012-04-16 04:21:49 +02:00
|
|
|
#define set_param_1f(param, x, constanttable) \
|
2012-04-18 05:01:17 +02:00
|
|
|
if (param) constanttable->SetFloat(d3d_device_ptr, param, x)
|
2012-04-15 20:02:51 +02:00
|
|
|
|
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,
|
2013-04-12 21:56:43 +02:00
|
|
|
unsigned frame_counter,
|
2014-10-02 11:11:34 +02:00
|
|
|
const void *_info,
|
|
|
|
const void *_prev_info,
|
2015-08-30 18:37:41 +02:00
|
|
|
const void *_feedback_info,
|
2014-10-02 11:11:34 +02:00
|
|
|
const void *_fbo_info, unsigned fbo_info_cnt)
|
2012-04-14 20:33:56 +02:00
|
|
|
{
|
2014-03-07 20:17:25 +01:00
|
|
|
d3d_video_t *d3d = (d3d_video_t*)data;
|
2014-03-07 05:31:24 +01:00
|
|
|
LPDIRECT3DDEVICE d3d_device_ptr = (LPDIRECT3DDEVICE)d3d->dev;
|
2015-07-12 04:16:40 +02:00
|
|
|
const struct gfx_tex_info *info = (const struct gfx_tex_info*)_info;
|
|
|
|
const struct gfx_tex_info *prev_info = (const struct gfx_tex_info*)_prev_info;
|
2015-08-30 18:37:41 +02:00
|
|
|
(void)_feedback_info;
|
2015-07-12 04:16:40 +02:00
|
|
|
const struct gfx_tex_info *fbo_info = (const struct gfx_tex_info*)_fbo_info;
|
2015-12-05 07:33:21 +01:00
|
|
|
hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)shader_data;
|
2014-10-02 11:11:34 +02:00
|
|
|
|
2014-10-26 07:12:09 +01:00
|
|
|
if (!hlsl)
|
2012-04-14 20:33:56 +02:00
|
|
|
return;
|
|
|
|
|
2012-04-16 18:11:20 +02:00
|
|
|
const float ori_size[2] = { (float)width, (float)height };
|
|
|
|
const float tex_size[2] = { (float)tex_width, (float)tex_height };
|
|
|
|
const float out_size[2] = { (float)out_width, (float)out_height };
|
2013-04-12 21:56:43 +02:00
|
|
|
float frame_cnt = frame_counter;
|
2012-04-18 02:57:46 +02:00
|
|
|
|
2014-10-26 07:12:09 +01:00
|
|
|
hlsl->prg[hlsl->active_idx].f_ctable->SetDefaults(d3d_device_ptr);
|
|
|
|
hlsl->prg[hlsl->active_idx].v_ctable->SetDefaults(d3d_device_ptr);
|
2012-04-15 20:02:51 +02:00
|
|
|
|
2014-10-26 07:12:09 +01: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);
|
|
|
|
set_param_1f(hlsl->prg[hlsl->active_idx].frame_cnt_f, frame_cnt, hlsl->prg[hlsl->active_idx].f_ctable);
|
2015-09-16 11:14:43 +02:00
|
|
|
set_param_1f(hlsl->prg[hlsl->active_idx].frame_dir_f, state_manager_frame_is_reversed() ? -1.0 : 1.0, hlsl->prg[hlsl->active_idx].f_ctable);
|
2012-04-15 20:02:51 +02:00
|
|
|
|
2014-10-26 07:12:09 +01: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);
|
|
|
|
set_param_1f(hlsl->prg[hlsl->active_idx].frame_cnt_v, frame_cnt, hlsl->prg[hlsl->active_idx].v_ctable);
|
2015-09-16 11:14:43 +02:00
|
|
|
set_param_1f(hlsl->prg[hlsl->active_idx].frame_dir_v, state_manager_frame_is_reversed() ? -1.0 : 1.0, hlsl->prg[hlsl->active_idx].v_ctable);
|
2013-04-12 20:06:08 +02:00
|
|
|
|
|
|
|
/* TODO - set lookup textures/FBO textures/state parameters/etc */
|
2012-04-14 20:33:56 +02:00
|
|
|
}
|
|
|
|
|
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)
|
2012-04-14 20:33:56 +02:00
|
|
|
{
|
2016-04-14 03:20:19 +02:00
|
|
|
hlsl_shader_data_t *hlsl = (hlsl_shader_data_t*)data;
|
2016-04-14 03:41:53 +02:00
|
|
|
d3d_video_t *d3d = (d3d_video_t*)hlsl->d3d;
|
2016-04-16 07:39:41 +02:00
|
|
|
struct shader_program_hlsl_data *program = (struct shader_program_hlsl_data*)program_data;
|
2014-03-07 05:31:24 +01:00
|
|
|
LPDIRECT3DDEVICE d3d_device_ptr = (LPDIRECT3DDEVICE)d3d->dev;
|
2012-05-28 14:05:28 +02:00
|
|
|
HRESULT ret, ret_fp, ret_vp;
|
2012-04-14 20:33:56 +02:00
|
|
|
ID3DXBuffer *listing_f = NULL;
|
|
|
|
ID3DXBuffer *listing_v = NULL;
|
|
|
|
ID3DXBuffer *code_f = NULL;
|
|
|
|
ID3DXBuffer *code_v = NULL;
|
|
|
|
|
2016-04-16 04:58:03 +02:00
|
|
|
if (!program)
|
|
|
|
program = &hlsl->prg[idx];
|
|
|
|
|
2016-04-14 03:38:45 +02:00
|
|
|
if (program_info->is_file)
|
2012-04-14 20:33:56 +02:00
|
|
|
{
|
2016-04-14 03:38:45 +02:00
|
|
|
ret_fp = D3DXCompileShaderFromFile(program_info->combined, NULL, NULL,
|
|
|
|
"main_fragment", "ps_3_0", 0, &code_f, &listing_f, &program->f_ctable);
|
|
|
|
ret_vp = D3DXCompileShaderFromFile(program_info->combined, NULL, NULL,
|
|
|
|
"main_vertex", "vs_3_0", 0, &code_v, &listing_v, &program->v_ctable);
|
2012-04-14 20:33:56 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-04-14 22:19:39 +02:00
|
|
|
/* TODO - crashes currently - to do with 'end of line' of stock shader */
|
2016-04-14 03:38:45 +02:00
|
|
|
ret_fp = D3DXCompileShader(program_info->combined, strlen(program_info->combined), NULL, NULL,
|
|
|
|
"main_fragment", "ps_3_0", 0, &code_f, &listing_f, &program->f_ctable );
|
|
|
|
ret_vp = D3DXCompileShader(program_info->combined, strlen(program_info->combined), NULL, NULL,
|
|
|
|
"main_vertex", "vs_3_0", 0, &code_v, &listing_v, &program->v_ctable );
|
2012-04-14 20:33:56 +02:00
|
|
|
}
|
|
|
|
|
2012-05-28 14:05:28 +02:00
|
|
|
if (ret_fp < 0 || ret_vp < 0 || listing_v || listing_f)
|
2012-04-14 20:33:56 +02:00
|
|
|
{
|
2013-04-12 20:06:08 +02:00
|
|
|
RARCH_ERR("Cg/HLSL error:\n");
|
2012-04-14 20:33:56 +02:00
|
|
|
if(listing_f)
|
2012-04-21 23:25:32 +02:00
|
|
|
RARCH_ERR("Fragment:\n%s\n", (char*)listing_f->GetBufferPointer());
|
2012-04-14 20:33:56 +02:00
|
|
|
if(listing_v)
|
2012-04-21 23:25:32 +02:00
|
|
|
RARCH_ERR("Vertex:\n%s\n", (char*)listing_v->GetBufferPointer());
|
2012-04-14 20:33:56 +02:00
|
|
|
|
|
|
|
ret = false;
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
|
2016-04-14 03:38:45 +02:00
|
|
|
d3d_device_ptr->CreatePixelShader((const DWORD*)code_f->GetBufferPointer(), &program->fprg);
|
|
|
|
d3d_device_ptr->CreateVertexShader((const DWORD*)code_v->GetBufferPointer(), &program->vprg);
|
2012-04-14 20:33:56 +02:00
|
|
|
code_f->Release();
|
|
|
|
code_v->Release();
|
|
|
|
|
|
|
|
end:
|
2012-04-16 18:11:20 +02:00
|
|
|
if (listing_f)
|
2012-04-15 16:34:09 +02:00
|
|
|
listing_f->Release();
|
2012-04-16 18:11:20 +02:00
|
|
|
if (listing_v)
|
2012-04-15 16:34:09 +02:00
|
|
|
listing_v->Release();
|
2012-04-14 20:33:56 +02:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-11-30 02:28:35 +01:00
|
|
|
static bool hlsl_load_stock(hlsl_shader_data_t *hlsl, void *data)
|
2012-04-14 20:33:56 +02:00
|
|
|
{
|
2016-04-14 03:38:45 +02:00
|
|
|
struct shader_program_info program_info;
|
|
|
|
|
|
|
|
program_info.combined = stock_hlsl_program;
|
|
|
|
program_info.is_file = false;
|
|
|
|
|
2016-04-14 03:41:53 +02:00
|
|
|
hlsl->d3d = (d3d_video_t*)data;
|
|
|
|
|
|
|
|
if (!hlsl_compile_program(hlsl, 0, &hlsl->prg[0], &program_info))
|
2012-04-14 20:33:56 +02:00
|
|
|
{
|
2012-04-21 23:25:32 +02:00
|
|
|
RARCH_ERR("Failed to compile passthrough shader, is something wrong with your environment?\n");
|
2012-04-14 20:33:56 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-11-30 02:28:35 +01:00
|
|
|
static void hlsl_set_program_attributes(hlsl_shader_data_t *hlsl, unsigned i)
|
2012-05-21 18:01:51 +02:00
|
|
|
{
|
2014-10-26 07:12:09 +01:00
|
|
|
if (!hlsl)
|
|
|
|
return;
|
|
|
|
|
|
|
|
hlsl->prg[i].vid_size_f = hlsl->prg[i].f_ctable->GetConstantByName(NULL, "$IN.video_size");
|
|
|
|
hlsl->prg[i].tex_size_f = hlsl->prg[i].f_ctable->GetConstantByName(NULL, "$IN.texture_size");
|
|
|
|
hlsl->prg[i].out_size_f = hlsl->prg[i].f_ctable->GetConstantByName(NULL, "$IN.output_size");
|
|
|
|
hlsl->prg[i].frame_cnt_f = hlsl->prg[i].f_ctable->GetConstantByName(NULL, "$IN.frame_count");
|
|
|
|
hlsl->prg[i].frame_dir_f = hlsl->prg[i].f_ctable->GetConstantByName(NULL, "$IN.frame_direction");
|
|
|
|
hlsl->prg[i].vid_size_v = hlsl->prg[i].v_ctable->GetConstantByName(NULL, "$IN.video_size");
|
|
|
|
hlsl->prg[i].tex_size_v = hlsl->prg[i].v_ctable->GetConstantByName(NULL, "$IN.texture_size");
|
|
|
|
hlsl->prg[i].out_size_v = hlsl->prg[i].v_ctable->GetConstantByName(NULL, "$IN.output_size");
|
|
|
|
hlsl->prg[i].frame_cnt_v = hlsl->prg[i].v_ctable->GetConstantByName(NULL, "$IN.frame_count");
|
|
|
|
hlsl->prg[i].frame_dir_v = hlsl->prg[i].v_ctable->GetConstantByName(NULL, "$IN.frame_direction");
|
|
|
|
hlsl->prg[i].mvp = hlsl->prg[i].v_ctable->GetConstantByName(NULL, "$modelViewProj");
|
|
|
|
hlsl->prg[i].mvp_val = XMMatrixIdentity();
|
2012-05-21 18:01:51 +02:00
|
|
|
}
|
|
|
|
|
2015-11-30 02:28:35 +01:00
|
|
|
static bool hlsl_load_shader(hlsl_shader_data_t *hlsl,
|
2014-10-26 07:12:09 +01:00
|
|
|
void *data, const char *cgp_path, unsigned i)
|
2012-05-21 18:01:51 +02:00
|
|
|
{
|
2016-04-14 03:38:45 +02:00
|
|
|
struct shader_program_info program_info;
|
2015-06-13 02:10:06 +02:00
|
|
|
char path_buf[PATH_MAX_LENGTH] = {0};
|
|
|
|
|
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,
|
2014-10-26 07:12:09 +01:00
|
|
|
hlsl->cg_shader->pass[i].source.path, sizeof(path_buf));
|
2012-05-21 18:01:51 +02:00
|
|
|
|
2013-04-12 20:06:08 +02:00
|
|
|
RARCH_LOG("Loading Cg/HLSL shader: \"%s\".\n", path_buf);
|
2012-05-21 18:01:51 +02:00
|
|
|
|
2016-04-14 03:41:53 +02:00
|
|
|
hlsl->d3d = (d3d_video_t*)data;
|
|
|
|
|
2016-04-14 03:38:45 +02:00
|
|
|
if (!hlsl_compile_program(hlsl, data, i + 1, &hlsl->prg[i + 1], &program_info))
|
2013-04-12 20:06:08 +02:00
|
|
|
return false;
|
2012-05-21 18:01:51 +02:00
|
|
|
|
2013-04-12 20:06:08 +02:00
|
|
|
return true;
|
2012-05-21 18:01:51 +02:00
|
|
|
}
|
|
|
|
|
2015-11-30 02:28:35 +01:00
|
|
|
static bool hlsl_load_plain(hlsl_shader_data_t *hlsl, void *data, const char *path)
|
2012-04-14 20:33:56 +02:00
|
|
|
{
|
2015-11-30 02:28:35 +01:00
|
|
|
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));
|
2014-10-26 07:12:09 +01:00
|
|
|
if (!hlsl->cg_shader)
|
2012-04-14 20:33:56 +02:00
|
|
|
return false;
|
|
|
|
|
2014-10-26 07:12:09 +01:00
|
|
|
hlsl->cg_shader->passes = 1;
|
2012-04-14 20:33:56 +02:00
|
|
|
|
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
|
|
|
|
2014-10-26 07:12:09 +01:00
|
|
|
strlcpy(hlsl->cg_shader->pass[0].source.path,
|
|
|
|
path, sizeof(hlsl->cg_shader->pass[0].source.path));
|
2016-04-14 03:41:53 +02:00
|
|
|
|
|
|
|
hlsl->d3d = (d3d_video_t*)data;
|
2016-04-14 03:38:45 +02:00
|
|
|
if (!hlsl_compile_program(hlsl, data, 1, &hlsl->prg[1], &progarm_info))
|
2013-04-12 20:06:08 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
RARCH_LOG("Loading stock Cg/HLSL file.\n");
|
2014-10-26 07:12:09 +01:00
|
|
|
hlsl->prg[1] = hlsl->prg[0];
|
2013-01-22 14:00:34 +01:00
|
|
|
}
|
2012-04-14 20:33:56 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-10-26 07:12:09 +01:00
|
|
|
static void hlsl_deinit_progs(hlsl_shader_data_t *hlsl)
|
2012-04-17 05:12:03 +02:00
|
|
|
{
|
2014-10-26 07:12:09 +01:00
|
|
|
unsigned i;
|
|
|
|
for (i = 1; i < RARCH_HLSL_MAX_SHADERS; i++)
|
2012-04-17 05:12:03 +02:00
|
|
|
{
|
2014-10-26 07:12:09 +01:00
|
|
|
if (hlsl->prg[i].fprg && hlsl->prg[i].fprg != hlsl->prg[0].fprg)
|
|
|
|
hlsl->prg[i].fprg->Release();
|
|
|
|
if (hlsl->prg[i].vprg && hlsl->prg[i].vprg != hlsl->prg[0].vprg)
|
|
|
|
hlsl->prg[i].vprg->Release();
|
2016-04-14 03:16:24 +02:00
|
|
|
|
|
|
|
hlsl->prg[i].fprg = NULL;
|
2014-10-26 07:12:09 +01:00
|
|
|
hlsl->prg[i].vprg = NULL;
|
2012-04-17 05:12:03 +02:00
|
|
|
}
|
2012-05-06 23:40:29 +02:00
|
|
|
|
2014-10-26 07:12:09 +01:00
|
|
|
if (hlsl->prg[0].fprg)
|
|
|
|
hlsl->prg[0].fprg->Release();
|
|
|
|
if (hlsl->prg[0].vprg)
|
|
|
|
hlsl->prg[0].vprg->Release();
|
2016-04-14 03:16:24 +02:00
|
|
|
|
|
|
|
hlsl->prg[0].fprg = NULL;
|
2014-10-26 07:12:09 +01:00
|
|
|
hlsl->prg[0].vprg = NULL;
|
2012-04-17 05:12:03 +02:00
|
|
|
}
|
2012-04-14 20:33:56 +02:00
|
|
|
|
2014-10-26 07:12:09 +01:00
|
|
|
static void hlsl_deinit_state(hlsl_shader_data_t *hlsl)
|
2012-04-14 20:33:56 +02:00
|
|
|
{
|
2014-10-26 07:12:09 +01:00
|
|
|
hlsl_deinit_progs(hlsl);
|
|
|
|
memset(hlsl->prg, 0, sizeof(hlsl->prg));
|
2012-04-14 20:33:56 +02:00
|
|
|
|
2014-10-26 07:12:09 +01:00
|
|
|
if (hlsl->cg_shader)
|
|
|
|
free(hlsl->cg_shader);
|
|
|
|
hlsl->cg_shader = NULL;
|
2012-04-14 20:33:56 +02:00
|
|
|
}
|
|
|
|
|
2015-11-30 02:28:35 +01:00
|
|
|
static bool hlsl_load_preset(hlsl_shader_data_t *hlsl, void *data, const char *path)
|
2012-04-14 21:45:43 +02:00
|
|
|
{
|
2016-04-14 03:11:13 +02:00
|
|
|
unsigned i;
|
2016-04-14 03:09:15 +02:00
|
|
|
config_file_t *conf = NULL;
|
2015-11-30 02:28:35 +01:00
|
|
|
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
|
|
|
|
2014-10-26 07:12:09 +01: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));
|
2014-10-26 07:12:09 +01:00
|
|
|
if (!hlsl->cg_shader)
|
2016-04-14 03:09:15 +02:00
|
|
|
goto error;
|
2013-04-12 20:06:08 +02:00
|
|
|
|
2015-01-19 21:09:39 +01: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);
|
|
|
|
|
2014-10-26 07:12:09 +01:00
|
|
|
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);
|
2014-10-26 07:12:09 +01:00
|
|
|
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
|
|
|
{
|
2015-11-30 02:28:35 +01: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;
|
2012-04-14 21:45:43 +02:00
|
|
|
}
|
|
|
|
|
2015-12-05 07:33:21 +01:00
|
|
|
static void *hlsl_init(void *data, const char *path)
|
2012-04-14 20:33:56 +02:00
|
|
|
{
|
2015-11-30 02:28:35 +01:00
|
|
|
unsigned i;
|
2014-03-07 20:17:25 +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*)
|
|
|
|
calloc(1, sizeof(hlsl_shader_data_t));
|
2014-10-26 07:12:09 +01:00
|
|
|
|
2015-11-30 02:28:35 +01:00
|
|
|
if (!hlsl_data)
|
2015-12-05 07:33:21 +01:00
|
|
|
return NULL;
|
2012-04-14 22:05:56 +02:00
|
|
|
|
2016-01-20 06:16:55 +01:00
|
|
|
if (path && string_is_equal(path_get_extension(path), ".cgp"))
|
2012-04-14 20:33:56 +02:00
|
|
|
{
|
2015-11-30 02:28:35 +01:00
|
|
|
if (!hlsl_load_preset(hlsl_data, d3d, path))
|
2014-10-26 07:12:09 +01:00
|
|
|
goto error;
|
2012-04-14 20:33:56 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-11-30 02:28:35 +01:00
|
|
|
if (!hlsl_load_plain(hlsl_data, d3d, path))
|
2014-10-26 07:12:09 +01:00
|
|
|
goto error;
|
2012-04-14 20:33:56 +02:00
|
|
|
}
|
2013-04-12 20:06:08 +02:00
|
|
|
|
2015-11-30 02:28:35 +01:00
|
|
|
for(i = 1; i <= hlsl_data->cg_shader->passes; i++)
|
|
|
|
hlsl_set_program_attributes(hlsl_data, i);
|
2014-10-26 07:12:09 +01:00
|
|
|
|
2015-11-30 02:28:35 +01:00
|
|
|
d3d_set_vertex_shader(d3d->dev, 1, hlsl_data->prg[1].vprg);
|
|
|
|
d3d->dev->SetPixelShader(hlsl_data->prg[1].fprg);
|
2012-04-15 16:34:09 +02:00
|
|
|
|
2015-12-05 07:33:21 +01:00
|
|
|
return hlsl_data;
|
2014-10-26 07:12:09 +01:00
|
|
|
|
|
|
|
error:
|
2015-11-30 02:28:35 +01:00
|
|
|
if (hlsl_data)
|
|
|
|
free(hlsl_data);
|
2015-12-05 07:33:21 +01:00
|
|
|
return NULL;
|
2012-04-14 20:33:56 +02:00
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
2015-11-30 02:28:35 +01:00
|
|
|
hlsl_deinit_state(hlsl_data);
|
2014-10-26 07:12:09 +01:00
|
|
|
|
2015-11-30 02:28:35 +01:00
|
|
|
if (hlsl_data)
|
|
|
|
free(hlsl_data);
|
2013-04-12 20:06:08 +02:00
|
|
|
}
|
|
|
|
|
2016-04-15 05:08:03 +02:00
|
|
|
static void hlsl_use(void *data, void *shader_data, unsigned idx, bool set_active)
|
2012-04-14 20:33:56 +02:00
|
|
|
{
|
2014-03-07 20:17:25 +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;
|
2014-03-07 05:31:24 +01:00
|
|
|
LPDIRECT3DDEVICE d3dr = (LPDIRECT3DDEVICE)d3d->dev;
|
2014-10-26 07:12:09 +01:00
|
|
|
|
2015-11-30 02:28:35 +01:00
|
|
|
if (hlsl_data && hlsl_data->prg[idx].vprg && hlsl_data->prg[idx].fprg)
|
2012-05-06 21:57:01 +02:00
|
|
|
{
|
2016-04-15 05:08:03 +02:00
|
|
|
if (set_active)
|
|
|
|
{
|
|
|
|
hlsl_data->active_idx = idx;
|
|
|
|
}
|
|
|
|
|
2015-11-30 02:28:35 +01:00
|
|
|
d3d_set_vertex_shader(d3dr, idx, hlsl_data->prg[idx].vprg);
|
2013-04-16 21:33:40 +02:00
|
|
|
#ifdef _XBOX
|
2015-11-30 02:28:35 +01:00
|
|
|
D3DDevice_SetPixelShader(d3dr, hlsl_data->prg[idx].fprg);
|
2013-04-16 21:33:40 +02:00
|
|
|
#else
|
2015-11-30 02:28:35 +01:00
|
|
|
d3dr->SetPixelShader(hlsl_data->prg[idx].fprg);
|
2013-04-16 21:33:40 +02:00
|
|
|
#endif
|
2012-05-06 21:57:01 +02:00
|
|
|
}
|
2012-04-14 20:33:56 +02:00
|
|
|
}
|
|
|
|
|
2015-12-05 07:33:21 +01:00
|
|
|
static unsigned hlsl_num(void *data)
|
2012-04-14 20:33:56 +02:00
|
|
|
{
|
2015-12-05 07:33:21 +01:00
|
|
|
hlsl_shader_data_t *hlsl_data = (hlsl_shader_data_t*)data;
|
2015-11-30 02:28:35 +01:00
|
|
|
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
|
|
|
}
|
2012-04-14 20:33:56 +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;
|
2015-11-30 02:28:35 +01:00
|
|
|
if (hlsl_data && idx
|
|
|
|
&& (hlsl_data->cg_shader->pass[idx - 1].filter != RARCH_FILTER_UNSPEC))
|
2013-04-12 20:06:08 +02:00
|
|
|
{
|
2015-11-30 02:28:35 +01:00
|
|
|
*smooth = 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-06 06:21:11 +02:00
|
|
|
}
|
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;
|
2015-11-30 02:28:35 +01:00
|
|
|
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;
|
2013-04-12 21:25:16 +02:00
|
|
|
}
|
|
|
|
|
2015-12-05 07:33:21 +01:00
|
|
|
static bool hlsl_set_mvp(void *data, void *shader_data, const math_matrix_4x4 *mat)
|
2013-04-12 21:25:16 +02:00
|
|
|
{
|
2014-03-07 20:17:25 +01:00
|
|
|
d3d_video_t *d3d = (d3d_video_t*)data;
|
2014-03-07 05:31:24 +01:00
|
|
|
LPDIRECT3DDEVICE d3d_device_ptr = (LPDIRECT3DDEVICE)d3d->dev;
|
2015-12-05 07:33:21 +01:00
|
|
|
hlsl_shader_data_t *hlsl_data = (hlsl_shader_data_t*)shader_data;
|
2014-03-07 05:31:24 +01:00
|
|
|
|
2015-11-30 02:28:35 +01:00
|
|
|
if(hlsl_data && hlsl_data->prg[hlsl_data->active_idx].mvp)
|
2013-04-12 21:25:16 +02:00
|
|
|
{
|
2015-11-30 02:28:35 +01:00
|
|
|
hlsl_data->prg[hlsl_data->active_idx].v_ctable->SetMatrix(d3d_device_ptr,
|
|
|
|
hlsl_data->prg[hlsl_data->active_idx].mvp,
|
|
|
|
(D3DXMATRIX*)&hlsl_data->prg[hlsl_data->active_idx].mvp_val);
|
2013-04-12 21:25:16 +02:00
|
|
|
return true;
|
|
|
|
}
|
2014-08-27 03:28:22 +02:00
|
|
|
return false;
|
2013-04-12 21:25:16 +02:00
|
|
|
}
|
|
|
|
|
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)
|
2015-08-30 18:37:41 +02:00
|
|
|
{
|
|
|
|
(void)idx;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-12-05 07:33:21 +01:00
|
|
|
static struct video_shader *hlsl_get_current_shader(void *data)
|
2014-05-23 12:23:08 +02:00
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-10-02 11:11:34 +02:00
|
|
|
const shader_backend_t hlsl_backend = {
|
2013-04-12 21:25:16 +02:00
|
|
|
hlsl_init,
|
|
|
|
hlsl_deinit,
|
|
|
|
hlsl_set_params,
|
2016-04-16 19:38:35 +02:00
|
|
|
hlsl_uniform_set_parameter,
|
2013-04-12 21:25:16 +02:00
|
|
|
hlsl_use,
|
|
|
|
hlsl_num,
|
|
|
|
hlsl_filter_type,
|
2013-09-15 18:49:18 +02:00
|
|
|
NULL, /* hlsl_wrap_type */
|
2013-04-12 21:25:16 +02:00
|
|
|
hlsl_shader_scale,
|
2013-09-15 18:49:18 +02:00
|
|
|
NULL, /* hlsl_set_coords */
|
2013-04-12 21:25:16 +02:00
|
|
|
hlsl_set_mvp,
|
2013-09-15 18:49:18 +02:00
|
|
|
NULL, /* hlsl_get_prev_textures */
|
2015-08-30 18:37:41 +02:00
|
|
|
hlsl_get_feedback_pass,
|
2014-05-11 13:13:38 +02:00
|
|
|
hlsl_mipmap_input,
|
2014-05-23 12:23:08 +02:00
|
|
|
hlsl_get_current_shader,
|
2013-04-12 21:25:16 +02:00
|
|
|
|
|
|
|
RARCH_SHADER_HLSL,
|
2014-10-02 13:42:40 +02:00
|
|
|
"hlsl"
|
2013-04-12 21:25:16 +02:00
|
|
|
};
|