win32: use shader_parse for d3d

This commit is contained in:
OV2 2013-04-06 21:26:27 +02:00
parent 69c460bbec
commit 20d1fba464
5 changed files with 175 additions and 603 deletions

View File

@ -1,173 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CONFIG_FILE_HPP
#define __CONFIG_FILE_HPP
#include "../../conf/config_file.h"
#include <utility>
#include <cstdlib>
class ConfigFile
{
public:
ConfigFile(const std::string& _path = "") : path(_path)
{
conf = config_file_new(path.c_str());
if (!conf)
conf = config_file_new(nullptr);
}
operator bool() { return conf; }
ConfigFile& operator=(ConfigFile&& _in)
{
if (conf)
{
if (path[0])
config_file_write(conf, path.c_str());
config_file_free(conf);
conf = _in.conf;
_in.conf = nullptr;
path = _in.path;
}
return *this;
}
bool get(const std::string& key, int& out)
{
if (!conf) return false;
int val;
if (config_get_int(conf, key.c_str(), &val))
{
out = val;
return true;
}
return false;
}
bool get(const std::string& key, unsigned& out)
{
if (!conf) return false;
unsigned val;
if (config_get_uint(conf, key.c_str(), &val))
{
out = val;
return true;
}
return false;
}
bool get_hex(const std::string& key, unsigned& out)
{
if (!conf) return false;
unsigned val;
if (config_get_hex(conf, key.c_str(), &val))
{
out = val;
return true;
}
return false;
}
bool get(const std::string& key, char& out)
{
if (!conf) return false;
char val;
if (config_get_char(conf, key.c_str(), &val))
{
out = val;
return true;
}
return false;
}
bool get(const std::string& key, bool& out)
{
if (!conf) return false;
bool val;
if (config_get_bool(conf, key.c_str(), &val))
{
out = val;
return true;
}
return false;
}
bool get(const std::string& key, std::string& out)
{
if (!conf) return false;
char *val;
if (config_get_string(conf, key.c_str(), &val))
{
out = val;
std::free(val);
return out.length() > 0;
}
return false;
}
bool get(const std::string& key, double& out)
{
if (!conf) return false;
double val;
if (config_get_double(conf, key.c_str(), &val))
{
out = val;
return true;
}
return false;
}
void set(const std::string& key, int val)
{
if (conf) config_set_int(conf, key.c_str(), val);
}
void set(const std::string& key, double val)
{
if (conf) config_set_double(conf, key.c_str(), val);
}
void set(const std::string& key, const std::string& val)
{
if (conf) config_set_string(conf, key.c_str(), val.c_str());
}
void set(const std::string& key, char val)
{
if (conf) config_set_char(conf, key.c_str(), val);
}
void set(const std::string& key, bool val)
{
if (conf) config_set_bool(conf, key.c_str(), val);
}
void write() { if (conf && path[0]) config_file_write(conf, path.c_str()); }
ConfigFile(ConfigFile&& _in) { *this = std::move(_in); }
~ConfigFile() { if (conf) config_file_free(conf); }
private:
config_file_t *conf;
std::string path;
ConfigFile(const ConfigFile&); // Workaround lack of = delete.
void operator=(const ConfigFile&);
};
#endif

View File

