Big D3D9 cleanup.
Use bool for return instead of int (many bugs because of that ...). Remove all use of exceptions, use delayed constructors (due to no exceptions ...). Drop use of unique_ptr in D3D9 (not really needed).
This commit is contained in:
parent
2158076bd7
commit
b618306995
|
@ -215,11 +215,11 @@ static void d3d_get_poke_interface(void *data, const video_poke_interface_t **if
|
||||||
static void *d3d_init(const video_info_t *info, const input_driver_t **input,
|
static void *d3d_init(const video_info_t *info, const input_driver_t **input,
|
||||||
void **input_data)
|
void **input_data)
|
||||||
{
|
{
|
||||||
D3DVideo *vid = new D3DVideo(info, input, input_data);
|
D3DVideo *vid = new D3DVideo;
|
||||||
|
if (!vid->construct(info, input, input_data))
|
||||||
if (!vid)
|
|
||||||
{
|
{
|
||||||
RARCH_ERR("[D3D]: Failed to init D3D.\n");
|
RARCH_ERR("[D3D]: Failed to init D3D.\n");
|
||||||
|
delete vid;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,10 @@
|
||||||
#ifndef D3DVIDEO_HPP__
|
#ifndef D3DVIDEO_HPP__
|
||||||
#define D3DVIDEO_HPP__
|
#define D3DVIDEO_HPP__
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "../../config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../../general.h"
|
#include "../../general.h"
|
||||||
#include "../../driver.h"
|
#include "../../driver.h"
|
||||||
#include "../shader_parse.h"
|
#include "../shader_parse.h"
|
||||||
|
@ -30,7 +34,6 @@
|
||||||
#include "d3d_defines.h"
|
#include "d3d_defines.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory> //Needed for mingw
|
|
||||||
|
|
||||||
class RenderChain;
|
class RenderChain;
|
||||||
|
|
||||||
|
@ -53,12 +56,16 @@ typedef struct
|
||||||
class D3DVideo
|
class D3DVideo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
D3DVideo(const video_info_t* info, const input_driver_t **input,
|
D3DVideo();
|
||||||
void **input_data);
|
~D3DVideo();
|
||||||
|
|
||||||
|
// Delay constructor due to lack of exceptions.
|
||||||
|
bool construct(const video_info_t *info,
|
||||||
|
const input_driver_t **input, void **input_data);
|
||||||
|
|
||||||
bool frame(const void* frame,
|
bool frame(const void* frame,
|
||||||
unsigned width, unsigned height, unsigned pitch,
|
unsigned width, unsigned height, unsigned pitch,
|
||||||
const char *msg);
|
const char *msg);
|
||||||
~D3DVideo();
|
|
||||||
|
|
||||||
bool alive();
|
bool alive();
|
||||||
bool focus() const;
|
bool focus() const;
|
||||||
|
@ -68,7 +75,7 @@ class D3DVideo
|
||||||
bool read_viewport(uint8_t *buffer);
|
bool read_viewport(uint8_t *buffer);
|
||||||
void resize(unsigned new_width, unsigned new_height);
|
void resize(unsigned new_width, unsigned new_height);
|
||||||
bool set_shader(const std::string &path);
|
bool set_shader(const std::string &path);
|
||||||
int process_shader(void);
|
bool process_shader(void);
|
||||||
|
|
||||||
void set_filtering(unsigned index, bool smooth);
|
void set_filtering(unsigned index, bool smooth);
|
||||||
void set_font_rect(font_params_t *params);
|
void set_font_rect(font_params_t *params);
|
||||||
|
@ -121,8 +128,8 @@ class D3DVideo
|
||||||
|
|
||||||
void process(void);
|
void process(void);
|
||||||
|
|
||||||
int init(const video_info_t *info);
|
bool init(const video_info_t *info);
|
||||||
int init_base(const video_info_t *info);
|
bool init_base(const video_info_t *info);
|
||||||
void make_d3dpp(const video_info_t *info, D3DPRESENT_PARAMETERS *d3dpp);
|
void make_d3dpp(const video_info_t *info, D3DPRESENT_PARAMETERS *d3dpp);
|
||||||
void deinit(void);
|
void deinit(void);
|
||||||
RECT monitor_rect(void);
|
RECT monitor_rect(void);
|
||||||
|
@ -137,12 +144,11 @@ class D3DVideo
|
||||||
void deinit_cg();
|
void deinit_cg();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int init_imports(void);
|
bool init_imports(void);
|
||||||
void init_luts(void);
|
bool init_luts(void);
|
||||||
int init_singlepass(void);
|
bool init_singlepass(void);
|
||||||
int init_multipass(void);
|
bool init_multipass(void);
|
||||||
bool init_chain(const video_info_t *video_info);
|
bool init_chain(const video_info_t *video_info);
|
||||||
std::unique_ptr<RenderChain> chain;
|
|
||||||
void deinit_chain(void);
|
void deinit_chain(void);
|
||||||
|
|
||||||
bool init_font(void);
|
bool init_font(void);
|
||||||
|
@ -164,6 +170,8 @@ class D3DVideo
|
||||||
#ifdef HAVE_MENU
|
#ifdef HAVE_MENU
|
||||||
overlay_t rgui;
|
overlay_t rgui;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
RenderChain *chain;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -143,7 +143,7 @@ RECT D3DVideo::monitor_rect(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int D3DVideo::init_base(const video_info_t *info)
|
bool D3DVideo::init_base(const video_info_t *info)
|
||||||
{
|
{
|
||||||
D3DPRESENT_PARAMETERS d3dpp;
|
D3DPRESENT_PARAMETERS d3dpp;
|
||||||
make_d3dpp(info, &d3dpp);
|
make_d3dpp(info, &d3dpp);
|
||||||
|
@ -152,7 +152,7 @@ int D3DVideo::init_base(const video_info_t *info)
|
||||||
if (!g_pD3D)
|
if (!g_pD3D)
|
||||||
{
|
{
|
||||||
RARCH_ERR("Failed to create D3D interface!\n");
|
RARCH_ERR("Failed to create D3D interface!\n");
|
||||||
return 1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(Callback::d3d_err = g_pD3D->CreateDevice(
|
if (FAILED(Callback::d3d_err = g_pD3D->CreateDevice(
|
||||||
|
@ -175,11 +175,11 @@ int D3DVideo::init_base(const video_info_t *info)
|
||||||
&dev)))
|
&dev)))
|
||||||
{
|
{
|
||||||
RARCH_ERR("Failed to initialize device.\n");
|
RARCH_ERR("Failed to initialize device.\n");
|
||||||
return 1;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3DVideo::make_d3dpp(const video_info_t *info, D3DPRESENT_PARAMETERS *d3dpp)
|
void D3DVideo::make_d3dpp(const video_info_t *info, D3DPRESENT_PARAMETERS *d3dpp)
|
||||||
|
@ -214,9 +214,9 @@ void D3DVideo::make_d3dpp(const video_info_t *info, D3DPRESENT_PARAMETERS *d3dpp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int D3DVideo::init(const video_info_t *info)
|
bool D3DVideo::init(const video_info_t *info)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
bool ret = true;
|
||||||
if (!g_pD3D)
|
if (!g_pD3D)
|
||||||
ret = init_base(info);
|
ret = init_base(info);
|
||||||
else if (needs_restore)
|
else if (needs_restore)
|
||||||
|
@ -250,14 +250,14 @@ int D3DVideo::init(const video_info_t *info)
|
||||||
g_pD3D->Release();
|
g_pD3D->Release();
|
||||||
g_pD3D = NULL;
|
g_pD3D = NULL;
|
||||||
ret = init_base(info);
|
ret = init_base(info);
|
||||||
if (!ret)
|
if (ret)
|
||||||
RARCH_LOG("[D3D]: Recovered from dead state.\n");
|
RARCH_LOG("[D3D]: Recovered from dead state.\n");
|
||||||
else
|
else
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret)
|
if (!ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
calculate_rect(screen_width, screen_height, info->force_aspect, g_extern.system.aspect_ratio);
|
calculate_rect(screen_width, screen_height, info->force_aspect, g_extern.system.aspect_ratio);
|
||||||
|
@ -266,28 +266,37 @@ int D3DVideo::init(const video_info_t *info)
|
||||||
if (!init_cg())
|
if (!init_cg())
|
||||||
{
|
{
|
||||||
RARCH_ERR("Failed to initialize Cg.\n");
|
RARCH_ERR("Failed to initialize Cg.\n");
|
||||||
return 1;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!init_chain(info))
|
if (!init_chain(info))
|
||||||
{
|
{
|
||||||
RARCH_ERR("Failed to initialize render chain.\n");
|
RARCH_ERR("Failed to initialize render chain.\n");
|
||||||
return 1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!init_font())
|
if (!init_font())
|
||||||
{
|
{
|
||||||
RARCH_ERR("Failed to initialize font.\n");
|
RARCH_ERR("Failed to initialize font.\n");
|
||||||
return 1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3DVideo::set_viewport(int x, int y, unsigned width, unsigned height)
|
void D3DVideo::set_viewport(int x, int y, unsigned width, unsigned height)
|
||||||
{
|
{
|
||||||
D3DVIEWPORT viewport;
|
D3DVIEWPORT viewport;
|
||||||
viewport.X = max(x, 0); // D3D9 doesn't support negative X/Y viewports ...
|
|
||||||
viewport.Y = max(y, 0);
|
// D3D9 doesn't support negative X/Y viewports ...
|
||||||
|
if (x < 0)
|
||||||
|
x = 0;
|
||||||
|
if (y < 0)
|
||||||
|
y = 0;
|
||||||
|
|
||||||
|
viewport.X = x;
|
||||||
|
viewport.Y = y;
|
||||||
viewport.Width = width;
|
viewport.Width = width;
|
||||||
viewport.Height = height;
|
viewport.Height = height;
|
||||||
viewport.MinZ = 0.0f;
|
viewport.MinZ = 0.0f;
|
||||||
|
@ -440,12 +449,21 @@ void D3DVideo::calculate_rect(unsigned width, unsigned height,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DVideo::D3DVideo(const video_info_t *info, const input_driver_t **input,
|
D3DVideo::D3DVideo() :
|
||||||
void **input_data) :
|
|
||||||
g_pD3D(NULL), dev(NULL), font(NULL),
|
g_pD3D(NULL), dev(NULL), font(NULL),
|
||||||
rotation(0), needs_restore(false), cgCtx(NULL), overlays_enabled(false)
|
rotation(0), needs_restore(false),
|
||||||
|
#ifdef HAVE_CG
|
||||||
|
cgCtx(NULL),
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_OVERLAY
|
||||||
|
overlays_enabled(false),
|
||||||
|
#endif
|
||||||
|
chain(NULL)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool D3DVideo::construct(const video_info_t *info, const input_driver_t **input,
|
||||||
|
void **input_data)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
|
||||||
should_resize = false;
|
should_resize = false;
|
||||||
gfx_set_dwm();
|
gfx_set_dwm();
|
||||||
|
|
||||||
|
@ -536,10 +554,12 @@ D3DVideo::D3DVideo(const video_info_t *info, const input_driver_t **input,
|
||||||
cg_shader = g_settings.video.shader_path;
|
cg_shader = g_settings.video.shader_path;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
process_shader();
|
if (!process_shader())
|
||||||
|
return false;
|
||||||
|
|
||||||
video_info = *info;
|
video_info = *info;
|
||||||
ret = init(&video_info);
|
if (!init(&video_info))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (input && input_data)
|
if (input && input_data)
|
||||||
{
|
{
|
||||||
|
@ -549,6 +569,7 @@ D3DVideo::D3DVideo(const video_info_t *info, const input_driver_t **input,
|
||||||
}
|
}
|
||||||
|
|
||||||
RARCH_LOG("[D3D]: Init complete.\n");
|
RARCH_LOG("[D3D]: Init complete.\n");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3DVideo::deinit(void)
|
void D3DVideo::deinit(void)
|
||||||
|
@ -600,7 +621,7 @@ D3DVideo::~D3DVideo(void)
|
||||||
bool D3DVideo::restore(void)
|
bool D3DVideo::restore(void)
|
||||||
{
|
{
|
||||||
deinit();
|
deinit();
|
||||||
needs_restore = init(&video_info);
|
needs_restore = !init(&video_info);
|
||||||
|
|
||||||
if (needs_restore)
|
if (needs_restore)
|
||||||
RARCH_ERR("[D3D]: Restore error.\n");
|
RARCH_ERR("[D3D]: Restore error.\n");
|
||||||
|
@ -652,12 +673,19 @@ bool D3DVideo::frame(const void *frame,
|
||||||
{
|
{
|
||||||
if (dev->Present(NULL, NULL, NULL, NULL) != D3D_OK)
|
if (dev->Present(NULL, NULL, NULL, NULL) != D3D_OK)
|
||||||
{
|
{
|
||||||
|
RARCH_ERR("[D3D]: Present() failed.\n");
|
||||||
needs_restore = true;
|
needs_restore = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
dev->Clear(0, 0, D3DCLEAR_TARGET, 0, 1, 0);
|
dev->Clear(0, 0, D3DCLEAR_TARGET, 0, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!chain)
|
||||||
|
{
|
||||||
|
RARCH_ERR("[D3D]: Render chain is missing!.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!chain->render(frame, width, height, pitch, rotation))
|
if (!chain->render(frame, width, height, pitch, rotation))
|
||||||
{
|
{
|
||||||
RARCH_ERR("[D3D]: Failed to render scene.\n");
|
RARCH_ERR("[D3D]: Failed to render scene.\n");
|
||||||
|
@ -684,6 +712,7 @@ bool D3DVideo::frame(const void *frame,
|
||||||
if (dev->Present(NULL, NULL, NULL, NULL) != D3D_OK)
|
if (dev->Present(NULL, NULL, NULL, NULL) != D3D_OK)
|
||||||
{
|
{
|
||||||
needs_restore = true;
|
needs_restore = true;
|
||||||
|
RARCH_ERR("[D3D]: Present() failed.\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -776,7 +805,7 @@ void D3DVideo::deinit_cg(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int D3DVideo::init_singlepass(void)
|
bool D3DVideo::init_singlepass(void)
|
||||||
{
|
{
|
||||||
memset(&shader, 0, sizeof(shader));
|
memset(&shader, 0, sizeof(shader));
|
||||||
shader.passes = 1;
|
shader.passes = 1;
|
||||||
|
@ -786,13 +815,13 @@ int D3DVideo::init_singlepass(void)
|
||||||
pass.fbo.type_x = pass.fbo.type_y = RARCH_SCALE_VIEWPORT;
|
pass.fbo.type_x = pass.fbo.type_y = RARCH_SCALE_VIEWPORT;
|
||||||
strlcpy(pass.source.cg, cg_shader.c_str(), sizeof(pass.source.cg));
|
strlcpy(pass.source.cg, cg_shader.c_str(), sizeof(pass.source.cg));
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int D3DVideo::init_imports(void)
|
bool D3DVideo::init_imports(void)
|
||||||
{
|
{
|
||||||
if (!shader.variables)
|
if (!shader.variables)
|
||||||
return 0;
|
return true;
|
||||||
|
|
||||||
state_tracker_info tracker_info = {0};
|
state_tracker_info tracker_info = {0};
|
||||||
|
|
||||||
|
@ -814,7 +843,7 @@ int D3DVideo::init_imports(void)
|
||||||
if (!state_tracker)
|
if (!state_tracker)
|
||||||
{
|
{
|
||||||
RARCH_ERR("Failed to initialize state tracker.\n");
|
RARCH_ERR("Failed to initialize state tracker.\n");
|
||||||
return 1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<state_tracker_t> tracker(state_tracker, [](state_tracker_t *tracker) {
|
std::shared_ptr<state_tracker_t> tracker(state_tracker, [](state_tracker_t *tracker) {
|
||||||
|
@ -823,27 +852,32 @@ int D3DVideo::init_imports(void)
|
||||||
|
|
||||||
chain->add_state_tracker(tracker);
|
chain->add_state_tracker(tracker);
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3DVideo::init_luts(void)
|
bool D3DVideo::init_luts(void)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < shader.luts; i++)
|
for (unsigned i = 0; i < shader.luts; i++)
|
||||||
{
|
{
|
||||||
chain->add_lut(shader.lut[i].id, shader.lut[i].path,
|
bool ret = chain->add_lut(shader.lut[i].id, shader.lut[i].path,
|
||||||
shader.lut[i].filter == RARCH_FILTER_UNSPEC ?
|
shader.lut[i].filter == RARCH_FILTER_UNSPEC ?
|
||||||
g_settings.video.smooth :
|
g_settings.video.smooth :
|
||||||
(shader.lut[i].filter == RARCH_FILTER_LINEAR));
|
(shader.lut[i].filter == RARCH_FILTER_LINEAR));
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int D3DVideo::init_multipass(void)
|
bool D3DVideo::init_multipass(void)
|
||||||
{
|
{
|
||||||
config_file_t *conf = config_file_new(cg_shader.c_str());
|
config_file_t *conf = config_file_new(cg_shader.c_str());
|
||||||
if (!conf)
|
if (!conf)
|
||||||
{
|
{
|
||||||
RARCH_ERR("Failed to load preset.\n");
|
RARCH_ERR("Failed to load preset.\n");
|
||||||
return 1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&shader, 0, sizeof(shader));
|
memset(&shader, 0, sizeof(shader));
|
||||||
|
@ -852,7 +886,7 @@ int D3DVideo::init_multipass(void)
|
||||||
{
|
{
|
||||||
config_file_free(conf);
|
config_file_free(conf);
|
||||||
RARCH_ERR("Failed to parse CGP file.\n");
|
RARCH_ERR("Failed to parse CGP file.\n");
|
||||||
return 1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
config_file_free(conf);
|
config_file_free(conf);
|
||||||
|
@ -886,22 +920,18 @@ int D3DVideo::init_multipass(void)
|
||||||
pass.fbo.type_x = pass.fbo.type_y = RARCH_SCALE_VIEWPORT;
|
pass.fbo.type_x = pass.fbo.type_y = RARCH_SCALE_VIEWPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3DVideo::set_shader(const std::string &path)
|
bool D3DVideo::set_shader(const std::string &path)
|
||||||
{
|
{
|
||||||
auto old_shader = cg_shader;
|
auto old_shader = cg_shader;
|
||||||
bool restore_old = false;
|
bool restore_old = false;
|
||||||
try
|
|
||||||
{
|
|
||||||
cg_shader = path;
|
cg_shader = path;
|
||||||
process_shader();
|
|
||||||
restore();
|
if (!process_shader() || !restore())
|
||||||
}
|
|
||||||
catch (const std::exception &e)
|
|
||||||
{
|
{
|
||||||
RARCH_ERR("[D3D9]: Setting shader failed: (%s).\n", e.what());
|
RARCH_ERR("[D3D9]: Setting shader failed.\n");
|
||||||
restore_old = true;
|
restore_old = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -915,7 +945,7 @@ bool D3DVideo::set_shader(const std::string &path)
|
||||||
return !restore_old;
|
return !restore_old;
|
||||||
}
|
}
|
||||||
|
|
||||||
int D3DVideo::process_shader(void)
|
bool D3DVideo::process_shader(void)
|
||||||
{
|
{
|
||||||
if (strcmp(path_get_extension(cg_shader.c_str()), "cgp") == 0)
|
if (strcmp(path_get_extension(cg_shader.c_str()), "cgp") == 0)
|
||||||
return init_multipass();
|
return init_multipass();
|
||||||
|
@ -925,8 +955,6 @@ int D3DVideo::process_shader(void)
|
||||||
|
|
||||||
void D3DVideo::recompute_pass_sizes(void)
|
void D3DVideo::recompute_pass_sizes(void)
|
||||||
{
|
{
|
||||||
try
|
|
||||||
{
|
|
||||||
LinkInfo link_info = {0};
|
LinkInfo link_info = {0};
|
||||||
link_info.pass = &shader.pass[0];
|
link_info.pass = &shader.pass[0];
|
||||||
link_info.tex_w = link_info.tex_h = video_info.input_scale * RARCH_SCALE_BASE;
|
link_info.tex_w = link_info.tex_h = video_info.input_scale * RARCH_SCALE_BASE;
|
||||||
|
@ -936,7 +964,12 @@ void D3DVideo::recompute_pass_sizes(void)
|
||||||
unsigned out_width = 0;
|
unsigned out_width = 0;
|
||||||
unsigned out_height = 0;
|
unsigned out_height = 0;
|
||||||
|
|
||||||
chain->set_pass_size(0, current_width, current_height);
|
if (!chain->set_pass_size(0, current_width, current_height))
|
||||||
|
{
|
||||||
|
RARCH_ERR("[D3D]: Failed to set pass size.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned i = 1; i < shader.passes; i++)
|
for (unsigned i = 1; i < shader.passes; i++)
|
||||||
{
|
{
|
||||||
RenderChain::convert_geometry(link_info,
|
RenderChain::convert_geometry(link_info,
|
||||||
|
@ -946,36 +979,39 @@ void D3DVideo::recompute_pass_sizes(void)
|
||||||
link_info.tex_w = next_pow2(out_width);
|
link_info.tex_w = next_pow2(out_width);
|
||||||
link_info.tex_h = next_pow2(out_height);
|
link_info.tex_h = next_pow2(out_height);
|
||||||
|
|
||||||
chain->set_pass_size(i, link_info.tex_w, link_info.tex_h);
|
if (!chain->set_pass_size(i, link_info.tex_w, link_info.tex_h))
|
||||||
|
{
|
||||||
|
RARCH_ERR("[D3D]: Failed to set pass size.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
current_width = out_width;
|
current_width = out_width;
|
||||||
current_height = out_height;
|
current_height = out_height;
|
||||||
|
|
||||||
link_info.pass = &shader.pass[i];
|
link_info.pass = &shader.pass[i];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (const std::exception& e)
|
|
||||||
{
|
|
||||||
RARCH_ERR("[D3D9]: Render chain error: (%s).\n", e.what());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3DVideo::init_chain(const video_info_t *video_info)
|
bool D3DVideo::init_chain(const video_info_t *video_info)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
|
||||||
// Setup information for first pass.
|
// Setup information for first pass.
|
||||||
LinkInfo link_info = {0};
|
LinkInfo link_info = {0};
|
||||||
|
|
||||||
link_info.pass = &shader.pass[0];
|
link_info.pass = &shader.pass[0];
|
||||||
link_info.tex_w = link_info.tex_h = video_info->input_scale * RARCH_SCALE_BASE;
|
link_info.tex_w = link_info.tex_h = video_info->input_scale * RARCH_SCALE_BASE;
|
||||||
|
|
||||||
chain = std::unique_ptr<RenderChain>(
|
delete chain;
|
||||||
new RenderChain(
|
chain = new RenderChain(
|
||||||
video_info,
|
video_info,
|
||||||
dev, cgCtx,
|
dev, cgCtx,
|
||||||
link_info,
|
final_viewport);
|
||||||
video_info->rgb32 ? RenderChain::ARGB : RenderChain::RGB565,
|
|
||||||
final_viewport));
|
if (!chain->init(link_info,
|
||||||
|
video_info->rgb32 ? RenderChain::ARGB : RenderChain::RGB565))
|
||||||
|
{
|
||||||
|
RARCH_ERR("[D3D9]: Failed to init render chain.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned current_width = link_info.tex_w;
|
unsigned current_width = link_info.tex_w;
|
||||||
unsigned current_height = link_info.tex_h;
|
unsigned current_height = link_info.tex_h;
|
||||||
|
@ -995,15 +1031,22 @@ bool D3DVideo::init_chain(const video_info_t *video_info)
|
||||||
current_width = out_width;
|
current_width = out_width;
|
||||||
current_height = out_height;
|
current_height = out_height;
|
||||||
|
|
||||||
chain->add_pass(link_info);
|
if (!chain->add_pass(link_info))
|
||||||
|
{
|
||||||
|
RARCH_ERR("[D3D9]: Failed to add pass.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init_luts();
|
if (!init_luts())
|
||||||
ret = init_imports();
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
{
|
{
|
||||||
RARCH_ERR("[D3D9]: Render chain error.\n");
|
RARCH_ERR("[D3D9]: Failed to init LUTs.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!init_imports())
|
||||||
|
{
|
||||||
|
RARCH_ERR("[D3D9]: Failed to init imports.\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1012,7 +1055,8 @@ bool D3DVideo::init_chain(const video_info_t *video_info)
|
||||||
|
|
||||||
void D3DVideo::deinit_chain(void)
|
void D3DVideo::deinit_chain(void)
|
||||||
{
|
{
|
||||||
chain.reset();
|
delete chain;
|
||||||
|
chain = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3DVideo::init_font(void)
|
bool D3DVideo::init_font(void)
|
||||||
|
|
|
@ -62,14 +62,20 @@ RenderChain::~RenderChain()
|
||||||
RenderChain::RenderChain(const video_info_t *video_info,
|
RenderChain::RenderChain(const video_info_t *video_info,
|
||||||
LPDIRECT3DDEVICE dev_,
|
LPDIRECT3DDEVICE dev_,
|
||||||
CGcontext cgCtx_,
|
CGcontext cgCtx_,
|
||||||
const LinkInfo &info, PixelFormat fmt,
|
|
||||||
const D3DVIEWPORT &final_viewport_)
|
const D3DVIEWPORT &final_viewport_)
|
||||||
: dev(dev_), cgCtx(cgCtx_), video_info(*video_info), final_viewport(final_viewport_), frame_count(0)
|
: dev(dev_), cgCtx(cgCtx_), video_info(*video_info), final_viewport(final_viewport_), frame_count(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool RenderChain::init(const LinkInfo &info, PixelFormat fmt)
|
||||||
{
|
{
|
||||||
pixel_size = fmt == RGB565 ? 2 : 4;
|
pixel_size = fmt == RGB565 ? 2 : 4;
|
||||||
create_first_pass(info, fmt);
|
if (!create_first_pass(info, fmt))
|
||||||
|
return false;
|
||||||
log_info(info);
|
log_info(info);
|
||||||
compile_shaders(fStock, vStock, "");
|
if (!compile_shaders(fStock, vStock, ""))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderChain::clear()
|
void RenderChain::clear()
|
||||||
|
@ -113,7 +119,7 @@ void RenderChain::set_final_viewport(const D3DVIEWPORT9& final_viewport)
|
||||||
this->final_viewport = final_viewport;
|
this->final_viewport = final_viewport;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderChain::set_pass_size(unsigned pass_index, unsigned width, unsigned height)
|
bool RenderChain::set_pass_size(unsigned pass_index, unsigned width, unsigned height)
|
||||||
{
|
{
|
||||||
Pass &pass = passes[pass_index];
|
Pass &pass = passes[pass_index];
|
||||||
if (width != pass.info.tex_w || height != pass.info.tex_h)
|
if (width != pass.info.tex_w || height != pass.info.tex_h)
|
||||||
|
@ -128,7 +134,7 @@ void RenderChain::set_pass_size(unsigned pass_index, unsigned width, unsigned he
|
||||||
D3DPOOL_DEFAULT,
|
D3DPOOL_DEFAULT,
|
||||||
&pass.tex, NULL)))
|
&pass.tex, NULL)))
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to create texture ...");
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->SetTexture(0, pass.tex);
|
dev->SetTexture(0, pass.tex);
|
||||||
|
@ -136,9 +142,11 @@ void RenderChain::set_pass_size(unsigned pass_index, unsigned width, unsigned he
|
||||||
dev->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
|
dev->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
|
||||||
dev->SetTexture(0, NULL);
|
dev->SetTexture(0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderChain::add_pass(const LinkInfo &info)
|
bool RenderChain::add_pass(const LinkInfo &info)
|
||||||
{
|
{
|
||||||
Pass pass;
|
Pass pass;
|
||||||
pass.info = info;
|
pass.info = info;
|
||||||
|
@ -146,7 +154,8 @@ void RenderChain::add_pass(const LinkInfo &info)
|
||||||
pass.last_height = 0;
|
pass.last_height = 0;
|
||||||
|
|
||||||
compile_shaders(pass.fPrg, pass.vPrg, info.pass->source.cg);
|
compile_shaders(pass.fPrg, pass.vPrg, info.pass->source.cg);
|
||||||
init_fvf(pass);
|
if (!init_fvf(pass))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (FAILED(dev->CreateVertexBuffer(
|
if (FAILED(dev->CreateVertexBuffer(
|
||||||
4 * sizeof(Vertex),
|
4 * sizeof(Vertex),
|
||||||
|
@ -156,7 +165,7 @@ void RenderChain::add_pass(const LinkInfo &info)
|
||||||
&pass.vertex_buf,
|
&pass.vertex_buf,
|
||||||
NULL)))
|
NULL)))
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to create Vertex buf ...");
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(dev->CreateTexture(info.tex_w, info.tex_h, 1,
|
if (FAILED(dev->CreateTexture(info.tex_w, info.tex_h, 1,
|
||||||
|
@ -165,7 +174,7 @@ void RenderChain::add_pass(const LinkInfo &info)
|
||||||
D3DPOOL_DEFAULT,
|
D3DPOOL_DEFAULT,
|
||||||
&pass.tex, NULL)))
|
&pass.tex, NULL)))
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to create texture ...");
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->SetTexture(0, pass.tex);
|
dev->SetTexture(0, pass.tex);
|
||||||
|
@ -176,9 +185,10 @@ void RenderChain::add_pass(const LinkInfo &info)
|
||||||
passes.push_back(pass);
|
passes.push_back(pass);
|
||||||
|
|
||||||
log_info(info);
|
log_info(info);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderChain::add_lut(const std::string &id,
|
bool RenderChain::add_lut(const std::string &id,
|
||||||
const std::string &path,
|
const std::string &path,
|
||||||
bool smooth)
|
bool smooth)
|
||||||
{
|
{
|
||||||
|
@ -202,7 +212,7 @@ void RenderChain::add_lut(const std::string &id,
|
||||||
NULL,
|
NULL,
|
||||||
&lut)))
|
&lut)))
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to load LUT!");
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->SetTexture(0, lut);
|
dev->SetTexture(0, lut);
|
||||||
|
@ -212,6 +222,7 @@ void RenderChain::add_lut(const std::string &id,
|
||||||
|
|
||||||
lut_info info = { lut, id, smooth };
|
lut_info info = { lut, id, smooth };
|
||||||
luts.push_back(info);
|
luts.push_back(info);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderChain::add_state_tracker(std::shared_ptr<state_tracker_t> tracker)
|
void RenderChain::add_state_tracker(std::shared_ptr<state_tracker_t> tracker)
|
||||||
|
@ -327,7 +338,7 @@ D3DTEXTUREFILTERTYPE RenderChain::translate_filter(bool smooth)
|
||||||
return smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT;
|
return smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderChain::create_first_pass(const LinkInfo &info, PixelFormat fmt)
|
bool RenderChain::create_first_pass(const LinkInfo &info, PixelFormat fmt)
|
||||||
{
|
{
|
||||||
D3DXMATRIX ident;
|
D3DXMATRIX ident;
|
||||||
D3DXMatrixIdentity(&ident);
|
D3DXMatrixIdentity(&ident);
|
||||||
|
@ -353,7 +364,7 @@ void RenderChain::create_first_pass(const LinkInfo &info, PixelFormat fmt)
|
||||||
&prev.vertex_buf[i],
|
&prev.vertex_buf[i],
|
||||||
NULL)))
|
NULL)))
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to create Vertex buf ...");
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(dev->CreateTexture(info.tex_w, info.tex_h, 1, 0,
|
if (FAILED(dev->CreateTexture(info.tex_w, info.tex_h, 1, 0,
|
||||||
|
@ -361,7 +372,7 @@ void RenderChain::create_first_pass(const LinkInfo &info, PixelFormat fmt)
|
||||||
D3DPOOL_MANAGED,
|
D3DPOOL_MANAGED,
|
||||||
&prev.tex[i], NULL)))
|
&prev.tex[i], NULL)))
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to create texture ...");
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->SetTexture(0, prev.tex[i]);
|
dev->SetTexture(0, prev.tex[i]);
|
||||||
|
@ -375,11 +386,13 @@ void RenderChain::create_first_pass(const LinkInfo &info, PixelFormat fmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
compile_shaders(pass.fPrg, pass.vPrg, info.pass->source.cg);
|
compile_shaders(pass.fPrg, pass.vPrg, info.pass->source.cg);
|
||||||
init_fvf(pass);
|
if (!init_fvf(pass))
|
||||||
|
return false;
|
||||||
passes.push_back(pass);
|
passes.push_back(pass);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderChain::compile_shaders(CGprogram &fPrg, CGprogram &vPrg, const std::string &shader)
|
bool RenderChain::compile_shaders(CGprogram &fPrg, CGprogram &vPrg, const std::string &shader)
|
||||||
{
|
{
|
||||||
CGprofile vertex_profile = cgD3D9GetLatestVertexProfile();
|
CGprofile vertex_profile = cgD3D9GetLatestVertexProfile();
|
||||||
CGprofile fragment_profile = cgD3D9GetLatestPixelProfile();
|
CGprofile fragment_profile = cgD3D9GetLatestPixelProfile();
|
||||||
|
@ -421,10 +434,11 @@ void RenderChain::compile_shaders(CGprogram &fPrg, CGprogram &vPrg, const std::s
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fPrg || !vPrg)
|
if (!fPrg || !vPrg)
|
||||||
throw std::runtime_error("Failed to compile shaders!");
|
return false;
|
||||||
|
|
||||||
cgD3D9LoadProgram(fPrg, true, 0);
|
cgD3D9LoadProgram(fPrg, true, 0);
|
||||||
cgD3D9LoadProgram(vPrg, true, 0);
|
cgD3D9LoadProgram(vPrg, true, 0);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderChain::set_shaders(CGprogram &fPrg, CGprogram &vPrg)
|
void RenderChain::set_shaders(CGprogram &fPrg, CGprogram &vPrg)
|
||||||
|
@ -996,7 +1010,7 @@ static inline CGparameter find_param_from_semantic(CGprogram prog, const std::st
|
||||||
{ (WORD)(stream), (WORD)(offset * sizeof(float)), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, \
|
{ (WORD)(stream), (WORD)(offset * sizeof(float)), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, \
|
||||||
D3DDECLUSAGE_COLOR, (BYTE)(index) } \
|
D3DDECLUSAGE_COLOR, (BYTE)(index) } \
|
||||||
|
|
||||||
void RenderChain::init_fvf(Pass &pass)
|
bool RenderChain::init_fvf(Pass &pass)
|
||||||
{
|
{
|
||||||
static const D3DVERTEXELEMENT decl_end = D3DDECL_END();
|
static const D3DVERTEXELEMENT decl_end = D3DDECL_END();
|
||||||
static const D3DVERTEXELEMENT position_decl = DECL_FVF_POSITION(0);
|
static const D3DVERTEXELEMENT position_decl = DECL_FVF_POSITION(0);
|
||||||
|
@ -1006,7 +1020,7 @@ void RenderChain::init_fvf(Pass &pass)
|
||||||
|
|
||||||
D3DVERTEXELEMENT decl[MAXD3DDECLLENGTH] = {{0}};
|
D3DVERTEXELEMENT decl[MAXD3DDECLLENGTH] = {{0}};
|
||||||
if (cgD3D9GetVertexDeclaration(pass.vPrg, decl) == CG_FALSE)
|
if (cgD3D9GetVertexDeclaration(pass.vPrg, decl) == CG_FALSE)
|
||||||
throw std::runtime_error("Failed to get VertexDeclaration!");
|
return false;
|
||||||
|
|
||||||
unsigned count;
|
unsigned count;
|
||||||
for (count = 0; count < MAXD3DDECLLENGTH; count++)
|
for (count = 0; count < MAXD3DDECLLENGTH; count++)
|
||||||
|
@ -1112,7 +1126,9 @@ void RenderChain::init_fvf(Pass &pass)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(dev->CreateVertexDeclaration(decl, &pass.vertex_decl)))
|
if (FAILED(dev->CreateVertexDeclaration(decl, &pass.vertex_decl)))
|
||||||
throw std::runtime_error("Failed to set up FVF!");
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderChain::bind_tracker(Pass &pass, unsigned pass_index)
|
void RenderChain::bind_tracker(Pass &pass, unsigned pass_index)
|
||||||
|
|
|
@ -47,14 +47,15 @@ class RenderChain
|
||||||
#ifdef HAVE_CG
|
#ifdef HAVE_CG
|
||||||
CGcontext cgCtx,
|
CGcontext cgCtx,
|
||||||
#endif
|
#endif
|
||||||
const LinkInfo &info,
|
|
||||||
PixelFormat fmt,
|
|
||||||
const D3DVIEWPORT &final_viewport);
|
const D3DVIEWPORT &final_viewport);
|
||||||
|
~RenderChain();
|
||||||
|
|
||||||
void set_pass_size(unsigned pass, unsigned width, unsigned height);
|
bool init(const LinkInfo &info, PixelFormat fmt);
|
||||||
|
|
||||||
|
bool set_pass_size(unsigned pass, unsigned width, unsigned height);
|
||||||
void set_final_viewport(const D3DVIEWPORT9 &final_viewport);
|
void set_final_viewport(const D3DVIEWPORT9 &final_viewport);
|
||||||
void add_pass(const LinkInfo &info);
|
bool add_pass(const LinkInfo &info);
|
||||||
void add_lut(const std::string &id, const std::string &path, bool smooth);
|
bool add_lut(const std::string &id, const std::string &path, bool smooth);
|
||||||
void add_state_tracker(std::shared_ptr<state_tracker_t> tracker);
|
void add_state_tracker(std::shared_ptr<state_tracker_t> tracker);
|
||||||
|
|
||||||
bool render(const void *data,
|
bool render(const void *data,
|
||||||
|
@ -66,7 +67,6 @@ class RenderChain
|
||||||
const D3DVIEWPORT &final_viewport);
|
const D3DVIEWPORT &final_viewport);
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
~RenderChain();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -121,8 +121,8 @@ class RenderChain
|
||||||
D3DVIEWPORT final_viewport;
|
D3DVIEWPORT final_viewport;
|
||||||
unsigned frame_count;
|
unsigned frame_count;
|
||||||
|
|
||||||
void create_first_pass(const LinkInfo &info, PixelFormat fmt);
|
bool create_first_pass(const LinkInfo &info, PixelFormat fmt);
|
||||||
void compile_shaders(CGprogram &fPrg, CGprogram &vPrg, const std::string &shader);
|
bool compile_shaders(CGprogram &fPrg, CGprogram &vPrg, const std::string &shader);
|
||||||
|
|
||||||
void set_vertices(Pass &pass,
|
void set_vertices(Pass &pass,
|
||||||
unsigned width, unsigned height,
|
unsigned width, unsigned height,
|
||||||
|
@ -164,7 +164,7 @@ class RenderChain
|
||||||
void bind_tracker(Pass &pass, unsigned pass_index);
|
void bind_tracker(Pass &pass, unsigned pass_index);
|
||||||
void unbind_all();
|
void unbind_all();
|
||||||
|
|
||||||
void init_fvf(Pass &pass);
|
bool init_fvf(Pass &pass);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue