From e639c6042e0231061bc297f9f74c03829e639c24 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 7 Mar 2014 19:13:20 +0100 Subject: [PATCH] (D3D Refactor render_chain.cpp - shouldn't be a class --- gfx/d3d9/d3d.cpp | 110 ++++++----- gfx/d3d9/d3d9.hpp | 5 +- gfx/d3d9/d3d9_pc.cpp | 32 +-- gfx/d3d9/render_chain.cpp | 386 ++++++++++++++++++++----------------- gfx/d3d9/render_chain.hpp | 198 ++++++++++++------- gfx/d3d9/render_chain_cg.h | 218 +++++++++++---------- 6 files changed, 525 insertions(+), 424 deletions(-) diff --git a/gfx/d3d9/d3d.cpp b/gfx/d3d9/d3d.cpp index 125843513d..f58a1d12f4 100644 --- a/gfx/d3d9/d3d.cpp +++ b/gfx/d3d9/d3d.cpp @@ -234,11 +234,11 @@ bool d3d_restore(void *data) } #ifdef HAVE_OVERLAY -static void d3d_overlay_render(void *data, overlay_t &overlay) +static void d3d_overlay_render(void *data, overlay_t *overlay) { D3DVideo *d3d = reinterpret_cast(data); - if (!overlay.tex) + if (!overlay || !overlay->tex) return; struct overlay_vertex @@ -248,7 +248,7 @@ static void d3d_overlay_render(void *data, overlay_t &overlay) float r, g, b, a; } vert[4]; - if (!overlay.vert_buf) + if (!overlay->vert_buf) { d3d->dev->CreateVertexBuffer( sizeof(vert), @@ -259,7 +259,7 @@ static void d3d_overlay_render(void *data, overlay_t &overlay) #endif 0, D3DPOOL_MANAGED, - &overlay.vert_buf, + &overlay->vert_buf, NULL); } @@ -267,29 +267,29 @@ static void d3d_overlay_render(void *data, overlay_t &overlay) { vert[i].z = 0.5f; vert[i].r = vert[i].g = vert[i].b = 1.0f; - vert[i].a = overlay.alpha_mod; + vert[i].a = overlay->alpha_mod; } float overlay_width = d3d->final_viewport.Width; float overlay_height = d3d->final_viewport.Height; - vert[0].x = overlay.vert_coords.x * overlay_width; - vert[1].x = (overlay.vert_coords.x + overlay.vert_coords.w) * overlay_width; - vert[2].x = overlay.vert_coords.x * overlay_width; - vert[3].x = (overlay.vert_coords.x + overlay.vert_coords.w) * overlay_width; - vert[0].y = overlay.vert_coords.y * overlay_height; - vert[1].y = overlay.vert_coords.y * overlay_height; - vert[2].y = (overlay.vert_coords.y + overlay.vert_coords.h) * overlay_height; - vert[3].y = (overlay.vert_coords.y + overlay.vert_coords.h) * overlay_height; + vert[0].x = overlay->vert_coords.x * overlay_width; + vert[1].x = (overlay->vert_coords.x + overlay->vert_coords.w) * overlay_width; + vert[2].x = overlay->vert_coords.x * overlay_width; + vert[3].x = (overlay->vert_coords.x + overlay->vert_coords.w) * overlay_width; + vert[0].y = overlay->vert_coords.y * overlay_height; + vert[1].y = overlay->vert_coords.y * overlay_height; + vert[2].y = (overlay->vert_coords.y + overlay->vert_coords.h) * overlay_height; + vert[3].y = (overlay->vert_coords.y + overlay->vert_coords.h) * overlay_height; - vert[0].u = overlay.tex_coords.x; - vert[1].u = overlay.tex_coords.x + overlay.tex_coords.w; - vert[2].u = overlay.tex_coords.x; - vert[3].u = overlay.tex_coords.x + overlay.tex_coords.w; - vert[0].v = overlay.tex_coords.y; - vert[1].v = overlay.tex_coords.y; - vert[2].v = overlay.tex_coords.y + overlay.tex_coords.h; - vert[3].v = overlay.tex_coords.y + overlay.tex_coords.h; + vert[0].u = overlay->tex_coords.x; + vert[1].u = overlay->tex_coords.x + overlay->tex_coords.w; + vert[2].u = overlay->tex_coords.x; + vert[3].u = overlay->tex_coords.x + overlay->tex_coords.w; + vert[0].v = overlay->tex_coords.y; + vert[1].v = overlay->tex_coords.y; + vert[2].v = overlay->tex_coords.y + overlay->tex_coords.h; + vert[3].v = overlay->tex_coords.y + overlay->tex_coords.h; // Align texels and vertices. for (unsigned i = 0; i < 4; i++) @@ -299,9 +299,9 @@ static void d3d_overlay_render(void *data, overlay_t &overlay) } void *verts; - overlay.vert_buf->Lock(0, sizeof(vert), &verts, 0); + overlay->vert_buf->Lock(0, sizeof(vert), &verts, 0); memcpy(verts, vert, sizeof(vert)); - overlay.vert_buf->Unlock(); + overlay->vert_buf->Unlock(); // enable alpha d3d->dev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); @@ -320,9 +320,9 @@ static void d3d_overlay_render(void *data, overlay_t &overlay) d3d->dev->SetVertexDeclaration(vertex_decl); vertex_decl->Release(); - d3d->dev->SetStreamSource(0, overlay.vert_buf, 0, sizeof(overlay_vertex)); + d3d->dev->SetStreamSource(0, overlay->vert_buf, 0, sizeof(overlay_vertex)); - if (overlay.fullscreen) + if (overlay->fullscreen) { // set viewport to full window D3DVIEWPORT vp_full; @@ -336,7 +336,7 @@ static void d3d_overlay_render(void *data, overlay_t &overlay) } // render overlay - d3d->dev->SetTexture(0, overlay.tex); + d3d->dev->SetTexture(0, overlay->tex); d3d->dev->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); d3d->dev->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); d3d->dev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); @@ -439,7 +439,7 @@ static bool d3d_frame(void *data, const void *frame, if (d3d->should_resize) { d3d_calculate_rect(d3d, d3d->screen_width, d3d->screen_height, d3d->video_info.force_aspect, g_extern.system.aspect_ratio); - d3d->chain->set_final_viewport(d3d->final_viewport); + renderchain_set_final_viewport(d3d->chain, &d3d->final_viewport); d3d_recompute_pass_sizes(d3d); d3d->should_resize = false; @@ -468,7 +468,7 @@ static bool d3d_frame(void *data, const void *frame, d3d->dev->Clear(0, 0, D3DCLEAR_TARGET, 0, 1, 0); } - if (!d3d->chain->render(frame, width, height, pitch, d3d->dev_rotation)) + if (!renderchain_render(d3d->chain, frame, width, height, pitch, d3d->dev_rotation)) { RARCH_ERR("[D3D]: Failed to render scene.\n"); return false; @@ -478,7 +478,7 @@ static bool d3d_frame(void *data, const void *frame, d3d->font_ctx->render_msg(d3d, msg, NULL); #ifdef HAVE_MENU - if (d3d->rgui.enabled) + if (d3d->rgui && d3d->rgui->enabled) d3d_overlay_render(d3d, d3d->rgui); #endif @@ -486,7 +486,7 @@ static bool d3d_frame(void *data, const void *frame, if (d3d->overlays_enabled) { for (unsigned i = 0; i < d3d->overlays.size(); i++) - d3d_overlay_render(d3d, d3d->overlays[i]); + d3d_overlay_render(d3d, &d3d->overlays[i]); } #endif @@ -564,7 +564,7 @@ static void d3d_free(void *data) d3d_free_overlays(d3d); #endif #ifdef HAVE_MENU - d3d_free_overlay(d3d, &d3d->rgui); + d3d_free_overlay(d3d, d3d->rgui); #endif if (d3d->dev) d3d->dev->Release(); @@ -864,27 +864,27 @@ static void d3d_set_rgui_texture_frame(void *data, { D3DVideo *d3d = reinterpret_cast(data); - if (!d3d->rgui.tex || d3d->rgui.tex_w != width || d3d->rgui.tex_h != height) + if (!d3d->rgui->tex || d3d->rgui->tex_w != width || d3d->rgui->tex_h != height) { - if (d3d->rgui.tex) - d3d->rgui.tex->Release(); + if (d3d->rgui && d3d->rgui->tex) + d3d->rgui->tex->Release(); if (FAILED(d3d->dev->CreateTexture(width, height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, - &d3d->rgui.tex, NULL))) + &d3d->rgui->tex, NULL))) { RARCH_ERR("[D3D]: Failed to create rgui texture\n"); return; } - d3d->rgui.tex_w = width; - d3d->rgui.tex_h = height; + d3d->rgui->tex_w = width; + d3d->rgui->tex_h = height; } - d3d->rgui.alpha_mod = alpha; + d3d->rgui->alpha_mod = alpha; D3DLOCKED_RECT d3dlr; - if (SUCCEEDED(d3d->rgui.tex->LockRect(0, &d3dlr, NULL, D3DLOCK_NOSYSLOCK))) + if (SUCCEEDED(d3d->rgui->tex->LockRect(0, &d3dlr, NULL, D3DLOCK_NOSYSLOCK))) { if (rgb32) { @@ -918,15 +918,20 @@ static void d3d_set_rgui_texture_frame(void *data, } } - d3d->rgui.tex->UnlockRect(0); + if (d3d->rgui) + d3d->rgui->tex->UnlockRect(0); } } static void d3d_set_rgui_texture_enable(void *data, bool state, bool full_screen) { D3DVideo *d3d = reinterpret_cast(data); - d3d->rgui.enabled = state; - d3d->rgui.fullscreen = full_screen; + + if (!d3d || !d3d->rgui) + return; + + d3d->rgui->enabled = state; + d3d->rgui->fullscreen = full_screen; } #endif @@ -964,15 +969,18 @@ static bool d3d_construct(void *data, const video_info_t *info, const input_driv #endif #ifdef HAVE_MENU - memset(&d3d->rgui, 0, sizeof(d3d->rgui)); - d3d->rgui.tex_coords.x = 0; - d3d->rgui.tex_coords.y = 0; - d3d->rgui.tex_coords.w = 1; - d3d->rgui.tex_coords.h = 1; - d3d->rgui.vert_coords.x = 0; - d3d->rgui.vert_coords.y = 1; - d3d->rgui.vert_coords.w = 1; - d3d->rgui.vert_coords.h = -1; + if (d3d->rgui) + free(d3d->rgui); + + d3d->rgui = (overlay_t*)calloc(1, sizeof(overlay_t)); + d3d->rgui->tex_coords.x = 0; + d3d->rgui->tex_coords.y = 0; + d3d->rgui->tex_coords.w = 1; + d3d->rgui->tex_coords.h = 1; + d3d->rgui->vert_coords.x = 0; + d3d->rgui->vert_coords.y = 1; + d3d->rgui->vert_coords.w = 1; + d3d->rgui->vert_coords.h = -1; #endif #ifdef HAVE_WINDOW diff --git a/gfx/d3d9/d3d9.hpp b/gfx/d3d9/d3d9.hpp index b5ffc677d2..d3227fb040 100644 --- a/gfx/d3d9/d3d9.hpp +++ b/gfx/d3d9/d3d9.hpp @@ -130,10 +130,9 @@ struct D3DVideo #endif #ifdef HAVE_MENU - overlay_t rgui; + overlay_t *rgui; #endif - - RenderChain *chain; + void *chain; }; #ifndef _XBOX diff --git a/gfx/d3d9/d3d9_pc.cpp b/gfx/d3d9/d3d9_pc.cpp index b0a17c3be8..d0340c1040 100644 --- a/gfx/d3d9/d3d9_pc.cpp +++ b/gfx/d3d9/d3d9_pc.cpp @@ -167,7 +167,7 @@ void d3d_recompute_pass_sizes(void *data) unsigned out_width = 0; unsigned out_height = 0; - if (!d3d->chain->set_pass_size(0, current_width, current_height)) + if (!renderchain_set_pass_size(d3d->chain, 0, current_width, current_height)) { RARCH_ERR("[D3D]: Failed to set pass size.\n"); return; @@ -175,14 +175,14 @@ void d3d_recompute_pass_sizes(void *data) for (unsigned i = 1; i < d3d->shader.passes; i++) { - RenderChain::convert_geometry(link_info, + renderchain_convert_geometry(d3d->chain, &link_info, out_width, out_height, - current_width, current_height, d3d->final_viewport); + current_width, current_height, &d3d->final_viewport); link_info.tex_w = next_pow2(out_width); link_info.tex_h = next_pow2(out_height); - if (!d3d->chain->set_pass_size(i, link_info.tex_w, link_info.tex_h)) + if (!renderchain_set_pass_size(d3d->chain, i, link_info.tex_w, link_info.tex_h)) { RARCH_ERR("[D3D]: Failed to set pass size.\n"); return; @@ -238,7 +238,7 @@ bool d3d_init_imports(void *data) return false; } - d3d->chain->add_state_tracker(state_tracker); + renderchain_add_state_tracker(d3d->chain, state_tracker); return true; } @@ -247,7 +247,7 @@ bool d3d_init_luts(void *data) D3DVideo *d3d = reinterpret_cast(data); for (unsigned i = 0; i < d3d->shader.luts; i++) { - bool ret = d3d->chain->add_lut(d3d->shader.lut[i].id, d3d->shader.lut[i].path, + bool ret = renderchain_add_lut(d3d->chain, d3d->shader.lut[i].id, d3d->shader.lut[i].path, d3d->shader.lut[i].filter == RARCH_FILTER_UNSPEC ? g_settings.video.smooth : (d3d->shader.lut[i].filter == RARCH_FILTER_LINEAR)); @@ -324,14 +324,14 @@ bool d3d_init_chain(void *data, const video_info_t *video_info) link_info.pass = &d3d->shader.pass[0]; link_info.tex_w = link_info.tex_h = video_info->input_scale * RARCH_SCALE_BASE; - delete d3d->chain; - d3d->chain = new RenderChain( - &d3d->video_info, - d3dr, d3d->cgCtx, - d3d->final_viewport); + if (d3d->chain) + free(d3d->chain); + d3d->chain = (renderchain_t*)calloc(1, sizeof(renderchain_t)); + if (!d3d->chain) + return false; - if (!d3d->chain->init(link_info, - d3d->video_info.rgb32 ? RenderChain::ARGB : RenderChain::RGB565)) + if (!renderchain_init(d3d->chain, &d3d->video_info, d3dr, d3d->cgCtx, &d3d->final_viewport, &link_info, + d3d->video_info.rgb32 ? ARGB : RGB565)) { RARCH_ERR("[D3D9]: Failed to init render chain.\n"); return false; @@ -344,9 +344,9 @@ bool d3d_init_chain(void *data, const video_info_t *video_info) for (unsigned i = 1; i < d3d->shader.passes; i++) { - RenderChain::convert_geometry(link_info, + renderchain_convert_geometry(d3d->chain, &link_info, out_width, out_height, - current_width, current_height, d3d->final_viewport); + current_width, current_height, &d3d->final_viewport); link_info.pass = &d3d->shader.pass[i]; link_info.tex_w = next_pow2(out_width); @@ -355,7 +355,7 @@ bool d3d_init_chain(void *data, const video_info_t *video_info) current_width = out_width; current_height = out_height; - if (!d3d->chain->add_pass(link_info)) + if (!renderchain_add_pass(d3d->chain, &link_info)) { RARCH_ERR("[D3D9]: Failed to add pass.\n"); return false; diff --git a/gfx/d3d9/render_chain.cpp b/gfx/d3d9/render_chain.cpp index 13a38dfbcd..e42e37c894 100644 --- a/gfx/d3d9/render_chain.cpp +++ b/gfx/d3d9/render_chain.cpp @@ -16,80 +16,105 @@ #include "render_chain.hpp" #include +static inline D3DTEXTUREFILTERTYPE translate_filter(enum gfx_filter_type type) +{ + if (type == RARCH_FILTER_UNSPEC) + return g_settings.video.smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT; + else + return type == RARCH_FILTER_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT; +} + +static inline D3DTEXTUREFILTERTYPE translate_filter(bool smooth) +{ + return smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT; +} + #ifdef HAVE_CG #include "render_chain_cg.h" #endif -RenderChain::~RenderChain() +void renderchain_free(void *data) { - clear(); - destroy_stock_shader(); - if (tracker) - state_tracker_free(tracker); + renderchain_t *chain = (renderchain_t*)data; + + renderchain_clear(chain); + renderchain_destroy_stock_shader(chain); + if (chain->tracker) + state_tracker_free(chain->tracker); } -RenderChain::RenderChain(const video_info_t *video_info, +bool renderchain_init(void *data, const video_info_t *video_info, LPDIRECT3DDEVICE dev_, CGcontext cgCtx_, - const D3DVIEWPORT &final_viewport_) - : dev(dev_), cgCtx(cgCtx_), video_info(*video_info), tracker(NULL), - final_viewport(final_viewport_), frame_count(0) -{} - -bool RenderChain::init(const LinkInfo &info, PixelFormat fmt) + const D3DVIEWPORT *final_viewport_, + const LinkInfo *info, PixelFormat fmt) { - pixel_size = fmt == RGB565 ? 2 : 4; - if (!create_first_pass(info, fmt)) + renderchain_t *chain = (renderchain_t*)data; + + if (!chain) return false; - log_info(info); - if (!compile_shaders(fStock, vStock, "")) + + chain->dev = dev_; + chain->cgCtx = cgCtx_; + chain->video_info = video_info; + chain->tracker = NULL; + chain->final_viewport = (D3DVIEWPORT*)final_viewport_; + chain->frame_count = 0; + chain->pixel_size = fmt == RGB565 ? 2 : 4; + if (!renderchain_create_first_pass(chain, info, fmt)) + return false; + renderchain_log_info(chain, info); + if (!renderchain_compile_shaders(chain, chain->fStock, chain->vStock, "")) return false; return true; } -void RenderChain::clear(void) +void renderchain_clear(void *data) { - for (unsigned i = 0; i < Textures; i++) + renderchain_t *chain = (renderchain_t*)data; + for (unsigned i = 0; i < TEXTURES; i++) { - if (prev.tex[i]) - prev.tex[i]->Release(); - if (prev.vertex_buf[i]) - prev.vertex_buf[i]->Release(); + if (chain->prev.tex[i]) + chain->prev.tex[i]->Release(); + if (chain->prev.vertex_buf[i]) + chain->prev.vertex_buf[i]->Release(); } - if (passes[0].vertex_decl) - passes[0].vertex_decl->Release(); - for (unsigned i = 1; i < passes.size(); i++) + if (chain->passes[0].vertex_decl) + chain->passes[0].vertex_decl->Release(); + for (unsigned i = 1; i < chain->passes.size(); i++) { - if (passes[i].tex) - passes[i].tex->Release(); - if (passes[i].vertex_buf) - passes[i].vertex_buf->Release(); - if (passes[i].vertex_decl) - passes[i].vertex_decl->Release(); - destroy_shader(i); + if (chain->passes[i].tex) + chain->passes[i].tex->Release(); + if (chain->passes[i].vertex_buf) + chain->passes[i].vertex_buf->Release(); + if (chain->passes[i].vertex_decl) + chain->passes[i].vertex_decl->Release(); + renderchain_destroy_shader(chain, i); } - for (unsigned i = 0; i < luts.size(); i++) + for (unsigned i = 0; i < chain->luts.size(); i++) { - if (luts[i].tex) - luts[i].tex->Release(); + if (chain->luts[i].tex) + chain->luts[i].tex->Release(); } - passes.clear(); - luts.clear(); + chain->passes.clear(); + chain->luts.clear(); } -void RenderChain::set_final_viewport(const D3DVIEWPORT& final_viewport) +void renderchain_set_final_viewport(void *data, const D3DVIEWPORT *final_viewport) { - this->final_viewport = final_viewport; + renderchain_t *chain = (renderchain_t*)data; + chain->final_viewport = (D3DVIEWPORT*)final_viewport; } -bool RenderChain::set_pass_size(unsigned pass_index, unsigned width, unsigned height) +bool renderchain_set_pass_size(void *data, unsigned pass_index, unsigned width, unsigned height) { - LPDIRECT3DDEVICE d3dr = dev; - Pass &pass = passes[pass_index]; + renderchain_t *chain = (renderchain_t*)data; + LPDIRECT3DDEVICE d3dr = chain->dev; + Pass &pass = chain->passes[pass_index]; if (width != pass.info.tex_w || height != pass.info.tex_h) { pass.tex->Release(); @@ -98,7 +123,7 @@ bool RenderChain::set_pass_size(unsigned pass_index, unsigned width, unsigned he if (FAILED(d3dr->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, - passes.back().info.pass->fbo.fp_fbo ? D3DFMT_A32B32G32R32F : D3DFMT_A8R8G8B8, + chain->passes.back().info.pass->fbo.fp_fbo ? D3DFMT_A32B32G32R32F : D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pass.tex, NULL))) return false; @@ -112,16 +137,17 @@ bool RenderChain::set_pass_size(unsigned pass_index, unsigned width, unsigned he return true; } -bool RenderChain::add_pass(const LinkInfo &info) +bool renderchain_add_pass(void *data, const LinkInfo *info) { - LPDIRECT3DDEVICE d3dr = dev; + renderchain_t *chain = (renderchain_t*)data; + LPDIRECT3DDEVICE d3dr = chain->dev; Pass pass; - pass.info = info; + pass.info = *info; pass.last_width = 0; pass.last_height = 0; - compile_shaders(pass.fPrg, pass.vPrg, info.pass->source.cg); - if (!init_shader_fvf(pass)) + renderchain_compile_shaders(chain, pass.fPrg, pass.vPrg, info->pass->source.cg); + if (!renderchain_init_shader_fvf(chain, pass)) return false; if (FAILED(d3dr->CreateVertexBuffer( @@ -133,9 +159,9 @@ bool RenderChain::add_pass(const LinkInfo &info) NULL))) return false; - if (FAILED(d3dr->CreateTexture(info.tex_w, info.tex_h, 1, + if (FAILED(d3dr->CreateTexture(info->tex_w, info->tex_h, 1, D3DUSAGE_RENDERTARGET, - passes.back().info.pass->fbo.fp_fbo ? D3DFMT_A32B32G32R32F : D3DFMT_A8R8G8B8, + chain->passes.back().info.pass->fbo.fp_fbo ? D3DFMT_A32B32G32R32F : D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pass.tex, NULL))) return false; @@ -145,18 +171,19 @@ bool RenderChain::add_pass(const LinkInfo &info) d3dr->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); d3dr->SetTexture(0, NULL); - passes.push_back(pass); + chain->passes.push_back(pass); - log_info(info); + renderchain_log_info(chain, info); return true; } -bool RenderChain::add_lut(const std::string &id, +bool renderchain_add_lut(void *data, const std::string &id, const std::string &path, bool smooth) { + renderchain_t *chain = (renderchain_t*)data; LPDIRECT3DTEXTURE lut; - LPDIRECT3DDEVICE d3dr = dev; + LPDIRECT3DDEVICE d3dr = chain->dev; RARCH_LOG("[D3D]: Loading LUT texture: %s.\n", path.c_str()); @@ -183,62 +210,67 @@ bool RenderChain::add_lut(const std::string &id, d3dr->SetTexture(0, NULL); lut_info info = { lut, id, smooth }; - luts.push_back(info); + chain->luts.push_back(info); return true; } -void RenderChain::add_state_tracker(state_tracker_t *tracker) +void renderchain_add_state_tracker(void *data, state_tracker_t *tracker) { - if (this->tracker) - state_tracker_free(this->tracker); - this->tracker = tracker; + renderchain_t *chain = (renderchain_t*)data; + if (chain->tracker) + state_tracker_free(chain->tracker); + chain->tracker = tracker; } -void RenderChain::start_render(void) +void renderchain_start_render(void *data) { - passes[0].tex = prev.tex[prev.ptr]; - passes[0].vertex_buf = prev.vertex_buf[prev.ptr]; - passes[0].last_width = prev.last_width[prev.ptr]; - passes[0].last_height = prev.last_height[prev.ptr]; + renderchain_t *chain = (renderchain_t*)data; + chain->passes[0].tex = chain->prev.tex[chain->prev.ptr]; + chain->passes[0].vertex_buf = chain->prev.vertex_buf[chain->prev.ptr]; + chain->passes[0].last_width = chain->prev.last_width[chain->prev.ptr]; + chain->passes[0].last_height = chain->prev.last_height[chain->prev.ptr]; } -void RenderChain::end_render(void) +void renderchain_end_render(void *data) { - prev.last_width[prev.ptr] = passes[0].last_width; - prev.last_height[prev.ptr] = passes[0].last_height; - prev.ptr = (prev.ptr + 1) & TexturesMask; + renderchain_t *chain = (renderchain_t*)data; + chain->prev.last_width[chain->prev.ptr] = chain->passes[0].last_width; + chain->prev.last_height[chain->prev.ptr] = chain->passes[0].last_height; + chain->prev.ptr = (chain->prev.ptr + 1) & TEXTURESMASK; } -bool RenderChain::render(const void *data, +bool renderchain_render(void *chain_data, const void *data, unsigned width, unsigned height, unsigned pitch, unsigned rotation) { - LPDIRECT3DDEVICE d3dr = dev; - start_render(); + renderchain_t *chain = (renderchain_t*)chain_data; + LPDIRECT3DDEVICE d3dr = chain->dev; + renderchain_start_render(chain); - unsigned current_width = width, current_height = height; - unsigned out_width = 0, out_height = 0; - convert_geometry(passes[0].info, out_width, out_height, - current_width, current_height, final_viewport); - - blit_to_texture(data, width, height, pitch); + unsigned current_width = width; + unsigned current_height = height; + unsigned out_width = 0; + unsigned out_height = 0; + renderchain_convert_geometry(chain, &chain->passes[0].info, out_width, out_height, + current_width, current_height, chain->final_viewport); + renderchain_blit_to_texture(chain, data, width, height, pitch); // Grab back buffer. LPDIRECT3DSURFACE back_buffer; d3dr->GetRenderTarget(0, &back_buffer); // In-between render target passes. - for (unsigned i = 0; i < passes.size() - 1; i++) + for (unsigned i = 0; i < chain->passes.size() - 1; i++) { - Pass &from_pass = passes[i]; - Pass &to_pass = passes[i + 1]; + Pass &from_pass = chain->passes[i]; + Pass &to_pass = chain->passes[i + 1]; LPDIRECT3DSURFACE target; to_pass.tex->GetSurfaceLevel(0, &target); d3dr->SetRenderTarget(0, target); - convert_geometry(from_pass.info, + renderchain_convert_geometry(chain, &from_pass.info, out_width, out_height, - current_width, current_height, final_viewport); + current_width, current_height, chain->final_viewport); // Clear out whole FBO. D3DVIEWPORT viewport = {0}; @@ -251,14 +283,14 @@ bool RenderChain::render(const void *data, viewport.Width = out_width; viewport.Height = out_height; - set_viewport(viewport); + renderchain_set_viewport(chain, &viewport); - set_vertices(from_pass, + renderchain_set_vertices(chain, from_pass, current_width, current_height, out_width, out_height, out_width, out_height, 0); - render_pass(from_pass, i + 1); + renderchain_render_pass(chain, from_pass, i + 1); current_width = out_width; current_height = out_height; @@ -267,103 +299,92 @@ bool RenderChain::render(const void *data, // Final pass d3dr->SetRenderTarget(0, back_buffer); - Pass &last_pass = passes.back(); + Pass &last_pass = chain->passes.back(); - convert_geometry(last_pass.info, + renderchain_convert_geometry(chain, &last_pass.info, out_width, out_height, - current_width, current_height, final_viewport); - set_viewport(final_viewport); - set_vertices(last_pass, + current_width, current_height, chain->final_viewport); + renderchain_set_viewport(chain, chain->final_viewport); + renderchain_set_vertices(chain, last_pass, current_width, current_height, out_width, out_height, - final_viewport.Width, final_viewport.Height, + chain->final_viewport->Width, chain->final_viewport->Height, rotation); - render_pass(last_pass, passes.size()); + renderchain_render_pass(chain, last_pass, chain->passes.size()); - frame_count++; + chain->frame_count++; back_buffer->Release(); - end_render(); - set_shaders(fStock, vStock); - set_mvp(vStock, final_viewport.Width, final_viewport.Height, 0); + renderchain_end_render(chain); + renderchain_set_shaders(chain, chain->fStock, chain->vStock); + renderchain_set_mvp(chain, chain->vStock, chain->final_viewport->Width, chain->final_viewport->Height, 0); return true; } -D3DTEXTUREFILTERTYPE RenderChain::translate_filter(enum gfx_filter_type type) -{ - if (type == RARCH_FILTER_UNSPEC) - return g_settings.video.smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT; - else - return type == RARCH_FILTER_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT; -} - -D3DTEXTUREFILTERTYPE RenderChain::translate_filter(bool smooth) -{ - return smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT; -} - -bool RenderChain::create_first_pass(const LinkInfo &info, PixelFormat fmt) +bool renderchain_create_first_pass(void *data, const LinkInfo *info, PixelFormat fmt) { + renderchain_t *chain = (renderchain_t*)data; D3DXMATRIX ident; D3DXMatrixIdentity(&ident); - LPDIRECT3DDEVICE d3dr = dev; + LPDIRECT3DDEVICE d3dr = (LPDIRECT3DDEVICE)chain->dev; d3dr->SetTransform(D3DTS_WORLD, &ident); d3dr->SetTransform(D3DTS_VIEW, &ident); Pass pass; - pass.info = info; + pass.info = *info; pass.last_width = 0; pass.last_height = 0; - prev.ptr = 0; - for (unsigned i = 0; i < Textures; i++) + chain->prev.ptr = 0; + for (unsigned i = 0; i < TEXTURES; i++) { - prev.last_width[i] = 0; - prev.last_height[i] = 0; + chain->prev.last_width[i] = 0; + chain->prev.last_height[i] = 0; if (FAILED(d3dr->CreateVertexBuffer( 4 * sizeof(Vertex), d3dr->GetSoftwareVertexProcessing() ? D3DUSAGE_SOFTWAREPROCESSING : 0, 0, D3DPOOL_DEFAULT, - &prev.vertex_buf[i], + &chain->prev.vertex_buf[i], NULL))) { return false; } - if (FAILED(d3dr->CreateTexture(info.tex_w, info.tex_h, 1, 0, + if (FAILED(d3dr->CreateTexture(info->tex_w, info->tex_h, 1, 0, fmt == RGB565 ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, - &prev.tex[i], NULL))) + &chain->prev.tex[i], NULL))) { return false; } - d3dr->SetTexture(0, prev.tex[i]); + d3dr->SetTexture(0, chain->prev.tex[i]); d3dr->SetSamplerState(0, D3DSAMP_MINFILTER, - translate_filter(info.pass->filter)); + translate_filter(info->pass->filter)); d3dr->SetSamplerState(0, D3DSAMP_MAGFILTER, - translate_filter(info.pass->filter)); + translate_filter(info->pass->filter)); d3dr->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); d3dr->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); d3dr->SetTexture(0, NULL); } - compile_shaders(pass.fPrg, pass.vPrg, info.pass->source.cg); - if (!init_shader_fvf(pass)) + renderchain_compile_shaders(chain, pass.fPrg, pass.vPrg, info->pass->source.cg); + if (!renderchain_init_shader_fvf(chain, pass)) return false; - passes.push_back(pass); + chain->passes.push_back(pass); return true; } -void RenderChain::set_vertices(Pass &pass, +void renderchain_set_vertices(void *data, Pass &pass, unsigned width, unsigned height, unsigned out_width, unsigned out_height, unsigned vp_width, unsigned vp_height, unsigned rotation) { + renderchain_t *chain = (renderchain_t*)data; const LinkInfo &info = pass.info; if (pass.last_width != width || pass.last_height != height) @@ -420,23 +441,25 @@ void RenderChain::set_vertices(Pass &pass, pass.vertex_buf->Unlock(); } - set_mvp(pass.vPrg, vp_width, vp_height, rotation); - set_shader_params(pass, + renderchain_set_mvp(chain, pass.vPrg, vp_width, vp_height, rotation); + renderchain_set_shader_params(chain, pass, width, height, info.tex_w, info.tex_h, vp_width, vp_height); } -void RenderChain::set_viewport(const D3DVIEWPORT &vp) +void renderchain_set_viewport(void *data, D3DVIEWPORT *vp) { - LPDIRECT3DDEVICE d3dr = dev; - d3dr->SetViewport(&vp); + renderchain_t *chain = (renderchain_t*)data; + LPDIRECT3DDEVICE d3dr = (LPDIRECT3DDEVICE)chain->dev; + d3dr->SetViewport(vp); } -void RenderChain::set_mvp(CGprogram &vPrg, +void renderchain_set_mvp(void *data, CGprogram &vPrg, unsigned vp_width, unsigned vp_height, unsigned rotation) { + renderchain_t *chain = (renderchain_t*)data; D3DXMATRIX proj, ortho, rot, tmp; D3DXMatrixOrthoOffCenterLH(&ortho, 0, vp_width, 0, vp_height, 0, 1); @@ -448,11 +471,12 @@ void RenderChain::set_mvp(CGprogram &vPrg, D3DXMatrixMultiply(&proj, &ortho, &rot); D3DXMatrixTranspose(&tmp, &proj); - set_shader_mvp(vPrg, tmp); + renderchain_set_shader_mvp(chain, vPrg, tmp); } -void RenderChain::clear_texture(Pass &pass) +void renderchain_clear_texture(void *data, Pass &pass) { + renderchain_t *chain = (renderchain_t*)data; D3DLOCKED_RECT d3dlr; if (SUCCEEDED(pass.tex->LockRect(0, &d3dlr, NULL, D3DLOCK_NOSYSLOCK))) { @@ -461,49 +485,51 @@ void RenderChain::clear_texture(Pass &pass) } } -void RenderChain::convert_geometry(const LinkInfo &info, +void renderchain_convert_geometry(void *data, const LinkInfo *info, unsigned &out_width, unsigned &out_height, unsigned width, unsigned height, - const D3DVIEWPORT &final_viewport) + D3DVIEWPORT *final_viewport) { - switch (info.pass->fbo.type_x) + renderchain_t *chain = (renderchain_t*)data; + switch (info->pass->fbo.type_x) { case RARCH_SCALE_VIEWPORT: - out_width = info.pass->fbo.scale_x * final_viewport.Width; + out_width = info->pass->fbo.scale_x * final_viewport->Width; break; case RARCH_SCALE_ABSOLUTE: - out_width = info.pass->fbo.abs_x; + out_width = info->pass->fbo.abs_x; break; case RARCH_SCALE_INPUT: - out_width = info.pass->fbo.scale_x * width; + out_width = info->pass->fbo.scale_x * width; break; } - switch (info.pass->fbo.type_y) + switch (info->pass->fbo.type_y) { case RARCH_SCALE_VIEWPORT: - out_height = info.pass->fbo.scale_y * final_viewport.Height; + out_height = info->pass->fbo.scale_y * final_viewport->Height; break; case RARCH_SCALE_ABSOLUTE: - out_height = info.pass->fbo.abs_y; + out_height = info->pass->fbo.abs_y; break; case RARCH_SCALE_INPUT: - out_height = info.pass->fbo.scale_y * height; + out_height = info->pass->fbo.scale_y * height; break; } } -void RenderChain::blit_to_texture(const void *frame, +void renderchain_blit_to_texture(void *data, const void *frame, unsigned width, unsigned height, unsigned pitch) { - Pass &first = passes[0]; + renderchain_t *chain = (renderchain_t*)data; + Pass &first = chain->passes[0]; if (first.last_width != width || first.last_height != height) - clear_texture(first); + renderchain_clear_texture(chain, first); D3DLOCKED_RECT d3dlr; if (SUCCEEDED(first.tex->LockRect(0, &d3dlr, NULL, D3DLOCK_NOSYSLOCK))) @@ -512,17 +538,18 @@ void RenderChain::blit_to_texture(const void *frame, { const uint8_t *in = reinterpret_cast(frame) + y * pitch; uint8_t *out = reinterpret_cast(d3dlr.pBits) + y * d3dlr.Pitch; - memcpy(out, in, width * pixel_size); + memcpy(out, in, width * chain->pixel_size); } first.tex->UnlockRect(0); } } -void RenderChain::render_pass(Pass &pass, unsigned pass_index) +void renderchain_render_pass(void *data, Pass &pass, unsigned pass_index) { - LPDIRECT3DDEVICE d3dr = dev; - set_shaders(pass.fPrg, pass.vPrg); + renderchain_t *chain = (renderchain_t*)data; + LPDIRECT3DDEVICE d3dr = (LPDIRECT3DDEVICE)chain->dev; + renderchain_set_shaders(chain, pass.fPrg, pass.vPrg); d3dr->SetTexture(0, pass.tex); d3dr->SetSamplerState(0, D3DSAMP_MINFILTER, translate_filter(pass.info.pass->filter)); @@ -533,11 +560,11 @@ void RenderChain::render_pass(Pass &pass, unsigned pass_index) for (unsigned i = 0; i < 4; i++) d3dr->SetStreamSource(i, pass.vertex_buf, 0, sizeof(Vertex)); - bind_orig(pass); - bind_prev(pass); - bind_pass(pass, pass_index); - bind_luts(pass); - bind_tracker(pass, pass_index); + renderchain_bind_orig(chain, pass); + renderchain_bind_prev(chain, pass); + renderchain_bind_pass(chain, pass, pass_index); + renderchain_bind_luts(chain, pass); + renderchain_bind_tracker(chain, pass, pass_index); if (SUCCEEDED(d3dr->BeginScene())) { @@ -552,67 +579,68 @@ void RenderChain::render_pass(Pass &pass, unsigned pass_index) d3dr->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); - unbind_all(); + renderchain_unbind_all(chain); } -void RenderChain::log_info(const LinkInfo &info) +void renderchain_log_info(void *data, const LinkInfo *info) { RARCH_LOG("[D3D]: Render pass info:\n"); - RARCH_LOG("\tTexture width: %u\n", info.tex_w); - RARCH_LOG("\tTexture height: %u\n", info.tex_h); + RARCH_LOG("\tTexture width: %u\n", info->tex_w); + RARCH_LOG("\tTexture height: %u\n", info->tex_h); RARCH_LOG("\tScale type (X): "); - switch (info.pass->fbo.type_x) + switch (info->pass->fbo.type_x) { case RARCH_SCALE_INPUT: - RARCH_LOG("Relative @ %fx\n", info.pass->fbo.scale_x); + RARCH_LOG("Relative @ %fx\n", info->pass->fbo.scale_x); break; case RARCH_SCALE_VIEWPORT: - RARCH_LOG("Viewport @ %fx\n", info.pass->fbo.scale_x); + RARCH_LOG("Viewport @ %fx\n", info->pass->fbo.scale_x); break; case RARCH_SCALE_ABSOLUTE: - RARCH_LOG("Absolute @ %u px\n", info.pass->fbo.abs_x); + RARCH_LOG("Absolute @ %u px\n", info->pass->fbo.abs_x); break; } RARCH_LOG("\tScale type (Y): "); - switch (info.pass->fbo.type_y) + switch (info->pass->fbo.type_y) { case RARCH_SCALE_INPUT: - RARCH_LOG("Relative @ %fx\n", info.pass->fbo.scale_y); + RARCH_LOG("Relative @ %fx\n", info->pass->fbo.scale_y); break; case RARCH_SCALE_VIEWPORT: - RARCH_LOG("Viewport @ %fx\n", info.pass->fbo.scale_y); + RARCH_LOG("Viewport @ %fx\n", info->pass->fbo.scale_y); break; case RARCH_SCALE_ABSOLUTE: - RARCH_LOG("Absolute @ %u px\n", info.pass->fbo.abs_y); + RARCH_LOG("Absolute @ %u px\n", info->pass->fbo.abs_y); break; } - RARCH_LOG("\tBilinear filter: %s\n", info.pass->filter == RARCH_FILTER_LINEAR ? "true" : "false"); + RARCH_LOG("\tBilinear filter: %s\n", info->pass->filter == RARCH_FILTER_LINEAR ? "true" : "false"); } -void RenderChain::unbind_all() +void renderchain_unbind_all(void *data) { - LPDIRECT3DDEVICE d3dr = dev; + renderchain_t *chain = (renderchain_t*)data; + LPDIRECT3DDEVICE d3dr = chain->dev; // Have to be a bit anal about it. // Render targets hate it when they have filters apparently. - for (unsigned i = 0; i < bound_tex.size(); i++) + for (unsigned i = 0; i < chain->bound_tex.size(); i++) { - d3dr->SetSamplerState(bound_tex[i], D3DSAMP_MAGFILTER, + d3dr->SetSamplerState(chain->bound_tex[i], D3DSAMP_MAGFILTER, D3DTEXF_POINT); - d3dr->SetSamplerState(bound_tex[i], D3DSAMP_MINFILTER, + d3dr->SetSamplerState(chain->bound_tex[i], D3DSAMP_MINFILTER, D3DTEXF_POINT); - d3dr->SetTexture(bound_tex[i], NULL); + d3dr->SetTexture(chain->bound_tex[i], NULL); } - for (unsigned i = 0; i < bound_vert.size(); i++) - d3dr->SetStreamSource(bound_vert[i], 0, 0, 0); + for (unsigned i = 0; i < chain->bound_vert.size(); i++) + d3dr->SetStreamSource(chain->bound_vert[i], 0, 0, 0); - bound_tex.clear(); - bound_vert.clear(); + chain->bound_tex.clear(); + chain->bound_vert.clear(); } \ No newline at end of file diff --git a/gfx/d3d9/render_chain.hpp b/gfx/d3d9/render_chain.hpp index 94702a287c..bd4d5fdfef 100644 --- a/gfx/d3d9/render_chain.hpp +++ b/gfx/d3d9/render_chain.hpp @@ -36,21 +36,135 @@ struct LinkInfo struct gfx_shader_pass *pass; }; +enum PixelFormat +{ + RGB565 = 0, + ARGB +}; + +#define MAX_VARIABLES 64 + +enum +{ + TEXTURES = 8, + TEXTURESMASK = TEXTURES - 1 +}; + +struct Pass +{ + LinkInfo info; + LPDIRECT3DTEXTURE tex; + LPDIRECT3DVERTEXBUFFER vertex_buf; +#ifdef HAVE_CG + CGprogram vPrg, fPrg; +#endif + unsigned last_width, last_height; +#ifdef HAVE_D3D9 + LPDIRECT3DVERTEXDECLARATION vertex_decl; +#endif + std::vector attrib_map; +}; + +struct lut_info +{ + LPDIRECT3DTEXTURE tex; + std::string id; + bool smooth; +}; + +typedef struct renderchain +{ + LPDIRECT3DDEVICE dev; +#ifdef HAVE_CG + CGcontext cgCtx; +#endif + unsigned pixel_size; + const video_info_t *video_info; + state_tracker_t *tracker; + struct state_tracker_uniform uniform_info[MAX_VARIABLES]; + unsigned uniform_cnt; + struct + { + LPDIRECT3DTEXTURE tex[TEXTURES]; + LPDIRECT3DVERTEXBUFFER vertex_buf[TEXTURES]; + unsigned ptr; + unsigned last_width[TEXTURES]; + unsigned last_height[TEXTURES]; + } prev; + std::vector passes; +#ifdef HAVE_CG + CGprogram vStock, fStock; +#endif + std::vector luts; + D3DVIEWPORT *final_viewport; + unsigned frame_count; + std::vector bound_tex; + std::vector bound_vert; +} renderchain_t; + +void renderchain_free(void *data); +bool renderchain_init(void *data, const video_info_t *video_info, + LPDIRECT3DDEVICE dev_, + CGcontext cgCtx_, + const D3DVIEWPORT *final_viewport_, + const LinkInfo *info, + PixelFormat fmt); +void renderchain_clear(void *data); +void renderchain_set_final_viewport(void *data, const D3DVIEWPORT *final_viewport); +bool renderchain_set_pass_size(void *data, unsigned pass_index, unsigned width, unsigned height); +bool renderchain_add_pass(void *data, const LinkInfo *info); +bool renderchain_add_lut(void *data, const std::string &id, + const std::string &path, + bool smooth); +void renderchain_add_state_tracker(void *data, state_tracker_t *tracker); +void renderchain_start_render(void *data); +void renderchain_end_render(void *data); +bool renderchain_render(void *chain_data, const void *data, + unsigned width, unsigned height, unsigned pitch, unsigned rotation); +D3DTEXTUREFILTERTYPE renderchain_translate_filter(enum gfx_filter_type type); +D3DTEXTUREFILTERTYPE renderchain_translate_filter(bool smooth); +bool renderchain_create_first_pass(void *data, const LinkInfo *info, PixelFormat fmt); +void renderchain_set_vertices(void *data, Pass &pass, + unsigned width, unsigned height, + unsigned out_width, unsigned out_height, + unsigned vp_width, unsigned vp_height, + unsigned rotation); +void renderchain_set_viewport(void *data, D3DVIEWPORT *vp); +void renderchain_set_mvp(void *data, CGprogram &vPrg, + unsigned vp_width, unsigned vp_height, + unsigned rotation); +void renderchain_clear_texture(void *data, Pass &pass); +void renderchain_convert_geometry(void *data, const LinkInfo *info, + unsigned &out_width, unsigned &out_height, + unsigned width, unsigned height, + D3DVIEWPORT *final_viewport); +void renderchain_blit_to_texture(void *data, const void *frame, + unsigned width, unsigned height, + unsigned pitch); +void renderchain_render_pass(void *data, Pass &pass, unsigned pass_index); +void renderchain_log_info(void *data, const LinkInfo *info); +void renderchain_unbind_all(void *data); + +bool renderchain_compile_shaders(void *data, CGprogram &fPrg, CGprogram &vPrg, const std::string &shader); +void renderchain_set_shaders(void *data, CGprogram &fPrg, CGprogram &vPrg); +void renderchain_destroy_stock_shader(void *data); +void renderchain_destroy_shader(void *data, int i); +void renderchain_set_shader_mvp(void *data, CGprogram &vPrg, D3DXMATRIX &tmp); +void renderchain_set_shader_params(void *data, Pass &pass, + unsigned video_w, unsigned video_h, + unsigned tex_w, unsigned tex_h, + unsigned viewport_w, unsigned viewport_h); +void renderchain_bind_tracker(void *data, Pass &pass, unsigned pass_index); +bool renderchain_init_shader_fvf(void *data, Pass &pass); +void renderchain_bind_orig(void *data, Pass &pass); +void renderchain_bind_prev(void *data, Pass &pass); +void renderchain_bind_luts(void *data, Pass &pass); +void renderchain_bind_pass(void *data, Pass &pass, unsigned pass_index); + +#if 0 class RenderChain { public: - enum PixelFormat { RGB565, ARGB }; - - RenderChain(const video_info_t *video_info, - LPDIRECT3DDEVICE dev, -#ifdef HAVE_CG - CGcontext cgCtx, -#endif - const D3DVIEWPORT &final_viewport); - ~RenderChain(); - - bool init(const LinkInfo &info, PixelFormat fmt); - bool set_pass_size(unsigned pass, unsigned width, unsigned height); void set_final_viewport(const D3DVIEWPORT &final_viewport); bool add_pass(const LinkInfo &info); @@ -68,62 +182,6 @@ class RenderChain void clear(); private: - - LPDIRECT3DDEVICE dev; -#ifdef HAVE_CG - CGcontext cgCtx; -#endif - unsigned pixel_size; - - const video_info_t &video_info; - -#define MAX_VARIABLES 64 - state_tracker_t *tracker; - struct state_tracker_uniform uniform_info[MAX_VARIABLES]; - unsigned uniform_cnt; - - enum { Textures = 8, TexturesMask = Textures - 1 }; - struct - { - LPDIRECT3DTEXTURE tex[Textures]; - LPDIRECT3DVERTEXBUFFER vertex_buf[Textures]; - unsigned ptr; - unsigned last_width[Textures]; - unsigned last_height[Textures]; - } prev; - - struct Pass - { - LinkInfo info; - LPDIRECT3DTEXTURE tex; - LPDIRECT3DVERTEXBUFFER vertex_buf; -#ifdef HAVE_CG - CGprogram vPrg, fPrg; -#endif - unsigned last_width, last_height; - -#ifdef HAVE_D3D9 - LPDIRECT3DVERTEXDECLARATION vertex_decl; -#endif - std::vector attrib_map; - }; - std::vector passes; - -#ifdef HAVE_CG - CGprogram vStock, fStock; -#endif - - struct lut_info - { - LPDIRECT3DTEXTURE tex; - std::string id; - bool smooth; - }; - std::vector luts; - - D3DVIEWPORT final_viewport; - unsigned frame_count; - bool create_first_pass(const LinkInfo &info, PixelFormat fmt); #if defined(HAVE_CG) bool compile_shaders(CGprogram &fPrg, CGprogram &vPrg, const std::string &shader); @@ -167,12 +225,10 @@ class RenderChain void start_render(); void end_render(); - - std::vector bound_tex; - std::vector bound_vert; void unbind_all(); }; +#endif #endif diff --git a/gfx/d3d9/render_chain_cg.h b/gfx/d3d9/render_chain_cg.h index 8d9687f977..0a1113d834 100644 --- a/gfx/d3d9/render_chain_cg.h +++ b/gfx/d3d9/render_chain_cg.h @@ -77,8 +77,9 @@ static inline CGparameter find_param_from_semantic(CGprogram prog, const std::st return find_param_from_semantic(cgGetFirstParameter(prog, CG_PROGRAM), sem); } -bool RenderChain::compile_shaders(CGprogram &fPrg, CGprogram &vPrg, const std::string &shader) +bool renderchain_compile_shaders(void *data, CGprogram &fPrg, CGprogram &vPrg, const std::string &shader) { + renderchain_t *chain = (renderchain_t*)data; CGprofile vertex_profile = cgD3D9GetLatestVertexProfile(); CGprofile fragment_profile = cgD3D9GetLatestPixelProfile(); RARCH_LOG("[D3D Cg]: Vertex profile: %s\n", cgGetProfileString(vertex_profile)); @@ -89,33 +90,33 @@ bool RenderChain::compile_shaders(CGprogram &fPrg, CGprogram &vPrg, const std::s if (shader.length() > 0) { RARCH_LOG("[D3D Cg]: Compiling shader: %s.\n", shader.c_str()); - fPrg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, + fPrg = cgCreateProgramFromFile(chain->cgCtx, CG_SOURCE, shader.c_str(), fragment_profile, "main_fragment", fragment_opts); - if (cgGetLastListing(cgCtx)) - RARCH_ERR("[D3D Cg]: Fragment error:\n%s\n", cgGetLastListing(cgCtx)); + if (cgGetLastListing(chain->cgCtx)) + RARCH_ERR("[D3D Cg]: Fragment error:\n%s\n", cgGetLastListing(chain->cgCtx)); - vPrg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, + vPrg = cgCreateProgramFromFile(chain->cgCtx, CG_SOURCE, shader.c_str(), vertex_profile, "main_vertex", vertex_opts); - if (cgGetLastListing(cgCtx)) - RARCH_ERR("[D3D Cg]: Vertex error:\n%s\n", cgGetLastListing(cgCtx)); + if (cgGetLastListing(chain->cgCtx)) + RARCH_ERR("[D3D Cg]: Vertex error:\n%s\n", cgGetLastListing(chain->cgCtx)); } else { RARCH_LOG("[D3D Cg]: Compiling stock shader.\n"); - fPrg = cgCreateProgram(cgCtx, CG_SOURCE, stock_program, + fPrg = cgCreateProgram(chain->cgCtx, CG_SOURCE, stock_program, fragment_profile, "main_fragment", fragment_opts); - if (cgGetLastListing(cgCtx)) - RARCH_ERR("[D3D Cg]: Fragment error:\n%s\n", cgGetLastListing(cgCtx)); + if (cgGetLastListing(chain->cgCtx)) + RARCH_ERR("[D3D Cg]: Fragment error:\n%s\n", cgGetLastListing(chain->cgCtx)); - vPrg = cgCreateProgram(cgCtx, CG_SOURCE, stock_program, + vPrg = cgCreateProgram(chain->cgCtx, CG_SOURCE, stock_program, vertex_profile, "main_vertex", vertex_opts); - if (cgGetLastListing(cgCtx)) - RARCH_ERR("[D3D Cg]: Vertex error:\n%s\n", cgGetLastListing(cgCtx)); + if (cgGetLastListing(chain->cgCtx)) + RARCH_ERR("[D3D Cg]: Vertex error:\n%s\n", cgGetLastListing(chain->cgCtx)); } if (!fPrg || !vPrg) @@ -126,29 +127,31 @@ bool RenderChain::compile_shaders(CGprogram &fPrg, CGprogram &vPrg, const std::s return true; } -void RenderChain::set_shaders(CGprogram &fPrg, CGprogram &vPrg) +void renderchain_set_shaders(void *data, CGprogram &fPrg, CGprogram &vPrg) { cgD3D9BindProgram(fPrg); cgD3D9BindProgram(vPrg); } -void RenderChain::destroy_stock_shader(void) +void renderchain_destroy_stock_shader(void *data) { - if (fStock) - cgDestroyProgram(fStock); - if (vStock) - cgDestroyProgram(vStock); + renderchain_t *chain = (renderchain_t*)data; + if (chain->fStock) + cgDestroyProgram(chain->fStock); + if (chain->vStock) + cgDestroyProgram(chain->vStock); } -void RenderChain::destroy_shader(int i) +void renderchain_destroy_shader(void *data, int i) { - if (passes[i].fPrg) - cgDestroyProgram(passes[i].fPrg); - if (passes[i].vPrg) - cgDestroyProgram(passes[i].vPrg); + renderchain_t *chain = (renderchain_t*)data; + if (chain->passes[i].fPrg) + cgDestroyProgram(chain->passes[i].fPrg); + if (chain->passes[i].vPrg) + cgDestroyProgram(chain->passes[i].vPrg); } -void RenderChain::set_shader_mvp(CGprogram &vPrg, D3DXMATRIX &tmp) +void renderchain_set_shader_mvp(void *data, CGprogram &vPrg, D3DXMATRIX &tmp) { CGparameter cgpModelViewProj = cgGetNamedParameter(vPrg, "modelViewProj"); if (cgpModelViewProj) @@ -161,11 +164,12 @@ void RenderChain::set_shader_mvp(CGprogram &vPrg, D3DXMATRIX &tmp) cgD3D9SetUniform(cgp, &val); \ } while(0) -void RenderChain::set_shader_params(Pass &pass, +void renderchain_set_shader_params(void *data, Pass &pass, unsigned video_w, unsigned video_h, unsigned tex_w, unsigned tex_h, unsigned viewport_w, unsigned viewport_h) { + renderchain_t *chain = (renderchain_t*)data; D3DXVECTOR2 video_size, texture_size, output_size; video_size.x = video_w; video_size.y = video_h; @@ -181,26 +185,27 @@ void RenderChain::set_shader_params(Pass &pass, set_cg_param(pass.vPrg, "IN.output_size", output_size); set_cg_param(pass.fPrg, "IN.output_size", output_size); - float frame_cnt = frame_count; + float frame_cnt = chain->frame_count; if (pass.info.pass->frame_count_mod) - frame_cnt = frame_count % pass.info.pass->frame_count_mod; + frame_cnt = chain->frame_count % pass.info.pass->frame_count_mod; set_cg_param(pass.fPrg, "IN.frame_count", frame_cnt); set_cg_param(pass.vPrg, "IN.frame_count", frame_cnt); } -void RenderChain::bind_tracker(Pass &pass, unsigned pass_index) +void renderchain_bind_tracker(void *data, Pass &pass, unsigned pass_index) { - if (!tracker) + renderchain_t *chain = (renderchain_t*)data; + if (!chain->tracker) return; if (pass_index == 1) - uniform_cnt = state_get_uniform(tracker, uniform_info, MAX_VARIABLES, frame_count); + chain->uniform_cnt = state_get_uniform(chain->tracker, chain->uniform_info, MAX_VARIABLES, chain->frame_count); - for (unsigned i = 0; i < uniform_cnt; i++) + for (unsigned i = 0; i < chain->uniform_cnt; i++) { - set_cg_param(pass.fPrg, uniform_info[i].id, uniform_info[i].value); - set_cg_param(pass.vPrg, uniform_info[i].id, uniform_info[i].value); + set_cg_param(pass.fPrg, chain->uniform_info[i].id, chain->uniform_info[i].value); + set_cg_param(pass.vPrg, chain->uniform_info[i].id, chain->uniform_info[i].value); } } @@ -215,8 +220,9 @@ void RenderChain::bind_tracker(Pass &pass, unsigned pass_index) D3DDECLUSAGE_COLOR, (BYTE)(index) } \ -bool RenderChain::init_shader_fvf(Pass &pass) +bool renderchain_init_shader_fvf(void *data, Pass &pass) { + renderchain_t *chain = (renderchain_t*)data; static const D3DVERTEXELEMENT decl_end = D3DDECL_END(); static const D3DVERTEXELEMENT position_decl = DECL_FVF_POSITION(0); static const D3DVERTEXELEMENT tex_coord0 = DECL_FVF_TEXCOORD(1, 3, 0); @@ -330,19 +336,20 @@ bool RenderChain::init_shader_fvf(Pass &pass) } } - if (FAILED(dev->CreateVertexDeclaration(decl, &pass.vertex_decl))) + if (FAILED(chain->dev->CreateVertexDeclaration(decl, &pass.vertex_decl))) return false; return true; } -void RenderChain::bind_orig(Pass &pass) +void renderchain_bind_orig(void *data, Pass &pass) { + renderchain_t *chain = (renderchain_t*)data; D3DXVECTOR2 video_size, texture_size; - video_size.x = passes[0].last_width; - video_size.y = passes[0].last_height; - texture_size.x = passes[0].info.tex_w; - texture_size.y = passes[0].info.tex_h; + video_size.x = chain->passes[0].last_width; + video_size.y = chain->passes[0].last_height; + texture_size.x = chain->passes[0].info.tex_w; + texture_size.y = chain->passes[0].info.tex_h; set_cg_param(pass.vPrg, "ORIG.video_size", video_size); set_cg_param(pass.fPrg, "ORIG.video_size", video_size); @@ -353,27 +360,28 @@ void RenderChain::bind_orig(Pass &pass) if (param) { unsigned index = cgGetParameterResourceIndex(param); - dev->SetTexture(index, passes[0].tex); - dev->SetSamplerState(index, D3DSAMP_MAGFILTER, - translate_filter(passes[0].info.pass->filter)); - dev->SetSamplerState(index, D3DSAMP_MINFILTER, - translate_filter(passes[0].info.pass->filter)); - dev->SetSamplerState(index, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); - dev->SetSamplerState(index, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); - bound_tex.push_back(index); + chain->dev->SetTexture(index, chain->passes[0].tex); + chain->dev->SetSamplerState(index, D3DSAMP_MAGFILTER, + translate_filter(chain->passes[0].info.pass->filter)); + chain->dev->SetSamplerState(index, D3DSAMP_MINFILTER, + translate_filter(chain->passes[0].info.pass->filter)); + chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); + chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); + chain->bound_tex.push_back(index); } param = cgGetNamedParameter(pass.vPrg, "ORIG.tex_coord"); if (param) { unsigned index = pass.attrib_map[cgGetParameterResourceIndex(param)]; - dev->SetStreamSource(index, passes[0].vertex_buf, 0, sizeof(Vertex)); - bound_vert.push_back(index); + chain->dev->SetStreamSource(index, chain->passes[0].vertex_buf, 0, sizeof(Vertex)); + chain->bound_vert.push_back(index); } } -void RenderChain::bind_prev(Pass &pass) +void renderchain_bind_prev(void *data, Pass &pass) { + renderchain_t *chain = (renderchain_t*)data; static const char *prev_names[] = { "PREV", "PREV1", @@ -387,10 +395,10 @@ void RenderChain::bind_prev(Pass &pass) char attr_texture[64], attr_input_size[64], attr_tex_size[64], attr_coord[64]; D3DXVECTOR2 texture_size; - texture_size.x = passes[0].info.tex_w; - texture_size.y = passes[0].info.tex_h; + texture_size.x = chain->passes[0].info.tex_w; + texture_size.y = chain->passes[0].info.tex_h; - for (unsigned i = 0; i < Textures - 1; i++) + for (unsigned i = 0; i < TEXTURES - 1; i++) { snprintf(attr_texture, sizeof(attr_texture), "%s.texture", prev_names[i]); snprintf(attr_input_size, sizeof(attr_input_size), "%s.video_size", prev_names[i]); @@ -398,8 +406,8 @@ void RenderChain::bind_prev(Pass &pass) snprintf(attr_coord, sizeof(attr_coord), "%s.tex_coord", prev_names[i]); D3DXVECTOR2 video_size; - video_size.x = prev.last_width[(prev.ptr - (i + 1)) & TexturesMask]; - video_size.y = prev.last_height[(prev.ptr - (i + 1)) & TexturesMask]; + video_size.x = chain->prev.last_width[(chain->prev.ptr - (i + 1)) & TEXTURESMASK]; + video_size.y = chain->prev.last_height[(chain->prev.ptr - (i + 1)) & TEXTURESMASK]; set_cg_param(pass.vPrg, attr_input_size, video_size); set_cg_param(pass.fPrg, attr_input_size, video_size); @@ -411,71 +419,73 @@ void RenderChain::bind_prev(Pass &pass) { unsigned index = cgGetParameterResourceIndex(param); - LPDIRECT3DTEXTURE tex = prev.tex[(prev.ptr - (i + 1)) & TexturesMask]; - dev->SetTexture(index, tex); - bound_tex.push_back(index); + LPDIRECT3DTEXTURE tex = chain->prev.tex[(chain->prev.ptr - (i + 1)) & TEXTURESMASK]; + chain->dev->SetTexture(index, tex); + chain->bound_tex.push_back(index); - dev->SetSamplerState(index, D3DSAMP_MAGFILTER, - translate_filter(passes[0].info.pass->filter)); - dev->SetSamplerState(index, D3DSAMP_MINFILTER, - translate_filter(passes[0].info.pass->filter)); - dev->SetSamplerState(index, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); - dev->SetSamplerState(index, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); + chain->dev->SetSamplerState(index, D3DSAMP_MAGFILTER, + translate_filter(chain->passes[0].info.pass->filter)); + chain->dev->SetSamplerState(index, D3DSAMP_MINFILTER, + translate_filter(chain->passes[0].info.pass->filter)); + chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); + chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); } param = cgGetNamedParameter(pass.vPrg, attr_coord); if (param) { unsigned index = pass.attrib_map[cgGetParameterResourceIndex(param)]; - LPDIRECT3DVERTEXBUFFER vert_buf = prev.vertex_buf[(prev.ptr - (i + 1)) & TexturesMask]; - bound_vert.push_back(index); + LPDIRECT3DVERTEXBUFFER vert_buf = chain->prev.vertex_buf[(chain->prev.ptr - (i + 1)) & TEXTURESMASK]; + chain->bound_vert.push_back(index); - dev->SetStreamSource(index, vert_buf, 0, sizeof(Vertex)); + chain->dev->SetStreamSource(index, vert_buf, 0, sizeof(Vertex)); } } } -void RenderChain::bind_luts(Pass &pass) +void renderchain_bind_luts(void *data, Pass &pass) { - for (unsigned i = 0; i < luts.size(); i++) + renderchain_t *chain = (renderchain_t*)data; + for (unsigned i = 0; i < chain->luts.size(); i++) { - CGparameter fparam = cgGetNamedParameter(pass.fPrg, luts[i].id.c_str()); + CGparameter fparam = cgGetNamedParameter(pass.fPrg, chain->luts[i].id.c_str()); int bound_index = -1; if (fparam) { unsigned index = cgGetParameterResourceIndex(fparam); bound_index = index; - dev->SetTexture(index, luts[i].tex); - dev->SetSamplerState(index, D3DSAMP_MAGFILTER, - translate_filter(luts[i].smooth)); - dev->SetSamplerState(index, D3DSAMP_MINFILTER, - translate_filter(luts[i].smooth)); - dev->SetSamplerState(index, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); - dev->SetSamplerState(index, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); - bound_tex.push_back(index); + chain->dev->SetTexture(index, chain->luts[i].tex); + chain->dev->SetSamplerState(index, D3DSAMP_MAGFILTER, + translate_filter(chain->luts[i].smooth)); + chain->dev->SetSamplerState(index, D3DSAMP_MINFILTER, + translate_filter(chain->luts[i].smooth)); + chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); + chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); + chain->bound_tex.push_back(index); } - CGparameter vparam = cgGetNamedParameter(pass.vPrg, luts[i].id.c_str()); + CGparameter vparam = cgGetNamedParameter(pass.vPrg, chain->luts[i].id.c_str()); if (vparam) { unsigned index = cgGetParameterResourceIndex(vparam); if (index != (unsigned)bound_index) { - dev->SetTexture(index, luts[i].tex); - dev->SetSamplerState(index, D3DSAMP_MAGFILTER, - translate_filter(luts[i].smooth)); - dev->SetSamplerState(index, D3DSAMP_MINFILTER, - translate_filter(luts[i].smooth)); - dev->SetSamplerState(index, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); - dev->SetSamplerState(index, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); - bound_tex.push_back(index); + chain->dev->SetTexture(index, chain->luts[i].tex); + chain->dev->SetSamplerState(index, D3DSAMP_MAGFILTER, + translate_filter(chain->luts[i].smooth)); + chain->dev->SetSamplerState(index, D3DSAMP_MINFILTER, + translate_filter(chain->luts[i].smooth)); + chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); + chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); + chain->bound_tex.push_back(index); } } } } -void RenderChain::bind_pass(Pass &pass, unsigned pass_index) +void renderchain_bind_pass(void *data, Pass &pass, unsigned pass_index) { + renderchain_t *chain = (renderchain_t*)data; // We only bother binding passes which are two indices behind. if (pass_index < 3) return; @@ -495,10 +505,10 @@ void RenderChain::bind_pass(Pass &pass, unsigned pass_index) attr_tex_coord += "tex_coord"; D3DXVECTOR2 video_size, texture_size; - video_size.x = passes[i].last_width; - video_size.y = passes[i].last_height; - texture_size.x = passes[i].info.tex_w; - texture_size.y = passes[i].info.tex_h; + video_size.x = chain->passes[i].last_width; + video_size.y = chain->passes[i].last_height; + texture_size.x = chain->passes[i].info.tex_w; + texture_size.y = chain->passes[i].info.tex_h; set_cg_param(pass.vPrg, attr_video_size.c_str(), video_size); set_cg_param(pass.fPrg, attr_video_size.c_str(), video_size); @@ -509,23 +519,23 @@ void RenderChain::bind_pass(Pass &pass, unsigned pass_index) if (param) { unsigned index = cgGetParameterResourceIndex(param); - bound_tex.push_back(index); + chain->bound_tex.push_back(index); - dev->SetTexture(index, passes[i].tex); - dev->SetSamplerState(index, D3DSAMP_MAGFILTER, - translate_filter(passes[i].info.pass->filter)); - dev->SetSamplerState(index, D3DSAMP_MINFILTER, - translate_filter(passes[i].info.pass->filter)); - dev->SetSamplerState(index, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); - dev->SetSamplerState(index, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); + chain->dev->SetTexture(index, chain->passes[i].tex); + chain->dev->SetSamplerState(index, D3DSAMP_MAGFILTER, + translate_filter(chain->passes[i].info.pass->filter)); + chain->dev->SetSamplerState(index, D3DSAMP_MINFILTER, + translate_filter(chain->passes[i].info.pass->filter)); + chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); + chain->dev->SetSamplerState(index, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); } param = cgGetNamedParameter(pass.vPrg, attr_tex_coord.c_str()); if (param) { unsigned index = pass.attrib_map[cgGetParameterResourceIndex(param)]; - dev->SetStreamSource(index, passes[i].vertex_buf, 0, sizeof(Vertex)); - bound_vert.push_back(index); + chain->dev->SetStreamSource(index, chain->passes[i].vertex_buf, 0, sizeof(Vertex)); + chain->bound_vert.push_back(index); } } }