@ -28,7 +28,7 @@
#include "d3d9.hpp" #include "d3d9.hpp"
#include "render_chain.hpp" #include "render_chain.hpp"
#include "config_file.hpp" #include "../../file.h"
#include "../gfx_common.h" #include "../gfx_common.h"
#include "../../compat/posix_string.h" #include "../../compat/posix_string.h"
#include "../../performance.h" #include "../../performance.h"
@ -475,6 +475,8 @@ D3DVideo::D3DVideo(const video_info_t *info) :
cg_shader = g_settings.video.cg_shader_path; cg_shader = g_settings.video.cg_shader_path;
#endif #endif
process_shader();
video_info = *info; video_info = *info;
init(video_info); init(video_info);
@ -644,26 +646,12 @@ void D3DVideo::deinit_cg()
} }
#endif #endif
void D3DVideo::init_chain_singlepass(const video_info_t &video_info) void D3DVideo::init_singlepass()
{ {
LinkInfo info = {0}; memset(&shader, 0, sizeof(shader));
LinkInfo info_second = {0}; shader.passes = 1;
gfx_shader_pass &pass = shader.pass[0];
#ifdef HAVE_CG strlcpy(pass.source.cg, cg_shader.c_str(), sizeof(pass.source.cg));
info.shader_path = cg_shader;
#endif
info.scale_x = info.scale_y = 1.0f;
info.filter_linear = video_info.smooth;
info.tex_w = info.tex_h = RARCH_SCALE_BASE * video_info.input_scale;
info.scale_type_x = info.scale_type_y = LinkInfo::Viewport;
chain = std::unique_ptr<RenderChain>(new RenderChain(
video_info,
dev, cgCtx,
info,
video_info.rgb32 ? RenderChain::ARGB : RenderChain::RGB565,
final_viewport));
} }
static std::vector<std::string> tokenize(const std::string &str) static std::vector<std::string> tokenize(const std::string &str)
@ -683,105 +671,13 @@ static std::vector<std::string> tokenize(const std::string &str)
return list; return list;
} }
void D3DVideo::init_imports(ConfigFile &conf, const std::string &basedir) void D3DVideo::init_imports()
{ {
std::string imports;
if (!conf.get("imports", imports))
return;
std::vector<std::string> list = tokenize(imports);
state_tracker_info tracker_info = {0}; state_tracker_info tracker_info = {0};
std::vector<state_tracker_uniform_info> uniforms;
for (auto itr = list.begin(); itr != list.end(); ++itr)
{
auto &elem = *itr;
state_tracker_uniform_info info;
std::memset(&info, 0, sizeof(info));
std::string semantic, wram, input_slot, mask, equal;
state_tracker_type tracker_type;
state_ram_type ram_type = RARCH_STATE_NONE;
conf.get(elem + "_semantic", semantic);
if (semantic == "capture")
tracker_type = RARCH_STATE_CAPTURE;
else if (semantic == "transition")
tracker_type = RARCH_STATE_TRANSITION;
else if (semantic == "transition_count")
tracker_type = RARCH_STATE_TRANSITION_COUNT;
else if (semantic == "capture_previous")
tracker_type = RARCH_STATE_CAPTURE_PREV;
else if (semantic == "transition_previous")
tracker_type = RARCH_STATE_TRANSITION_PREV;
#ifdef HAVE_PYTHON
else if (semantic == "python")
tracker_type = RARCH_STATE_PYTHON;
#endif
else
throw std::logic_error("Invalid semantic.");
unsigned addr = 0;
#ifdef HAVE_PYTHON
if (tracker_type != RARCH_STATE_PYTHON)
#endif
{
unsigned input_slot = 0;
if (conf.get_hex(elem + "_input_slot", input_slot))
{
switch (input_slot)
{
case 1:
ram_type = RARCH_STATE_INPUT_SLOT1;
break;
case 2:
ram_type = RARCH_STATE_INPUT_SLOT2;
break;
default:
throw std::logic_error("Invalid input slot for import.");
}
}
else if (conf.get_hex(elem + "_wram", addr))
ram_type = RARCH_STATE_WRAM;
else
throw std::logic_error("No address assigned to semantic.");
}
unsigned memtype;
switch (ram_type)
{
case RARCH_STATE_WRAM:
memtype = RETRO_MEMORY_SYSTEM_RAM;
break;
default:
memtype = -1u;
}
if ((memtype != -1u) && (addr >= pretro_get_memory_size(memtype)))
throw std::logic_error("Semantic address out of bounds.");
unsigned bitmask = 0, bitequal = 0;
conf.get_hex(elem + "_mask", bitmask);
conf.get_hex(elem + "_equal", bitequal);
strlcpy(info.id, elem.c_str(), sizeof(info.id));
info.addr = addr;
info.type = tracker_type;
info.ram_type = ram_type;
info.mask = bitmask;
info.equal = bitequal;
uniforms.push_back(info);
}
tracker_info.wram = (uint8_t*)pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM); tracker_info.wram = (uint8_t*)pretro_get_memory_data(RETRO_MEMORY_SYSTEM_RAM);
tracker_info.info = uniforms.data(); tracker_info.info = shader.variable;
tracker_info.info_elem = uniforms.size(); tracker_info.info_elem = shader.variables;
std::string py_path; std::string py_path;
std::string py_class; std::string py_class;
@ -802,41 +698,31 @@ void D3DVideo::init_imports(ConfigFile &conf, const std::string &basedir)
chain->add_state_tracker(tracker); chain->add_state_tracker(tracker);
} }
void D3DVideo::init_luts(ConfigFile &conf, const std::string &basedir) void D3DVideo::init_luts()
{ {
std::string textures; for (unsigned i = 0; i < shader.luts; i++)
if (!conf.get("textures", textures))
return;
std::vector<std::string> list = tokenize(textures);
for (unsigned i = 0; i < list.size(); i++)
{ {
const std::string &id = list[i]; chain->add_lut(shader.lut[i].id, shader.lut[i].path, shader.lut[i].filter == RARCH_FILTER_LINEAR);
bool smooth = true;
conf.get(id + "_filter", smooth);
std::string path;
if (!conf.get(id, path))
throw std::runtime_error("Failed to get LUT texture path!");
chain->add_lut(id, basedir + path, smooth);
} }
} }
void D3DVideo::init_chain_multipass(const video_info_t &info) void D3DVideo::init_multipass()
{ {
ConfigFile conf(cg_shader); config_file_t *conf = config_file_new(cg_shader.c_str());
if (!conf)
throw std::runtime_error("Failed to load preset");
int shaders = 0; memset(&shader, 0, sizeof(shader));
if (!conf.get("shaders", shaders))
throw std::runtime_error("Couldn't find \"shaders\" in meta-shader");
if (shaders < 1) if (!gfx_shader_read_conf_cgp(conf, &shader))
throw std::runtime_error("Must have at least one shader!"); {
config_file_free(conf);
throw std::runtime_error("Failed to parse CGP file.");
}
RARCH_LOG("[D3D9 Meta-Cg] Found %d shaders.\n", shaders); config_file_free(conf);
RARCH_LOG("[D3D9 Meta-Cg] Found %d shaders.\n", shader.passes);
std::string basedir = cg_shader; std::string basedir = cg_shader;
size_t pos = basedir.rfind('/'); size_t pos = basedir.rfind('/');
@ -848,237 +734,24 @@ void D3DVideo::init_chain_multipass(const video_info_t &info)
else else
basedir = "./"; basedir = "./";
bool use_extra_pass = false; for (unsigned i = 0; i < shader.passes; i++)
bool use_first_pass_only = false;
std::vector<std::string> shader_paths;
std::vector<LinkInfo::ScaleType> scale_types_x;
std::vector<LinkInfo::ScaleType> scale_types_y;
std::vector<float> scales_x;
std::vector<float> scales_y;
std::vector<unsigned> abses_x;
std::vector<unsigned> abses_y;
std::vector<bool> filters;
std::vector<unsigned> frame_count_mods;
std::vector<bool> float_fbos;
// Shader paths.
for (int i = 0; i < shaders; i++)
{ {
char buf[256]; if (!shader.pass[i].fbo.valid)
snprintf(buf, sizeof(buf), "shader%d", i);
std::string relpath;
if (!conf.get(buf, relpath))
throw std::runtime_error("Couldn't locate shader path in meta-shader");
shader_paths.push_back(basedir);
shader_paths.back() += relpath;
}
// Dimensions.
for (int i = 0; i < shaders; i++)
{
char attr_type[64];
char attr_type_x[64];
char attr_type_y[64];
char attr_scale[64];
char attr_scale_x[64];
char attr_scale_y[64];
int abs_x = RARCH_SCALE_BASE * info.input_scale;
int abs_y = RARCH_SCALE_BASE * info.input_scale;
double scale_x = 1.0f;
double scale_y = 1.0f;
std::string attr = "source";
std::string attr_x = "source";
std::string attr_y = "source";
snprintf(attr_type, sizeof(attr_type), "scale_type%d", i);
snprintf(attr_type_x, sizeof(attr_type_x), "scale_type_x%d", i);
snprintf(attr_type_y, sizeof(attr_type_x), "scale_type_y%d", i);
snprintf(attr_scale, sizeof(attr_scale), "scale%d", i);
snprintf(attr_scale_x, sizeof(attr_scale_x), "scale_x%d", i);
snprintf(attr_scale_y, sizeof(attr_scale_y), "scale_y%d", i);
bool has_scale = false;
if (conf.get(attr_type, attr))
{ {
attr_x = attr_y = attr; shader.pass[i].fbo.scale_x = shader.pass[i].fbo.scale_y = 1.0f;
has_scale = true; shader.pass[i].fbo.type_x = shader.pass[i].fbo.type_y = RARCH_SCALE_INPUT;
} }
else std::string rel_shader = shader.pass[i].source.cg;
{ fill_pathname_resolve_relative(shader.pass[i].source.cg, basedir.c_str(),
if (conf.get(attr_type_x, attr_x)) rel_shader.c_str(), sizeof(shader.pass[i].source.cg));
has_scale = true;
if (conf.get(attr_type_y, attr_y))
has_scale = true;
}
if (attr_x == "source")
scale_types_x.push_back(LinkInfo::Relative);
else if (attr_x == "viewport")
scale_types_x.push_back(LinkInfo::Viewport);
else if (attr_x == "absolute")
scale_types_x.push_back(LinkInfo::Absolute);
else
throw std::runtime_error("Invalid scale_type_x!");
if (attr_y == "source")
scale_types_y.push_back(LinkInfo::Relative);
else if (attr_y == "viewport")
scale_types_y.push_back(LinkInfo::Viewport);
else if (attr_y == "absolute")
scale_types_y.push_back(LinkInfo::Absolute);
else
throw std::runtime_error("Invalid scale_type_y!");
double scale = 0.0;
if (conf.get(attr_scale, scale))
scale_x = scale_y = scale;
else
{
conf.get(attr_scale_x, scale_x);
conf.get(attr_scale_y, scale_y);
}
int absolute = 0;
if (conf.get(attr_scale, absolute))
abs_x = abs_y = absolute;
else
{
conf.get(attr_scale_x, abs_x);
conf.get(attr_scale_y, abs_y);
}
scales_x.push_back(scale_x);
scales_y.push_back(scale_y);
abses_x.push_back(abs_x);
abses_y.push_back(abs_y);
if (has_scale && i == shaders - 1)
use_extra_pass = true;
else if (!has_scale && i == 0)
use_first_pass_only = true;
else if (i > 0)
use_first_pass_only = false;
} }
// Filter options. for (unsigned i = 0; i < shader.luts; i++)
for (int i = 0; i < shaders; i++)
{ {
char attr_filter[64]; std::string rel_lut = shader.lut[i].path;
snprintf(attr_filter, sizeof(attr_filter), "filter_linear%d", i); fill_pathname_resolve_relative(shader.lut[i].path, basedir.c_str(),
bool filter = info.smooth; rel_lut.c_str(), sizeof(shader.lut[i].path));
conf.get(attr_filter, filter);
filters.push_back(filter);
} }
// Frame counter modulo.
for (int i = 0; i < shaders; i++)
{
char attr_frame_count_mod[64];
snprintf(attr_frame_count_mod, sizeof(attr_frame_count_mod), "frame_count_mod%d", i);
unsigned frame_count_mod = 0;
conf.get(attr_frame_count_mod, frame_count_mod);
frame_count_mods.push_back(frame_count_mod);
}
// Floating point framebuffers.
for (int i = 0; i < shaders; i++)
{
char attr_float_framebuffer[64];
snprintf(attr_float_framebuffer, sizeof(attr_float_framebuffer), "float_framebuffer%d", i);
bool float_framebuffer = false;
conf.get(attr_float_framebuffer, float_framebuffer);
float_fbos.push_back(float_framebuffer);
}
// Setup information for first pass.
LinkInfo link_info = {0};
link_info.shader_path = shader_paths[0];
if (use_first_pass_only)
{
link_info.scale_x = link_info.scale_y = 1.0f;
link_info.scale_type_x = link_info.scale_type_y = LinkInfo::Viewport;
}
else
{
link_info.scale_x = scales_x[0];
link_info.scale_y = scales_y[0];
link_info.abs_x = abses_x[0];
link_info.abs_y = abses_y[0];
link_info.scale_type_x = scale_types_x[0];
link_info.scale_type_y = scale_types_y[0];
}
link_info.filter_linear = filters[0];
link_info.tex_w = link_info.tex_h = info.input_scale * RARCH_SCALE_BASE;
link_info.frame_count_mod = frame_count_mods[0];
link_info.float_framebuffer = false;
chain = std::unique_ptr<RenderChain>(
new RenderChain(
video_info,
dev, cgCtx,
link_info,
info.rgb32 ? RenderChain::ARGB : RenderChain::RGB565,
final_viewport));
unsigned current_width = link_info.tex_w;
unsigned current_height = link_info.tex_h;
unsigned out_width = 0;
unsigned out_height = 0;
for (int i = 1; i < shaders; i++)
{
RenderChain::convert_geometry(link_info,
out_width, out_height,
current_width, current_height, final_viewport);
link_info.scale_x = scales_x[i];
link_info.scale_y = scales_y[i];
link_info.tex_w = next_pow2(out_width);
link_info.tex_h = next_pow2(out_height);
link_info.scale_type_x = scale_types_x[i];
link_info.scale_type_y = scale_types_y[i];
link_info.filter_linear = filters[i];
link_info.shader_path = shader_paths[i];
link_info.frame_count_mod = frame_count_mods[i];
link_info.float_framebuffer = float_fbos[i-1];
current_width = out_width;
current_height = out_height;
if (i == shaders - 1 && !use_extra_pass)
{
link_info.scale_x = link_info.scale_y = 1.0f;
link_info.scale_type_x = link_info.scale_type_y = LinkInfo::Viewport;
}
chain->add_pass(link_info);
}
if (use_extra_pass)
{
RenderChain::convert_geometry(link_info,
out_width, out_height,
current_width, current_height, final_viewport);
link_info.scale_x = link_info.scale_y = 1.0f;
link_info.scale_type_x = link_info.scale_type_y = LinkInfo::Viewport;
link_info.filter_linear = info.smooth;
link_info.tex_w = next_pow2(out_width);
link_info.tex_h = next_pow2(out_height);
link_info.shader_path = "";
link_info.float_framebuffer = float_fbos.back();
chain->add_pass(link_info);
}
init_luts(conf, basedir);
init_imports(conf, basedir);
} }
bool D3DVideo::set_shader(const std::string &path) bool D3DVideo::set_shader(const std::string &path)
@ -1088,6 +761,7 @@ bool D3DVideo::set_shader(const std::string &path)
try try
{ {
cg_shader = path; cg_shader = path;
process_shader();
restore(); restore();
} }
catch (const std::exception &e) catch (const std::exception &e)
@ -1099,20 +773,98 @@ bool D3DVideo::set_shader(const std::string &path)
if (restore_old) if (restore_old)
{ {
cg_shader = old_shader; cg_shader = old_shader;
process_shader();
restore(); restore();
} }
return !restore_old; return !restore_old;
} }
void D3DVideo::process_shader()
{
if (cg_shader.find(".cgp") != std::string::npos)
init_multipass();
else
init_singlepass();
}
bool D3DVideo::init_chain(const video_info_t &video_info) bool D3DVideo::init_chain(const video_info_t &video_info)
{ {
try try
{ {
if (cg_shader.find(".cgp") != std::string::npos) // Setup information for first pass.
init_chain_multipass(video_info); LinkInfo link_info = {0};
else
init_chain_singlepass(video_info); if (shader.passes == 1 && !shader.pass[0].fbo.valid)
{
gfx_shader_pass &pass = shader.pass[0];
pass.filter = video_info.smooth ? RARCH_FILTER_LINEAR : RARCH_FILTER_NEAREST;
pass.fbo.scale_x = pass.fbo.scale_y = 1.0f;
pass.fbo.type_x = pass.fbo.type_y = RARCH_SCALE_VIEWPORT;
}
link_info.pass = &shader.pass[0];
link_info.tex_w = link_info.tex_h = video_info.input_scale * RARCH_SCALE_BASE;
chain = std::unique_ptr<RenderChain>(
new RenderChain(
video_info,
dev, cgCtx,
link_info,
video_info.rgb32 ? RenderChain::ARGB : RenderChain::RGB565,
final_viewport));
unsigned current_width = link_info.tex_w;
unsigned current_height = link_info.tex_h;
unsigned out_width = 0;
unsigned out_height = 0;
bool use_extra_pass = shader.pass[shader.passes - 1].fbo.valid;
for (int i = 1; i < shader.passes; i++)
{
RenderChain::convert_geometry(link_info,
out_width, out_height,
current_width, current_height, final_viewport);
link_info.pass = &shader.pass[i];
link_info.tex_w = next_pow2(out_width);
link_info.tex_h = next_pow2(out_height);
current_width = out_width;
current_height = out_height;
if (i == shader.passes - 1 && !use_extra_pass)
{
gfx_shader_pass &pass = shader.pass[i];
pass.filter = video_info.smooth ? RARCH_FILTER_LINEAR : RARCH_FILTER_NEAREST;
pass.fbo.scale_x = pass.fbo.scale_y = 1.0f;
pass.fbo.type_x = pass.fbo.type_y = RARCH_SCALE_VIEWPORT;
}
chain->add_pass(link_info);
}
if (use_extra_pass)
{
RenderChain::convert_geometry(link_info,
out_width, out_height,
current_width, current_height, final_viewport);
gfx_shader_pass &pass = shader.pass[shader.passes - 1];
pass.filter = video_info.smooth ? RARCH_FILTER_LINEAR : RARCH_FILTER_NEAREST;
pass.fbo.scale_x = pass.fbo.scale_y = 1.0f;
pass.fbo.type_x = pass.fbo.type_y = RARCH_SCALE_VIEWPORT;
link_info.pass = &pass;
link_info.tex_w = next_pow2(out_width);
link_info.tex_h = next_pow2(out_height);
chain->add_pass(link_info);
}
init_luts();
init_imports();
} }
catch (const std::exception &e) catch (const std::exception &e)
{ {

View File

@ -18,6 +18,7 @@
#include "../../general.h" #include "../../general.h"
#include "../../driver.h" #include "../../driver.h"
#include "../shader_parse.h"
#include <d3d9.h> #include <d3d9.h>
#include <d3dx9.h> #include <d3dx9.h>
@ -31,7 +32,6 @@
#include <vector> #include <vector>
#include <memory> #include <memory>
class ConfigFile;
class RenderChain; class RenderChain;
class D3DVideo class D3DVideo
@ -51,6 +51,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);
void process_shader();
#ifdef HAVE_OVERLAY #ifdef HAVE_OVERLAY
bool overlay_load(const uint32_t *image, unsigned width, unsigned height); bool overlay_load(const uint32_t *image, unsigned width, unsigned height);
@ -79,6 +80,8 @@ class D3DVideo
std::string cg_shader; std::string cg_shader;
struct gfx_shader shader;
void process(); void process();
void init(const video_info_t &info); void init(const video_info_t &info);
@ -97,10 +100,10 @@ class D3DVideo
void deinit_cg(); void deinit_cg();
#endif #endif
void init_imports(ConfigFile &conf, const std::string &basedir); void init_imports();
void init_luts(ConfigFile &conf, const std::string &basedir); void init_luts();
void init_chain_singlepass(const video_info_t &video_info); void init_singlepass();
void init_chain_multipass(const video_info_t &video_info); void init_multipass();
bool init_chain(const video_info_t &video_info); bool init_chain(const video_info_t &video_info);
std::unique_ptr<RenderChain> chain; std::unique_ptr<RenderChain> chain;
void deinit_chain(); void deinit_chain();

View File

@ -115,7 +115,7 @@ void RenderChain::add_pass(const LinkInfo &info)
pass.last_width = 0; pass.last_width = 0;
pass.last_height = 0; pass.last_height = 0;
compile_shaders(pass.fPrg, pass.vPrg, info.shader_path); compile_shaders(pass.fPrg, pass.vPrg, info.pass->source.cg);
init_fvf(pass); init_fvf(pass);
if (FAILED(dev->CreateVertexBuffer( if (FAILED(dev->CreateVertexBuffer(
@ -131,7 +131,7 @@ void RenderChain::add_pass(const LinkInfo &info)
if (FAILED(dev->CreateTexture(info.tex_w, info.tex_h, 1, if (FAILED(dev->CreateTexture(info.tex_w, info.tex_h, 1,
D3DUSAGE_RENDERTARGET, D3DUSAGE_RENDERTARGET,
info.float_framebuffer ? D3DFMT_A32B32G32R32F : D3DFMT_X8R8G8B8, passes.back().info.pass->fbo.fp_fbo ? D3DFMT_A32B32G32R32F : D3DFMT_X8R8G8B8,
D3DPOOL_DEFAULT, D3DPOOL_DEFAULT,
&pass.tex, nullptr))) &pass.tex, nullptr)))
{ {
@ -319,15 +319,15 @@ void RenderChain::create_first_pass(const LinkInfo &info, PixelFormat fmt)
dev->SetTexture(0, prev.tex[i]); dev->SetTexture(0, prev.tex[i]);
dev->SetSamplerState(0, D3DSAMP_MINFILTER, dev->SetSamplerState(0, D3DSAMP_MINFILTER,
info.filter_linear ? D3DTEXF_LINEAR : D3DTEXF_POINT); info.pass->filter == RARCH_FILTER_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT);
dev->SetSamplerState(0, D3DSAMP_MAGFILTER, dev->SetSamplerState(0, D3DSAMP_MAGFILTER,
info.filter_linear ? D3DTEXF_LINEAR : D3DTEXF_POINT); info.pass->filter == RARCH_FILTER_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT);
dev->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); dev->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
dev->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); dev->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
dev->SetTexture(0, nullptr); dev->SetTexture(0, nullptr);
} }
compile_shaders(pass.fPrg, pass.vPrg, info.shader_path); compile_shaders(pass.fPrg, pass.vPrg, info.pass->source.cg);
init_fvf(pass); init_fvf(pass);
passes.push_back(pass); passes.push_back(pass);
} }
@ -514,8 +514,8 @@ void RenderChain::set_cg_params(Pass &pass,
set_cg_param(pass.fPrg, "IN.output_size", output_size); set_cg_param(pass.fPrg, "IN.output_size", output_size);
float frame_cnt = frame_count; float frame_cnt = frame_count;
if (pass.info.frame_count_mod) if (pass.info.pass->frame_count_mod)
frame_cnt = frame_count % pass.info.frame_count_mod; frame_cnt = frame_count % pass.info.pass->frame_count_mod;
set_cg_param(pass.fPrg, "IN.frame_count", frame_cnt); set_cg_param(pass.fPrg, "IN.frame_count", frame_cnt);
set_cg_param(pass.vPrg, "IN.frame_count", frame_cnt); set_cg_param(pass.vPrg, "IN.frame_count", frame_cnt);
} }
@ -535,33 +535,33 @@ void RenderChain::convert_geometry(const LinkInfo &info,
unsigned width, unsigned height, unsigned width, unsigned height,
const D3DVIEWPORT9 &final_viewport) const D3DVIEWPORT9 &final_viewport)
{ {
switch (info.scale_type_x) switch (info.pass->fbo.type_x)
{ {
case LinkInfo::Viewport: case RARCH_SCALE_VIEWPORT:
out_width = info.scale_x * final_viewport.Width; out_width = info.pass->fbo.scale_x * final_viewport.Width;
break; break;
case LinkInfo::Absolute: case RARCH_SCALE_ABSOLUTE:
out_width = info.abs_x; out_width = info.pass->fbo.abs_x;
break; break;
case LinkInfo::Relative: case RARCH_SCALE_INPUT:
out_width = info.scale_x * width; out_width = info.pass->fbo.scale_x * width;
break; break;
} }
switch (info.scale_type_y) switch (info.pass->fbo.type_y)
{ {
case LinkInfo::Viewport: case RARCH_SCALE_VIEWPORT:
out_height = info.scale_y * final_viewport.Height; out_height = info.pass->fbo.scale_y * final_viewport.Height;
break; break;
case LinkInfo::Absolute: case RARCH_SCALE_ABSOLUTE:
out_height = info.abs_y; out_height = info.pass->fbo.abs_y;
break; break;
case LinkInfo::Relative: case RARCH_SCALE_INPUT:
out_height = info.scale_y * height; out_height = info.pass->fbo.scale_y * height;
break; break;
} }
} }
@ -593,9 +593,9 @@ void RenderChain::render_pass(Pass &pass, unsigned pass_index)
set_shaders(pass.fPrg, pass.vPrg); set_shaders(pass.fPrg, pass.vPrg);
dev->SetTexture(0, pass.tex); dev->SetTexture(0, pass.tex);
dev->SetSamplerState(0, D3DSAMP_MINFILTER, dev->SetSamplerState(0, D3DSAMP_MINFILTER,
pass.info.filter_linear ? D3DTEXF_LINEAR : D3DTEXF_POINT); pass.info.pass->filter == RARCH_FILTER_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT);
dev->SetSamplerState(0, D3DSAMP_MAGFILTER, dev->SetSamplerState(0, D3DSAMP_MAGFILTER,
pass.info.filter_linear ? D3DTEXF_LINEAR : D3DTEXF_POINT); pass.info.pass->filter == RARCH_FILTER_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT);
dev->SetVertexDeclaration(pass.vertex_decl); dev->SetVertexDeclaration(pass.vertex_decl);
for (unsigned i = 0; i < 4; i++) for (unsigned i = 0; i < 4; i++)
@ -631,38 +631,38 @@ void RenderChain::log_info(const LinkInfo &info)
RARCH_LOG("\tTexture height: %u\n", info.tex_h); RARCH_LOG("\tTexture height: %u\n", info.tex_h);
RARCH_LOG("\tScale type (X): "); RARCH_LOG("\tScale type (X): ");
switch (info.scale_type_x) switch (info.pass->fbo.type_x)
{ {
case LinkInfo::Relative: case RARCH_SCALE_INPUT:
RARCH_LOG("Relative @ %fx\n", info.scale_x); RARCH_LOG("Relative @ %fx\n", info.pass->fbo.scale_x);
break; break;
case LinkInfo::Viewport: case RARCH_SCALE_VIEWPORT:
RARCH_LOG("Viewport @ %fx\n", info.scale_x); RARCH_LOG("Viewport @ %fx\n", info.pass->fbo.scale_x);
break; break;
case LinkInfo::Absolute: case RARCH_SCALE_ABSOLUTE:
RARCH_LOG("Absolute @ %d px\n", info.abs_x); RARCH_LOG("Absolute @ %d px\n", info.pass->fbo.scale_x);
break; break;
} }
RARCH_LOG("\tScale type (Y): "); RARCH_LOG("\tScale type (Y): ");
switch (info.scale_type_y) switch (info.pass->fbo.type_y)
{ {
case LinkInfo::Relative: case RARCH_SCALE_INPUT:
RARCH_LOG("Relative @ %fx\n", info.scale_y); RARCH_LOG("Relative @ %fx\n", info.pass->fbo.scale_y);
break; break;
case LinkInfo::Viewport: case RARCH_SCALE_VIEWPORT:
RARCH_LOG("Viewport @ %fx\n", info.scale_y); RARCH_LOG("Viewport @ %fx\n", info.pass->fbo.scale_y);
break; break;
case LinkInfo::Absolute: case RARCH_SCALE_ABSOLUTE:
RARCH_LOG("Absolute @ %d px\n", info.abs_y); RARCH_LOG("Absolute @ %d px\n", info.pass->fbo.scale_y);
break; break;
} }
RARCH_LOG("\tBilinear filter: %s\n", info.filter_linear ? "true" : "false"); RARCH_LOG("\tBilinear filter: %s\n", info.pass->filter == RARCH_FILTER_LINEAR ? "true" : "false");
} }
void RenderChain::bind_orig(Pass &pass) void RenderChain::bind_orig(Pass &pass)
@ -686,9 +686,9 @@ void RenderChain::bind_orig(Pass &pass)
unsigned index = cgGetParameterResourceIndex(param); unsigned index = cgGetParameterResourceIndex(param);
dev->SetTexture(index, passes[0].tex); dev->SetTexture(index, passes[0].tex);
dev->SetSamplerState(index, D3DSAMP_MAGFILTER, dev->SetSamplerState(index, D3DSAMP_MAGFILTER,
passes[0].info.filter_linear ? D3DTEXF_LINEAR : D3DTEXF_POINT); passes[0].info.pass->filter == RARCH_FILTER_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT);
dev->SetSamplerState(index, D3DSAMP_MINFILTER, dev->SetSamplerState(index, D3DSAMP_MINFILTER,
passes[0].info.filter_linear ? D3DTEXF_LINEAR : D3DTEXF_POINT); passes[0].info.pass->filter == RARCH_FILTER_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT);
dev->SetSamplerState(index, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); dev->SetSamplerState(index, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
dev->SetSamplerState(index, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); dev->SetSamplerState(index, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
bound_tex.push_back(index); bound_tex.push_back(index);
@ -750,9 +750,9 @@ void RenderChain::bind_prev(Pass &pass)
bound_tex.push_back(index); bound_tex.push_back(index);
dev->SetSamplerState(index, D3DSAMP_MAGFILTER, dev->SetSamplerState(index, D3DSAMP_MAGFILTER,
passes[0].info.filter_linear ? D3DTEXF_LINEAR : D3DTEXF_POINT); passes[0].info.pass->filter == RARCH_FILTER_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT);
dev->SetSamplerState(index, D3DSAMP_MINFILTER, dev->SetSamplerState(index, D3DSAMP_MINFILTER,
passes[0].info.filter_linear ? D3DTEXF_LINEAR : D3DTEXF_POINT); passes[0].info.pass->filter == RARCH_FILTER_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT);
dev->SetSamplerState(index, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); dev->SetSamplerState(index, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
dev->SetSamplerState(index, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); dev->SetSamplerState(index, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
} }
@ -810,9 +810,9 @@ void RenderChain::bind_pass(Pass &pass, unsigned pass_index)
dev->SetTexture(index, passes[i].tex); dev->SetTexture(index, passes[i].tex);
dev->SetSamplerState(index, D3DSAMP_MAGFILTER, dev->SetSamplerState(index, D3DSAMP_MAGFILTER,
passes[i].info.filter_linear ? D3DTEXF_LINEAR : D3DTEXF_POINT); passes[i].info.pass->filter == RARCH_FILTER_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT);
dev->SetSamplerState(index, D3DSAMP_MINFILTER, dev->SetSamplerState(index, D3DSAMP_MINFILTER,
passes[i].info.filter_linear ? D3DTEXF_LINEAR : D3DTEXF_POINT); passes[i].info.pass->filter == RARCH_FILTER_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT);
dev->SetSamplerState(index, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); dev->SetSamplerState(index, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
dev->SetSamplerState(index, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); dev->SetSamplerState(index, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
} }

View File

@ -18,6 +18,7 @@
#include "d3d9.hpp" #include "d3d9.hpp"
#include "../state_tracker.h" #include "../state_tracker.h"
#include "../shader_parse.h"
#include <map> #include <map>
#include <utility> #include <utility>
#include <memory> #include <memory>
@ -32,19 +33,8 @@ struct Vertex
struct LinkInfo struct LinkInfo
{ {
enum ScaleType { Relative, Absolute, Viewport };
unsigned tex_w, tex_h; unsigned tex_w, tex_h;
struct gfx_shader_pass *pass;
float scale_x, scale_y;
unsigned abs_x, abs_y;
bool filter_linear;
ScaleType scale_type_x, scale_type_y;
unsigned frame_count_mod;
bool float_framebuffer;
std::string shader_path;
}; };
class RenderChain class RenderChain