/* * Copyright (C) 2007-2009 Gabest * http://www.gabest.org * * This Program 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 Foundation; either version 2, or (at your option) * any later version. * * This Program 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 GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA. * http://www.gnu.org/copyleft/gpl.html * */ #include "stdafx.h" #include "GSdx.h" #include "GSDeviceDX.h" #include HMODULE GSDeviceDX::s_d3d_compiler_dll = nullptr; decltype(&D3DCompile) GSDeviceDX::s_pD3DCompile = nullptr; bool GSDeviceDX::s_old_d3d_compiler_dll; GSDeviceDX::GSDeviceDX() { m_upscale_multiplier = theApp.GetConfigI("upscale_multiplier"); m_msaa = theApp.GetConfigB("UserHacks") ? theApp.GetConfigI("UserHacks_MSAA") : 0; m_msaa_desc.Count = 1; m_msaa_desc.Quality = 0; } GSDeviceDX::~GSDeviceDX() { } bool GSDeviceDX::LoadD3DCompiler() { // Windows 8.1 and later come with the latest d3dcompiler_47.dll, but // Windows 7 devs might also have the dll available for use (which will // have to be placed in the application directory) s_d3d_compiler_dll = LoadLibraryEx(D3DCOMPILER_DLL, nullptr, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32); // Windows Vista and 7 can use the older version. If the previous LoadLibrary // call fails on Windows 8.1 and later, then the user's system is likely // broken. if (s_d3d_compiler_dll) { s_old_d3d_compiler_dll = false; } else { if (!IsWindows8Point1OrGreater()) // Use LoadLibrary instead of LoadLibraryEx, some Windows 7 systems // have issues with it. s_d3d_compiler_dll = LoadLibrary("D3DCompiler_43.dll"); if (s_d3d_compiler_dll == nullptr) return false; s_old_d3d_compiler_dll = true; } s_pD3DCompile = reinterpret_cast(GetProcAddress(s_d3d_compiler_dll, "D3DCompile")); if (s_pD3DCompile) return true; FreeLibrary(s_d3d_compiler_dll); s_d3d_compiler_dll = nullptr; return false; } void GSDeviceDX::FreeD3DCompiler() { s_pD3DCompile = nullptr; if (s_d3d_compiler_dll) FreeLibrary(s_d3d_compiler_dll); s_d3d_compiler_dll = nullptr; } GSTexture* GSDeviceDX::FetchSurface(int type, int w, int h, bool msaa, int format) { if(m_msaa < 2) { msaa = false; } return __super::FetchSurface(type, w, h, msaa, format); } bool GSDeviceDX::SetFeatureLevel(D3D_FEATURE_LEVEL level, bool compat_mode) { m_shader.level = level; switch(level) { case D3D_FEATURE_LEVEL_10_0: m_shader.model = "0x400"; m_shader.vs = "vs_4_0"; m_shader.gs = "gs_4_0"; m_shader.ps = "ps_4_0"; m_shader.cs = "cs_4_0"; break; case D3D_FEATURE_LEVEL_10_1: m_shader.model = "0x401"; m_shader.vs = "vs_4_1"; m_shader.gs = "gs_4_1"; m_shader.ps = "ps_4_1"; m_shader.cs = "cs_4_1"; break; case D3D_FEATURE_LEVEL_11_0: m_shader.model = "0x500"; m_shader.vs = "vs_5_0"; m_shader.gs = "gs_5_0"; m_shader.ps = "ps_5_0"; m_shader.cs = "cs_5_0"; break; default: ASSERT(0); return false; } return true; } // (A - B) * C + D // A: Cs/Cd/0 // B: Cs/Cd/0 // C: As/Ad/FIX // D: Cs/Cd/0 // bogus: 0100, 0110, 0120, 0200, 0210, 0220, 1001, 1011, 1021 // tricky: 1201, 1211, 1221 // Source.rgb = float3(1, 1, 1); // 1201 Cd*(1 + As) => Source * Dest color + Dest * Source alpha // 1211 Cd*(1 + Ad) => Source * Dest color + Dest * Dest alpha // 1221 Cd*(1 + F) => Source * Dest color + Dest * Factor // Special blending method table: // # (tricky) => 1 * Cd + Cd * F => Use (Cd, F) as factor of color (1, Cd) // * (bogus) => C * (1 + F ) + ... => factor is always bigger than 1 (except above case) const GSDeviceDX::D3D11Blend GSDeviceDX::m_blendMapD3D11[3*3*3*3] = { {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO} , // 0000: (Cs - Cs)*As + Cs ==> Cs {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ONE} , // 0001: (Cs - Cs)*As + Cd ==> Cd {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ZERO} , // 0002: (Cs - Cs)*As + 0 ==> 0 {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO} , // 0010: (Cs - Cs)*Ad + Cs ==> Cs {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ONE} , // 0011: (Cs - Cs)*Ad + Cd ==> Cd {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ZERO} , // 0012: (Cs - Cs)*Ad + 0 ==> 0 {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO} , // 0020: (Cs - Cs)*F + Cs ==> Cs {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ONE} , // 0021: (Cs - Cs)*F + Cd ==> Cd {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ZERO} , // 0022: (Cs - Cs)*F + 0 ==> 0 {1, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_ONE , D3D11_BLEND_SRC_ALPHA} , //*0100: (Cs - Cd)*As + Cs ==> Cs*(As + 1) - Cd*As {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_SRC_ALPHA , D3D11_BLEND_INV_SRC_ALPHA} , // 0101: (Cs - Cd)*As + Cd ==> Cs*As + Cd*(1 - As) {0, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_SRC_ALPHA , D3D11_BLEND_SRC_ALPHA} , // 0102: (Cs - Cd)*As + 0 ==> Cs*As - Cd*As {1, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_ONE , D3D11_BLEND_DEST_ALPHA} , //*0110: (Cs - Cd)*Ad + Cs ==> Cs*(Ad + 1) - Cd*Ad {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_DEST_ALPHA , D3D11_BLEND_INV_DEST_ALPHA} , // 0111: (Cs - Cd)*Ad + Cd ==> Cs*Ad + Cd*(1 - Ad) {0, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_DEST_ALPHA , D3D11_BLEND_DEST_ALPHA} , // 0112: (Cs - Cd)*Ad + 0 ==> Cs*Ad - Cd*Ad {1, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_ONE , D3D11_BLEND_BLEND_FACTOR} , //*0120: (Cs - Cd)*F + Cs ==> Cs*(F + 1) - Cd*F {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_BLEND_FACTOR , D3D11_BLEND_INV_BLEND_FACTOR} , // 0121: (Cs - Cd)*F + Cd ==> Cs*F + Cd*(1 - F) {0, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_BLEND_FACTOR , D3D11_BLEND_BLEND_FACTOR} , // 0122: (Cs - Cd)*F + 0 ==> Cs*F - Cd*F {1, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO} , //*0200: (Cs - 0)*As + Cs ==> Cs*(As + 1) {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_SRC_ALPHA , D3D11_BLEND_ONE} , // 0201: (Cs - 0)*As + Cd ==> Cs*As + Cd {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_SRC_ALPHA , D3D11_BLEND_ZERO} , // 0202: (Cs - 0)*As + 0 ==> Cs*As {1, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO} , //*0210: (Cs - 0)*Ad + Cs ==> Cs*(Ad + 1) {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_DEST_ALPHA , D3D11_BLEND_ONE} , // 0211: (Cs - 0)*Ad + Cd ==> Cs*Ad + Cd {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_DEST_ALPHA , D3D11_BLEND_ZERO} , // 0212: (Cs - 0)*Ad + 0 ==> Cs*Ad {1, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO} , //*0220: (Cs - 0)*F + Cs ==> Cs*(F + 1) {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_BLEND_FACTOR , D3D11_BLEND_ONE} , // 0221: (Cs - 0)*F + Cd ==> Cs*F + Cd {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_BLEND_FACTOR , D3D11_BLEND_ZERO} , // 0222: (Cs - 0)*F + 0 ==> Cs*F {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_INV_SRC_ALPHA , D3D11_BLEND_SRC_ALPHA} , // 1000: (Cd - Cs)*As + Cs ==> Cd*As + Cs*(1 - As) {1, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_SRC_ALPHA , D3D11_BLEND_ONE} , //*1001: (Cd - Cs)*As + Cd ==> Cd*(As + 1) - Cs*As {0, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_SRC_ALPHA , D3D11_BLEND_SRC_ALPHA} , // 1002: (Cd - Cs)*As + 0 ==> Cd*As - Cs*As {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_INV_DEST_ALPHA , D3D11_BLEND_DEST_ALPHA} , // 1010: (Cd - Cs)*Ad + Cs ==> Cd*Ad + Cs*(1 - Ad) {1, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_DEST_ALPHA , D3D11_BLEND_ONE} , //*1011: (Cd - Cs)*Ad + Cd ==> Cd*(Ad + 1) - Cs*Ad {0, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_DEST_ALPHA , D3D11_BLEND_DEST_ALPHA} , // 1012: (Cd - Cs)*Ad + 0 ==> Cd*Ad - Cs*Ad {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_INV_BLEND_FACTOR , D3D11_BLEND_BLEND_FACTOR} , // 1020: (Cd - Cs)*F + Cs ==> Cd*F + Cs*(1 - F) {1, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_BLEND_FACTOR , D3D11_BLEND_ONE} , //*1021: (Cd - Cs)*F + Cd ==> Cd*(F + 1) - Cs*F {0, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_BLEND_FACTOR , D3D11_BLEND_BLEND_FACTOR} , // 1022: (Cd - Cs)*F + 0 ==> Cd*F - Cs*F {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO} , // 1100: (Cd - Cd)*As + Cs ==> Cs {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ONE} , // 1101: (Cd - Cd)*As + Cd ==> Cd {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ZERO} , // 1102: (Cd - Cd)*As + 0 ==> 0 {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO} , // 1110: (Cd - Cd)*Ad + Cs ==> Cs {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ONE} , // 1111: (Cd - Cd)*Ad + Cd ==> Cd {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ZERO} , // 1112: (Cd - Cd)*Ad + 0 ==> 0 {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO} , // 1120: (Cd - Cd)*F + Cs ==> Cs {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ONE} , // 1121: (Cd - Cd)*F + Cd ==> Cd {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ZERO} , // 1122: (Cd - Cd)*F + 0 ==> 0 {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_SRC_ALPHA} , // 1200: (Cd - 0)*As + Cs ==> Cs + Cd*As {2, D3D11_BLEND_OP_ADD , D3D11_BLEND_DEST_COLOR , D3D11_BLEND_SRC_ALPHA} , //#1201: (Cd - 0)*As + Cd ==> Cd*(1 + As) // ffxii main menu background glow effect {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_SRC_ALPHA} , // 1202: (Cd - 0)*As + 0 ==> Cd*As {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_DEST_ALPHA} , // 1210: (Cd - 0)*Ad + Cs ==> Cs + Cd*Ad {2, D3D11_BLEND_OP_ADD , D3D11_BLEND_DEST_COLOR , D3D11_BLEND_DEST_ALPHA} , //#1211: (Cd - 0)*Ad + Cd ==> Cd*(1 + Ad) {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_DEST_ALPHA} , // 1212: (Cd - 0)*Ad + 0 ==> Cd*Ad {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_BLEND_FACTOR} , // 1220: (Cd - 0)*F + Cs ==> Cs + Cd*F {2, D3D11_BLEND_OP_ADD , D3D11_BLEND_DEST_COLOR , D3D11_BLEND_BLEND_FACTOR} , //#1221: (Cd - 0)*F + Cd ==> Cd*(1 + F) {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_BLEND_FACTOR} , // 1222: (Cd - 0)*F + 0 ==> Cd*F {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_INV_SRC_ALPHA , D3D11_BLEND_ZERO} , // 2000: (0 - Cs)*As + Cs ==> Cs*(1 - As) {0, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_SRC_ALPHA , D3D11_BLEND_ONE} , // 2001: (0 - Cs)*As + Cd ==> Cd - Cs*As {0, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_SRC_ALPHA , D3D11_BLEND_ZERO} , // 2002: (0 - Cs)*As + 0 ==> 0 - Cs*As {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_INV_DEST_ALPHA , D3D11_BLEND_ZERO} , // 2010: (0 - Cs)*Ad + Cs ==> Cs*(1 - Ad) {0, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_DEST_ALPHA , D3D11_BLEND_ONE} , // 2011: (0 - Cs)*Ad + Cd ==> Cd - Cs*Ad {0, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_DEST_ALPHA , D3D11_BLEND_ZERO} , // 2012: (0 - Cs)*Ad + 0 ==> 0 - Cs*Ad {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_INV_BLEND_FACTOR , D3D11_BLEND_ZERO} , // 2020: (0 - Cs)*F + Cs ==> Cs*(1 - F) {0, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_BLEND_FACTOR , D3D11_BLEND_ONE} , // 2021: (0 - Cs)*F + Cd ==> Cd - Cs*F {0, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_BLEND_FACTOR , D3D11_BLEND_ZERO} , // 2022: (0 - Cs)*F + 0 ==> 0 - Cs*F {0, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_ONE , D3D11_BLEND_SRC_ALPHA} , // 2100: (0 - Cd)*As + Cs ==> Cs - Cd*As {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_INV_SRC_ALPHA} , // 2101: (0 - Cd)*As + Cd ==> Cd*(1 - As) {0, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_ZERO , D3D11_BLEND_SRC_ALPHA} , // 2102: (0 - Cd)*As + 0 ==> 0 - Cd*As {0, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_ONE , D3D11_BLEND_DEST_ALPHA} , // 2110: (0 - Cd)*Ad + Cs ==> Cs - Cd*Ad {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_INV_DEST_ALPHA} , // 2111: (0 - Cd)*Ad + Cd ==> Cd*(1 - Ad) {0, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_ONE , D3D11_BLEND_DEST_ALPHA} , // 2112: (0 - Cd)*Ad + 0 ==> 0 - Cd*Ad {0, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_ONE , D3D11_BLEND_BLEND_FACTOR} , // 2120: (0 - Cd)*F + Cs ==> Cs - Cd*F {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_INV_BLEND_FACTOR} , // 2121: (0 - Cd)*F + Cd ==> Cd*(1 - F) {0, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_ONE , D3D11_BLEND_BLEND_FACTOR} , // 2122: (0 - Cd)*F + 0 ==> 0 - Cd*F {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO} , // 2200: (0 - 0)*As + Cs ==> Cs {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ONE} , // 2201: (0 - 0)*As + Cd ==> Cd {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ZERO} , // 2202: (0 - 0)*As + 0 ==> 0 {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO} , // 2210: (0 - 0)*Ad + Cs ==> Cs {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ONE} , // 2211: (0 - 0)*Ad + Cd ==> Cd {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ZERO} , // 2212: (0 - 0)*Ad + 0 ==> 0 {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO} , // 2220: (0 - 0)*F + Cs ==> Cs {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ONE} , // 2221: (0 - 0)*F + Cd ==> Cd {0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ZERO} , // 2222: (0 - 0)*F + 0 ==> 0 };